From 28c5ed6882f9a587e0f48a08983bb1d07e22ee4e Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Tue, 19 Aug 2025 21:11:19 +0800 Subject: [PATCH 01/35] Changed: GitHub API check to check connection and rate limit separately --- baseunits/GitHubRepoV3.pas | 13 +++++++++++++ languages/fmd.de.po | 10 ++++++++-- languages/fmd.el_GR.po | 10 ++++++++-- languages/fmd.en.po | 14 ++++++++++++-- languages/fmd.es.po | 10 ++++++++-- languages/fmd.fr.po | 10 ++++++++-- languages/fmd.id_ID.po | 14 ++++++++++++-- languages/fmd.pl_PL.po | 10 ++++++++-- languages/fmd.pot | 10 ++++++++-- languages/fmd.pt_BR.po | 10 ++++++++-- languages/fmd.ru_RU.po | 10 ++++++++-- languages/fmd.tr_TR.po | 10 ++++++++-- languages/fmd.zh.po | 10 ++++++++-- mangadownloader/forms/frmLuaModulesUpdater.lfm | 4 ++-- mangadownloader/forms/frmLuaModulesUpdater.pas | 16 ++++++++++++++-- 15 files changed, 133 insertions(+), 28 deletions(-) diff --git a/baseunits/GitHubRepoV3.pas b/baseunits/GitHubRepoV3.pas index 297f9458e..32bf6b41b 100644 --- a/baseunits/GitHubRepoV3.pas +++ b/baseunits/GitHubRepoV3.pas @@ -47,6 +47,7 @@ TGitHubRepo = class function GetLastCommitMessage(const FRepoPath: String): String; function GetTree: Boolean; function GetUpdate: Boolean; + function CheckConnection: Boolean; function CheckRateLimited: Boolean; function GetDownloadURL(const AName: String): String; end; @@ -303,6 +304,18 @@ function TGitHubRepo.GetUpdate: Boolean; FDirty := Result; end; + +function TGitHubRepo.CheckConnection: Boolean; +begin + Result := False; + HTTP.ResetBasic; + + if HTTP.GET(api_url) then + begin + Result := True; + end; +end; + function TGitHubRepo.CheckRateLimited: Boolean; var s: String; diff --git a/languages/fmd.de.po b/languages/fmd.de.po index dfb3abeff..6eb98f3fe 100644 --- a/languages/fmd.de.po +++ b/languages/fmd.de.po @@ -187,14 +187,20 @@ msgstr "Herunterladen abschließen" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.el_GR.po b/languages/fmd.el_GR.po index 2284b3375..e6eb7a44a 100644 --- a/languages/fmd.el_GR.po +++ b/languages/fmd.el_GR.po @@ -187,14 +187,20 @@ msgstr "" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.en.po b/languages/fmd.en.po index 25ec36793..d965d6997 100644 --- a/languages/fmd.en.po +++ b/languages/fmd.en.po @@ -185,9 +185,13 @@ msgid "Finish download" msgstr "Finish download" #: frmluamodulesupdater.rs_githubconnectfail +#, fuzzy +#| msgid "" +#| "Failed to connect to GitHub API for latest module updates.\n" +#| "Please try again later." msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" "Failed to connect to GitHub API for latest module updates.\n" "Please try again later." @@ -196,6 +200,12 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "Connecting to GitHub..." +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.es.po b/languages/fmd.es.po index da933ab7f..af2a6a7af 100644 --- a/languages/fmd.es.po +++ b/languages/fmd.es.po @@ -187,14 +187,20 @@ msgstr "Descarga terminada" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.fr.po b/languages/fmd.fr.po index e9ea04c59..2ad8b24fa 100644 --- a/languages/fmd.fr.po +++ b/languages/fmd.fr.po @@ -187,14 +187,20 @@ msgstr "Finir le téléchargement" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.id_ID.po b/languages/fmd.id_ID.po index 075b0b71e..c69fc2142 100644 --- a/languages/fmd.id_ID.po +++ b/languages/fmd.id_ID.po @@ -189,9 +189,13 @@ msgid "Finish download" msgstr "Selesai mengunduh" #: frmluamodulesupdater.rs_githubconnectfail +#, fuzzy +#| msgid "" +#| "Failed to connect to GitHub API for latest module updates.\n" +#| "Please try again later." msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" "Gagal menyambung ke GitHub API untuk pemutakhiran modul terbaru.\n" "Silakan coba lagi nanti." @@ -200,6 +204,12 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "Menyambungkan GitHub..." +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.pl_PL.po b/languages/fmd.pl_PL.po index f4939f3a5..4da8d755b 100644 --- a/languages/fmd.pl_PL.po +++ b/languages/fmd.pl_PL.po @@ -184,14 +184,20 @@ msgstr "" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.pot b/languages/fmd.pot index 9c714856c..0f4fd3821 100644 --- a/languages/fmd.pot +++ b/languages/fmd.pot @@ -173,14 +173,20 @@ msgstr "" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.pt_BR.po b/languages/fmd.pt_BR.po index 2b35dbc5e..6052c356b 100644 --- a/languages/fmd.pt_BR.po +++ b/languages/fmd.pt_BR.po @@ -186,14 +186,20 @@ msgstr "Terminar donwload" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.ru_RU.po b/languages/fmd.ru_RU.po index b3fc8c677..978c7950f 100644 --- a/languages/fmd.ru_RU.po +++ b/languages/fmd.ru_RU.po @@ -186,14 +186,20 @@ msgstr "Скачано" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.tr_TR.po b/languages/fmd.tr_TR.po index e710d7e2d..7e007de98 100644 --- a/languages/fmd.tr_TR.po +++ b/languages/fmd.tr_TR.po @@ -188,14 +188,20 @@ msgstr "İndirmeyi durdur" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/languages/fmd.zh.po b/languages/fmd.zh.po index 4acd06feb..d8f152059 100644 --- a/languages/fmd.zh.po +++ b/languages/fmd.zh.po @@ -186,14 +186,20 @@ msgstr "下载完成" #: frmluamodulesupdater.rs_githubconnectfail msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Please try again later." +"Failed to connect to GitHub API.\n" +"Please check your internet connection or try again later." msgstr "" #: frmluamodulesupdater.rs_githubconnecting msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubratelimited +msgid "" +"Failed to connect to GitHub API for latest module updates.\n" +"Change the network or try again after 15 minutes" +msgstr "" + #: frmluamodulesupdater.rs_githubratestats #, object-pascal-format msgid "GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s" diff --git a/mangadownloader/forms/frmLuaModulesUpdater.lfm b/mangadownloader/forms/frmLuaModulesUpdater.lfm index 90397981d..67706b6bd 100644 --- a/mangadownloader/forms/frmLuaModulesUpdater.lfm +++ b/mangadownloader/forms/frmLuaModulesUpdater.lfm @@ -9,9 +9,9 @@ object LuaModulesUpdaterForm: TLuaModulesUpdaterForm ChildSizing.VerticalSpacing = 6 ClientHeight = 394 ClientWidth = 580 + LCLVersion = '4.0.0.2' OnCreate = FormCreate OnDestroy = FormDestroy - LCLVersion = '3.8.0.0' object vtLuaModulesRepos: TVirtualStringTree AnchorSideLeft.Control = Owner AnchorSideTop.Control = btCheckUpdate @@ -104,8 +104,8 @@ object LuaModulesUpdaterForm: TLuaModulesUpdaterForm FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 } - OnClick = btCheckUpdateClick TabOrder = 0 + OnClick = btCheckUpdateClick end object btCheckUpdateTerminate: TSpeedButton AnchorSideLeft.Control = btCheckUpdate diff --git a/mangadownloader/forms/frmLuaModulesUpdater.pas b/mangadownloader/forms/frmLuaModulesUpdater.pas index b7a6f5cb3..3c1f0ac59 100644 --- a/mangadownloader/forms/frmLuaModulesUpdater.pas +++ b/mangadownloader/forms/frmLuaModulesUpdater.pas @@ -137,6 +137,7 @@ TCheckUpdateThread = class(TStatusBarDownload) procedure SyncFinishDownload; procedure SyncFinal; procedure SyncGitHubConnectFail; + procedure SyncGitHubRateLimited; function SyncRepos(const ARepos, AReposUp: TLuaModulesRepos): Boolean; procedure Download; procedure DoSync; @@ -151,7 +152,8 @@ TCheckUpdateThread = class(TStatusBarDownload) LuaModulesUpdaterForm: TLuaModulesUpdaterForm; resourcestring - RS_GitHubConnectFail = 'Failed to connect to GitHub API for latest module updates.'#13#10'Please try again later.'; + RS_GitHubConnectFail = 'Failed to connect to GitHub API.'#13#10'Please check your internet connection or try again later.'; + RS_GitHubRateLimited = 'Failed to connect to GitHub API for latest module updates.'#13#10'Change the network or try again after 15 minutes'; RS_GitHubRateStats = 'GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s'; RS_CheckLocalModules = 'Checking local modules...'; RS_AwaitingProceed = 'Awaiting permission to proceed...'; @@ -584,6 +586,11 @@ procedure TCheckUpdateThread.SyncGitHubConnectFail; CenteredMessageDlg(MainForm, RS_GitHubConnectFail, mtError, [mbOk], 0); end; +procedure TCheckUpdateThread.SyncGitHubRateLimited; +begin + CenteredMessageDlg(MainForm, RS_GitHubRateLimited, mtError, [mbOk], 0); +end; + function TCheckUpdateThread.SyncRepos(const ARepos, AReposUp: TLuaModulesRepos): Boolean; var i, j, imax, jmax, k, inew, iupdate: Integer; @@ -777,11 +784,16 @@ procedure TCheckUpdateThread.DoSync; LoadingProgressBar; UpdateStatusText(RS_GitHubConnecting); - if FGitHubRepo.CheckRateLimited then + if not FGitHubRepo.CheckConnection then begin Synchronize(@SyncGitHubConnectFail); end; + if FGitHubRepo.CheckRateLimited then + begin + Synchronize(@SyncGitHubRateLimited); + end; + if FGitHubRepo.GetUpdate then begin FReposUp := TLuaModulesRepos.Create; From 572cbfbb185a407a2e3400bf7f02cbc7c706f480 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Sun, 14 Sep 2025 14:22:09 +0800 Subject: [PATCH 02/35] Fixed: ImageMagick not working with multiple formats Changed: Status bar to update more frequently for faster loading animation --- baseunits/StatusBarDownload.pas | 2 +- baseunits/uDownloadsManager.pas | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/baseunits/StatusBarDownload.pas b/baseunits/StatusBarDownload.pas index ab606d491..e0fc01f96 100644 --- a/baseunits/StatusBarDownload.pas +++ b/baseunits/StatusBarDownload.pas @@ -128,7 +128,7 @@ procedure TStatusBarDownload.SyncCreate; StatusBarResize(FStatusBar); FTimerRepaint := TTimer.Create(FStatusBar); - FTimerRepaint.Interval := 500; + FTimerRepaint.Interval := 100; FTimerRepaint.OnTimer := @TimerRepaintTimer; FTimerRepaint.Enabled := True; FNeedRepaint := True; diff --git a/baseunits/uDownloadsManager.pas b/baseunits/uDownloadsManager.pas index 51f520459..3d0f6086b 100644 --- a/baseunits/uDownloadsManager.pas +++ b/baseunits/uDownloadsManager.pas @@ -667,7 +667,7 @@ function TTaskThread.Convert: Boolean; end else begin - FilePath := AppendPathDelim(ExpandFileName(TempPath)) + '*' + ExtractFileExt(FilePath); + FilePath := AppendPathDelim(ExpandFileName(TempPath)) + '*'; end; Result := ImageMagick.ConvertImage(FilePath, CurrentWorkingDir); From 8a39e7deb43eed38c69864a6ef22c7052a57857e Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Wed, 8 Oct 2025 22:39:42 +0800 Subject: [PATCH 03/35] Fixed: Max filename path not accommodating extensions with 4 characters --- baseunits/uBaseUnit.pas | 6 +++--- baseunits/uDownloadsManager.pas | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/baseunits/uBaseUnit.pas b/baseunits/uBaseUnit.pas index f08207159..04b007a09 100644 --- a/baseunits/uBaseUnit.pas +++ b/baseunits/uBaseUnit.pas @@ -236,13 +236,13 @@ interface {$ifdef windows} // MAX_PATH = 260 // MAX_PATH - 12 - 1 - MAX_PATHDIR = 247; + MAX_PATHDIR = 246; // fmd max file extension = 4 // max path + file in windows explorer is 259 // = MAX_PATH - fmd max file extension - 1 // 1 is pahtdelim "/" - FMDMaxImageFilePath = 255; - // if directory length is max_pathdir, the remaining allowed filename is 7 + FMDMaxImageFilePath = 254; + // if directory length is MAX_PATHDIR, the remaining allowed filename is 7 // = 259 - fmd max file extension - 1 {$endif} diff --git a/baseunits/uDownloadsManager.pas b/baseunits/uDownloadsManager.pas index 3d0f6086b..77106692e 100644 --- a/baseunits/uDownloadsManager.pas +++ b/baseunits/uDownloadsManager.pas @@ -762,12 +762,18 @@ procedure TTaskThread.SetCurrentWorkingDir(AValue: String); begin if FCurrentWorkingDir = AValue then Exit; FCurrentWorkingDir := CorrectPathSys(AValue); + {$IFDEF Windows} s := UTF8Decode(FCurrentWorkingDir); + if MainForm.cbOptionEnableLongNamePaths.Checked then - FCurrentMaxFileNameLength := FMDMaxImageFilePath + Length(s) + begin + FCurrentMaxFileNameLength := FMDMaxImageFilePath + Length(s); + end else + begin FCurrentMaxFileNameLength := FMDMaxImageFilePath - Length(s); + end; {$ENDIF} end; From 77a02cc141a27ed26a44846fcde3d6fc8c508ef6 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Mon, 3 Nov 2025 20:23:14 +0800 Subject: [PATCH 04/35] Changed: FQDN List name character limit to prevent failed file creation --- baseunits/uBaseUnit.pas | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/baseunits/uBaseUnit.pas b/baseunits/uBaseUnit.pas index 04b007a09..457d50f1e 100644 --- a/baseunits/uBaseUnit.pas +++ b/baseunits/uBaseUnit.pas @@ -2207,8 +2207,12 @@ function CreateFQDNName(AFileName: String): String; var UniqueTimestampName: String; begin - UniqueTimestampName := StringReplace(ExtractFileName(AFileName), ExtractFileExt(AFileName), '', [rfReplaceAll])+ '_' + FormatDateTime('yyyy-mm-dd_hh-nn-ss', Now); - Result := StringReplace(('FQDNList_' + UniqueTimestampName), ' ', '_', [rfReplaceAll]); + UniqueTimestampName := StringReplace(ExtractFileName(AFileName), ExtractFileExt(AFileName), '', [rfReplaceAll]); + UniqueTimestampName := RemoveSymbols(UniqueTimestampName); + Delete(UniqueTimestampName, 100, 200); + UniqueTimestampName := UniqueTimestampName + '_' + FormatDateTime('yyyy-mm-dd_hh-nn-ss', Now); + UniqueTimestampName := StringReplace(('FQDNList_' + UniqueTimestampName), ' ', '_', [rfReplaceAll]); + Result := UniqueTimestampName; end; function CreateFQDNFolder(Sender: TObject; ACurrentDir, AFileName: String): String; From f489a5a7adbb4ea730738e0ffcfa15a810a8a52c Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Thu, 1 Jan 2026 15:34:08 +0800 Subject: [PATCH 05/35] Changed: Timeout for imagemagick for larger file amount operations Added: Comments for imagemagick command --- baseunits/imagemagickmanager.pas | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/baseunits/imagemagickmanager.pas b/baseunits/imagemagickmanager.pas index 17c4e2233..d3fbf71e5 100644 --- a/baseunits/imagemagickmanager.pas +++ b/baseunits/imagemagickmanager.pas @@ -31,7 +31,7 @@ TImageMagickManager = class function IdentifyCommand(const QueryCommand: String): TStringList; procedure CacheSupportedFormats; procedure CacheCompressionTypes; - function ExecuteMagickCommand(const Params: array of String; TimeoutMS: Cardinal = 300000): Boolean; + function ExecuteMagickCommand(const Params: array of String; TimeoutMS: Cardinal = 600000): Boolean; function StreamToString(Stream: TMemoryStream): String; constructor CreatePrivate; @@ -501,7 +501,7 @@ function TImageMagickManager.IsFormatSupported(const Format: String): Boolean; end; end; -function TImageMagickManager.ExecuteMagickCommand(const Params: array of String; TimeoutMS: Cardinal = 300000): Boolean; +function TImageMagickManager.ExecuteMagickCommand(const Params: array of String; TimeoutMS: Cardinal = 600000): Boolean; var Process: TProcess; Param, ErrorStreamOutput: String; @@ -667,6 +667,20 @@ function TImageMagickManager.ConvertImage(InputFile, OutputDir: String): Boolean OutputFile := QuoteStr((OutputDir + '%[filename:name].' + FSaveAs), '"'); OutputDir := QuoteStr(ExcludeTrailingPathDelimiter(OutputDir), '"'); + // if FMogrify then: + // 'mogrify' command first + // 'path' command for OutputDir + // input directory to mogrify + + // else: + // input file list first + // 'adjoin' command to treat each file in list as a seperate command + // 'set filename:name' command to set output file name same as input + // output file with directory and file name + + // 'quality' command to set output image quality + // 'compress' command for compression type + // 'format' command to set output file format Result := ExecuteMagickCommand([ IFThen(FMogrify, 'mogrify', InputFile), '-quality', GetQualityString, From e1e5e7ad5d2f514bdab57182f72fe650ea7fd5ce Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Thu, 1 Jan 2026 15:37:42 +0800 Subject: [PATCH 06/35] Changed: Status bar refresh interval --- baseunits/StatusBarDownload.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baseunits/StatusBarDownload.pas b/baseunits/StatusBarDownload.pas index e0fc01f96..8d33551f4 100644 --- a/baseunits/StatusBarDownload.pas +++ b/baseunits/StatusBarDownload.pas @@ -128,7 +128,7 @@ procedure TStatusBarDownload.SyncCreate; StatusBarResize(FStatusBar); FTimerRepaint := TTimer.Create(FStatusBar); - FTimerRepaint.Interval := 100; + FTimerRepaint.Interval := 50; FTimerRepaint.OnTimer := @TimerRepaintTimer; FTimerRepaint.Enabled := True; FNeedRepaint := True; From bca960db0308a8302084b8eab1dd6cda11a94003 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Mon, 2 Feb 2026 14:55:14 +0800 Subject: [PATCH 07/35] Fixed: Long paths to truncate at hard limit of 255 per folder/file #2732 --- baseunits/FMDOptions.pas | 1 + baseunits/uBaseUnit.pas | 32 ++++++++++++++++----- baseunits/uDownloadsManager.pas | 8 +++++- mangadownloader/forms/frmMain.pas | 47 ++++++++++++++++++++++++++++--- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/baseunits/FMDOptions.pas b/baseunits/FMDOptions.pas index 0ea1c30d5..e085d0b17 100644 --- a/baseunits/FMDOptions.pas +++ b/baseunits/FMDOptions.pas @@ -103,6 +103,7 @@ interface OptionLetFMDDo: TFMDDo = DO_NOTHING; OptionDeleteCompletedTasksOnClose: Boolean = False; OptionSortDownloadsOnNewTasks: Boolean = False; + OptionLongNamePaths: Boolean = False; // saveto OptionChangeUnicodeCharacter: Boolean = False; diff --git a/baseunits/uBaseUnit.pas b/baseunits/uBaseUnit.pas index 457d50f1e..f1427cfcd 100644 --- a/baseunits/uBaseUnit.pas +++ b/baseunits/uBaseUnit.pas @@ -1462,7 +1462,7 @@ function CorrectPathSys(const Path: String): String; if Length(s) > MAX_PATHDIR then begin s := MainForm.CheckLongNamePaths(s); - if not MainForm.cbOptionEnableLongNamePaths.Checked then + if not OptionLongNamePaths then begin SetLength(s, MAX_PATHDIR); end; @@ -1793,10 +1793,13 @@ function CustomRename(const AString, AWebsite, AMangaName, AAuthor, AArtist, ACh Result := AString; // for rename chapter only - if AChapter <> '' then begin + if AChapter <> '' then + begin // numbering/index if (Pos(CR_NUMBERING, Result) = 0) and (Pos(CR_CHAPTER, Result) = 0) then + begin Result := ANumbering + Result; + end; Result := StringReplaceBrackets(Result, CR_NUMBERING, ANumbering, [rfReplaceAll]); // pad number @@ -1804,20 +1807,27 @@ function CustomRename(const AString, AWebsite, AMangaName, AAuthor, AArtist, ACh if OptionConvertDigitVolume then begin if OptionConvertDigitChapter then - VolumeChapterPadZero(fchapter, OptionConvertDigitVolumeLength, OptionConvertDigitChapterLength) + begin + VolumeChapterPadZero(fchapter, OptionConvertDigitVolumeLength, OptionConvertDigitChapterLength); + end else + begin VolumeChapterPadZero(fchapter, OptionConvertDigitVolumeLength, 0); + end; end - else - if OptionConvertDigitChapter then + else if OptionConvertDigitChapter then + begin VolumeChapterPadZero(fchapter, 0, OptionConvertDigitChapterLength); + end; fchapter := FixStringLocal(fchapter); Result := StringReplaceBrackets(Result, CR_CHAPTER, fchapter, [rfReplaceAll]); if Result = '' then + begin Result := ANumbering; + end; end; Result := StringReplaceBrackets(Result, CR_WEBSITE, FixStringLocal(AWebsite), [rfReplaceAll]); @@ -1825,9 +1835,17 @@ function CustomRename(const AString, AWebsite, AMangaName, AAuthor, AArtist, ACh Result := StringReplaceBrackets(Result, CR_AUTHOR, FixStringLocal(AAuthor), [rfReplaceAll]); Result := StringReplaceBrackets(Result, CR_ARTIST, FixStringLocal(AArtist), [rfReplaceAll]); Result := StringReplaceBrackets(Result, CR_FILENAME, FixStringLocal(AFileName), [rfReplaceAll]); - if Result = '' then Result := FixStringLocal(AMangaName); + if Result = '' then + begin + Result := FixStringLocal(AMangaName); + end; - if Result = '' then Exit; + if Result = '' then + begin + Exit; + end; + + Result := MainForm.CheckSingularCharacterLimit(Result); // remove pathdelim Result := TrimChar(Result, AllowDirectorySeparators); diff --git a/baseunits/uDownloadsManager.pas b/baseunits/uDownloadsManager.pas index 77106692e..ecca26599 100644 --- a/baseunits/uDownloadsManager.pas +++ b/baseunits/uDownloadsManager.pas @@ -536,9 +536,15 @@ function TTaskThread.GetFileName(const AWorkId: Integer): String; Result := ''; if (Container.FileNames.Count = Container.PageLinks.Count) and (AWorkId < Container.FileNames.Count) then + begin Result := Container.FileNames[AWorkId]; + end; + if Result = '' then + begin Result := Format('%.3d', [AWorkId + 1]); + end; + Result := StringReplace(CurrentCustomFileName, CR_FILENAME, Result, [rfReplaceAll]); {$IFDEF WINDOWS} s := UTF8Decode(Result); @@ -766,7 +772,7 @@ procedure TTaskThread.SetCurrentWorkingDir(AValue: String); {$IFDEF Windows} s := UTF8Decode(FCurrentWorkingDir); - if MainForm.cbOptionEnableLongNamePaths.Checked then + if OptionLongNamePaths then begin FCurrentMaxFileNameLength := FMDMaxImageFilePath + Length(s); end diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 628f1d125..e69f98f14 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -21,7 +21,7 @@ interface ExtCtrls, ComCtrls, Buttons, Spin, Menus, VirtualTrees, RichMemo, simpleipc, process, lclproc, types, LCLIntf, EditBtn, GroupedEdit, PairSplitter, MultiLog, FileChannel, FileUtil, LazStringUtils, TAGraph, TASources, TASeries, TATools, - AnimatedGif, uBaseUnit, uDownloadsManager, uFavoritesManager, + AnimatedGif, uBaseUnit, uDownloadsManager, uFavoritesManager, StrUtils, uSilentThread, uMisc, uGetMangaInfosThread, frmDropTarget, frmAccountManager, frmAccountSet, frmWebsiteOptionCustom, frmCustomColor, frmLogger, frmTransferFavorites, frmLuaModulesUpdater, CheckUpdate, DBDataProcess, uDarkStyleParams, uWin32WidgetSetDark, @@ -773,6 +773,9 @@ TMainForm = class(TForm) procedure AddChapterNameToList; + // Check and trim to max 255 character limit per folder/file + function CheckSingularCharacterLimit(APath: String; ALimit: Integer = 255): String; + // Check and set path for long path compatibilty function CheckLongNamePaths(APath: String): String; @@ -5375,18 +5378,53 @@ procedure TMainForm.AddSilentThread(URL: string); AddSilentThread(URL, mt); end; + +function TMainForm.CheckSingularCharacterLimit(APath: String; ALimit: Integer = 255): String; +var + TruncLength: Integer; + FileNamePos: Integer = 0; + HasFileName: Boolean = False; + CharsToTrim: Set of Char; +begin + ALimit := Min(Alimit, 255); + CharsToTrim := [' ', '.']; + HasFileName := APath.Contains(CR_FILENAME); + + if HasFileName then + begin + FileNamePos := Pos(CR_FILENAME, APath); + ALimit := ALimit - 3 - 5; + end; + + if Length(APath) >= ALimit then + begin + TruncLength := LastDelimiter(' ', Copy(APath, 1, ALimit)); + APath := Copy(APath, 1, TruncLength); + APath := TrimRightSet(APath, CharsToTrim); + end; + + if HasFileName then + begin + if FileNamePos > Alimit then + begin + APath := APath + CR_FILENAME; + end; + end; + + Result := APath; +end; function TMainForm.CheckLongNamePaths(APath: String): String; begin - if cbOptionEnableLongNamePaths.Checked then + if OptionLongNamePaths then begin if Pos('\\?\', APath) = 0 then begin APath := '\\?\' + APath; end; - end; - Result := APath; + Result := APath; + end; end; function TMainForm.TrimPath(APath: String): String; @@ -6136,6 +6174,7 @@ procedure TMainForm.ApplyOptions; OptionEnableLoadCover := cbOptionEnableLoadCover.Checked; OptionDeleteCompletedTasksOnClose := cbOptionDeleteCompletedTasksOnClose.Checked; OptionSortDownloadsOnNewTasks := cbOptionSortDownloadsOnNewTasks.Checked; + OptionLongNamePaths := cbOptionEnableLongNamePaths.Checked; DLManager.DB.AutoVacuum:=cbOptionVacuumDatabasesOnExit.Checked; FavoriteManager.DB.AutoVacuum:=cbOptionVacuumDatabasesOnExit.Checked; From 56de62b58acb90b084bc69721b93e1111d5d99ff Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Mon, 2 Feb 2026 19:04:28 +0800 Subject: [PATCH 08/35] Fixed: Cover loading gif in dark theme (Credit to @jesuscc1993) #2608 --- images/waiting-dark.gif | Bin 0 -> 5986 bytes mangadownloader/forms/frmMain.pas | 11 +++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 images/waiting-dark.gif diff --git a/images/waiting-dark.gif b/images/waiting-dark.gif new file mode 100644 index 0000000000000000000000000000000000000000..f14a193f62b160386608a33b5fefc4f5a6566f9d GIT binary patch literal 5986 zcmd6LXIN8N+jTlgfKU+~9u>vz*oJXz&-ezvDSBPsyuaV`C+F6$-@fSR z=#Y?**x1;O8#j7;do!8LZQHi(+O=!lx^-n`Wipv;!-fqB2?@Twz7-V}v$M0WU%&3{ z?R9Z+ad&rjb8{1m#nsi-larHOU0w0<@jM>S)z!7QxOiY-prxgSMx*8A6g~GtVz`c9-%H{GKH*O3L4yshDrlzI?2M*NK z)U>y^hlPcurKLGKI!;VXw6(P@EG!5F0;N*9YSk)GK8nzj5I{X|MGT z3HD;~y=e|qFi%}Csll*Y*L#79IYN5(KT z_e;$bJoa;!^aM{lYv~W{(wJV!sWDi02S@uTD%A<==I-F`>Q0TIyTwM4u{0{pg+g_r zP+je5RE7(c;pmF}^TKNeOpT6Z2su7~4ySqY#K)zlr!Xj#J$v>z>~V5PPTfv%)DVF} zrBP@!drc4fw7p5`5gGPLX;yz_;KZawrN*bE$0sLYmoi2~Chto3#A_z||5lNh@^{*# zG>6YCa)?S!q+~>-P#hhoORM^;V^Gll-Ze4t@7`(Y!kB;N`~OXx7P2=bh9ZnfOWu_l z6{G2HwKP-;!z(o=B0V`ZBsqDc??r%xU~didb}!o9omcW&SM&(A;oICt~L^=q?NXRchnG=1^H)a1nY`5(qcM}~*g z=e{2t=s$a=?{x2}p6;&Bj`ovnCypOG+IpnraC1|ms-gZ+U2RQuRb@qaS!s!~SW#41 zke`<;&&ke`NhRV;(ZK`X?f-V)-i$rFccrJL?o3HeO5Bm~O?=$;*qG?3$cXT5Teoc9 z6c)O1!}@h0!9oF_w>Bs+z~7JS>*LMwVzZcQR(pD^Vz|@YTwR=0y9H zwe)Ci79ZBeQ*}sJbpyO)eTQU*gFGFz%yz`|be#-3r8O->j@Vv3Ce@na&&ixej)>1o zPYmiW$m}e-E$kl8is1uoFnEWywRN;fmm^s+m@I^oH-&SDGQk&-nI_DgV{~?NY;AU7ZIg@nL?e{G}5WOz*$%m7UWCJ~Xz@d+7**z-=E#X!m0I3UX@XA|ud1NP~ zJAzU!W^)J26d~qdYl>^^ zA;^c*mJ5S69}Uu;P3H|1Y|3F>YD4)1awcNiqV1LdCkLSqU}>TF={5%&4P ziKFg@vALPCX|Z)On|*%RuUTdTu>O)|UK%QCSXQ_y7hq9TCV@b+O_hKGv{AW`1qN$n z)hM%30>SDsNHZ8)C2h^kLR+2?G!$xgf+@1zIvJ;5z$mj;Lr&GojK*!sp=#?(N2NC7 zXcb%CA|90g)+iD;b7BAZ2N(m%Z%q8xmc}RG~nIj1)m!$caEC zL7=1ot5$j;oOa*YgD}xyIomiYUxPy1*(h4(9 zP0r70r7v0l<&Tv%%+}XYGtGEztMl8%$1_s1=V3LG25uXxq$6c-s42>W18n-LYPa=4504%so5f?9T-i@Be`WM zDu<#k@(dTSfq+FcxCmiOO^NXnTO^mq1fAa4yL?OFI{g zRg@Q);jnh>JE12b9!tljC{BbTAPChc7g-c@4l?#Oyz60u zmfgCrQhLCTxP-Pa9sFFktu|XQv9%^MyvgYn8%LA(wk~S^_P`-_Iww5x zGJcLH68-n(un>-6=`vQ%UFA##B$ED+8QqKCvK>d1X1J+_@9a^mVBwf&x?(`ZhnYKj z=H(ABHPmy)pAmcFFEy{&wfet%y`FfLP`2Irc$WVKnZX*%{0d{K&k~OL8jLY=kaBZEv>Uy$I2h*w&r))UYh67QkI;xXy5e)e4n9My?}Kb#Ts&mPC}%dNDukXheA z`kC!D80`s^N%hXVqlGNkA#PweH-sFB*RWcM4PD8$3j>%uj!=x2zyK(*(Q)H^zr1EO z_jpZzta}7(>ZWp-<=4=N2#1vCeucx7P-TyB}T>l*T1N&Za-Sl3!Z+2ibI&3Q-ZogG2ryF;WBYmu?|8 z(x52I%P+{M=KxWKr7|c#A5#o0z?+qc4R}25yz1h7HxS6P4BEtlY4FX-!9MoaTVhxTOrjz2nd2G~ z3$@Qd?p+e=op;NNE+yhlDu^2^*_>*E_h{#OX~PK=yj(LD9cx{L90AS-(uRVYe7ks#{uHV(c@ND9I<2ruti@83Lc~C1A zM{P0@H15xc=+n;|l?P#x$WZvgXdbC3W50VY!n`zU|06S~BzC$YlwXcN`|CHP8r;DQ zdt#RSl0;Md|E~Q;8k|>XsQkJ18)|?QX6MLr^MpE59xPv(4=v&;ahQ^vvZ8z!Ah5Wm zPMU{9sesibhbwZ8jsfY-<++$HVvX=*F0l*OKbX^S%)5V}HyeIbg@TWd2#vd3@<;^2 z2_e6z3D?z>7eu);+@>J@aw7=6=<`aI^E^bap9+6-B<=@!N59Yh%OB>+0xfYS z(*>8oo;kfQh-r=A=sSZb`JFxHVe&+U*uMw*g&7+GK>y&Y*;`5YP?grwdH6ck*?&|Dx`2d;3!I|TU#kc zqeiEdszQWhczRl|3aMo%xo~~dxcl1e{%)c7Z4~5zcx0N0dp0%p^tA+sdG+SQpxz&! z0G2u2YhI!u2^@NvTh^f(3UM~WZ|3@Q)Op}{RV$gyD$nI$m`F5~>^-iq_Lw$Ir7dvx z@&kL#_;;@#S#F!vs!srqUH~qm#RHfeTgHv-RPHBth2!{br_} z$g)HsHVMHcTxTsG_>oI!;skZYdNt_?=UK#8QJt)oX)di(9WWXPCb$GX)g%kuZ! znUSo*ZQTR#+014A=V*z!@skgyI`43ht+6u^yH~Ekht~h7{gpo;zw!rJR<;DGrKOXj zDRKy22~1I*gM^jTRMbh7H6@5c6;-MdNOO6ED*u>5{|HRC{dgPyR5`M==S&43+V}m) zXtuBM_{5|!ZcGRRUYWTHLH+A>o^!*~d8U8^w2?R24dMZUde@=Mv zT1frv`O9~{i*FHF*8CMX-X_vRDYz@^z?egj8FzBLOY@BM4NTNK$FRo0ckc9%`MYDr z;yA#|a4&tGLbG69G4Z8BuS8(O6#yEJXtAK-D7X+FJ&4LOyEBUAdR;msA;UexiBN=C z=ChyrE`oFQ2mrjj$`wGZ%>oj`!>rcRxCetXRH%bqKSi-JEyu!3yW* z?E%{|zc?Cz0Y+cfxvXp%BsVV~!p~6@%M5sB{P;CNB% z$#x;y2;CvXVQ}pfOM$?#9SsDcAdP67!9jAn-taK-jIw`XklF4%Jv^#ljL!AqhSW3PrTQLg~v2=6j@Qshc_0Js8gMF9g%ayPs z9uUNGz+F)TMB6wO+jHq>?AFOqgZDcPL?99rHV(mYIb5J8(sS0ewMM>2x})a;Hb)d# zC9(KEWZt~I49&&tZ7wfq7ht`7jJBvln~KHYN2^)DOao3&6W0irf}LS~zmdJ!f-iMB+GtA88@0RB zHQLw(@;6bbNzd0IDi8(ug8n!a7t_A1Z~qWHsR>En*>^TWA9CUJw<~0K7_Zk&0i(2i zlccWO$)F;a?Yl7IXmTJ%aot0AYWzY``b5 zXf~@qDK=~uv(v!NfdA(N(b!yM(`BM zp*2ibF)j)MH-~>5$ZS1!jiVi`WIrO@wUu*{+HDw$((TrUYrJ~RkH-211&}0g*=uU_-mjbS#{drH{7A@1r6}A_!vH z%kz#(I110Od4y#$bNA!9rQ|ug|BRPeM>IDz7`6bkd^dY`kQzq(NN~FbYRfo~r{w_i zgsV&0gqqa|LHJ~;2n*-wkWDzs7$F Date: Mon, 2 Feb 2026 19:38:39 +0800 Subject: [PATCH 09/35] Fixed: Downloads task counter when merging completed tasks #660 --- baseunits/uDownloadsManager.pas | 2 +- mangadownloader/forms/frmMain.pas | 33 ++++++++++++++++++------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/baseunits/uDownloadsManager.pas b/baseunits/uDownloadsManager.pas index ecca26599..85cd288f2 100644 --- a/baseunits/uDownloadsManager.pas +++ b/baseunits/uDownloadsManager.pas @@ -501,7 +501,7 @@ destructor TTaskThread.Destroy; (CurrentDownloadChapterPtr >= ChapterLinks.Count) and (not FailedChaptersExist) then begin - DownloadInfo.Status := Format('[%d/%d] %s',[Container.ChapterLinks.Count,Container.ChapterLinks.Count,RS_Finish]); + DownloadInfo.Status := Format('[%d/%d] %s', [Container.ChapterLinks.Count, Container.ChapterLinks.Count, RS_Finish]); DownloadInfo.Progress := ''; Status := STATUS_FINISH; end diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 0133f50dc..cd6a9bdfd 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -2349,26 +2349,30 @@ procedure TMainForm.miDownloadMergeCompletedClick(Sender: TObject); begin DLManager.Lock; try - i:=DLManager.Count-1; - while i>0 do begin - ic:=DLManager.Items[i]; - if ic.Status=STATUS_FINISH then + i := DLManager.Count - 1; + while i > 0 do + begin + ic := DLManager.Items[i]; + if ic.Status = STATUS_FINISH then begin - j:=i-1; - while j>0 do begin - jc:=DLManager.Items[j]; - if (i<>j) and + j := i - 1; + while j >= 0 do + begin + jc := DLManager.Items[j]; + if (i <> j) and (jc.Status = STATUS_FINISH) and - SameText(ic.DownloadInfo.title,jc.DownloadInfo.title) and - SameText(ic.DownloadInfo.ModuleID,jc.DownloadInfo.ModuleID) and - SameText(ic.DownloadInfo.saveTo,jc.DownloadInfo.saveTo) then + SameText(ic.DownloadInfo.title, jc.DownloadInfo.title) and + SameText(ic.DownloadInfo.ModuleID, jc.DownloadInfo.ModuleID) and + SameText(ic.DownloadInfo.saveTo, jc.DownloadInfo.saveTo) then begin - ic.ChapterLinks.Text:=jc.ChapterLinks.Text+ic.ChapterLinks.Text; - ic.ChapterNames.Text:=jc.ChapterNames.Text+ic.ChapterNames.Text; - ic.DownloadInfo.DateAdded:=jc.DownloadInfo.DateAdded; + ic.ChapterLinks.Text := jc.ChapterLinks.Text + ic.ChapterLinks.Text; + ic.ChapterNames.Text := jc.ChapterNames.Text + ic.ChapterNames.Text; + ic.DownloadInfo.DateAdded := jc.DownloadInfo.DateAdded; + ic.DownloadInfo.Status := Format('[%d/%d] %s', [ic.ChapterLinks.Count, ic.ChapterLinks.Count, RS_Finish]); DLManager.Delete(j); Dec(i); end; + Dec(j); end; end; @@ -2377,6 +2381,7 @@ procedure TMainForm.miDownloadMergeCompletedClick(Sender: TObject); finally DLManager.UnLock; end; + UpdateVtDownload; end; From a3161418f6f0d5ec0e79a3ebf97f8c14deff92c1 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Mon, 2 Feb 2026 22:13:54 +0800 Subject: [PATCH 10/35] Fixed: Caption not showing exe arguments when changing languages --- mangadownloader/forms/frmMain.pas | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index cd6a9bdfd..1c7dc3986 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -529,6 +529,8 @@ TMainForm = class(TForm) procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); + procedure SetCaption; + procedure btDownloadClick(Sender: TObject); procedure btFavoritesCheckNewChapterClick(Sender: TObject); procedure btOptionApplyClick(Sender: TObject); @@ -1415,9 +1417,21 @@ procedure TMainForm.FormCreate(Sender: TObject); AddToAboutStatus(RS_Revision, REVISION_NUMBER+' ('+REVISION_SHA+')', pnAboutVersion); end; - if AlwaysLoadLuaFromFile then +procedure TMainForm.SetCaption; +var + i: Integer; +begin + if not ContainsText(Caption, FMD_VERSION_STRING) then + begin + Caption := Caption + ' v' + FMD_VERSION_STRING; + end; + + for i := 0 to AppParams.Count - 1 do begin - Caption := Caption + ' --lua-dofile'; + if not ContainsText(Caption, AppParams[i]) then + begin + Caption := Caption + ' ' + AppParams[i]; + end; end; end; @@ -6887,7 +6901,8 @@ procedure TMainForm.ApplyLanguage; cbWebPSaveAs.ItemIndex := idxOptionWebPConvertTo; cbPNGCompressionLevel.ItemIndex := idxOptionWebPPNGLevel; Self.Repaint; - Self.Caption := Self.Caption + ' v' + FMD_VERSION_STRING; + SetCaption; + vtMangaList.Repaint; tvDownloadFilterRefresh(True); From 68d05af4948b06a7552c9e656d5a267c84a136c4 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Mon, 2 Feb 2026 22:14:42 +0800 Subject: [PATCH 11/35] Fixed: Code good practice (mainly if statements) --- baseunits/FMDOptions.pas | 9 +- baseunits/lua/LuaBase.pas | 6 +- baseunits/lua/LuaHandler.pas | 8 +- baseunits/lua/LuaWebsiteModules.pas | 96 ++++-- baseunits/uFavoritesManager.pas | 494 +++++++++++++++++++++------- mangadownloader/forms/frmMain.pas | 406 +++++++++++++++++------ updater/uMain.pas | 30 +- 7 files changed, 787 insertions(+), 262 deletions(-) diff --git a/baseunits/FMDOptions.pas b/baseunits/FMDOptions.pas index e085d0b17..20ccff48b 100644 --- a/baseunits/FMDOptions.pas +++ b/baseunits/FMDOptions.pas @@ -307,10 +307,13 @@ procedure doInitialization; var i: Integer; begin - AppParams:=TStringList.Create; - AppParams.Sorted:=False; - for i:=1 to ParamCount do + AppParams := TStringList.Create; + AppParams.Sorted := False; + for i := 1 to ParamCount do + begin AppParams.Add(ParamStr(i)); + end; + GetProgramVersion(FMD_VERSION_NUMBER); FMD_VERSION_STRING := ProgramversionToStr(FMD_VERSION_NUMBER); SetFMDdirectory(ExtractFilePath(Application.ExeName)); diff --git a/baseunits/lua/LuaBase.pas b/baseunits/lua/LuaBase.pas index 2cef16f86..867f9fb2a 100644 --- a/baseunits/lua/LuaBase.pas +++ b/baseunits/lua/LuaBase.pas @@ -218,9 +218,13 @@ function LuaLoadFromStreamOrFile(const L: Plua_State; const AStream: TMemoryStream; const AFileName: String): Integer; begin if (not AlwaysLoadLuaFromFile) and (AStream <> nil) then - Result := luaL_loadbuffer(L, AStream.Memory, AStream.Size, PAnsiChar(AFileName)) + begin + Result := luaL_loadbuffer(L, AStream.Memory, AStream.Size, PAnsiChar(AFileName)); + end else + begin Result := luaL_loadfile(L, PAnsiChar(AFileName)); + end; end; procedure LuaExecute(const L: Plua_State; const AStream: TMemoryStream; diff --git a/baseunits/lua/LuaHandler.pas b/baseunits/lua/LuaHandler.pas index 3d33ba861..7d2c17be4 100644 --- a/baseunits/lua/LuaHandler.pas +++ b/baseunits/lua/LuaHandler.pas @@ -97,14 +97,20 @@ function TLuaHandler.LoadChunkExecute(const AName: String; l: Integer; begin Result := 0; + l := FLoadedChunks.IndexOf(AName); if (l <> -1) then begin if AlwaysLoadLuaFromFile then - FLoadedChunks.Delete(l) + begin + FLoadedChunks.Delete(l); + end else + begin Exit; + end; end; + Result := LuaLoadFromStreamOrFile(FHandle, AChunk, AName); if Result = 0 then begin diff --git a/baseunits/lua/LuaWebsiteModules.pas b/baseunits/lua/LuaWebsiteModules.pas index c75ecd18d..876a779e4 100644 --- a/baseunits/lua/LuaWebsiteModules.pas +++ b/baseunits/lua/LuaWebsiteModules.pas @@ -692,8 +692,16 @@ destructor TLuaWebsiteModulesContainer.Destroy; function TLuaWebsiteModulesContainer.ByteCode: TMemoryStream; begin // don't need to cache lua file on --lua-dofile - if AlwaysLoadLuaFromFile then Exit(nil); - if FByteCode <> nil then Exit(FByteCode); + if AlwaysLoadLuaFromFile then + begin + Exit(nil); + end; + + if FByteCode <> nil then + begin + Exit(FByteCode); + end; + if TryEnterCriticalSection(FGuardian) <> 0 then begin try @@ -738,7 +746,11 @@ function TLuaWebsiteModule.AddOption(const AName, ACaption: String; const AClass o: TOptionItem; begin Result := Options.Add(AName); - if Result = -1 then Exit; + if Result = -1 then + begin + Exit; + end; + o := TOptionItem(AClass.Create); o.Caption := ACaption; Options.Objects[Result] := o; @@ -751,7 +763,11 @@ procedure TLuaWebsiteModule.AddOptionCheckBox(const AName, ACaption: String; i: Integer; begin i := AddOption(AName, ACaption, TOptionItemCheckBox); - if i = -1 then Exit; + if i = -1 then + begin + Exit; + end; + o := TOptionItemCheckBox(Options.Objects[i]); o.Value := ADefault; Module.AddOptionCheckBox(@o.Value, Options[i], @o.Caption); @@ -763,7 +779,11 @@ procedure TLuaWebsiteModule.AddOptionEdit(const AName, ACaption: String; const A i: Integer; begin i := AddOption(AName, ACaption, TOptionItemEdit); - if i = -1 then Exit; + if i = -1 then + begin + Exit; + end; + o := TOptionItemEdit(Options.Objects[i]); o.Value := ADefault; Module.AddOptionEdit(@o.Value, Options[i], @o.Caption); @@ -776,7 +796,11 @@ procedure TLuaWebsiteModule.AddOptionSpinEdit(const AName, ACaption: String; i: Integer; begin i := AddOption(AName, ACaption, TOptionItemSpinEdit); - if i = -1 then Exit; + if i = -1 then + begin + Exit; + end; + o := TOptionItemSpinEdit(Options.Objects[i]); o.Value := ADefault; Module.AddOptionSpinEdit(@o.Value, Options[i], @o.Caption); @@ -789,7 +813,11 @@ procedure TLuaWebsiteModule.AddOptionComboBox(const AName, ACaption, AItems: Str i: Integer; begin i := AddOption(AName, ACaption, TOptionItemComboBox); - if i = -1 then Exit; + if i = -1 then + begin + Exit; + end; + o := TOptionItemComboBox(Options.Objects[i]); o.Items := AItems; o.Value := ADefault; @@ -868,17 +896,26 @@ function lua_addservercookies(L: Plua_State): Integer; cdecl; begin Result := 0; if lua_gettop(L) = 2 then - TLuaWebsiteModule(luaClassGetObject(L)).Module.CookieManager.AddServerCookies(luaToString(L, 1), luaToString(L, 2), Now) + begin + TLuaWebsiteModule(luaClassGetObject(L)).Module.CookieManager.AddServerCookies(luaToString(L, 1), luaToString(L, 2), Now); + end else + begin TLuaWebsiteModule(luaClassGetObject(L)).Module.CookieManager.AddServerCookies('', luaToString(L, 1), Now); + end; end; function lua_getservercookies(L: Plua_State): Integer; cdecl; begin if lua_gettop(L) = 2 then - lua_pushstring(L, TLuaWebsiteModule(luaClassGetObject(L)).Module.CookieManager.GetServerCookies(luaToString(L, 1), luaToString(L, 2))) + begin + lua_pushstring(L, TLuaWebsiteModule(luaClassGetObject(L)).Module.CookieManager.GetServerCookies(luaToString(L, 1), luaToString(L, 2))); + end else + begin lua_pushstring(L, TLuaWebsiteModule(luaClassGetObject(L)).Module.CookieManager.GetServerCookies(luaToString(L, 1), '')); + end; + Result := 1; end; @@ -886,9 +923,13 @@ function lua_removecookies(L: Plua_State): Integer; cdecl; begin Result := 0; if lua_gettop(L) = 2 then - TLuaWebsiteModule(luaClassGetObject(L)).Module.CookieManager.RemoveCookies(luaToString(L, 1), luaToString(L, 2)) + begin + TLuaWebsiteModule(luaClassGetObject(L)).Module.CookieManager.RemoveCookies(luaToString(L, 1), luaToString(L, 2)); + end else + begin TLuaWebsiteModule(luaClassGetObject(L)).Module.CookieManager.RemoveCookies(luaToString(L, 1), ''); + end; end; function lua_clearcookies(L: Plua_State): Integer; cdecl; @@ -904,26 +945,35 @@ function lua_getoption(L: Plua_State): Integer; cdecl; o: TObject; begin m := TLuaWebsiteModule(luaClassGetObject(L)); - i:=m.Options.IndexOf(luaToString(L, 1)); + i := m.Options.IndexOf(luaToString(L, 1)); Result := 1; if i = -1 then + begin lua_pushnil(L) + end else begin o := m.Options.Objects[i]; if o is TOptionItemCheckBox then - lua_pushboolean(L, TOptionItemCheckBox(o).Value) - else - if o is TOptionItemEdit then - lua_pushstring(L, TOptionItemEdit(o).Value) - else - if o is TOptionItemSpinEdit then - lua_pushinteger(L, TOptionItemSpinEdit(o).Value) - else - if o is TOptionItemComboBox then - lua_pushinteger(L, TOptionItemComboBox(o).Value) + begin + lua_pushboolean(L, TOptionItemCheckBox(o).Value); + end + else if o is TOptionItemEdit then + begin + lua_pushstring(L, TOptionItemEdit(o).Value); + end + else if o is TOptionItemSpinEdit then + begin + lua_pushinteger(L, TOptionItemSpinEdit(o).Value); + end + else if o is TOptionItemComboBox then + begin + lua_pushinteger(L, TOptionItemComboBox(o).Value); + end else + begin lua_pushnil(L); + end; end; end; @@ -1010,8 +1060,10 @@ procedure luaWebsiteModuleAddMetaTable(const L: Plua_State; const Obj: Pointer; luaClassAddObject(L, MetaTable, Storage, 'Storage', @luaStringsStorageAddMetaTable); - if Module.Account<>nil then + if Module.Account <> nil then + begin luaClassAddObject(L, MetaTable, Module.Account, 'Account', @luaWebsiteModuleAccountAddMetaTable); + end; luaClassAddIntegerProperty(L, MetaTable, 'Tag', @Module.Tag); end; diff --git a/baseunits/uFavoritesManager.pas b/baseunits/uFavoritesManager.pas index 80c6cf815..9dbab90b5 100644 --- a/baseunits/uFavoritesManager.pas +++ b/baseunits/uFavoritesManager.pas @@ -190,14 +190,25 @@ implementation procedure TFavoriteContainer.SetEnabled(AValue: Boolean); begin - if FEnabled = AValue then Exit; + if FEnabled = AValue then + begin + Exit; + end; + FEnabled := AValue; if FEnabled then - Inc(FManager.FEnabledCount) + begin + Inc(FManager.FEnabledCount); + end else + begin Dec(FManager.FEnabledCount); + end; + if not FManager.isRunningRestore then + begin DBUpdateEnabled; + end; end; constructor TFavoriteContainer.Create(const M: TFavoriteManager); @@ -217,18 +228,22 @@ destructor TFavoriteContainer.Destroy; Thread.WaitFor; Thread := nil; end; + if Assigned(NewMangaInfo) then begin NewMangaInfo.Free; NewMangaInfoChaptersPos.Free; end; + inherited Destroy; end; procedure TFavoriteContainer.DBInsert; begin - Fid:=LowerCase(FavoriteInfo.ModuleID+FavoriteInfo.Link); + Fid := LowerCase(FavoriteInfo.ModuleID + FavoriteInfo.Link); + with FavoriteInfo do + begin FManager.FFavoritesDB.Add( Fid, FOrder, @@ -241,13 +256,16 @@ procedure TFavoriteContainer.DBInsert; DownloadedChapterList, SaveTo, DateAdded - ); + ); + end; end; procedure TFavoriteContainer.DBReplace(const OldId: String); begin Fid := LowerCase(FavoriteInfo.ModuleID+FavoriteInfo.Link); + with FavoriteInfo do + begin FManager.FFavoritesDB.Replace( OldId, Fid, @@ -261,34 +279,39 @@ procedure TFavoriteContainer.DBReplace(const OldId: String); DownloadedChapterList, SaveTo, DateAdded - ); + ); + end; end; procedure TFavoriteContainer.DBUpdateTitle; begin - FManager.FFavoritesDB.UpdateTitle(Fid,FavoriteInfo.Title); + FManager.FFavoritesDB.UpdateTitle(Fid, FavoriteInfo.Title); end; procedure TFavoriteContainer.DBUpdateEnabled; begin - FManager.FFavoritesDB.UpdateEnabled(Fid,FEnabled); + FManager.FFavoritesDB.UpdateEnabled(Fid, FEnabled); end; procedure TFavoriteContainer.DBUpdateDateLastChecked; begin with FavoriteInfo do - FManager.FFavoritesDB.UpdateLastChecked(Fid,Status,CurrentChapter,DateLastChecked); + begin + FManager.FFavoritesDB.UpdateLastChecked(Fid, Status, CurrentChapter, DateLastChecked); + end; end; procedure TFavoriteContainer.DBUpdateSaveTo; begin - FManager.FFavoritesDB.UpdateSaveTo(Fid,FavoriteInfo.SaveTo); + FManager.FFavoritesDB.UpdateSaveTo(Fid, FavoriteInfo.SaveTo); end; procedure TFavoriteContainer.DBUpdateLastUpdated; begin with FavoriteInfo do - FManager.FFavoritesDB.UpdateLastUpdated(Fid,DownloadedChapterList,DateLastUpdated); + begin + FManager.FFavoritesDB.UpdateLastUpdated(Fid, DownloadedChapterList, DateLastUpdated); + end; end; { TFavoriteThread } @@ -310,10 +333,15 @@ procedure TFavoriteThread.Execute; end; end else + begin FContainer.Status := STATUS_CHECKED; + end; + FContainer.Thread := nil; if not Terminated then + begin FTask.UpdateStatus; + end; end; end; @@ -322,12 +350,16 @@ procedure TFavoriteThread.DoCheck; DLChapters: TStringList; i: Integer; begin - if (FContainer.FavoriteInfo.Link) = '' then Exit; + if (FContainer.FavoriteInfo.Link) = '' then + begin + Exit; + end; FContainer.Status := STATUS_CHECKING; FTask.UpdateStatus; with FContainer do + begin try FMangaInformation.HTTP.Reset; FMangaInformation.MangaInfo.Clear; @@ -335,6 +367,7 @@ procedure TFavoriteThread.DoCheck; FMangaInformation.isGetByUpdater := False; // get new manga info FMangaInformation.GetInfoFromURL(FavoriteInfo.Link); + if not Terminated then begin NewMangaInfo := FMangaInformation.MangaInfo.Clone; @@ -342,6 +375,7 @@ procedure TFavoriteThread.DoCheck; // update current chapters count immedietly FavoriteInfo.CurrentChapter := IntToStr(NewMangaInfo.ChapterLinks.Count); FavoriteInfo.Status := NewMangaInfo.Status; + if NewMangaInfo.ChapterLinks.Count > 0 then begin // tag 100 for transfer favorite, add all chapter to downloaded chapter list @@ -351,16 +385,22 @@ procedure TFavoriteThread.DoCheck; FContainer.Tag := 0; end else - try - DLChapters := TStringList.Create; - DLChapters.Sorted := False; - DLChapters.Text := FavoriteInfo.DownloadedChapterList; - DLChapters.Sorted := True; - for i := 0 to NewMangaInfo.ChapterLinks.Count - 1 do - if DLChapters.IndexOf(NewMangaInfo.ChapterLinks[i]) = -1 then - NewMangaInfoChaptersPos.Add(i); - finally - DLChapters.Free; + begin + try + DLChapters := TStringList.Create; + DLChapters.Sorted := False; + DLChapters.Text := FavoriteInfo.DownloadedChapterList; + DLChapters.Sorted := True; + for i := 0 to NewMangaInfo.ChapterLinks.Count - 1 do + begin + if DLChapters.IndexOf(NewMangaInfo.ChapterLinks[i]) = -1 then + begin + NewMangaInfoChaptersPos.Add(i); + end; + end; + finally + DLChapters.Free; + end; end; end; @@ -368,7 +408,9 @@ procedure TFavoriteThread.DoCheck; begin FContainer.FavoriteInfo.DateLastChecked := Now; if (NewMangaInfoChaptersPos.Count <> 0) then + begin FContainer.FavoriteInfo.DateLastUpdated := Now; + end; end; // free unneeded objects @@ -383,6 +425,7 @@ procedure TFavoriteThread.DoCheck; on E: Exception do ExceptionHandle(Self, E); end; + end; end; constructor TFavoriteThread.Create(const ATask: TFavoriteTask); @@ -410,7 +453,9 @@ procedure TFavoriteTask.DoCustomTerminate(Sender: TObject); EnterCriticalsection(FCS_Threads); try for i := 0 to FThreads.Count - 1 do + begin FThreads[i].Terminate; + end; finally LeaveCriticalsection(FCS_Threads); end; @@ -427,7 +472,8 @@ procedure TFavoriteTask.TimerRepaintOnTimer(Sender: TObject); procedure TFavoriteTask.SyncStartChecking; begin - with MainForm do begin + with MainForm do + begin btCancelFavoritesCheck.Visible := True; btFavoritesCheckNewChapter.Width := btFavoritesCheckNewChapter.Width - btCancelFavoritesCheck.Width - 6; @@ -450,8 +496,11 @@ procedure TFavoriteTask.SyncFinishChecking; rbFavoritesShowDisabled.Enabled := True; rbFavoritesShowEnabled.Enabled := True; vtFavorites.Repaint; + if OptionAutoCheckFavInterval and (not tmCheckFavorites.Enabled) then + begin tmCheckFavorites.Enabled := True; + end; end; end; @@ -472,38 +521,56 @@ procedure TFavoriteTask.Execute; // wait for FThreads to finish while FThreads.Count > 0 do + begin Sleep(HeartBeatRate); + end; // reset all status FManager.Lock; try for i := 0 to FManager.Items.Count - 1 do + begin with FManager.Items[i] do begin - if Status=STATUS_CHECKED then + if Status = STATUS_CHECKED then + begin DBUpdateDateLastChecked; - if Status<>STATUS_IDLE then + end; + + if Status <> STATUS_IDLE then + begin Status := STATUS_IDLE; + end; end; + end; finally FManager.UnLock; end; if (not Terminated) and (not isDlgCounter) then - Synchronize(FManager.ShowResult) - else - // free unused unit begin + Synchronize(FManager.ShowResult); + end + else + begin + // free unused unit EnterCriticalsection(FManager.FGuardian); try for i := 0 to FManager.Items.Count - 1 do + begin with FManager.Items[i] do begin if Assigned(NewMangaInfo) then + begin FreeAndNil(NewMangaInfo); + end; + if Assigned(NewMangaInfoChaptersPos) then + begin FreeAndNil(NewMangaInfoChaptersPos); + end; end; + end; finally LeaveCriticalsection(FManager.FGuardian); end; @@ -569,28 +636,42 @@ function TFavoriteTask.GetNext(var C: TfavoriteContainer): Boolean; Result := False; C := nil; - if FThreads.Count > OptionMaxFavoriteThreads then Exit; + if FThreads.Count > OptionMaxFavoriteThreads then + begin + Exit; + end; EnterCriticalSection(FCS_GetNext); try FPendingCount := 0; for i in FManager.Items do begin - if Terminated then Break; + if Terminated then + begin + Break; + end; + if (i.Status = STATUS_CHECK) then begin if i.FavoriteInfo.Module = nil then - i.Status := STATUS_IDLE - else - if C = nil then - C := i + begin + i.Status := STATUS_IDLE; + end + else if C = nil then + begin + C := i; + end else + begin Inc(FPendingCount); + end; end; end; if (FPendingCount > 0) and (FThreads.Count < OptionMaxFavoriteThreads) then + begin TFavoriteThread.Create(Self); + end; finally LeaveCriticalSection(FCS_GetNext); end; @@ -601,6 +682,7 @@ function TFavoriteTask.GetNext(var C: TfavoriteContainer): Boolean; procedure TFavoriteTask.AddThread(const T: TFavoriteThread); begin EnterCriticalSection(FCS_Threads); + try FThreads.Add(T); finally @@ -611,6 +693,7 @@ procedure TFavoriteTask.AddThread(const T: TFavoriteThread); procedure TFavoriteTask.RemoveThread(const T: TFavoriteThread); begin EnterCriticalSection(FCS_Threads); + try FThreads.Remove(T); finally @@ -639,28 +722,38 @@ procedure TFavoriteManager.DBUpdateOrder; var i: Integer; begin - if FUpdateOrderCount=0 then Exit; - for i := 0 to Items.Count-1 do - with Items[i] do begin - if i<>FOrder then + if FUpdateOrderCount = 0 then + begin + Exit; + end; + + for i := 0 to Items.Count - 1 do + begin + with Items[i] do begin - FOrder:=i; - FFavoritesDB.tempSQL+='UPDATE "favorites" SET "order"='+PrepSQLValue(FOrder)+' WHERE "id"='+PrepSQLValue(Fid)+';'; - Inc(FFavoritesDB.tempSQLcount); - if FFavoritesDB.tempSQLcount>=MAX_BIG_SQL_FLUSH_QUEUE then - FFavoritesDB.FlushSQL(False); + if i <> FOrder then + begin + FOrder := i; + FFavoritesDB.tempSQL += 'UPDATE "favorites" SET "order"=' + PrepSQLValue(FOrder) + ' WHERE "id"=' + PrepSQLValue(Fid) + ';'; + Inc(FFavoritesDB.tempSQLcount); + if FFavoritesDB.tempSQLcount >= MAX_BIG_SQL_FLUSH_QUEUE then + begin + FFavoritesDB.FlushSQL(False); + end; + end; end; end; - FUpdateOrderCount:=0; + + FUpdateOrderCount := 0; end; constructor TFavoriteManager.Create; begin inherited Create; InitCriticalSection(FGuardian); - isRunningRestore:=False; - FUpdateOrderCount:=0; - FEnabledCount:=0; + isRunningRestore := False; + FUpdateOrderCount := 0; + FEnabledCount := 0; ForceDirectories(USERDATA_FOLDER); isRunning := False; Items := TFavoriteContainers.Create;; @@ -676,8 +769,11 @@ destructor TFavoriteManager.Destroy; begin StopChekForNewChapter; for i := 0 to Items.Count - 1 do + begin Items[i].Free; + end; end; + Items.Free; FFavoritesDB.Free; DoneCriticalsection(FGuardian); @@ -689,23 +785,33 @@ procedure TFavoriteManager.CheckForNewChapter(FavoriteIndex: Integer); i: Integer; toCheckCount: Integer; begin - if isDlgCounter then Exit; - if Items.Count = 0 then Exit; + if isDlgCounter then + begin + Exit; + end; + if Items.Count = 0 then + begin + Exit; + end; + try toCheckCount := 0; if FavoriteIndex > -1 then begin with Items[FavoriteIndex] do + begin if Assigned(FavoriteInfo.Module) and FEnabled and (Status = STATUS_IDLE) then begin Status := STATUS_CHECK; Inc(toCheckCount); if Assigned(TaskThread) then + begin InterLockedIncrement(TaskThread.FPendingCount); + end; end; + end; end - else - if isRunning then + else if isRunning then begin if not isAuto then begin @@ -717,18 +823,25 @@ procedure TFavoriteManager.CheckForNewChapter(FavoriteIndex: Integer); EnterCriticalsection(FGuardian); try for i := 0 to Items.Count - 1 do + begin with Items[i] do + begin if Assigned(FavoriteInfo.Module) and FEnabled and (Status = STATUS_IDLE) and (Trim(FavoriteInfo.Link) <> '') then begin Status := STATUS_CHECK; Inc(toCheckCount); end; + end; + end; finally LeaveCriticalsection(FGuardian); end; end; + if (toCheckCount > 0) and (TaskThread = nil) then + begin TaskThread := TFavoriteTask.Create(Self); + end; except on E: Exception do ExceptionHandle(Self, E); @@ -737,26 +850,36 @@ procedure TFavoriteManager.CheckForNewChapter(FavoriteIndex: Integer); procedure TFavoriteManager.StopChekForNewChapter(WaitFor: Boolean; FavoriteIndex: Integer); begin - if not isRunning then Exit; + if not isRunning then + begin + Exit; + end; + if FavoriteIndex > -1 then begin - with Items[FavoriteIndex] do begin + with Items[FavoriteIndex] do + begin if Thread <> nil then begin Thread.Terminate; if WaitFor then + begin Thread.WaitFor; + end; end; if Status <> STATUS_IDLE then + begin Status := STATUS_IDLE; + end; end; end - else - if Assigned(TaskThread) then + else if Assigned(TaskThread) then begin TaskThread.Terminate; if WaitFor then + begin TaskThread.WaitFor; + end; end; end; @@ -770,10 +893,19 @@ procedure TFavoriteManager.ShowResult; newChapterListStr: String = ''; removeListStr: String = ''; begin - if isDlgCounter then Exit; + if isDlgCounter then + begin + Exit; + end; + if (Self.DLManager = nil) and Assigned(DLManager) then + begin Self.DLManager := DLManager; - if Self.DLManager = nil then Exit; + end; + if Self.DLManager = nil then + begin + Exit; + end; Self.Sort(Self.FSortColumn); Lock; @@ -785,6 +917,7 @@ procedure TFavoriteManager.ShowResult; try // check for all favorites for i := 0 to Items.Count - 1 do + begin with Items[i] do begin if Assigned(NewMangaInfo) then @@ -798,9 +931,8 @@ procedure TFavoriteManager.ShowResult; Inc(numOfMangaNewChapters); Inc(numOfNewChapters, NewMangaInfoChaptersPos.Count); end - else // completed series add to notification - if OptionAutoCheckFavRemoveCompletedManga and + else if OptionAutoCheckFavRemoveCompletedManga and (NewMangaInfo.Status = MangaInfo_StatusCompleted) then begin removeListStr += LineEnding + Format('- %s <%s>', @@ -809,11 +941,13 @@ procedure TFavoriteManager.ShowResult; end; end; end; + end; // if there is completed mangas, show dialog if numOfCompleted > 0 then begin with TNewChapter.Create(MainForm) do + begin try Caption := RS_DlgCompletedMangaCaption; lbNotification.Caption := Format(RS_LblMangaWillBeRemoved, [numOfCompleted]); @@ -828,21 +962,28 @@ procedure TFavoriteManager.ShowResult; finally Free; end; + end; //delete complete FFavorites if LNCResult = ncrDownload then begin i := 0; while i < Items.Count do + begin with Items[i] do begin if Assigned(NewMangaInfo) and (NewMangaInfoChaptersPos.Count = 0) and (NewMangaInfo.Status = MangaInfo_StatusCompleted) then - Delete(i) + begin + Delete(i); + end else + begin Inc(i); + end; end; + end; end; end; @@ -850,13 +991,16 @@ procedure TFavoriteManager.ShowResult; if numOfNewChapters > 0 then begin if OptionAutoCheckFavDownload then - LNCResult := ncrDownload + begin + LNCResult := ncrDownload; + end else + begin with TNewChapter.Create(MainForm) do + begin try Caption := RS_DlgNewChapterCaption; - lbNotification.Caption := - Format(RS_LblNewChapterFound, [numOfNewChapters, numOfMangaNewChapters]); + lbNotification.Caption := Format(RS_LblNewChapterFound, [numOfNewChapters, numOfMangaNewChapters]); mmMemo.Lines.Text := Trim(newChapterListStr); btDownload.Caption := RS_BtnDownload; btQueue.Caption := RS_BtnAddToQueue; @@ -869,67 +1013,76 @@ procedure TFavoriteManager.ShowResult; finally Free; end; + end; + end; // generate download task if LNCResult <> ncrCancel then begin while DLManager.isRunningBackup do + begin Sleep(100); + end; DLManager.Lock; try for i := 0 to Items.Count - 1 do - with Items[i] do - if Assigned(NewMangaInfo) and - (NewMangaInfoChaptersPos.Count > 0) then + begin + with Items[i] do begin - with DLManager.AddTask do + if Assigned(NewMangaInfo) and (NewMangaInfoChaptersPos.Count > 0) then begin - Manager := DLManager; - CurrentDownloadChapterPtr := 0; - DownloadInfo.Module := FavoriteInfo.Module; - DownloadInfo.Link := FavoriteInfo.Link; - DownloadInfo.Title := FavoriteInfo.Title; - DownloadInfo.SaveTo := FavoriteInfo.SaveTo; - DownloadInfo.DateAdded := Now; - DownloadInfo.DateLastDownloaded := Now; - - for j := 0 to NewMangaInfoChaptersPos.Count - 1 do + with DLManager.AddTask do begin - ChapterLinks.Add(NewMangaInfo.ChapterLinks[NewMangaInfoChaptersPos[j]]); - ChapterNames.Add(CustomRename( - OptionChapterCustomRename, - FavoriteInfo.Website, - FavoriteInfo.Title, - NewMangaInfo.Authors, - NewMangaInfo.Artists, - NewMangaInfo.ChapterNames[NewMangaInfoChaptersPos[j]], - Format('%.4d', [NewMangaInfoChaptersPos[j] + 1]), - OptionChangeUnicodeCharacter, - OptionChangeUnicodeCharacterStr)); + Manager := DLManager; + CurrentDownloadChapterPtr := 0; + DownloadInfo.Module := FavoriteInfo.Module; + DownloadInfo.Link := FavoriteInfo.Link; + DownloadInfo.Title := FavoriteInfo.Title; + DownloadInfo.SaveTo := FavoriteInfo.SaveTo; + DownloadInfo.DateAdded := Now; + DownloadInfo.DateLastDownloaded := Now; + + for j := 0 to NewMangaInfoChaptersPos.Count - 1 do + begin + ChapterLinks.Add(NewMangaInfo.ChapterLinks[NewMangaInfoChaptersPos[j]]); + ChapterNames.Add(CustomRename( + OptionChapterCustomRename, + FavoriteInfo.Website, + FavoriteInfo.Title, + NewMangaInfo.Authors, + NewMangaInfo.Artists, + NewMangaInfo.ChapterNames[NewMangaInfoChaptersPos[j]], + Format('%.4d', [NewMangaInfoChaptersPos[j] + 1]), + OptionChangeUnicodeCharacter, + OptionChangeUnicodeCharacterStr)); + end; + + if LNCResult = ncrDownload then + begin + DownloadInfo.Status := Format('[%d/%d] %s',[0,ChapterLinks.Count,RS_Waiting]); + Status := STATUS_WAIT; + end + else + begin + DownloadInfo.Status := Format('[%d/%d] %s',[0,ChapterLinks.Count,RS_Stopped]); + Status := STATUS_STOP; + end; + + DBInsert; + // add to downloaded chapter list + FavoriteInfo.downloadedChapterList := MergeCaseInsensitive([FavoriteInfo.DownloadedChapterList, chapterLinks.Text]); + // add to downloaded chapter list in downloadmanager + DLManager.DownloadedChapters.Chapters[FavoriteInfo.ModuleID, FavoriteInfo.Link] := chapterLinks.Text; end; - if LNCResult = ncrDownload then - begin - DownloadInfo.Status := Format('[%d/%d] %s',[0,ChapterLinks.Count,RS_Waiting]); - Status := STATUS_WAIT; - end - else - begin - DownloadInfo.Status := Format('[%d/%d] %s',[0,ChapterLinks.Count,RS_Stopped]); - Status := STATUS_STOP; - end; - DBInsert; - // add to downloaded chapter list - FavoriteInfo.downloadedChapterList := MergeCaseInsensitive([FavoriteInfo.DownloadedChapterList, chapterLinks.Text]); - // add to downloaded chapter list in downloadmanager - DLManager.DownloadedChapters.Chapters[FavoriteInfo.ModuleID, FavoriteInfo.Link] := chapterLinks.Text; + DBUpdateLastUpdated; + // free unused objects + FreeAndNil(NewMangaInfo); + FreeAndNil(NewMangaInfoChaptersPos); end; - DBUpdateLastUpdated; - // free unused objects - FreeAndNil(NewMangaInfo); - FreeAndNil(NewMangaInfoChaptersPos); end; + end; finally DLManager.UnLock; end; @@ -937,17 +1090,27 @@ procedure TFavoriteManager.ShowResult; if LNCResult in [ncrDownload, ncrQueue] then begin if OptionSortDownloadsOnNewTasks then + begin DLManager.Sort(DLManager.SortColumn); + end; if LNCResult = ncrDownload then + begin DLManager.CheckAndActiveTask; + end; if OptionShowDownloadsTabOnNewTasks then + begin MainForm.pcMain.ActivePage := MainForm.tsDownload; + end; end; if Assigned(OnUpdateDownload) then + begin OnUpdateDownload; + end; if Assigned(OnUpdateFavorite) then + begin OnUpdateFavorite; + end; end; end; @@ -958,12 +1121,16 @@ procedure TFavoriteManager.ShowResult; // check again for unused objects and free them for i := 0 to Items.Count - 1 do + begin with Items[i] do + begin if Assigned(NewMangaInfo) then begin FreeAndNil(NewMangaInfo); FreeAndNil(NewMangaInfoChaptersPos); end; + end; + end; finally UnLock; end; @@ -974,11 +1141,20 @@ function TFavoriteManager.LocateManga(const ATitle, AWebsite: String): TFavorite i: Integer; begin Result := nil; + if Items.Count <> 0 then + begin for i := 0 to Items.Count - 1 do + begin with Items[i].FavoriteInfo do + begin if SameText(ATitle, Title) and SameText(AWebsite, ModuleID) then + begin Exit(Items[i]); + end; + end; + end; + end; end; function TFavoriteManager.IsMangaExist(const ATitle, AWebsite: String): Boolean; @@ -991,11 +1167,20 @@ function TFavoriteManager.LocateMangaByLink(const AModuleID, ALink: String): TFa i: Integer; begin Result := nil; + if Items.Count <> 0 then + begin for i := 0 to Items.Count - 1 do + begin with Items[i].FavoriteInfo do + begin if SameText(AModuleID, ModuleID) and SameText(ALink, Link) then + begin Exit(Items[i]); + end; + end; + end; + end; end; function TFavoriteManager.IsMangaExistByLink(const AModuleID, ALink: String): Boolean; @@ -1008,14 +1193,23 @@ procedure TFavoriteManager.Add(const AModule: Pointer; const ATitle, AStatus, AC var F: TFavoriteContainer; begin - if AModule = nil then Exit; + if AModule = nil then + begin + Exit; + end; + Lock; try - if IsMangaExist(ATitle, TModuleContainer(AModule).ID) then Exit; - F:=TFavoriteContainer.Create(Self); + if IsMangaExist(ATitle, TModuleContainer(AModule).ID) then + begin + Exit; + end; + + F := TFavoriteContainer.Create(Self); F.Enabled := AEnabled; F.FOrder:=Items.Add(F); - with F.FavoriteInfo do begin + with F.FavoriteInfo do + begin Module := AModule; Title := ATitle; Status := AStatus; @@ -1027,13 +1221,17 @@ procedure TFavoriteManager.Add(const AModule: Pointer; const ATitle, AStatus, AC DateLastChecked := Now; DateLastUpdated := Now; end; + F.Status:=STATUS_IDLE; F.DBInsert; finally UnLock; end; + if not isRunning then + begin Sort(SortColumn); + end; end; procedure TFavoriteManager.Replace(const OldId: String; const AModule: Pointer; const ATitle, AStatus, ACurrentChapter, @@ -1041,12 +1239,18 @@ procedure TFavoriteManager.Replace(const OldId: String; const AModule: Pointer; var F: TFavoriteContainer; begin - if AModule = nil then Exit; + if AModule = nil then + begin + Exit; + end; + Lock; try - F:=TFavoriteContainer.Create(Self); + F := TFavoriteContainer.Create(Self); F.FOrder:=Items.Add(F); - with F.FavoriteInfo do begin + + with F.FavoriteInfo do + begin Module := AModule; Title := ATitle; Status := AStatus; @@ -1058,13 +1262,16 @@ procedure TFavoriteManager.Replace(const OldId: String; const AModule: Pointer; DateLastChecked := Now; DateLastUpdated := Now; end; + F.Status:=STATUS_IDLE; F.DBReplace(OldId); finally UnLock; end; if not isRunning then + begin Sort(SortColumn); + end; end; procedure TFavoriteManager.Delete(const Pos: Integer); @@ -1073,6 +1280,7 @@ procedure TFavoriteManager.Delete(const Pos: Integer); begin Dec(FEnabledCount); end; + FFavoritesDB.Delete(Items[Pos].Fid); Items[Pos].Free; Items.Delete(Pos); @@ -1085,6 +1293,7 @@ procedure TFavoriteManager.Remove(const T: TFavoriteContainer); begin Dec(FEnabledCount); end; + FFavoritesDB.Delete(T.Fid); T.Free; Items.Remove(T); @@ -1095,12 +1304,23 @@ procedure TFavoriteManager.Restore; var F: TFavoriteContainer; begin - if not FFavoritesDB.Connection.Connected then Exit; - if not FFavoritesDB.OpenTable(False) then Exit; + if not FFavoritesDB.Connection.Connected then + begin + Exit; + end; + if not FFavoritesDB.OpenTable(False) then + begin + Exit; + end; + try - if FFavoritesDB.Table.RecordCount = 0 then Exit; + if FFavoritesDB.Table.RecordCount = 0 then + begin + Exit; + end; + Lock; - isRunningRestore:=True; + isRunningRestore := True; try //FFavoritesDB.Table.Last; //load all to memory FFavoritesDB.Table.First; @@ -1129,7 +1349,8 @@ procedure TFavoriteManager.Restore; finally UnLock; end; - isRunningRestore:=False; + + isRunningRestore := False; finally FFavoritesDB.CloseTable; end; @@ -1138,6 +1359,7 @@ procedure TFavoriteManager.Restore; procedure TFavoriteManager.Backup; begin Lock; + try DBUpdateOrder; FFavoritesDB.Commit(False); @@ -1151,16 +1373,24 @@ procedure TFavoriteManager.AddToDownloadedChaptersList(const AWebsite, var i: Integer; begin - if (Items.Count = 0) or (AWebsite = '') or (ALink = '') or (AValue.Count = 0) then Exit; + if (Items.Count = 0) or (AWebsite = '') or (ALink = '') or (AValue.Count = 0) then + begin + Exit; + end; + try EnterCriticalsection(FGuardian); for i := 0 to Items.Count - 1 do + begin with Items[i].FavoriteInfo do + begin if SameText(AWebsite, ModuleID) and SameText(ALink, Link) then begin DownloadedChapterList := MergeCaseInsensitive([DownloadedChapterList, AValue.Text]); Break; end; + end; + end; finally LeaveCriticalsection(FGuardian); end; @@ -1171,6 +1401,7 @@ function CompareFavoriteContainer(const Item1, Item2: TFavoriteContainer): Integ function GetStr(ARow: TFavoriteContainer): String; begin with ARow.FavoriteInfo do + begin case ARow.FManager.SortColumn of 1: Result := Title; 2: Result := currentChapter; @@ -1180,11 +1411,13 @@ function CompareFavoriteContainer(const Item1, Item2: TFavoriteContainer): Integ else Result := ''; end; + end; end; function GetDateTime(ARow: TFavoriteContainer): TDateTime; begin with ARow.FavoriteInfo do + begin case ARow.FManager.SortColumn of 6: Result := DateAdded; 7: Result := DateLastChecked; @@ -1192,29 +1425,44 @@ function CompareFavoriteContainer(const Item1, Item2: TFavoriteContainer): Integ else Result := Now; end; + end; end; begin if (Item1.FManager.SortColumn >= 6) and (Item1.FManager.SortColumn <= 8) then begin if Item1.FManager.SortDirection then - Result := CompareDateTime(GetDateTime(Item2), GetDateTime(Item1)) + begin + Result := CompareDateTime(GetDateTime(Item2), GetDateTime(Item1)); + end else + begin Result := CompareDateTime(GetDateTime(Item1), GetDateTime(Item2)); + end; end else begin if Item1.FManager.SortDirection then - Result := NaturalCompareStr(GetStr(Item2), GetStr(Item1)) + begin + Result := NaturalCompareStr(GetStr(Item2), GetStr(Item1)); + end else Result := NaturalCompareStr(GetStr(Item1), GetStr(Item2)); end; - if Result = 0 then Result := NaturalCompareStr(Item1.FavoriteInfo.Title, Item2.FavoriteInfo.Title); + + if Result = 0 then + begin + Result := NaturalCompareStr(Item1.FavoriteInfo.Title, Item2.FavoriteInfo.Title); + end; end; procedure TFavoriteManager.Sort(const AColumn: Integer); begin - if Items.Count < 2 then Exit; + if Items.Count < 2 then + begin + Exit; + end; + EnterCriticalSection(FGuardian); try SortColumn := AColumn; diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 1c7dc3986..68005611c 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -1414,8 +1414,9 @@ procedure TMainForm.FormCreate(Sender: TObject); AddToAboutStatus(RS_Version, FMD_VERSION_STRING, pnAboutVersion); if REVISION_NUMBER <> '' then begin - AddToAboutStatus(RS_Revision, REVISION_NUMBER+' ('+REVISION_SHA+')', pnAboutVersion); + AddToAboutStatus(RS_Revision, REVISION_NUMBER + ' (' + REVISION_SHA + ')', pnAboutVersion); end; +end; procedure TMainForm.SetCaption; var @@ -1437,17 +1438,18 @@ procedure TMainForm.SetCaption; procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin - if (END_SESSION=False) and + if (END_SESSION = False) and (cbOptionShowQuitDialog.Checked and (DoAfterFMD = DO_NOTHING) and (not OptionRestartFMD)) then begin if CenteredMessageDlg(Self, RS_DlgQuit, mtConfirmation, [mbYes, mbNo], 0) <> mrYes then begin - Logger.Send(Self.ClassName+'.FormClose aborted!'); + Logger.Send(Self.ClassName + '.FormClose aborted!'); CloseAction := caNone; Exit; end; end; - Logger.Send(Self.ClassName+'.FormClose'); + + Logger.Send(Self.ClassName + '.FormClose'); Hide; CloseNow; CloseAction := caFree; @@ -1456,38 +1458,94 @@ procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure TMainForm.CloseNow; begin if OptionDeleteCompletedTasksOnClose then + begin miDownloadDeleteCompletedClick(nil); + end; isExiting := True; {$ifdef windows} if Assigned(PrevWndProc) then + begin windows.SetWindowLongPtr(Self.Handle, GWL_WNDPROC, PtrInt(PrevWndProc)); + end; {$endif} if FavoriteManager.isRunning then + begin FavoriteManager.StopChekForNewChapter(True); + end; + if SilentThreadManager.Count > 0 then + begin SilentThreadManager.StopAll(True); - if DLManager.ItemsActiveTask.Count > 0 then + end; + + if DLManager.ItemsActiveTask.Count > 0 then begin DLManager.StopAllDownloadTasksForExit; + end; //Terminating all threads and wait for it - if Assigned(CheckUpdateThread) then CheckUpdateThread.Terminate; - if Assigned(SearchDBThread) then SearchDBThread.Terminate; - if Assigned(OpenDBThread) then OpenDBThread.Terminate; - if Assigned(GetInfosThread) then try GetInfosThread.Terminate; except end; - if isUpdating then updateList.Terminate; - if Assigned(DBUpdaterThread) then DBUpdaterThread.Terminate; - if Assigned(SelfUpdaterThread) then SelfUpdaterThread.Terminate; - - if Assigned(CheckUpdateThread) then CheckUpdateThread.WaitFor; - if Assigned(SearchDBThread) then SearchDBThread.WaitFor; - if Assigned(OpenDBThread) then OpenDBThread.WaitFor; - if Assigned(GetInfosThread) then GetInfosThread.WaitFor; - if isUpdating then updateList.WaitFor; - if Assigned(DBUpdaterThread) then DBUpdaterThread.WaitFor; - if Assigned(SelfUpdaterThread) then SelfUpdaterThread.WaitFor; + if Assigned(CheckUpdateThread) then + begin + CheckUpdateThread.Terminate; + end; + if Assigned(SearchDBThread) then + begin + SearchDBThread.Terminate; + end; + if Assigned(OpenDBThread) then + begin + OpenDBThread.Terminate; + end; + if Assigned(GetInfosThread) then + begin + try + GetInfosThread.Terminate; + except + end; + end; + if isUpdating then + begin + updateList.Terminate; + end; + if Assigned(DBUpdaterThread) then + begin + DBUpdaterThread.Terminate; + end; + if Assigned(SelfUpdaterThread) then + begin + SelfUpdaterThread.Terminate; + end; + + if Assigned(CheckUpdateThread) then + begin + CheckUpdateThread.WaitFor; + end; + if Assigned(SearchDBThread) then + begin + SearchDBThread.WaitFor; + end; + if Assigned(OpenDBThread) then + begin + OpenDBThread.WaitFor; + end; + if Assigned(GetInfosThread) then + begin + GetInfosThread.WaitFor; + end; + if isUpdating then + begin + updateList.WaitFor; + end; + if Assigned(DBUpdaterThread) then + begin + DBUpdaterThread.WaitFor; + end; + if Assigned(SelfUpdaterThread) then + begin + SelfUpdaterThread.WaitFor; + end; Timer1Hour.Enabled := False; TimerBackup.Enabled := False; @@ -1504,10 +1562,14 @@ procedure TMainForm.CloseNow; //embed form if Assigned(AccountManagerForm) then + begin AccountManagerForm.Close; + end; if Assigned(FormDropTarget) then + begin FormDropTarget.Close; + end; if FMDInstance <> nil then begin @@ -1644,14 +1706,21 @@ procedure TMainForm.miFavoritesEnableClick(Sender: TObject); var Node: PVirtualNode; begin - if vtFavorites.SelectedCount = 0 then Exit; + if vtFavorites.SelectedCount = 0 then + begin + Exit; + end; + FavoriteManager.Lock; try Node := vtFavorites.GetFirstSelected(); while Assigned(Node) do begin if Sender = miFavoritesDisable then + begin FavoriteManager.StopChekForNewChapter(False, Node^.Index); + end; + FavoriteManager[Node^.Index].Enabled := (Sender = miFavoritesEnable); Node := vtFavorites.GetNextSelected(Node); end; @@ -1673,6 +1742,7 @@ procedure TMainForm.miFavoritesRenameClick(Sender: TObject); begin t := FavoriteManager.Items[node^.Index]; tt := t.FavoriteInfo.Title; + if InputQuery('', RS_InfoTitle, tt) then begin t.FavoriteInfo.Title := tt; @@ -1688,37 +1758,46 @@ procedure TMainForm.miFavoritesTransferWebsiteClick(Sender: TObject); Data: PFavContainer; begin with TTransferFavoritesForm.Create(nil) do - try - FavoriteManager.isRunning := True; - sm := mrNone; + begin try - Node := vtFavorites.GetFirstSelected(); - while Assigned(Node) do - begin - AddFav(FavoriteManager.Items[Node^.Index]); - Node := vtFavorites.GetNextSelected(Node); + FavoriteManager.isRunning := True; + sm := mrNone; + try + Node := vtFavorites.GetFirstSelected(); + + while Assigned(Node) do + begin + AddFav(FavoriteManager.Items[Node^.Index]); + Node := vtFavorites.GetNextSelected(Node); + end; + + sm := ShowModal; + finally + FavoriteManager.isRunning := False; end; - sm := ShowModal; - finally - FavoriteManager.isRunning := False; - end; - if sm = mrOK then - begin - UpdateVtFavorites; - if ckClearDownloadedChapters.Checked then + + if sm = mrOK then begin - Node := vtFavs.GetFirst(); - while Assigned(Node) do + UpdateVtFavorites; + if ckClearDownloadedChapters.Checked then begin - Data := vtFavs.GetNodeData(Node); - if Data^.NewLink <> '' then - FavoriteManager.CheckForNewChapter(FavoriteManager.Items.IndexOf(Data^.Fav)); - Node := vtFavs.GetNext(Node); + Node := vtFavs.GetFirst(); + + while Assigned(Node) do + begin + Data := vtFavs.GetNodeData(Node); + if Data^.NewLink <> '' then + begin + FavoriteManager.CheckForNewChapter(FavoriteManager.Items.IndexOf(Data^.Fav)); + end; + + Node := vtFavs.GetNext(Node); + end; end; end; + finally + Free; end; - finally - Free; end; end; @@ -1726,8 +1805,15 @@ procedure TMainForm.rbFavoritesShowAllChange(Sender: TObject); var xNode: PVirtualNode; begin - if rbFavoritesShowAll.Checked = False then Exit; - if vtFavorites.RootNodeCount = 0 then Exit; + if rbFavoritesShowAll.Checked = False then + begin + Exit; + end; + if vtFavorites.RootNodeCount = 0 then + begin + Exit; + end; + vtFavorites.BeginUpdate; try xNode := vtFavorites.GetFirst(); @@ -1745,8 +1831,15 @@ procedure TMainForm.rbFavoritesShowDisabledChange(Sender: TObject); var xNode: PVirtualNode; begin - if rbFavoritesShowDisabled.Checked = False then Exit; - if vtFavorites.RootNodeCount = 0 then Exit; + if rbFavoritesShowDisabled.Checked = False then + begin + Exit; + end; + if vtFavorites.RootNodeCount = 0 then + begin + Exit; + end; + vtFavorites.BeginUpdate; try xNode := vtFavorites.GetFirst(); @@ -1764,8 +1857,15 @@ procedure TMainForm.rbFavoritesShowEnabledChange(Sender: TObject); var xNode: PVirtualNode; begin - if rbFavoritesShowEnabled.Checked = False then Exit; - if vtFavorites.RootNodeCount = 0 then Exit; + if rbFavoritesShowEnabled.Checked = False then + begin + Exit; + end; + if vtFavorites.RootNodeCount = 0 then + begin + Exit; + end; + vtFavorites.BeginUpdate; try xNode := vtFavorites.GetFirst(); @@ -1781,7 +1881,11 @@ procedure TMainForm.rbFavoritesShowEnabledChange(Sender: TObject); procedure TMainForm.tbmiDownloadMoveTopClick(Sender: TObject); begin - if vtDownload.SelectedCount = 0 then Exit; + if vtDownload.SelectedCount = 0 then + begin + Exit; + end; + vtDownloadMoveItems(0, dmAbove); end; @@ -1789,10 +1893,16 @@ procedure TMainForm.tbmiDownloadMoveUpClick(Sender: TObject); var p: Cardinal; begin - if vtDownload.SelectedCount = 0 then Exit; + if vtDownload.SelectedCount = 0 then + begin + Exit; + end; + p := vtDownload.GetFirstSelected()^.Index; if p > 0 then + begin vtDownloadMoveItems(p - 1, dmAbove); + end; end; procedure TMainForm.tbWebsitesSelectAllClick(Sender: TObject); @@ -1802,7 +1912,7 @@ procedure TMainForm.tbWebsitesSelectAllClick(Sender: TObject); begin { Check if any top level entries are expanded } node := vtOptionMangaSiteSelection.GetFirstVisible(); - while node<>nil do + while node <> nil do begin if node^.ChildCount = 0 then begin @@ -1810,22 +1920,28 @@ procedure TMainForm.tbWebsitesSelectAllClick(Sender: TObject); // If at least one element without child elements is visible, we don't have to expand all elements: break; end; + node := vtOptionMangaSiteSelection.GetNextVisible(node); end; // If all top level entries are collapsed, expand all: - if b = False then vtOptionMangaSiteSelection.FullExpand; + if b = False then + begin + vtOptionMangaSiteSelection.FullExpand; + end; { Set all visible elements to checked state } node := vtOptionMangaSiteSelection.GetFirstVisible(); - while node<>nil do + while node <> nil do begin if node^.ChildCount = 0 then begin node^.CheckState := csCheckedNormal; end; + node := vtOptionMangaSiteSelection.GetNextVisible(node); end; + vtOptionMangaSiteSelection.Refresh(); end; @@ -1836,7 +1952,7 @@ procedure TMainForm.tbWebsitesUnselectAllClick(Sender: TObject); begin { Check if any top level entries are expanded } node := vtOptionMangaSiteSelection.GetFirstVisible(); - while node<>nil do + while node <> nil do begin if node^.ChildCount = 0 then begin @@ -1848,16 +1964,20 @@ procedure TMainForm.tbWebsitesUnselectAllClick(Sender: TObject); end; // If all top level entries are collapsed, expand all: - if b = False then vtOptionMangaSiteSelection.FullExpand; + if b = False then + begin + vtOptionMangaSiteSelection.FullExpand; + end; { Set all visible elements to unchecked state } node := vtOptionMangaSiteSelection.GetFirstVisible(); - while node<>nil do + while node <> nil do begin if node^.ChildCount = 0 then begin node^.CheckState := csUncheckedNormal; end; + node := vtOptionMangaSiteSelection.GetNextVisible(node); end; vtOptionMangaSiteSelection.Refresh(); @@ -1865,14 +1985,22 @@ procedure TMainForm.tbWebsitesUnselectAllClick(Sender: TObject); procedure TMainForm.tbmiDownloadMoveDownClick(Sender: TObject); begin - if vtDownload.SelectedCount = 0 then Exit; + if vtDownload.SelectedCount = 0 then + begin + Exit; + end; + vtDownloadMoveItems(vtDownload.GetFirstSelected()^.Index, dmBelow); end; procedure TMainForm.tbmiDownloadMoveBottomClick(Sender: TObject); begin - if vtDownload.SelectedCount = 0 then Exit; - vtDownloadMoveItems(vtDownload.RootNodeCount - 1, dmBelow); + if vtDownload.SelectedCount = 0 then + begin + Exit; + end; + + vtDownloadMoveItems(vtDownload.RootNodeCount - 1, dmBelow); end; procedure TMainForm.tmAnimateMangaInfoTimer(Sender: TObject); @@ -1882,13 +2010,18 @@ procedure TMainForm.tmAnimateMangaInfoTimer(Sender: TObject); procedure TMainForm.tmCheckFavoritesTimer(Sender: TObject); begin - if IsDlgCounter then Exit; + if IsDlgCounter then + begin + Exit; + end; + tmCheckFavorites.Enabled := False; if OptionAutoCheckLatestVersion then begin btCheckLatestVersionClick(btCheckLatestVersion); LuaModulesUpdaterForm.btCheckUpdateClick(LuaModulesUpdaterForm.btCheckUpdate); end; + FavoriteManager.isAuto := True; FavoriteManager.CheckForNewChapter; end; @@ -1896,43 +2029,52 @@ procedure TMainForm.tmCheckFavoritesTimer(Sender: TObject); function TMainForm.ShowExitCounter: Boolean; begin IsDlgCounter := True; - with TShutdownCounterForm.Create(nil) do try - case DoAfterFMD of - DO_POWEROFF: - begin - WaitTimeout := 60; - LabelMessage := RS_LblMessageShutdown; - end; - DO_HIBERNATE: - begin - WaitTimeout := 30; - LabelMessage := RS_LblMessageHibernate; - end; - DO_EXIT: - begin - WaitTimeout := 5; - LabelMessage := RS_LblMessageExit; - end; - else; + + with TShutdownCounterForm.Create(nil) do + begin + try + case DoAfterFMD of + DO_POWEROFF: + begin + WaitTimeout := 60; + LabelMessage := RS_LblMessageShutdown; + end; + DO_HIBERNATE: + begin + WaitTimeout := 30; + LabelMessage := RS_LblMessageHibernate; + end; + DO_EXIT: + begin + WaitTimeout := 5; + LabelMessage := RS_LblMessageExit; + end; + else; + end; + Result := (ShowModal = mrOK); + finally + Free; end; - Result := (ShowModal = mrOK); - finally - Free; end; - isPendingExitCounter:=False; + + isPendingExitCounter := False; IsDlgCounter := False; end; procedure TMainForm.OpenDataDB(const AWebsite: String); begin if OpenDBThread = nil then + begin OpenDBThread := TOpenDBThread.Create(AWebsite); + end; end; procedure TMainForm.SearchDataDB(const ATitle: String); begin if SearchDBThread = nil then - SearchDBThread := TSearchDBThread.Create(ATitle) + begin + SearchDBThread := TSearchDBThread.Create(ATitle); + end else begin SearchDBThread.NewSearch(ATitle); @@ -1944,8 +2086,12 @@ procedure TMainForm.FilterGenreChangeAllState(const AState: TCheckBoxState); i: Integer; begin for i := 0 to pnGenres.ControlCount - 1 do + begin if pnGenres.Controls[i] is TCheckBox then + begin TCheckBox(pnGenres.Controls[i]).State := AState; + end; + end; end; procedure TMainForm.FilterChapterList(const SearchStr: String; @@ -1955,30 +2101,44 @@ procedure TMainForm.FilterChapterList(const SearchStr: String; S: String; isShow: Boolean; begin - if clbChapterList.RootNodeCount = 0 then Exit; + if clbChapterList.RootNodeCount = 0 then + begin + Exit; + end; + with clbChapterList do + begin try BeginUpdate; S := AnsiUpperCase(SearchStr); Node := GetFirst(); + while Assigned(Node) do begin isShow := True; if HideDownloaded then + begin isShow := not ChapterList[Node^.Index].Downloaded; + end; + if isShow and (S <> '') then + begin isShow := Pos(S, AnsiUpperCase(ChapterList[Node^.Index].Title)) <> 0; + end; + IsVisible[Node] := isShow; Node := GetNext(Node); end; finally EndUpdate; end; + end; end; procedure TMainForm.tmExitCommandTimer(Sender: TObject); begin tmExitCommand.Enabled := False; + if DoAfterFMD <> DO_NOTHING then begin if DoAfterFMD in [DO_POWEROFF, DO_HIBERNATE, DO_EXIT] then @@ -1987,19 +2147,23 @@ procedure TMainForm.tmExitCommandTimer(Sender: TObject); begin Self.CloseNow; if DoAfterFMD = DO_POWEROFF then - fmdPowerOff - else - if DoAfterFMD = DO_HIBERNATE then + begin + fmdPowerOff; + end + else if DoAfterFMD = DO_HIBERNATE then + begin fmdHibernate; + end; + Self.Close; end; end - else - if DoAfterFMD = DO_UPDATE then + else if DoAfterFMD = DO_UPDATE then begin Self.CloseNow; Self.Close; end; + DoAfterFMD := DO_NOTHING; end; end; @@ -2008,14 +2172,16 @@ procedure TMainForm.tmRefreshDownloadsInfoStartTimer(Sender: TObject); begin if Assigned(DLManager) then begin - TransferRateGraphInit(round(TransferRateGraph.Width/4)+1); + TransferRateGraphInit(round(TransferRateGraph.Width / 4) + 1); TransferRateGraph.Visible := True; {$ifdef windows} StandbyCounter := 0; {$endif} end else + begin tmRefreshDownloadsInfo.Enabled := False; + end; end; procedure TMainForm.tmRefreshDownloadsInfoStopTimer(Sender: TObject); @@ -2044,24 +2210,33 @@ procedure DumpLoadedModules; i: Integer; s: string; begin - s:=#10; - for i:=0 to Modules.Count-1 do - if Modules.Count<>0 then - s+=Modules[i].ID+' '+Modules[i].Name+#10; - Logger.Send('loaded modules: '+IntToStr(Modules.Count),s); + s := #10; + for i := 0 to Modules.Count - 1 do + begin + if Modules.Count <> 0 then + begin + s += Modules[i].ID + ' ' + Modules[i].Name + #10; + end; + end; + + Logger.Send('loaded modules: ' + IntToStr(Modules.Count), s); end; procedure TMainForm.tmStartupTimer(Sender: TObject); begin try - if Sender=tmStartup then + if Sender = tmStartup then + begin FreeAndNil(tmStartup); + end; //load lua modules ScanLuaWebsiteModulesFile; AddToAboutStatus('Modules', IntToStr(Modules.Count)); if AppParams.IndexOf('--dump-loaded-modules') <> -1 then + begin DumpLoadedModules; + end; Modules.LoadFromFile; WebsiteOptionCustomForm.CreateWebsiteOption; @@ -2081,7 +2256,6 @@ procedure TMainForm.tmStartupTimer(Sender: TObject); Logger.SendException('tmStartup Error!', E); end; - if OptionAutoCheckLatestVersion then begin btCheckLatestVersionClick(btCheckLatestVersion); @@ -2102,7 +2276,9 @@ procedure TMainForm.tmStartupTimer(Sender: TObject); UpdateVtFavorites; if cbSelectManga.ItemIndex <> -1 then + begin OpenDataDB(TModuleContainer(currentWebsite).ID); + end; end; procedure TMainForm.medURLCutClick(Sender: TObject); @@ -4427,7 +4603,10 @@ procedure TMainForm.UniqueInstanceFMDOtherInstance(Sender: TObject; ParamCount: Integer; Parameters: array of String); begin if WindowState = wsMinimized then + begin WindowState := wsNormal; + end; + Show; BringToFront; end; @@ -6854,10 +7033,27 @@ procedure TMainForm.ApplyLanguage; idxOptionWebPConvertTo, idxOptionWebPPNGLevel: Integer; begin - if AvailableLanguages.Count = 0 then Exit; - if cbLanguages.ItemIndex < 0 then Exit; - if cbLanguages.ItemIndex >= AvailableLanguages.Count then Exit; - if winBuildNumber < 17763 then cbDarkmode.Enabled := False else cbDarkmode.Enabled := True; + if AvailableLanguages.Count = 0 then + begin + Exit; + end; + if cbLanguages.ItemIndex < 0 then + begin + Exit; + end; + if cbLanguages.ItemIndex >= AvailableLanguages.Count then + begin + Exit; + end; + if winBuildNumber < 17763 then + begin + cbDarkmode.Enabled := False + end + else + begin + cbDarkmode.Enabled := True; + end; + if SimpleTranslator.LastSelected <> AvailableLanguages.Names[cbLanguages.ItemIndex] then begin // TCombobox.Items will be cleared upon changing language, @@ -6890,7 +7086,7 @@ procedure TMainForm.ApplyLanguage; cbPNGCompressionLevel.Items.Text := RS_WebPPNGLevel; // restore ItemIndex - cbSelectManga.ItemIndex:=idxSelectManga; + cbSelectManga.ItemIndex := idxSelectManga; cbLanguages.ItemIndex := idxLanguages; cbDarkmode.ItemIndex := idxDarkmode; cbFilterStatus.ItemIndex := idxFilterStatus; diff --git a/updater/uMain.pas b/updater/uMain.pas index cfb7b45fb..e599b8cc4 100644 --- a/updater/uMain.pas +++ b/updater/uMain.pas @@ -605,9 +605,13 @@ procedure TfrmMain.FormShow(Sender: TObject); Break; end else if s = '-q' then - _NoError := True + begin + _NoError := True; + end else if s = '-x' then - _Extract := True + begin + _Extract := True; + end else if i + 1 <= Paramcount then begin //**Update Mode @@ -618,11 +622,17 @@ procedure TfrmMain.FormShow(Sender: TObject); end //**Max Retry else if s = '-r' then - _MaxRetry := StrToIntDef(ParamStrUTF8(i + 1), 1) + begin + _MaxRetry := StrToIntDef(ParamStrUTF8(i + 1), 1); + end else if s = '-l' then - _LaunchApp := ParamStrUTF8(i + 1) + begin + _LaunchApp := ParamStrUTF8(i + 1); + end else if (LowerCase(s) = '--lang') then + begin SimpleTranslator.SetLang(ParamStrUTF8(i + 1), 'updater'); + end; end; end; end; @@ -634,20 +644,26 @@ procedure TfrmMain.FormShow(Sender: TObject); frmMessage.ShowModal; Self.Close; end - else - if (_URL <> '') then + else if (_URL <> '') then begin if Pos('://', _URL) = 0 then + begin _URL := 'http://' + _URL; + end; if ExecRegExpr('^\w+?\://[^/]*\w+\.\w+(\:\d+)?(/|\Z).*$', _URL) then begin dl := TDownloadThread.Create; dl.URL := _URL; dl.MaxRetry := _MaxRetry; if _UpdApp then - dl.DirPath := FMD_DIR + begin + dl.DirPath := FMD_DIR; + end else + begin dl.DirPath := FMD_DIR + 'data' + PathDelim; + end; + dl.Extract := _Extract; dl.Start; itMonitor.Enabled := True; From a696a49b0f74b9608469d89510cce9c6456633f3 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Mon, 2 Feb 2026 22:36:20 +0800 Subject: [PATCH 12/35] Fixed: Dbl click on favourites status instead of save to opening folder --- mangadownloader/forms/frmMain.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 68005611c..55a3c0d92 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -5003,7 +5003,7 @@ procedure TMainForm.vtFavoritesChange(Sender: TBaseVirtualTree; procedure TMainForm.vtFavoritesColumnDblClick(Sender: TBaseVirtualTree; Column: TColumnIndex; Shift: TShiftState); begin - if Column = 4 then + if Column = 5 then begin miFavoritesOpenFolderClick(Sender) end From e6d2b06f7edfc84c579830ddf2d9f441a2c7231b Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Tue, 3 Feb 2026 00:25:04 +0800 Subject: [PATCH 13/35] Fixed: Downloads popup open not disabling on non existing folder #2696 --- mangadownloader/forms/frmMain.pas | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 55a3c0d92..33922e963 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -4376,12 +4376,21 @@ procedure TMainForm.pmDownloadPopup(Sender: TObject); miDownloadDelete.Enabled := True; miDownloadDeleteTask.Enabled := True; miDownloadDeleteTaskData.Enabled := True; - miDownloadOpenWith.Enabled := vtDownload.SelectedCount = 1; - miDownloadOpenFolder.Enabled := miDownloadOpenWith.Enabled; - miDownloadViewMangaInfo.Enabled := miDownloadOpenFolder.Enabled and - (DLManager[vtDownload.FocusedNode^.Index].DownloadInfo.Link <> ''); miDownloadEnable.Enabled := iEnable; miDownloadDisable.Enabled := iDisable; + + if (vtDownload.SelectedCount = 1) and Assigned(vtDownload.FocusedNode) then + begin + miDownloadOpenFolder.Enabled := DirectoryExistsUTF8(DLManager.Items[vtDownload.FocusedNode^.Index].DownloadInfo.SaveTo); + miDownloadOpenWith.Enabled := miDownloadOpenFolder.Enabled; + miDownloadViewMangaInfo.Enabled := (DLManager[vtDownload.FocusedNode^.Index].DownloadInfo.Link <> ''); + end + else + begin + miDownloadOpenFolder.Enabled := False; + miDownloadOpenWith.Enabled := False; + miDownloadViewMangaInfo.Enabled := False; + end; end; end; end; From 335ff24387cc3fc84d059f6d6dbacc9aed4ebe8d Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Tue, 3 Feb 2026 00:25:18 +0800 Subject: [PATCH 14/35] Fixed: More good code practice --- mangadownloader/forms/frmMain.pas | 307 ++++++++++++++++++++++-------- 1 file changed, 223 insertions(+), 84 deletions(-) diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 33922e963..34c679928 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -4324,12 +4324,16 @@ procedure TMainForm.pmDownloadPopup(Sender: TObject); iEnable := False; iDisable := False; Node := vtDownload.GetFirstSelected(); + while Assigned(Node) do begin if DLManager[Node^.Index].Enabled then begin if not iDisable then + begin iDisable := True; + end; + case DLManager[Node^.Index].Status of STATUS_DOWNLOAD, STATUS_PREPARE, @@ -4342,9 +4346,15 @@ procedure TMainForm.pmDownloadPopup(Sender: TObject); end; end else if not iEnable then + begin iEnable := True; + end; + if iStop and iResume and iRedownload and iEnable and iDisable then + begin Break; + end; + Node := vtDownload.GetNextSelected(Node); end; end; @@ -4352,6 +4362,7 @@ procedure TMainForm.pmDownloadPopup(Sender: TObject); begin miDownloadDeleteCompleted.Enabled := DLManager.Count > 0; miDownloadMergeCompleted.Enabled := miDownloadDeleteCompleted.Enabled; + with DLManager do begin if (vtDownload.SelectedCount = 0) or (vtDownload.FocusedNode = nil) then begin @@ -4423,12 +4434,16 @@ procedure TMainForm.pmFavoritesPopup(Sender: TObject); iEnable := False; iDisable := False; Node := vtFavorites.GetFirstSelected(); + while Assigned(Node) do begin if FavoriteManager[Node^.Index].Enabled then begin if not iDisable then + begin iDisable := True; + end; + case FavoriteManager[Node^.Index].Status of STATUS_IDLE : if not iCheck then iCheck := True; STATUS_CHECK, @@ -4437,9 +4452,15 @@ procedure TMainForm.pmFavoritesPopup(Sender: TObject); end; end else if not iEnable then + begin iEnable := True; + end; + if iEnable and iDisable and iCheck and iStop then + begin Break; + end; + Node := vtFavorites.GetNextSelected(Node); end; end; @@ -4466,6 +4487,7 @@ procedure TMainForm.pmFavoritesPopup(Sender: TObject); miFavoritesEnable.Enabled := iEnable; miFavoritesDisable.Enabled := iDisable; miFavoritesTransferWebsite.Enabled := True; + if (vtFavorites.SelectedCount = 1) and Assigned(vtFavorites.FocusedNode) then begin miFavoritesViewInfos.Enabled := True; @@ -4487,6 +4509,7 @@ procedure TMainForm.pmFavoritesPopup(Sender: TObject); miFavoritesRename.Enabled := False; end; end; + if FavoriteManager.isRunning then begin miFavoritesDelete.Enabled := False; @@ -4503,8 +4526,7 @@ procedure TMainForm.pmMangaListPopup(Sender: TObject); pmMangaList.Items[1].Enabled := True; pmMangaList.Items[2].Enabled := True; end - else - if vtMangaList.SelectedCount > 1 then + else if vtMangaList.SelectedCount > 1 then begin pmMangaList.Items[0].Enabled := False; pmMangaList.Items[1].Enabled := True; @@ -4518,10 +4540,14 @@ procedure TMainForm.pmSbMainPopup(Sender: TObject); if Assigned(SilentThreadManager) then begin if SilentThreadManager.Count = 0 then + begin Abort; + end; end else + begin Abort; + end; end; procedure TMainForm.pmTrayPopup(Sender: TObject); @@ -4529,20 +4555,25 @@ procedure TMainForm.pmTrayPopup(Sender: TObject); i: Integer; begin with miTrayAfterDownloadFinish do + begin for i := 0 to Count - 1 do + begin if Items[i].Tag = Integer(OptionLetFMDDo) then begin Items[i].Checked := True; Break; end; + end; + end; + miTrayShowDropBox.Checked := Assigned(FormDropTarget); end; procedure TMainForm.rgOptionCompressSelectionChanged(Sender: TObject); begin - seOptionPDFQuality.Enabled:=rgOptionCompress.ItemIndex=3; - lbOptionPDFQuality.Enabled:=seOptionPDFQuality.Enabled; - lbOptionPDFQualityHint.Enabled:=seOptionPDFQuality.Enabled; + seOptionPDFQuality.Enabled := rgOptionCompress.ItemIndex = 3; + lbOptionPDFQuality.Enabled := seOptionPDFQuality.Enabled; + lbOptionPDFQualityHint.Enabled := seOptionPDFQuality.Enabled; end; procedure TMainForm.seOptionAutoCheckFavIntervalMinutesChange(Sender: TObject); @@ -4559,7 +4590,9 @@ procedure TMainForm.spMainSplitterMoved(Sender: TObject); procedure TMainForm.tbDownloadDeleteCompletedClick(Sender: TObject); begin if DLManager.TaskStatusPresent([STATUS_FINISH]) then + begin miDownloadDeleteCompletedClick(miDownloadDeleteCompleted); + end; end; procedure TMainForm.tbDownloadResumeAllClick(Sender: TObject); @@ -4578,7 +4611,9 @@ procedure TMainForm.tbDropTargetOpacityChange(Sender: TObject); begin frmDropTarget.FAlphaBlendValue := tbDropTargetOpacity.Position; if Assigned(FormDropTarget) then + begin FormDropTarget.AlphaBlendValue := frmDropTarget.FAlphaBlendValue; + end; end; procedure TMainForm.tbWebsitesCollapseAllClick(Sender: TObject); @@ -4600,7 +4635,9 @@ procedure TMainForm.TrayIconDblClick(Sender: TObject); Show; end else + begin Application.BringToFront; + end; end; procedure TMainForm.tvDownloadFilterSelectionChanged(Sender: TObject); @@ -4628,21 +4665,30 @@ procedure TMainForm.vtDownloadAfterCellPaint(Sender: TBaseVirtualTree; Percents: double; ww, hh: Integer; begin - if Column <> 2 then Exit; + if Column <> 2 then + begin + Exit; + end; + with DLManager.Items[Node^.Index], TargetCanvas do begin if Status in [STATUS_FINISH, STATUS_COMPRESS, STATUS_FAILED] then - Percents := 1 - else - if (DLManager.Items[Node^.Index].DownCounter = 0) or + begin + Percents := 1; + end + else if (DLManager.Items[Node^.Index].DownCounter = 0) or (DLManager.Items[Node^.Index].PageNumber = 0) then - Percents := 0 + begin + Percents := 0; + end else + begin Percents := DLManager.Items[Node^.Index].DownCounter / DLManager.Items[Node^.Index].PageNumber; + end; // base bar BarRect := CellRect; - BarRect.Inflate(-2,-2); + BarRect.Inflate(-2, -2); BarRect.Right -= 1; Pen.Style := psSolid; Brush.Style := bsSolid; @@ -4702,9 +4748,13 @@ procedure TMainForm.vtDownloadColumnDblClick(Sender: TBaseVirtualTree; Column: TColumnIndex; Shift: TShiftState); begin if Column = 5 then - miDownloadOpenFolderClick(Sender) + begin + miDownloadOpenFolderClick(Sender); + end else + begin miDownloadOpenWithClick(Sender); + end; end; procedure TMainForm.vtDownloadDragAllowed(Sender : TBaseVirtualTree; @@ -4719,58 +4769,84 @@ procedure TMainForm.vtDownloadMoveItems(NextIndex: Cardinal; Mode: TDropMode); cNode: PVirtualNode; ConTemp: TTaskContainers; begin - if vtDownload.SelectedCount=0 then Exit; - nIndex:=NextIndex; + if vtDownload.SelectedCount = 0 then + begin + Exit; + end; + + nIndex := NextIndex; vtDownload.BeginUpdate; - ConTemp:=TTaskContainers.Create; + ConTemp := TTaskContainers.Create; DLManager.Lock; + try - i:=0; - cNode:=vtDownload.GetFirstSelected(); - while cNode<>nil do - begin - vtDownload.Selected[cNode]:=False; - ConTemp.Add(DLManager.Items[cNode^.Index-i]); - DLManager.Items.Delete(cNode^.Index-i); - if (nIndex>0) and (cNode^.Index nil do + begin + vtDownload.Selected[cNode] := False; + ConTemp.Add(DLManager.Items[cNode^.Index - i]); + DLManager.Items.Delete(cNode^.Index - i); + + if (nIndex > 0) and (cNode^.Index < nIndex) then + begin Dec(nIndex); + end; + Inc(i); - cNode:=vtDownload.GetNextSelected(cNode); + cNode := vtDownload.GetNextSelected(cNode); end; - for i:=0 to ConTemp.Count-1 do + for i := 0 to ConTemp.Count - 1 do begin - if (i=0) and (Mode in [dmBelow,dmNowhere]) then + if (i = 0) and (Mode in [dmBelow, dmNowhere]) then + begin Inc(nIndex) - else if (i>0) and (nIndex 0) and (nIndex < DLManager.Count) then + begin Inc(nIndex); - if nIndex>DLManager.Count then - nIndex:=DLManager.Count; + end; + + if nIndex > DLManager.Count then + begin + nIndex := DLManager.Count; + end; + DLManager.Items.Insert(nIndex, ConTemp[i]); end; - cNode:=vtDownload.GetFirst; - while cNode^.Index1) then + if (Source = vtDownload) and (vtDownload.RootNodeCount > 1) then begin if Mode = dmNowhere then - vtDownloadMoveItems(vtDownload.GetLast^.Index, Mode) + begin + vtDownloadMoveItems(vtDownload.GetLast^.Index, Mode); + end else + begin vtDownloadMoveItems(vtDownload.DropTargetNode^.Index, Mode); + end; end else begin @@ -4798,7 +4878,7 @@ procedure TMainForm.vtDownloadDragOver(Sender : TBaseVirtualTree; Source : TObject; Shift : TShiftState; State : TDragState; const Pt : TPoint; Mode : TDropMode; var Effect : LongWord; var Accept : Boolean); begin - Accept:=True; + Accept := True; end; procedure TMainForm.vtDownloadFocusChanged(Sender: TBaseVirtualTree; @@ -4816,38 +4896,55 @@ procedure TMainForm.vtDownloadGetHint(Sender: TBaseVirtualTree; l, i: Cardinal; begin with DLManager.Items[Node^.Index],DLManager.Items[Node^.Index].DownloadInfo do + begin case Column of 0: begin l := ChapterLinks.Count; - if l>0 then + if l > 0 then begin HintText:=''; - if l<30 then - for i:=0 to l-1 do begin - if HintText<>'' then HintText+=LineEnding; - HintText+=ChapterNames.Strings[i] + if l < 30 then + begin + for i := 0 to l - 1 do + begin + if HintText <> '' then + begin + HintText += LineEnding; + end; + HintText += ChapterNames.Strings[i] end + end else begin - for i:=0 to 14 do begin - if HintText<>'' then HintText+=LineEnding; - HintText+=ChapterNames.Strings[i] + for i := 0 to 14 do + begin + if HintText <> '' then + begin + HintText += LineEnding; + end; + HintText += ChapterNames.Strings[i] end; - HintText+=LineEnding+'...'; - for i:=l-15 to l-1 do begin - if HintText<>'' then HintText+=LineEnding; - HintText+=ChapterNames.Strings[i] + + HintText += LineEnding+'...'; + for i := l - 15 to l - 1 do + begin + if HintText <> '' then + begin + HintText += LineEnding; + end; + HintText += ChapterNames.Strings[i] end; end; end; end; - 1: HintText:=Status; - 2: HintText:=Progress; - 4: HintText:=Website; - 5: HintText:=SaveTo; - 6: HintText:=DateTimeToStr(DateAdded); - 7: HintText:=DateTimeToStr(DateLastDownloaded); + 1: HintText := Status; + 2: HintText := Progress; + 4: HintText := Website; + 5: HintText := SaveTo; + 6: HintText := DateTimeToStr(DateAdded); + 7: HintText := DateTimeToStr(DateLastDownloaded); end; + end; end; procedure TMainForm.vtDownloadGetImageIndex(Sender: TBaseVirtualTree; @@ -4855,10 +4952,16 @@ procedure TMainForm.vtDownloadGetImageIndex(Sender: TBaseVirtualTree; var Ghosted: Boolean; var ImageIndex: Integer); begin if vtDownload.Header.Columns[Column].Position = 0 then + begin if not DLManager[Node^.Index].Enabled then - ImageIndex := 8 + begin + ImageIndex := 8; + end else + begin ImageIndex := Integer(DLManager[Node^.Index].Status); + end; + end; end; procedure TMainForm.vtDownloadGetText(Sender: TBaseVirtualTree; @@ -4866,42 +4969,67 @@ procedure TMainForm.vtDownloadGetText(Sender: TBaseVirtualTree; var CellText: String); begin with DLManager[Node^.Index].DownloadInfo do + begin case Column of - 0: CellText:=Title; - 1: CellText:=Status; + 0: CellText := Title; + 1: CellText := Status; 2: begin - if Progress='' then CellText:='Empty' - else CellText:=Progress; + if Progress = '' then + begin + CellText := 'Empty' + end + else + begin + CellText := Progress; + end; end; - 3: CellText:=TransferRate; - 4: CellText:=Website; - 5: CellText:=SaveTo; - 6: CellText:=DateTimeToStr(DateAdded); - 7: CellText:=DateTimeToStr(DateLastDownloaded); + 3: CellText := TransferRate; + 4: CellText := Website; + 5: CellText := SaveTo; + 6: CellText := DateTimeToStr(DateAdded); + 7: CellText := DateTimeToStr(DateLastDownloaded); end; + end; end; procedure TMainForm.vtDownloadHeaderClick(Sender: TVTHeader; HitInfo: TVTHeaderHitInfo); begin - if HitInfo.Button <> mbLeft then Exit; - if (HitInfo.Column = 2) or (HitInfo.Column = 3) then Exit; + if HitInfo.Button <> mbLeft then + begin + Exit; + end; + if (HitInfo.Column = 2) or (HitInfo.Column = 3) then + begin + Exit; + end; + if DLManager.SortColumn = HitInfo.Column then + begin DLManager.SortDirection := not DLManager.SortDirection; + end; + DLManager.SortColumn := HitInfo.Column; vtDownload.Header.SortDirection := TSortDirection(DLManager.SortDirection); - vtDownload.Header.SortColumn := HitInfo.Column; + vtDownload.Header.SortColumn := HitInfo.Column + if DLManager.Count > 1 then + begin DLManager.Sort(HitInfo.Column); + end; + UpdateVtDownload; end; procedure TMainForm.vtDownloadKeyAction(Sender: TBaseVirtualTree; var CharCode: Word; var Shift: TShiftState; var DoDefault: Boolean); begin - if (ssCtrl in Shift) then begin - if (Sender.SelectedCount>0) and - (CharCode in [VK_UP,VK_DOWN,VK_HOME,VK_END]) then - DoDefault:=False; + if (ssCtrl in Shift) then + begin + if (Sender.SelectedCount > 0) and + (CharCode in [VK_UP, VK_DOWN, VK_HOME, VK_END]) then + begin + DoDefault := False; + end; end; end; @@ -4910,21 +5038,30 @@ procedure TMainForm.vtDownloadKeyDown(Sender : TObject; var Key : Word; var p: Cardinal; begin - if not (ssCtrl in Shift) then Exit; - if vtDownload.SelectedCount=0 then Exit; - p:=vtDownload.GetFirstSelected()^.Index; + if not (ssCtrl in Shift) then + begin + Exit; + end; + if vtDownload.SelectedCount = 0 then + begin + Exit; + end; + + p := vtDownload.GetFirstSelected()^.Index; case Key of - VK_UP : if p>0 then vtDownloadMoveItems(p-1,dmAbove); - VK_DOWN : vtDownloadMoveItems(p,dmBelow); - VK_HOME : vtDownloadMoveItems(0,dmAbove); - VK_END : vtDownloadMoveItems(vtDownload.RootNodeCount-1,dmBelow); + VK_UP : if p > 0 then vtDownloadMoveItems(p - 1, dmAbove); + VK_DOWN : vtDownloadMoveItems(p, dmBelow); + VK_HOME : vtDownloadMoveItems(0, dmAbove); + VK_END : vtDownloadMoveItems(vtDownload.RootNodeCount - 1, dmBelow); end; end; procedure TMainForm.vtDownloadKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_DELETE then + begin miDownloadDeleteTaskClick(miDownloadDeleteTask); + end; end; procedure TMainForm.vtDownloadPaintText(Sender: TBaseVirtualTree; @@ -4932,7 +5069,9 @@ procedure TMainForm.vtDownloadPaintText(Sender: TBaseVirtualTree; TextType: TVSTTextType); begin if not DLManager[Node^.Index].Enabled then + begin TargetCanvas.Font.Color := TVirtualStringTree(Sender).Colors.DisabledColor; + end; end; procedure TMainForm.vtFavoritesBeforeCellPaint(Sender: TBaseVirtualTree; From 7ea753a327b06c253ad91cdf517a80245a990db2 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Tue, 3 Feb 2026 14:35:57 +0800 Subject: [PATCH 15/35] Changed: How errors are handled from GitHub API with some more clarity --- baseunits/GitHubRepoV3.pas | 88 ++++++++++++----- languages/fmd.de.po | 24 ++++- languages/fmd.el_GR.po | 24 ++++- languages/fmd.en.po | 24 ++++- languages/fmd.es.po | 24 ++++- languages/fmd.fr.po | 24 ++++- languages/fmd.id_ID.po | 24 ++++- languages/fmd.pl_PL.po | 24 ++++- languages/fmd.pot | 24 ++++- languages/fmd.pt_BR.po | 24 ++++- languages/fmd.ru_RU.po | 24 ++++- languages/fmd.tr_TR.po | 24 ++++- languages/fmd.zh.po | 24 ++++- .../forms/frmLuaModulesUpdater.pas | 96 +++++++++++++++---- mangadownloader/forms/frmMain.pas | 2 +- 15 files changed, 407 insertions(+), 67 deletions(-) diff --git a/baseunits/GitHubRepoV3.pas b/baseunits/GitHubRepoV3.pas index 32bf6b41b..e65246409 100644 --- a/baseunits/GitHubRepoV3.pas +++ b/baseunits/GitHubRepoV3.pas @@ -39,6 +39,7 @@ TGitHubRepo = class tree_sha, tree_etag: String; + APIResetTime: TDateTime; Tree: TTreeItems; public constructor Create(const AConfigFile, AWorkFile: String; const AThread: TBaseThread = nil); @@ -48,7 +49,7 @@ TGitHubRepo = class function GetTree: Boolean; function GetUpdate: Boolean; function CheckConnection: Boolean; - function CheckRateLimited: Boolean; + procedure CheckRateLimited(AThread: TBaseThread); function GetDownloadURL(const AName: String): String; end; @@ -316,39 +317,77 @@ function TGitHubRepo.CheckConnection: Boolean; end; end; -function TGitHubRepo.CheckRateLimited: Boolean; +procedure TGitHubRepo.CheckRateLimited(AThread: TBaseThread); var - s: String; - d: TJSONData; + AUpdateThread: TCheckUpdateThread; + url, apiMessage: String; + jsonData, jsonCoreData: TJSONData; coreLimit, coreRemaining, coreReset, coreUsed: Integer; - convertedLocalTime: TDateTime; begin - Result := True; HTTP.ResetBasic; - s := AppendURLDelim(api_url) + 'rate_limit'; + url := AppendURLDelim(api_url) + 'rate_limit'; + + if not (AThread is TCheckUpdateThread) then + begin + Exit; + end; - if HTTP.GET(s) then + AUpdateThread := TCheckUpdateThread(AThread); + + if not HTTP.GET(url) then begin - d := GetJSON(HTTP.Document); - if Assigned(d) then - begin - try - if d.JSONType = jtObject then - begin - coreLimit := TJSONObject(d).FindPath('resources.core.limit').AsInteger; - coreRemaining := TJSONObject(d).FindPath('resources.core.remaining').AsInteger; - coreReset := TJSONObject(d).FindPath('resources.core.reset').AsInteger; - coreUsed := TJSONObject(d).FindPath('resources.core.used').AsInteger; + AUpdateThread.DoSyncGitHubConnectFail; + Exit; + end; - convertedLocalTime := UniversalTimeToLocal(UnixToDateTime(coreReset)); - Logger.Send(Self.ClassName + ': ' + Format(RS_GitHubRateStats, [coreLimit, coreRemaining, coreUsed, DateTimeToStr(convertedLocalTime)])); + jsonData := GetJSON(HTTP.Document); - Result := coreRemaining = 0; - end; - except + if not Assigned(jsonData) then + begin + AUpdateThread.DoSyncGitHubErrorMessage(False); + Exit; + end; + + try + if jsonData.JSONType <> jtObject then + begin + AUpdateThread.DoSyncGitHubErrorMessage(False); + Exit; + end; + + jsonCoreData := TJSONObject(jsonData).FindPath('resources.core'); + if not Assigned(jsonCoreData) then + begin + apiMessage := TJSONObject(jsonData).Get('message', ''); + + if apiMessage <> '' then + begin + AUpdateThread.DoSyncGitHubErrorMessage; + Logger.SendWarning(Self.ClassName + ': ' + apiMessage); + end + else + begin + AUpdateThread.DoSyncGitHubErrorMessage(False); end; - d.Free; + + Exit; + end; + + coreLimit := TJSONObject(jsonCoreData).Get('limit', 0); + coreRemaining := TJSONObject(jsonCoreData).Get('remaining', 0); + coreReset := TJSONObject(jsonCoreData).Get('reset', 0); + coreUsed := TJSONObject(jsonCoreData).Get('used', 0); + + APIResetTime := UniversalTimeToLocal(UnixToDateTime(coreReset)); + Logger.Send(Self.ClassName + ': ' + Format(RS_GitHubRateStats, [coreLimit, coreRemaining, coreUsed, DateTimeToStr(APIResetTime)])); + + if coreRemaining = 0 then + begin + AUpdateThread.DoSyncGitHubRateLimited; end; + + finally + jsonData.Free; end; end; @@ -361,6 +400,7 @@ function TGitHubRepo.GetDownloadURL(const AName: String): String; begin lpath := lpath + '/'; end; + Result := AppendURLDelim(download_url) + owner + '/' + name + '/' + ref + '/' + lpath + AName; end; diff --git a/languages/fmd.de.po b/languages/fmd.de.po index 6eb98f3fe..99b334536 100644 --- a/languages/fmd.de.po +++ b/languages/fmd.de.po @@ -195,10 +195,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.el_GR.po b/languages/fmd.el_GR.po index e6eb7a44a..c667c5634 100644 --- a/languages/fmd.el_GR.po +++ b/languages/fmd.el_GR.po @@ -195,10 +195,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.en.po b/languages/fmd.en.po index d965d6997..c22d7f808 100644 --- a/languages/fmd.en.po +++ b/languages/fmd.en.po @@ -200,10 +200,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "Connecting to GitHub..." +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.es.po b/languages/fmd.es.po index af2a6a7af..6087b3e31 100644 --- a/languages/fmd.es.po +++ b/languages/fmd.es.po @@ -195,10 +195,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.fr.po b/languages/fmd.fr.po index 2ad8b24fa..1218eefcd 100644 --- a/languages/fmd.fr.po +++ b/languages/fmd.fr.po @@ -195,10 +195,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.id_ID.po b/languages/fmd.id_ID.po index c69fc2142..7367ae90b 100644 --- a/languages/fmd.id_ID.po +++ b/languages/fmd.id_ID.po @@ -204,10 +204,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "Menyambungkan GitHub..." +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.pl_PL.po b/languages/fmd.pl_PL.po index 4da8d755b..7a77d24ad 100644 --- a/languages/fmd.pl_PL.po +++ b/languages/fmd.pl_PL.po @@ -192,10 +192,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.pot b/languages/fmd.pot index 0f4fd3821..1d27f6f54 100644 --- a/languages/fmd.pot +++ b/languages/fmd.pot @@ -181,10 +181,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.pt_BR.po b/languages/fmd.pt_BR.po index 6052c356b..98df9c61c 100644 --- a/languages/fmd.pt_BR.po +++ b/languages/fmd.pt_BR.po @@ -194,10 +194,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.ru_RU.po b/languages/fmd.ru_RU.po index 978c7950f..a8a16c4f3 100644 --- a/languages/fmd.ru_RU.po +++ b/languages/fmd.ru_RU.po @@ -194,10 +194,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.tr_TR.po b/languages/fmd.tr_TR.po index 7e007de98..5c468dce6 100644 --- a/languages/fmd.tr_TR.po +++ b/languages/fmd.tr_TR.po @@ -196,10 +196,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/languages/fmd.zh.po b/languages/fmd.zh.po index d8f152059..e2084e9ce 100644 --- a/languages/fmd.zh.po +++ b/languages/fmd.zh.po @@ -194,10 +194,30 @@ msgstr "" msgid "Connecting to GitHub..." msgstr "" +#: frmluamodulesupdater.rs_githubdownloadfailed +msgid "" +"Modules update failed to download modules from GitHub.\n" +"Please try update again." +msgstr "" + +#: frmluamodulesupdater.rs_githuberrormessage +msgid "" +"GitHub returned an error.\n" +"Check log for more information." +msgstr "" + +#: frmluamodulesupdater.rs_githubnoerrormessage +#, object-pascal-format +msgid "" +"GitHub API didn't return a valid response.\n" +"Try checking %s in your browser." +msgstr "" + #: frmluamodulesupdater.rs_githubratelimited +#, object-pascal-format msgid "" -"Failed to connect to GitHub API for latest module updates.\n" -"Change the network or try again after 15 minutes" +"GitHub API is rate limited.\n" +"Change the network or try again after %d minute(s)" msgstr "" #: frmluamodulesupdater.rs_githubratestats diff --git a/mangadownloader/forms/frmLuaModulesUpdater.pas b/mangadownloader/forms/frmLuaModulesUpdater.pas index 3c1f0ac59..17d8f6709 100644 --- a/mangadownloader/forms/frmLuaModulesUpdater.pas +++ b/mangadownloader/forms/frmLuaModulesUpdater.pas @@ -138,6 +138,9 @@ TCheckUpdateThread = class(TStatusBarDownload) procedure SyncFinal; procedure SyncGitHubConnectFail; procedure SyncGitHubRateLimited; + procedure SyncGitHubErrorMessage; + procedure SyncGitHubNoErrorMessage; + procedure SyncGitHubDownloadFailed; function SyncRepos(const ARepos, AReposUp: TLuaModulesRepos): Boolean; procedure Download; procedure DoSync; @@ -146,6 +149,9 @@ TCheckUpdateThread = class(TStatusBarDownload) constructor Create(const AOwner: TLuaModulesUpdaterForm); destructor Destroy; override; procedure AddStatus(const S: String); + procedure DoSyncGitHubConnectFail; + procedure DoSyncGitHubRateLimited; + procedure DoSyncGitHubErrorMessage(AError: Boolean = True); end; var @@ -153,8 +159,11 @@ TCheckUpdateThread = class(TStatusBarDownload) resourcestring RS_GitHubConnectFail = 'Failed to connect to GitHub API.'#13#10'Please check your internet connection or try again later.'; - RS_GitHubRateLimited = 'Failed to connect to GitHub API for latest module updates.'#13#10'Change the network or try again after 15 minutes'; + RS_GitHubRateLimited = 'GitHub API is rate limited.'#13#10'Change the network or try again after %d minute(s)'; RS_GitHubRateStats = 'GitHub API core rate - call limit: %d, remaining calls: %d, used calls: %d, limit refresh: %s'; + RS_GitHubErrorMessage = 'GitHub returned an error.'#13#10'Check log for more information.'; + RS_GitHubNoErrorMessage = 'GitHub API didn''t return a valid response.'#13#10'Try checking %s in your browser.'; + RS_GitHubDownloadFailed = 'Modules update failed to download modules from GitHub.'#13#10'Please try update again.'; RS_CheckLocalModules = 'Checking local modules...'; RS_AwaitingProceed = 'Awaiting permission to proceed...'; RS_DeletingFlaggedModules = 'Deleting flagged modules...'; @@ -403,6 +412,7 @@ procedure TDownloadThread.Execute; FOwner.FOwner.ListDirty; FOwner.UpdateProgressBar(FOwner.FDownloadedCount, FOwner.FDownloadTotalCount); FOwner.UpdateStatusText(Format(RS_DownloadingModule, [ExtractFileName(FModule.name)])); + if FHTTP.GET(FOwner.FGitHubRepo.GetDownloadURL(FModule.name)) then begin if ForceDirectories(LUA_REPO_FOLDER) then @@ -419,6 +429,7 @@ procedure TDownloadThread.Execute; if c then begin FHTTP.SaveDocumentToFile(f, False, FModule.last_modified); + if FileExists(f) then begin case FModule.oflag of @@ -427,6 +438,7 @@ procedure TDownloadThread.Execute; fFailedDownload: FOwner.AddStatus(Format(RS_StatusRedownloaded, [FModule.name])); else; end; + FModule.flag := fDownloaded; InterLockedIncrement(FOwner.FDownloadedCount); end; @@ -438,6 +450,7 @@ procedure TDownloadThread.Execute; FOwner.AddStatus(Format(RS_StatusFailed, [FModule.name])); FModule.flag := fFailedDownload; end; + FOwner.FOwner.ListDirty; end; @@ -586,9 +599,54 @@ procedure TCheckUpdateThread.SyncGitHubConnectFail; CenteredMessageDlg(MainForm, RS_GitHubConnectFail, mtError, [mbOk], 0); end; +procedure TCheckUpdateThread.DoSyncGitHubConnectFail; +begin + Synchronize(@SyncGitHubConnectFail); +end; + procedure TCheckUpdateThread.SyncGitHubRateLimited; +var + resetMinutesLeft: Integer; +begin + resetMinutesLeft := Round((FGitHubRepo.APIResetTime - Now) * 24 * 60); + if resetMinutesLeft <= 0 then + begin + resetMinutesLeft := 15; + end; + + CenteredMessageDlg(MainForm, Format(RS_GitHubRateLimited, [resetMinutesLeft]), mtError, [mbOk], 0); +end; + +procedure TCheckUpdateThread.DoSyncGitHubRateLimited; +begin + Synchronize(@SyncGitHubRateLimited); +end; + +procedure TCheckUpdateThread.SyncGitHubNoErrorMessage; +begin + CenteredMessageDlg(MainForm, Format(RS_GitHubNoErrorMessage, [FGitHubRepo.api_url + 'rate_limit']), mtError, [mbOk], 0); +end; + +procedure TCheckUpdateThread.SyncGitHubErrorMessage; +begin + CenteredMessageDlg(MainForm, RS_GitHubErrorMessage, mtError, [mbOk], 0); +end; + +procedure TCheckUpdateThread.DoSyncGitHubErrorMessage(AError: Boolean = True); +begin + if AError then + begin + Synchronize(@SyncGitHubErrorMessage); + end + else + begin + Synchronize(@SyncGitHubNoErrorMessage); + end; +end; + +procedure TCheckUpdateThread.SyncGitHubDownloadFailed; begin - CenteredMessageDlg(MainForm, RS_GitHubRateLimited, mtError, [mbOk], 0); + CenteredMessageDlg(MainForm, RS_GitHubDownloadFailed, mtError, [mbOk], 0); end; function TCheckUpdateThread.SyncRepos(const ARepos, AReposUp: TLuaModulesRepos): Boolean; @@ -774,7 +832,7 @@ procedure TCheckUpdateThread.Download; procedure TCheckUpdateThread.DoSync; var - foundupdate: Boolean; + foundUpdate, downloadFailed: Boolean; i, imax: Integer; m: TLuaModuleRepo; trepos: TLuaModulesRepos; @@ -784,15 +842,7 @@ procedure TCheckUpdateThread.DoSync; LoadingProgressBar; UpdateStatusText(RS_GitHubConnecting); - if not FGitHubRepo.CheckConnection then - begin - Synchronize(@SyncGitHubConnectFail); - end; - - if FGitHubRepo.CheckRateLimited then - begin - Synchronize(@SyncGitHubRateLimited); - end; + FGitHubRepo.CheckRateLimited(Self); if FGitHubRepo.GetUpdate then begin @@ -812,7 +862,7 @@ procedure TCheckUpdateThread.DoSync; if (FReposUp.Count <> 0) and not Terminated then begin // check - foundupdate := SyncRepos(FRepos, FReposUp); + foundUpdate := SyncRepos(FRepos, FReposUp); // look for missing local files and previously failed download for i := 0 to FRepos.Items.Count - 1 do @@ -823,15 +873,15 @@ procedure TCheckUpdateThread.DoSync; if m.flag = fFailedDownload then begin - foundupdate := True + foundUpdate := True end else if (not (m.flag in [fNew, fUpdate])) and (not FileExists(LUA_REPO_FOLDER + TrimFilename(m.name))) then begin m.flag := fFailedDownload; - if not foundupdate then + if not foundUpdate then begin - foundupdate := True; + foundUpdate := True; end; end; case m.flag of @@ -844,12 +894,12 @@ procedure TCheckUpdateThread.DoSync; end; // get properties - //if foundupdate and (not Terminated) then + //if foundUpdate and (not Terminated) then //LoadReposProps; Synchronize(@SyncFinishChecking); - if foundupdate and (not Terminated) then + if foundUpdate and (not Terminated) then begin if OptionModulesUpdaterShowUpdateWarning then begin @@ -870,6 +920,7 @@ procedure TCheckUpdateThread.DoSync; end; // cleanup + downloadFailed := False; i := 0; imax := FRepos.Items.Count; while i < imax do @@ -885,14 +936,22 @@ procedure TCheckUpdateThread.DoSync; if m.flag in [fNew, fUpdate, fFailedDownload] then begin m.flag := fFailedDownload; + downloadFailed := True; end else begin m.flag := fNone; end; + Inc(i); end; end; + + if downloadFailed and FProceed then + begin + Synchronize(@SyncGitHubDownloadFailed); + end; + trepos := FMainRepos; FMainRepos := FRepos; FRepos := trepos; @@ -995,6 +1054,7 @@ procedure TLuaModulesUpdaterForm.btCheckUpdateTerminateClick(Sender: TObject); begin if ThreadCheck <> nil then begin + ThreadCheck.FProceed := False; ThreadCheck.Terminate; end; end; diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 34c679928..05d30e540 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -5010,7 +5010,7 @@ procedure TMainForm.vtDownloadHeaderClick(Sender: TVTHeader; HitInfo: TVTHeaderH DLManager.SortColumn := HitInfo.Column; vtDownload.Header.SortDirection := TSortDirection(DLManager.SortDirection); - vtDownload.Header.SortColumn := HitInfo.Column + vtDownload.Header.SortColumn := HitInfo.Column; if DLManager.Count > 1 then begin From e4b76164b20f394568cfa51cfc7d75c08cda7d68 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Thu, 5 Feb 2026 17:27:40 +0800 Subject: [PATCH 16/35] Added: Error to notify and close FMD if in folder path with unicode char Added: Console output for debug leaks dev build --- languages/fmd.de.po | 4 ++++ languages/fmd.el_GR.po | 4 ++++ languages/fmd.en.po | 4 ++++ languages/fmd.es.po | 4 ++++ languages/fmd.fr.po | 4 ++++ languages/fmd.id_ID.po | 4 ++++ languages/fmd.pl_PL.po | 4 ++++ languages/fmd.pot | 4 ++++ languages/fmd.pt_BR.po | 4 ++++ languages/fmd.ru_RU.po | 4 ++++ languages/fmd.tr_TR.po | 4 ++++ languages/fmd.zh.po | 4 ++++ mangadownloader/forms/frmMain.pas | 1 + mangadownloader/md.lpi | 3 ++- mangadownloader/md.lpr | 21 ++++++++++++++++++++- 15 files changed, 71 insertions(+), 2 deletions(-) diff --git a/languages/fmd.de.po b/languages/fmd.de.po index 99b334536..ba4ead0e0 100644 --- a/languages/fmd.de.po +++ b/languages/fmd.de.po @@ -415,6 +415,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "Free Manga Downloader läuft bereits!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.el_GR.po b/languages/fmd.el_GR.po index c667c5634..dad92a58e 100644 --- a/languages/fmd.el_GR.po +++ b/languages/fmd.el_GR.po @@ -415,6 +415,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "Το Free Manga Downloader εκτελείται ήδη!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.en.po b/languages/fmd.en.po index c22d7f808..4459699e1 100644 --- a/languages/fmd.en.po +++ b/languages/fmd.en.po @@ -420,6 +420,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "Free Manga Downloader already running!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.es.po b/languages/fmd.es.po index 6087b3e31..e3c2a4f7c 100644 --- a/languages/fmd.es.po +++ b/languages/fmd.es.po @@ -415,6 +415,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "¡Free Manga Downloader está ya ejecutandose!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.fr.po b/languages/fmd.fr.po index 1218eefcd..a39b4b2fc 100644 --- a/languages/fmd.fr.po +++ b/languages/fmd.fr.po @@ -417,6 +417,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "Free Manga Downloader est déjà en cours d'exécution !" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.id_ID.po b/languages/fmd.id_ID.po index 7367ae90b..aa7a744eb 100644 --- a/languages/fmd.id_ID.po +++ b/languages/fmd.id_ID.po @@ -424,6 +424,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "Free Manga Downloader sudah berjalan!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.pl_PL.po b/languages/fmd.pl_PL.po index 7a77d24ad..e5b6d2262 100644 --- a/languages/fmd.pl_PL.po +++ b/languages/fmd.pl_PL.po @@ -412,6 +412,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "Free Manga Downloader jest już uruchomiony!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.pot b/languages/fmd.pot index 1d27f6f54..9b91513ba 100644 --- a/languages/fmd.pot +++ b/languages/fmd.pot @@ -384,6 +384,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.pt_BR.po b/languages/fmd.pt_BR.po index 98df9c61c..eab3e5d57 100644 --- a/languages/fmd.pt_BR.po +++ b/languages/fmd.pt_BR.po @@ -414,6 +414,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "Free Manga Downloader já está em execução!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.ru_RU.po b/languages/fmd.ru_RU.po index a8a16c4f3..20b3ad58a 100644 --- a/languages/fmd.ru_RU.po +++ b/languages/fmd.ru_RU.po @@ -414,6 +414,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "Бесплатный Manga Downloader уже запущен!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.tr_TR.po b/languages/fmd.tr_TR.po index 5c468dce6..b38282279 100644 --- a/languages/fmd.tr_TR.po +++ b/languages/fmd.tr_TR.po @@ -416,6 +416,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "Free Manga Downloader zaten çalışıyor!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/languages/fmd.zh.po b/languages/fmd.zh.po index e2084e9ce..7fcceb3f5 100644 --- a/languages/fmd.zh.po +++ b/languages/fmd.zh.po @@ -414,6 +414,10 @@ msgstr "" msgid "Free Manga Downloader already running!" msgstr "免费漫画下载器已在运行!" +#: frmmain.rs_fmdunicodepatherror +msgid "UnicodePathError: Application can't run in a folder path with unicode characters." +msgstr "" + #: frmmain.rs_hintfavoriteproblem msgid "" "There is a problem with this data!\n" diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 05d30e540..ebea49bc1 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -1010,6 +1010,7 @@ TMangaInfoData = record RS_InfoStatus_Unknown = 'Unknown'; RS_InfoSummary = 'Summary:'; RS_FMDAlreadyRunning = 'Free Manga Downloader already running!'; + RS_FMDUnicodePathError = 'UnicodePathError: Application can''t run in a folder path with unicode characters.'; RS_ModeSearching = 'Mode: Searching...'; RS_FavoritesShowAll = 'All'; RS_FavoritesShowEnabled = 'Enabled'; diff --git a/mangadownloader/md.lpi b/mangadownloader/md.lpi index ac004ad05..1cdb0c479 100644 --- a/mangadownloader/md.lpi +++ b/mangadownloader/md.lpi @@ -285,13 +285,14 @@ - + + diff --git a/mangadownloader/md.lpr b/mangadownloader/md.lpr index 8ad5081f9..f05d75c10 100644 --- a/mangadownloader/md.lpr +++ b/mangadownloader/md.lpr @@ -264,11 +264,30 @@ 0: PreferredAppMode := pamAllowDark; 1: PreferredAppMode := pamForceDark; 2: PreferredAppMode := pamForceLight; - end; + end; Application.Scaled := True; uMetaDarkStyle.ApplyMetaDarkStyle(DefaultDark); Application.Initialize; + + try + // Perform the Unicode path check + for i := 1 to Length(ParamStr(0)) do + begin + if Ord(ParamStr(0)[i]) > 127 then + begin + raise Exception.Create(RS_FMDUnicodePathError); + end; + end; + + except + on E: Exception do + begin + SendLogException('ApplicationStartup.PathValidation', E); + raise; + end; + end; + Application.CreateForm(TMainForm, MainForm); MainForm.winBuildNumber := g_buildNumber; Application.Run; From e668cb944e55086d3babb648548f2145fa19e1bd Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Thu, 5 Feb 2026 18:01:56 +0800 Subject: [PATCH 17/35] Changed: Default sorted columns colour to be a subtle shade --- baseunits/FMDOptions.pas | 4 ++-- mangadownloader/forms/frmCustomColor.pas | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/baseunits/FMDOptions.pas b/baseunits/FMDOptions.pas index 20ccff48b..374c2141c 100644 --- a/baseunits/FMDOptions.pas +++ b/baseunits/FMDOptions.pas @@ -177,7 +177,7 @@ interface CL_BSUnfocesedSelectionText: TColor = clWindowText; CL_BSOdd: TColor = clBtnFace; CL_BSEven: TColor = clWindow; - CL_BSSortedColumn: TColor = $F8E6D6; + CL_BSSortedColumn: TColor = $F0F0F0; CL_BSEnabledWebsiteSettings: TColor = clYellow; // mangalist color @@ -199,7 +199,7 @@ interface // custom color darkmode // basiclist - CL_BSSortedColumnDark: TColor = $E19650; + CL_BSSortedColumnDark: TColor = $202020; CL_BSEnabledWebsiteSettingsDark: TColor = $009696; // mangalist color diff --git a/mangadownloader/forms/frmCustomColor.pas b/mangadownloader/forms/frmCustomColor.pas index ba6bad386..3db5bec1d 100644 --- a/mangadownloader/forms/frmCustomColor.pas +++ b/mangadownloader/forms/frmCustomColor.pas @@ -1019,7 +1019,7 @@ procedure TCustomColorForm.btResetColorsClick(Sender: TObject); VTBasicList.CI[18] := clWindowText; VTBasicList.CI[19] := clBtnFace; VTBasicList.CI[20] := clWindow; - VTBasicList.CI[21] := $F8E6D6; + VTBasicList.CI[21] := $F0F0F0; VTBasicList.CI[22] := clYellow; end else if SelectedColorList = VTMangaList then From 09ab2c01c0102d04e2c7c62480db4affedb8df79 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Thu, 5 Feb 2026 21:18:22 +0800 Subject: [PATCH 18/35] Fixed: Accidental no return if long paths disabled causing chaos --- mangadownloader/forms/frmMain.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index ebea49bc1..2d3f413df 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -5772,9 +5772,9 @@ function TMainForm.CheckLongNamePaths(APath: String): String; begin APath := '\\?\' + APath; end; - - Result := APath; end; + + Result := APath; end; function TMainForm.TrimPath(APath: String): String; From 50eda48f1d88f3de334fb83261e7ddbd6571df97 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Fri, 6 Feb 2026 14:18:51 +0800 Subject: [PATCH 19/35] Changed: Prefill save to path in manga info to fix unwanted path changes --- baseunits/uGetMangaInfosThread.pas | 167 ++++++++++---- baseunits/uSilentThread.pas | 121 +++++++--- mangadownloader/forms/frmMain.pas | 344 +++++++++++++++++++---------- 3 files changed, 432 insertions(+), 200 deletions(-) diff --git a/baseunits/uGetMangaInfosThread.pas b/baseunits/uGetMangaInfosThread.pas index 4dfccaa83..3f2caef60 100644 --- a/baseunits/uGetMangaInfosThread.pas +++ b/baseunits/uGetMangaInfosThread.pas @@ -16,8 +16,8 @@ interface uses - SysUtils, Graphics, Dialogs, uBaseUnit, uData, FMDOptions, BaseThread, - ImgInfos, webp, MultiLog, MemBitmap, VirtualTrees; + SysUtils, LazFileUtils, Graphics, Dialogs, uBaseUnit, uData, FMDOptions, + BaseThread, ImgInfos, webp, MultiLog, MemBitmap, VirtualTrees; type @@ -32,6 +32,7 @@ TGetMangaInfosThread = class(TBaseThread) FInfo: TMangaInformation; FNumChapter: Cardinal; FIsHasMangaCover: Boolean; + FFillSaveTo: Boolean; protected procedure Execute; override; procedure MainThreadSyncInfos; @@ -43,6 +44,7 @@ TGetMangaInfosThread = class(TBaseThread) constructor Create(const AModule: Pointer; const ALink: String; const ANode: PVirtualNode); destructor Destroy; override; property Title: String read FTitle write FTitle; + property FillSaveTo: Boolean read FFillSaveTo write FFillSaveTo; end; implementation @@ -70,11 +72,14 @@ procedure TGetMangaInfosThread.Execute; FInfo.MangaInfo.Link := FLink; FInfo.MangaInfo.Title := FTitle; data := MainForm.vtMangaList.GetNodeData(FNode); - if Assigned(data) and (MainForm.cbSelectManga.ItemIndex<>-1) and + if Assigned(data) and (MainForm.cbSelectManga.ItemIndex <> -1) and (m = TModuleContainer(MainForm.cbSelectManga.Items.Objects[MainForm.cbSelectManga.ItemIndex])) then begin if FInfo.MangaInfo.Title = '' then + begin FInfo.MangaInfo.Title := data^.Title; + end; + FInfo.MangaInfo.AltTitles := data^.AltTitles; FInfo.MangaInfo.Link := data^.Link; FInfo.MangaInfo.Authors := data^.Authors; @@ -92,33 +97,75 @@ procedure TGetMangaInfosThread.Execute; infob := FInfo.GetInfoFromURL(FLink); - if Terminated or isExiting then Exit; - if infob <> NO_ERROR then Exit; + if Terminated or isExiting then + begin + Exit; + end; + + if infob <> NO_ERROR then + begin + Exit; + end; //set back if title changed if (FInfo.MangaInfo.Title <> '') and (FInfo.MangaInfo.Title <> FTitle) then + begin FTitle := FInfo.MangaInfo.Title; + end; data := MainForm.vtMangaList.GetNodeData(FNode); if Assigned(data) and dataProcess.WebsiteLoaded(m.ID) then //todo: use tmodulecontainer + begin + if not(m.InformationAvailable) then begin - if not(m.InformationAvailable) then + if FInfo.MangaInfo.AltTitles = '' then + begin + FInfo.MangaInfo.AltTitles := data^.AltTitles; + end; + + if FInfo.MangaInfo.Authors = '' then begin - if FInfo.MangaInfo.AltTitles = '' then - FInfo.MangaInfo.AltTitles := data^.AltTitles; - if FInfo.MangaInfo.Authors = '' then - FInfo.MangaInfo.Authors := data^.Authors; - if FInfo.MangaInfo.Artists = '' then - FInfo.MangaInfo.Artists := data^.Artists; - if FInfo.MangaInfo.Genres = '' then - FInfo.MangaInfo.Genres := data^.Genres; - if FInfo.MangaInfo.Summary = '' then - FInfo.MangaInfo.Summary := data^.Summary; + FInfo.MangaInfo.Authors := data^.Authors; end; - if not (Terminated or isExiting) then - Synchronize(MainThreadSyncInfos); + if FInfo.MangaInfo.Artists = '' then + begin + FInfo.MangaInfo.Artists := data^.Artists; + end; + + if FInfo.MangaInfo.Genres = '' then + begin + FInfo.MangaInfo.Genres := data^.Genres; + end; + + if FInfo.MangaInfo.Summary = '' then + begin + FInfo.MangaInfo.Summary := data^.Summary; + end; end; + + if not (Terminated or isExiting) then + begin + Synchronize(MainThreadSyncInfos); + end; + end; + + if FFillSaveTo and OptionGenerateMangaFolder then + begin + MainForm.edSaveTo.Text := AppendPathDelim(MainForm.edSaveTo.Text) + + CustomRename( + OptionMangaCustomRename, + FInfo.MangaInfo.Website, + FInfo.MangaInfo.Title, + FInfo.MangaInfo.Authors, + FInfo.MangaInfo.Artists, + '', + '', + OptionChangeUnicodeCharacter, + OptionChangeUnicodeCharacterStr + ); + end; + Result := True; except on E: Exception do @@ -132,23 +179,35 @@ procedure TGetMangaInfosThread.Execute; if not GetMangaInfo then begin if not (Terminated or isExiting) then + begin Synchronize(MainThreadShowCannotGetInfo); + end; end else begin - if Terminated or isExiting then Exit; + if Terminated or isExiting then + begin + Exit; + end; + Synchronize(MainThreadShowInfos); FCover.Clear; // If there's cover then we will load it to the TPicture component. if OptionEnableLoadCover and (Trim(FInfo.MangaInfo.CoverLink) <> '') then + begin try FInfo.HTTP.Document.Clear; if FInfo.HTTP.GET(FInfo.MangaInfo.CoverLink) then + begin LoadCover; + end; except end; + end; if not (Terminated or isExiting) then + begin Synchronize(MainThreadShowCover); + end; end; except on E: Exception do @@ -167,54 +226,73 @@ procedure TGetMangaInfosThread.MainThreadShowCannotGetInfo; procedure TGetMangaInfosThread.LoadCover; var - bmp:TMemBitmap; + bmp: TMemBitmap; begin - FIsHasMangaCover:=false; + FIsHasMangaCover := False; + with FInfo.HTTP do - if GetImageStreamExt(Document)='webp' then begin - bmp:=nil; - bmp:=WebPToMemBitmap(Document); - if Assigned(bmp) then - try - FCover.Bitmap:=bmp.Bitmap; - finally - FreeAndNil(bmp); - end + if GetImageStreamExt(Document) = 'webp' then + begin + bmp := nil; + bmp := WebPToMemBitmap(Document); + if Assigned(bmp) then + begin + try + FCover.Bitmap := bmp.Bitmap; + finally + FreeAndNil(bmp); + end + end + else + begin + Exit; + end; + end else - Exit; - end - else - FCover.LoadFromStream(FInfo.HTTP.Document); - FIsHasMangaCover:=True; + begin + FCover.LoadFromStream(Document); + end; + end; + + FIsHasMangaCover := True; end; procedure TGetMangaInfosThread.MainThreadShowInfos; var node: PVirtualNode; begin TransferMangaInfo(mangaInfo, FInfo.MangaInfo); + with MainForm do - try - if Assigned(FNode) and dataProcess.WebsiteLoaded(TModuleContainer(FInfo.Module).ID) then //todo: use tmodulecontainer + begin + try + if Assigned(FNode) and dataProcess.WebsiteLoaded(TModuleContainer(FInfo.Module).ID) then //todo: use tmodulecontainer begin vtMangaList.BeginUpdate; dataProcess.Refresh(dataProcess.Filtered); vtMangaList.ReinitNode(FNode, False); - if dataProcess.Filtered then begin + + if dataProcess.Filtered then + begin node := vtMangaList.GetNextVisible(FNode, False); - while Assigned(node) do begin + while Assigned(node) do + begin vtMangaList.ReinitNode(node, False); node := vtMangaList.GetNextVisible(node, False); end; + vtMangaList.RootNodeCount := dataProcess.RecordCount; MainForm.UpdateVtMangaListFilterStatus; end; + vtMangaList.EndUpdate; end; - ShowInformation; - except - on E: Exception do - Logger.SendException(Self.ClassName+'.MainThreadShowInfos error!', E); + + ShowInformation; + except + on E: Exception do + Logger.SendException(Self.ClassName+'.MainThreadShowInfos error!', E); + end; end; end; @@ -222,6 +300,7 @@ procedure TGetMangaInfosThread.MainThreadShowCover; begin MainForm.tmAnimateMangaInfo.Enabled := False; MainForm.pbWait.Visible := False; + if FIsHasMangaCover then begin try @@ -229,6 +308,7 @@ procedure TGetMangaInfosThread.MainThreadShowCover; except on E: Exception do ; end; + FCover.Clear; end; end; @@ -239,6 +319,7 @@ constructor TGetMangaInfosThread.Create(const AModule: Pointer; inherited Create(True); FCover := MainForm.mangaCover; FIsHasMangaCover := False; + FFillSaveTo := False; FInfo := TMangaInformation.Create(Self); FInfo.Module := AModule; FLink := ALink; diff --git a/baseunits/uSilentThread.pas b/baseunits/uSilentThread.pas index 6d0d7e4a8..1fa2397d3 100644 --- a/baseunits/uSilentThread.pas +++ b/baseunits/uSilentThread.pas @@ -118,8 +118,10 @@ function TSilentThreadManager.GetCount: Integer; procedure TSilentThreadManager.StartThread; begin - if FThreads.Count=0 then + if FThreads.Count = 0 then + begin TSilentThread.Create(Self); + end; end; procedure TSilentThreadManager.Add(const AType: TMetaDataType; @@ -139,14 +141,22 @@ procedure TSilentThreadManager.Add(const AType: TMetaDataType; const AModule: TModuleContainer; const ATitle, AURL: String; const ASaveTo, AStatus, ANumChapter, AChapterLinks: String; AEnabled: Boolean); begin - if ((AType=MD_AddToFavorites) or (AType=MD_ImportToFavorites)) and (FavoriteManager.IsMangaExist(ATitle,AModule.ID)) then Exit; + if ((AType = MD_AddToFavorites) or (AType = MD_ImportToFavorites)) and (FavoriteManager.IsMangaExist(ATitle, AModule.ID)) then + begin + Exit; + end; + EnterCriticalsection(FMetaDatasGuardian); + try FMetaDatas.Add(TSilentThreadMetaData.Create( AType, AModule, ATitle, AURL, ASaveTo, AStatus, ANumChapter, AChapterLinks, AEnabled)); + if not FLockAdd then + begin StartThread; + end; finally LeaveCriticalsection(FMetaDatasGuardian); end; @@ -155,6 +165,7 @@ procedure TSilentThreadManager.Add(const AType: TMetaDataType; procedure TSilentThreadManager.AddThread(const T: TSilentThread); begin EnterCriticalSection(FThreadsGuardian); + try FThreads.Add(T); finally @@ -165,6 +176,7 @@ procedure TSilentThreadManager.AddThread(const T: TSilentThread); procedure TSilentThreadManager.RemoveThread(const T: TSilentThread); begin EnterCriticalSection(FThreadsGuardian); + try FThreads.Remove(T); finally @@ -176,14 +188,16 @@ function TSilentThreadManager.GetMetaData(const T: TSilentThread): Boolean; var M: TSilentThreadMetaData; begin - Result:=False; + Result := False; EnterCriticalSection(FMetaDatasGuardian); + try - if FMetaDatas.Count=0 then + if FMetaDatas.Count = 0 then begin Exit; end; - if FThreads.Count>OptionMaxBackgroundLoadThreads then + + if FThreads.Count > OptionMaxBackgroundLoadThreads then begin Exit; end; @@ -202,7 +216,7 @@ function TSilentThreadManager.GetMetaData(const T: TSilentThread): Boolean; M.Free; Result := True; - if (FMetaDatas.Count>0) and (FThreads.Count 0) and (FThreads.Count < OptionMaxBackgroundLoadThreads) then begin TSilentThread.Create(Self); end; @@ -215,13 +229,20 @@ procedure TSilentThreadManager.StopAll(const WaitFor: Boolean); var i: Integer; begin - if Count = 0 then Exit; + if Count = 0 then + begin + Exit; + end; EnterCriticalsection(FThreadsGuardian); try if FThreads.Count > 0 then + begin for i := 0 to FThreads.Count - 1 do + begin FThreads[i].Terminate; + end; + end; finally LeaveCriticalsection(FThreadsGuardian); end; @@ -231,7 +252,10 @@ procedure TSilentThreadManager.StopAll(const WaitFor: Boolean); if FMetaDatas.Count > 0 then begin for i := 0 to FMetaDatas.Count - 1 do + begin FMetaDatas[i].Free; + end; + FMetaDatas.Clear; end; finally @@ -239,8 +263,12 @@ procedure TSilentThreadManager.StopAll(const WaitFor: Boolean); end; if WaitFor then - while FThreads.Count>0 do + begin + while FThreads.Count > 0 do + begin Sleep(HeartBeatRate); + end; + end; end; procedure TSilentThreadManager.UpdateLoadStatus; @@ -263,8 +291,11 @@ procedure TSilentThreadManager.BeginAdd; procedure TSilentThreadManager.EndAdd; begin FLockAdd := False; + if FMetaDatas.Count > 0 then + begin StartThread; + end; end; constructor TSilentThreadManager.Create; @@ -314,7 +345,10 @@ procedure TSilentThread.SyncDownloadAll; i: Integer; begin if FInfo.MangaInfo.NumChapter = 0 then + begin Exit; + end; + try with MainForm do begin @@ -325,7 +359,10 @@ procedure TSilentThread.SyncDownloadAll; d.DownloadInfo.Module := FModule; if Trim(FTitle) = '' then + begin FTitle := FInfo.MangaInfo.Title; + end; + for i := 0 to FInfo.MangaInfo.NumChapter - 1 do begin // generate folder name @@ -339,8 +376,7 @@ procedure TSilentThread.SyncDownloadAll; OptionChangeUnicodeCharacter, OptionChangeUnicodeCharacterStr); d.ChapterNames.Add(s); - d.chapterLinks.Add( - FInfo.MangaInfo.ChapterLinks.Strings[i]); + d.chapterLinks.Add(FInfo.MangaInfo.ChapterLinks.Strings[i]); end; if cbAddAsStopped.Checked then @@ -362,11 +398,11 @@ procedure TSilentThread.SyncDownloadAll; if FSaveTo = '' then begin - FillSaveTo; - OverrideSaveTo(d.DownloadInfo.Module); + FillSaveTo(d.DownloadInfo.Module); FSaveTo := TrimPath(edSaveTo.Text); // save to if OptionGenerateMangaFolder then + begin FSaveTo := AppendPathDelim(FSaveTo) + CustomRename( OptionMangaCustomRename, FModule.Name, @@ -377,7 +413,9 @@ procedure TSilentThread.SyncDownloadAll; '', OptionChangeUnicodeCharacter, OptionChangeUnicodeCharacterStr); + end; end; + d.downloadInfo.SaveTo := FSaveTo; d.DBInsert; finally @@ -410,26 +448,30 @@ procedure TSilentThread.SyncAddToFavorite; with MainForm do begin if Trim(FTitle) = '' then + begin FTitle := FInfo.MangaInfo.Title; - if FSaveTo = '' then + end; + + s := FSaveTo; + if s = '' then begin - FillSaveTo; - OverrideSaveTo(FModule); - s := TrimPath(edSaveTo.Text); - end - else - s := FSaveTo; - if OptionGenerateMangaFolder then - s := AppendPathDelim(s) + CustomRename( - OptionMangaCustomRename, - FModule.Name, - FTitle, - FInfo.MangaInfo.Authors, - FInfo.MangaInfo.Artists, - '', - '', - OptionChangeUnicodeCharacter, - OptionChangeUnicodeCharacterStr); + FillSaveTo(FModule); + s := TrimPath(edSaveTo.Text); + + if OptionGenerateMangaFolder then + begin + s := AppendPathDelim(s) + CustomRename( + OptionMangaCustomRename, + FModule.Name, + FTitle, + FInfo.MangaInfo.Authors, + FInfo.MangaInfo.Artists, + '', + '', + OptionChangeUnicodeCharacter, + OptionChangeUnicodeCharacterStr); + end; + end; FavoriteManager.Add( FModule, @@ -455,10 +497,10 @@ procedure TSilentThread.SyncImportToFavorite; begin FTitle := FInfo.MangaInfo.Title; end; + if FSaveTo = '' then begin - FillSaveTo; - OverrideSaveTo(FModule); + FillSaveTo(FModule); FSaveTo := TrimPath(edSaveTo.Text); end; @@ -489,21 +531,24 @@ procedure TSilentThread.Execute; FInfo.MangaInfo.Clear; FInfo.Module := FModule; FInfo.MangaInfo.Title := FTitle; + case FType of MD_DownloadAll: begin - if (FInfo.GetInfoFromURL(FURL)=NO_ERROR) and not(Terminated) then + if (FInfo.GetInfoFromURL(FURL) = NO_ERROR) and not(Terminated) then begin Synchronize(SyncDownloadAll); end; end; + MD_AddToFavorites: begin - if (FInfo.GetInfoFromURL(FURL)=NO_ERROR) and not(Terminated) then + if (FInfo.GetInfoFromURL(FURL) = NO_ERROR) and not(Terminated) then begin Synchronize(SyncAddToFavorite); end; end; + MD_ImportToFavorites: begin FInfo.MangaInfo.Status := FStatus; @@ -523,6 +568,7 @@ procedure TSilentThread.Execute; begin DLManager.Sort(DLManager.SortColumn); end; + MainForm.UpdateVtFavorites; MainForm.vtFavoritesFilterCountChange; end; @@ -530,8 +576,8 @@ procedure TSilentThread.Execute; constructor TSilentThread.Create(const AManager: TSilentThreadManager); begin inherited Create(False); - FInfo:=TMangaInformation.Create(Self); - FManager:=AManager; + FInfo := TMangaInformation.Create(Self); + FManager := AManager; FManager.AddThread(Self); end; @@ -539,7 +585,10 @@ destructor TSilentThread.Destroy; begin FManager.RemoveThread(Self); if not isExiting then + begin Synchronize(FManager.UpdateLoadStatus); + end; + FInfo.Free; inherited Destroy; end; diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 2d3f413df..e28ea6386 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -724,8 +724,6 @@ TMainForm = class(TForm) public LastSearchStr: String; LastSearchWeb: Pointer; - LastUserPickedSaveTo: String; - LastViewMangaInfoSender: TObject; CurrentFormLeft: Integer; CurrentFormTop: Integer; @@ -795,8 +793,8 @@ TMainForm = class(TForm) procedure AddTextToInfo(const ATitle, AValue: String); // fill edSaveTo with default path - procedure FillSaveTo; - procedure OverrideSaveTo(const AModule: Pointer); + procedure FillSaveTo(const AModule: Pointer); + function OverrideSaveTo(const AModule: Pointer): String; // View manga information procedure ViewMangaInfo(const AModule: Pointer; const ALink, ATitle, ASaveTo: String; @@ -2379,9 +2377,15 @@ procedure TMainForm.miDownloadEnableClick(Sender: TObject); procedure TMainForm.miDownloadViewMangaInfoClick(Sender: TObject); begin - if Assigned(vtDownload.FocusedNode) then - with DLManager.Items[vtDownload.FocusedNode^.Index].DownloadInfo do - ViewMangaInfo(Module, Link, Title, SaveTo, miDownloadViewMangaInfo); + if not Assigned(vtDownload.FocusedNode) then + begin + Exit; + end; + + with DLManager.Items[vtDownload.FocusedNode^.Index].DownloadInfo do + begin + ViewMangaInfo(Module, Link, Title, SaveTo, miDownloadViewMangaInfo); + end; end; procedure TMainForm.miChapterListHighlightClick(Sender: TObject); @@ -2391,12 +2395,21 @@ procedure TMainForm.miChapterListHighlightClick(Sender: TObject); miChapterListHighlight.Checked := not miChapterListHighlight.Checked; settingsfile.WriteBool('general', 'HighlightDownloadedChapters', miChapterListHighlight.Checked); end; - if Length(ChapterList) = 0 then Exit; + + if Length(ChapterList) = 0 then + begin + Exit; + end; + if miChapterListHighlight.Checked then - DLManager.GetDownloadedChaptersState(mangaInfo.ModuleID, mangaInfo.Link, - ChapterList) + begin + DLManager.GetDownloadedChaptersState(mangaInfo.ModuleID, mangaInfo.Link, ChapterList); + end else + begin ClearChapterListState; + end; + clbChapterList.Repaint; end; @@ -2411,10 +2424,12 @@ procedure TMainForm.miDownloadDeleteTaskClick(Sender: TObject); begin Exit; end; + if DLManager.Count = 0 then begin Exit; end; + if cbOptionShowDeleteTaskDialog.Checked then begin if CenteredMessageDlg(Self, RS_DlgRemoveTask, mtConfirmation, [mbYes, mbNo], 0) <> mrYes then @@ -2621,21 +2636,32 @@ procedure TMainForm.miFavoritesStopCheckNewChapterClick(Sender: TObject); var xNode: PVirtualNode; begin - if vtFavorites.SelectedCount = 0 then Exit; + if vtFavorites.SelectedCount = 0 then + begin + Exit; + end; + xNode := vtFavorites.GetFirstSelected; while Assigned(xNode) do begin FavoriteManager.StopChekForNewChapter(False, xNode^.Index); xNode := vtFavorites.GetNextSelected(xNode); end; + UpdateVtFavorites; end; procedure TMainForm.miFavoritesViewInfosClick(Sender: TObject); begin - if Assigned(vtFavorites.FocusedNode) then - with FavoriteManager.Items[vtFavorites.FocusedNode^.Index].FavoriteInfo do - ViewMangaInfo(Module, Link, Title, SaveTo, miFavoritesViewInfos); + if not Assigned(vtFavorites.FocusedNode) then + begin + Exit; + end; + + with FavoriteManager.Items[vtFavorites.FocusedNode^.Index].FavoriteInfo do + begin + ViewMangaInfo(Module, Link, Title, SaveTo, miFavoritesViewInfos); + end; end; procedure TMainForm.miHighlightNewMangaClick(Sender: TObject); @@ -2652,7 +2678,8 @@ procedure TMainForm.LoadAbout; _OpenSSSL_version: function(t: integer): PAnsiChar; cdecl; begin // load readme.rtf - if FileExistsUTF8(README_FILE) then begin + if FileExistsUTF8(README_FILE) then + begin fs := TFileStream.Create(README_FILE, fmOpenRead or fmShareDenyNone); try rmAbout.LoadRichText(fs); @@ -2664,7 +2691,10 @@ procedure TMainForm.LoadAbout; SetAboutTextAttributes; // load changelog.txt - if FileExistsUTF8(CHANGELOG_FILE) then mmChangelog.Lines.LoadFromFile(CHANGELOG_FILE); + if FileExistsUTF8(CHANGELOG_FILE) then + begin + mmChangelog.Lines.LoadFromFile(CHANGELOG_FILE); + end; // compiler info AddToAboutStatus('FPC Version', GetFPCVersion); @@ -2672,8 +2702,19 @@ procedure TMainForm.LoadAbout; AddToAboutStatus('WidgetSet', GetWidgetSetName); AddToAboutStatus('Target CPU-OS', GetTargetCPU_OS); AddToAboutStatus('Build Time', GetBuildTime); - if SQLiteLibraryHandle = 0 then InitializeSqlite(); - if SQLiteLibraryHandle <> 0 then try AddToAboutStatus('SQLite Version', sqlite3_version()); except end; + + if SQLiteLibraryHandle = 0 then + begin + InitializeSqlite(); + end; + if SQLiteLibraryHandle <> 0 then + begin + try + AddToAboutStatus('SQLite Version', sqlite3_version()); + except + + end; + end; if IsSSLloaded then begin @@ -2687,11 +2728,24 @@ procedure TMainForm.LoadAbout; _OpenSSSL_version := nil; end; end; + AddToAboutStatus('OpenSSL Version', s); end; - if WebPLibHandle = 0 then InitWebPModule; - if WebPLibHandle <> 0 then try AddToAboutStatus('WebP Version', WebPGetVersion); except end; + if WebPLibHandle = 0 then + begin + InitWebPModule; + end; + + if WebPLibHandle <> 0 then + begin + try + AddToAboutStatus('WebP Version', WebPGetVersion); + except + + end; + end; + AddToAboutStatus('PCRE Version', pcre2.Version); end; @@ -2701,10 +2755,16 @@ procedure TMainForm.AddToAboutStatus(const ACaption, AValue: String; function addaboutcomplbl(const ACaption: String): TLabel; begin Result := TLabel.Create(Self); + if APanel = nil then - Result.Parent := pnAboutComp + begin + Result.Parent := pnAboutComp; + end else + begin Result.Parent := APanel; + end; + Result.Caption := ACaption; end; @@ -2830,7 +2890,7 @@ procedure TMainForm.btDownloadClick(Sender: TObject); links := TStringList.Create; names := TStringList.Create; try - node:=clbChapterList.GetFirstChecked(); + node := clbChapterList.GetFirstChecked(); while Assigned(node) do begin if (vsVisible in node^.States) then @@ -2851,33 +2911,35 @@ procedure TMainForm.btDownloadClick(Sender: TObject); end; node := clbChapterList.GetNextChecked(node); end; + clbChapterList.Repaint; if links.Count <> 0 then begin // save to if edSaveTo.Text = '' then begin - FillSaveTo; - OverrideSaveTo(Modules.LocateModule(mangaInfo.ModuleID)); - end; - s := TrimPath(edSaveTo.Text); - if OptionGenerateMangaFolder then - begin - sRename := CustomRename( - OptionMangaCustomRename, - mangaInfo.Website, - mangaInfo.Title, - mangaInfo.Authors, - mangaInfo.Artists, - '', - '', - OptionChangeUnicodeCharacter, - OptionChangeUnicodeCharacterStr); - - if Pos(sRename, s) = 0 then + FillSaveTo(Modules.LocateModule(mangaInfo.ModuleID)); + s := TrimPath(edSaveTo.Text); + + if OptionGenerateMangaFolder then begin + sRename := CustomRename( + OptionMangaCustomRename, + mangaInfo.Website, + mangaInfo.Title, + mangaInfo.Authors, + mangaInfo.Artists, + '', + '', + OptionChangeUnicodeCharacter, + OptionChangeUnicodeCharacterStr); + s := AppendPathDelim(s) + sRename; end; + end + else + begin + s := TrimPath(edSaveTo.Text); end; s := ReplaceRegExpr('\.*$', s, '', False); @@ -2970,15 +3032,17 @@ procedure TMainForm.btAddToFavoritesClick(Sender: TObject); var s, sRename: String; begin - if mangaInfo.Title <> '' then + if mangaInfo.Title = '' then begin - // save to - if edSaveTo.Text = '' then - begin - FillSaveTo; - OverrideSaveTo(Modules.LocateModule(mangaInfo.ModuleID)); - end; + Exit; + end; + + // save to + if edSaveTo.Text = '' then + begin + FillSaveTo(Modules.LocateModule(mangaInfo.ModuleID)); s := TrimPath(edSaveTo.Text); + if OptionGenerateMangaFolder then begin sRename := CustomRename( @@ -2992,28 +3056,30 @@ procedure TMainForm.btAddToFavoritesClick(Sender: TObject); OptionChangeUnicodeCharacter, OptionChangeUnicodeCharacterStr); - if Pos(sRename, s) = 0 then - begin - s := AppendPathDelim(s) + sRename; - end; + s := AppendPathDelim(s) + sRename; end; + end + else + begin + s := TrimPath(edSaveTo.Text); + end; - FavoriteManager.Add( - mangaInfo.Module, - mangaInfo.Title, - MangaInfo.Status, - IntToStr(mangaInfo.NumChapter), - mangaInfo.ChapterLinks.Text, - s, - mangaInfo.Link); - UpdateVtFavorites; - vtFavoritesFilterCountChange; - btAddToFavorites.Enabled := False; - if OptionShowFavoritesTabOnNewManga then - begin - edFavoritesSearch.Text := mangaInfo.Title; - pcMain.ActivePage := tsFavorites; - end; + FavoriteManager.Add( + mangaInfo.Module, + mangaInfo.Title, + MangaInfo.Status, + IntToStr(mangaInfo.NumChapter), + mangaInfo.ChapterLinks.Text, + s, + mangaInfo.Link); + UpdateVtFavorites; + vtFavoritesFilterCountChange; + btAddToFavorites.Enabled := False; + + if OptionShowFavoritesTabOnNewManga then + begin + edFavoritesSearch.Text := mangaInfo.Title; + pcMain.ActivePage := tsFavorites; end; end; @@ -3638,15 +3704,18 @@ procedure TMainForm.miMangaListAddToFavoritesClick(Sender: TObject); xNode: PVirtualNode; data: PMangaInfoData; begin - if vtMangaList.SelectedCount = 0 then Exit; - LastUserPickedSaveTo := ''; - FillSaveTo; + if vtMangaList.SelectedCount = 0 then + begin + Exit; + end; + SilentThreadManager.BeginAdd; try xNode := vtMangaList.GetFirstSelected; while Assigned(xNode) do begin data := vtMangaList.GetNodeData(xNode); + FillSaveTo(data^.Module); SilentThreadManager.Add(MD_AddToFavorites, TModuleContainer(data^.Module), data^.Title, data^.Link); xNode := vtMangaList.GetNextSelected(xNode); end; @@ -4231,40 +4300,63 @@ procedure TMainForm.miMangaListDownloadAllClick(Sender: TObject); procedure TMainForm.miMangaListViewInfosClick(Sender: TObject); begin - if Assigned(vtMangaList.FocusedNode) then begin - with PMangaInfoData(vtMangaList.GetNodeData(vtMangaList.FocusedNode))^ do - ViewMangaInfo(Module, Link, Title, '', miMangaListViewInfos, vtMangaList.FocusedNode); - if pcInfo.ActivePage <> tsInfoManga then - pcInfo.ActivePage := tsInfoManga; + if not Assigned(vtMangaList.FocusedNode) then + begin + Exit; + end; + + with PMangaInfoData(vtMangaList.GetNodeData(vtMangaList.FocusedNode))^ do + begin + ViewMangaInfo(Module, Link, Title, '', miMangaListViewInfos, vtMangaList.FocusedNode); + end; + + if pcInfo.ActivePage <> tsInfoManga then + begin + pcInfo.ActivePage := tsInfoManga; end; end; procedure TMainForm.miFavoritesOpenFolderClick(Sender: TObject); begin - if Assigned(vtFavorites.FocusedNode) then - OpenDocument(CorrectPathSys( - FavoriteManager.Items[vtFavorites.FocusedNode^.Index].FavoriteInfo.SaveTo)); + if not Assigned(vtFavorites.FocusedNode) then + begin + Exit; + end; + + OpenDocument(CorrectPathSys(FavoriteManager.Items[vtFavorites.FocusedNode^.Index].FavoriteInfo.SaveTo)); end; procedure TMainForm.miDownloadOpenFolderClick(Sender: TObject); begin - if Assigned(vtDownload.FocusedNode) then - OpenDocument(CorrectPathSys( - DLManager.Items[vtDownload.FocusedNode^.Index].DownloadInfo.SaveTo)); + if not Assigned(vtDownload.FocusedNode) then + begin + Exit; + end; + + OpenDocument(CorrectPathSys(DLManager.Items[vtDownload.FocusedNode^.Index].DownloadInfo.SaveTo)); end; procedure TMainForm.miFavoritesOpenWithClick(Sender: TObject); begin - if Assigned(vtFavorites.FocusedNode) then - OpenWithExternalProgramChapters( - FavoriteManager.Items[vtFavorites.FocusedNode^.Index].FavoriteInfo.SaveTo); + if not Assigned(vtFavorites.FocusedNode) then + begin + Exit; + end; + + OpenWithExternalProgramChapters(FavoriteManager.Items[vtFavorites.FocusedNode^.Index].FavoriteInfo.SaveTo); end; procedure TMainForm.miDownloadOpenWithClick(Sender: TObject); begin - if Assigned(vtDownload.FocusedNode) then - with DLManager.Items[vtDownload.FocusedNode^.Index] do - OpenWithExternalProgramChapters(DownloadInfo.SaveTo, ChapterNames); + if not Assigned(vtDownload.FocusedNode) then + begin + Exit; + end; + + with DLManager.Items[vtDownload.FocusedNode^.Index] do + begin + OpenWithExternalProgramChapters(DownloadInfo.SaveTo, ChapterNames); + end; end; procedure TMainForm.miTrayExitClick(Sender: TObject); @@ -4274,11 +4366,13 @@ procedure TMainForm.miTrayExitClick(Sender: TObject); procedure TMainForm.miTrayFinishNothingClick(Sender: TObject); begin - if Sender is TMenuItem then + if not (Sender is TMenuItem) then begin - OptionLetFMDDo := TFMDDo(TMenuItem(Sender).Tag); - settingsfile.WriteInteger('general', 'LetFMDDo', Integer(OptionLetFMDDo)); + Exit; end; + + OptionLetFMDDo := TFMDDo(TMenuItem(Sender).Tag); + settingsfile.WriteInteger('general', 'LetFMDDo', Integer(OptionLetFMDDo)); end; procedure TMainForm.miTrayShowDropBoxClick(Sender: TObject); @@ -5895,33 +5989,41 @@ procedure TMainForm.AddTextToInfo(const ATitle, AValue: String); end; end; -procedure TMainForm.FillSaveTo; +procedure TMainForm.FillSaveTo(const AModule: Pointer); +var + saveToPath, saveToPathOverride: String; begin - if LastUserPickedSaveTo = '' then + saveToPath := Trim(settingsfile.ReadString('saveto', 'SaveTo', DEFAULT_PATH)); + + saveToPathOverride := OverrideSaveTo(AModule); + if saveToPathOverride <> '' then begin - LastUserPickedSaveTo := Trim(settingsfile.ReadString('saveto', 'SaveTo', DEFAULT_PATH)); + saveToPath := saveToPathOverride; end; - if LastUserPickedSaveTo = '' then + if saveToPath = '' then begin - LastUserPickedSaveTo := DEFAULT_PATH; + saveToPath := DEFAULT_PATH; end; - edSaveTo.Text := LastUserPickedSaveTo; + edSaveTo.Text := saveToPath; end; -procedure TMainForm.OverrideSaveTo(const AModule: Pointer); -var - s: String; +function TMainForm.OverrideSaveTo(const AModule: Pointer): String; begin - if Assigned(AModule) then + Result := ''; + + if not Assigned(AModule) then begin - s := TModuleContainer(AModule).Settings.OverrideSettings.SaveToPath; - if s <> '' then - begin - edSaveTo.Text := s; - end; + Exit; + end; + + if not TModuleContainer(AModule).Settings.Enabled then + begin + Exit; end; + + Result := TModuleContainer(AModule).Settings.OverrideSettings.SaveToPath; end; procedure TMainForm.ViewMangaInfo(const AModule: Pointer; const ALink, ATitle, @@ -5967,26 +6069,12 @@ procedure TMainForm.ViewMangaInfo(const AModule: Pointer; const ALink, ATitle, btDownloadSplit.Enabled := btDownload.Enabled; btReadOnline.Enabled := True; - // set saveto - edSaveTo.Text := ASaveTo; - LastViewMangaInfoSender := ASender; - if edSaveTo.Text = '' then - begin - FillSaveTo; - OverrideSaveTo(AModule); - end; - DisableAddToFavorites(AModule); //check if manga already in FavoriteManager list fav := FavoriteManager.LocateMangaByLink(TModuleContainer(AModule).ID, ALink); if fav <> nil then begin btAddToFavorites.Enabled := False; - if LastViewMangaInfoSender <> miDownloadViewMangaInfo then - begin - edSaveTo.Text := fav.FavoriteInfo.SaveTo; - LastViewMangaInfoSender := miFavoritesViewInfos; - end; end; // start the thread @@ -6000,6 +6088,14 @@ procedure TMainForm.ViewMangaInfo(const AModule: Pointer; const ALink, ATitle, GetInfosThread.Title := ATitle; end; + // set saveto + edSaveTo.Text := ASaveTo; + if edSaveTo.Text = '' then + begin + FillSaveTo(AModule); + GetInfosThread.FillSaveTo := True; + end; + GetInfosThread.Start; end; @@ -6012,6 +6108,7 @@ procedure TMainForm.ShowInformation; imCover.Picture.Assign(nil); with rmInformation do + begin try Lines.BeginUpdate; Lines.Clear; @@ -6037,6 +6134,7 @@ procedure TMainForm.ShowInformation; finally Lines.EndUpdate; end; + end; SetLength(ChapterList, mangaInfo.ChapterNames.Count); if Length(ChapterList) <> 0 then @@ -6794,9 +6892,10 @@ procedure TMainForm.edMangaListSearchKeyDown(Sender: TObject; var Key: Word; edMangaListSearch.Tag := 1; edMangaListSearchChange(edMangaListSearch); end - else - if edMangaListSearch.Tag <> 0 then + else if edMangaListSearch.Tag <> 0 then + begin edMangaListSearch.Tag := 0; + end; end; procedure TMainForm.edOptionDefaultPathButtonClick(Sender: TObject); @@ -6805,6 +6904,7 @@ procedure TMainForm.edOptionDefaultPathButtonClick(Sender: TObject); begin try InitialDir := TrimPath(edOptionDefaultPath.Text); + if Execute then begin edOptionDefaultPath.Text := FileName; @@ -6821,6 +6921,7 @@ procedure TMainForm.edOptionExternalPathButtonClick(Sender: TObject); begin try InitialDir := ExtractFileDir(edOptionExternalPath.Text); + if Execute then begin edOptionExternalPath.Text := FileName; @@ -6837,6 +6938,7 @@ procedure TMainForm.edSaveToButtonClick(Sender: TObject); begin try InitialDir := TrimPath(edSaveTo.Text); + if Execute then begin edSaveTo.Text := FileName; From a805fd934e45b38f0246c0af96b57b5e1daf62fc Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Fri, 6 Feb 2026 17:59:42 +0800 Subject: [PATCH 20/35] Changed: Image creation time to use local time Added: Option to use server image creation time over local time --- baseunits/FMDOptions.pas | 3 +++ baseunits/uBaseUnit.pas | 29 +++++++++++++++++++++-------- languages/fmd.de.po | 8 ++++++++ languages/fmd.el_GR.po | 8 ++++++++ languages/fmd.en.po | 8 ++++++++ languages/fmd.es.po | 8 ++++++++ languages/fmd.fr.po | 8 ++++++++ languages/fmd.id_ID.po | 8 ++++++++ languages/fmd.pl_PL.po | 8 ++++++++ languages/fmd.pot | 8 ++++++++ languages/fmd.pt_BR.po | 8 ++++++++ languages/fmd.ru_RU.po | 8 ++++++++ languages/fmd.tr_TR.po | 8 ++++++++ languages/fmd.zh.po | 8 ++++++++ mangadownloader/forms/frmMain.lfm | 26 ++++++++++++++++++++++++++ mangadownloader/forms/frmMain.lrj | 2 ++ mangadownloader/forms/frmMain.pas | 5 +++++ 17 files changed, 153 insertions(+), 8 deletions(-) diff --git a/baseunits/FMDOptions.pas b/baseunits/FMDOptions.pas index 374c2141c..7d36d7eeb 100644 --- a/baseunits/FMDOptions.pas +++ b/baseunits/FMDOptions.pas @@ -126,6 +126,9 @@ interface OptionPNGCompressionLevel: Integer = 1; OptionJPEGQuality: Integer = 80; + // image properties + OptionImageServerTime: Boolean = False; + // connections OptionConnectionTimeout: Integer = 30; OptionMaxFavoriteThreads: Integer = 1; diff --git a/baseunits/uBaseUnit.pas b/baseunits/uBaseUnit.pas index f1427cfcd..d5a89caa4 100644 --- a/baseunits/uBaseUnit.pas +++ b/baseunits/uBaseUnit.pas @@ -2463,14 +2463,20 @@ function SaveImageStreamToFile(Stream: TMemoryStream; Path, FileName: String; Ag if FileExists(FilePath) then begin Result := FilePath; - if Age > 0 then - begin - try + + try + if not OptionImageServerTime then + begin + Age := DateTimeToFileDate(Now); + end; + + if Age > 0 then + begin FileSetDateUTF8(FilePath, Age); - except - on E: Exception do - SendLogException('SaveImageStreamToFile.FileSetDate Error! ' + FilePath, E); end; + except + on E: Exception do + SendLogException('SaveImageStreamToFile.FileSetDate Error! ' + FilePath, E); end; end; end; @@ -2482,11 +2488,18 @@ function SaveImageStreamToFile(AHTTP: THTTPSend; Path, FileName: String): String lastmodified: LongInt; begin Result := ''; - if AHTTP = nil then Exit; - s := Trim(AHTTP.Headers.Values['last-modified']); + if AHTTP = nil then + begin + Exit; + end; + lastmodified := 0; + s := Trim(AHTTP.Headers.Values['last-modified']); if s <> '' then + begin lastmodified := DateTimeToFileDate(DecodeRfcDateTime(s)); + end; + Result := SaveImageStreamToFile(AHTTP.Document, Path, FileName, lastmodified); end; diff --git a/languages/fmd.de.po b/languages/fmd.de.po index ba4ead0e0..9cbe38932 100644 --- a/languages/fmd.de.po +++ b/languages/fmd.de.po @@ -1193,6 +1193,10 @@ msgstr "Suche in allen Manga-Seiten" msgid "For more manga sites, please go to Options->Manga sites" msgstr "Für mehr Manga-Seiten, bitte geh in die Optionen->Manga-Seiten" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Reguläre Ausdrücke" @@ -1663,6 +1667,10 @@ msgstr "Bildverarbeitung" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "Externes Programm" diff --git a/languages/fmd.el_GR.po b/languages/fmd.el_GR.po index dad92a58e..90e33c862 100644 --- a/languages/fmd.el_GR.po +++ b/languages/fmd.el_GR.po @@ -1189,6 +1189,10 @@ msgstr "Αναζήτηση σε όλους τους ιστότοπους manga" msgid "For more manga sites, please go to Options->Manga sites" msgstr "Για περισσότερους ιστότοπους manga, παρακαλώ δείτε στις Επιλογές->Ιστότοποι Manga" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Κανονική έκφραση" @@ -1710,6 +1714,10 @@ msgstr "" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "Εξωτερικό πρόγραμμα" diff --git a/languages/fmd.en.po b/languages/fmd.en.po index 4459699e1..4024e8697 100644 --- a/languages/fmd.en.po +++ b/languages/fmd.en.po @@ -1198,6 +1198,10 @@ msgstr "Search in all manga sites" msgid "For more manga sites, please go to Options->Manga sites" msgstr "For more manga sites, please go to Options->Manga sites" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Regular Expression" @@ -1668,6 +1672,10 @@ msgstr "Image Conversion" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "External program" diff --git a/languages/fmd.es.po b/languages/fmd.es.po index e3c2a4f7c..7ad5b4931 100644 --- a/languages/fmd.es.po +++ b/languages/fmd.es.po @@ -1193,6 +1193,10 @@ msgstr "Buscar en Todos Los Sitios de Manga" msgid "For more manga sites, please go to Options->Manga sites" msgstr "Para más Sitios de Mangas, Ve a Opciones->Sitios Manga" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Regular Expresión" @@ -1663,6 +1667,10 @@ msgstr "Conversión de Imagen" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "Programa Externo" diff --git a/languages/fmd.fr.po b/languages/fmd.fr.po index a39b4b2fc..d5f7475da 100644 --- a/languages/fmd.fr.po +++ b/languages/fmd.fr.po @@ -1195,6 +1195,10 @@ msgstr "Chercher dans tous les catalogues" msgid "For more manga sites, please go to Options->Manga sites" msgstr "Pour ajouter plus de sites, allez dans Options→Sites" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Expression régulière" @@ -1740,6 +1744,10 @@ msgstr "Conversion des images" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "Programme externe" diff --git a/languages/fmd.id_ID.po b/languages/fmd.id_ID.po index aa7a744eb..2164ea871 100644 --- a/languages/fmd.id_ID.po +++ b/languages/fmd.id_ID.po @@ -1202,6 +1202,10 @@ msgstr "Cari di semua situs komik" msgid "For more manga sites, please go to Options->Manga sites" msgstr "Untuk situs yang lain, silakan pilih di Pengaturan->Situs->Situs" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Persamaan reguler" @@ -1672,6 +1676,10 @@ msgstr "Konversi gambar" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "Program eksternal" diff --git a/languages/fmd.pl_PL.po b/languages/fmd.pl_PL.po index e5b6d2262..a4fb979e7 100644 --- a/languages/fmd.pl_PL.po +++ b/languages/fmd.pl_PL.po @@ -1176,6 +1176,10 @@ msgstr "Szukaj we wszystkich witrynach" msgid "For more manga sites, please go to Options->Manga sites" msgstr "Aby uzyskać więcej stron z mangami, przejdź do Opcje->Strony z mangami" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Wyrażenie regularne" @@ -1646,6 +1650,10 @@ msgstr "" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "Program zewnętrzny" diff --git a/languages/fmd.pot b/languages/fmd.pot index 9b91513ba..53dd7f3f6 100644 --- a/languages/fmd.pot +++ b/languages/fmd.pot @@ -1125,6 +1125,10 @@ msgstr "" msgid "For more manga sites, please go to Options->Manga sites" msgstr "" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "" @@ -1583,6 +1587,10 @@ msgstr "" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "" diff --git a/languages/fmd.pt_BR.po b/languages/fmd.pt_BR.po index eab3e5d57..7332601d7 100644 --- a/languages/fmd.pt_BR.po +++ b/languages/fmd.pt_BR.po @@ -1192,6 +1192,10 @@ msgstr "Buscar em todos sites de mangá" msgid "For more manga sites, please go to Options->Manga sites" msgstr "Para mais sites de mangá, por favor vá em Opções->Sites de Mangá" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Expressão Regular" @@ -1662,6 +1666,10 @@ msgstr "Conversão de imagem" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "Programa externo" diff --git a/languages/fmd.ru_RU.po b/languages/fmd.ru_RU.po index 20b3ad58a..d8e1b3cf8 100644 --- a/languages/fmd.ru_RU.po +++ b/languages/fmd.ru_RU.po @@ -1192,6 +1192,10 @@ msgstr "Поиск по всем сайтам манги" msgid "For more manga sites, please go to Options->Manga sites" msgstr "Для получения дополнительных сайтов с мангой откройте Настройки->Сайты с мангой" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Регулярное выражение (regexp)" @@ -1662,6 +1666,10 @@ msgstr "Конвертация изображений" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "Внешняя программа" diff --git a/languages/fmd.tr_TR.po b/languages/fmd.tr_TR.po index b38282279..addc4ecf3 100644 --- a/languages/fmd.tr_TR.po +++ b/languages/fmd.tr_TR.po @@ -1194,6 +1194,10 @@ msgstr "Tüm manga sitelerinde ara" msgid "For more manga sites, please go to Options->Manga sites" msgstr "Daha fazla manga sitesi için, lütfen Ayarlar->Manga siteleri'ne gidin" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "Düzenli İfadeler" @@ -1663,6 +1667,10 @@ msgstr "Resim Dönüştürme" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "Harici program" diff --git a/languages/fmd.zh.po b/languages/fmd.zh.po index 7fcceb3f5..364a12618 100644 --- a/languages/fmd.zh.po +++ b/languages/fmd.zh.po @@ -1194,6 +1194,10 @@ msgstr "在所有漫画网站中搜索" msgid "For more manga sites, please go to Options->Manga sites" msgstr "如需更多漫画网站,请前往选项 -> 漫画网站" +#: tmainform.cbservercreationtime.caption +msgid "Use server creation time over local time" +msgstr "" + #: tmainform.cbuseregexpr.caption msgid "Regular Expression" msgstr "正则表达式" @@ -1664,6 +1668,10 @@ msgstr "图像转换" msgid "Image Magick" msgstr "" +#: tmainform.gbimageproperties.caption +msgid "Image Properties" +msgstr "" + #: tmainform.gboptionexternal.caption msgid "External program" msgstr "外部程序" diff --git a/mangadownloader/forms/frmMain.lfm b/mangadownloader/forms/frmMain.lfm index 8c9b51ce8..826f6cc4d 100644 --- a/mangadownloader/forms/frmMain.lfm +++ b/mangadownloader/forms/frmMain.lfm @@ -4589,6 +4589,32 @@ object MainForm: TMainForm ShowHint = True Visible = False end + object gbImageProperties: TGroupBox + AnchorSideLeft.Control = sbSaveTo + AnchorSideTop.Control = gbImageConversion + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = sbSaveTo + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = gbOptionRenaming + Left = 4 + Height = 50 + Top = 271 + Width = 812 + Anchors = [akTop, akLeft, akRight] + Caption = 'Image Properties' + ClientHeight = 30 + ClientWidth = 808 + ParentBackground = False + TabOrder = 7 + object cbServerCreationTime: TCheckBox + Left = 4 + Height = 19 + Top = 4 + Width = 225 + Caption = 'Use server creation time over local time' + TabOrder = 0 + end + end end end object tsUpdate: TTabSheet diff --git a/mangadownloader/forms/frmMain.lrj b/mangadownloader/forms/frmMain.lrj index a022e736d..183121aef 100644 --- a/mangadownloader/forms/frmMain.lrj +++ b/mangadownloader/forms/frmMain.lrj @@ -257,6 +257,8 @@ {"hash":142739353,"name":"tmainform.lbimagemagickquality.caption","sourcebytes":[73,109,97,103,101,32,113,117,97,108,105,116,121],"value":"Image quality"}, {"hash":24397,"name":"tmainform.lbimagemagickhint.caption","sourcebytes":[91,63,93],"value":"[?]"}, {"hash":24397,"name":"tmainform.lbimageconversionhint.caption","sourcebytes":[91,63,93],"value":"[?]"}, +{"hash":196727763,"name":"tmainform.gbimageproperties.caption","sourcebytes":[73,109,97,103,101,32,80,114,111,112,101,114,116,105,101,115],"value":"Image Properties"}, +{"hash":209737461,"name":"tmainform.cbservercreationtime.caption","sourcebytes":[85,115,101,32,115,101,114,118,101,114,32,99,114,101,97,116,105,111,110,32,116,105,109,101,32,111,118,101,114,32,108,111,99,97,108,32,116,105,109,101],"value":"Use server creation time over local time"}, {"hash":208308883,"name":"tmainform.tsupdate.caption","sourcebytes":[85,112,100,97,116,101,115],"value":"Updates"}, {"hash":71634382,"name":"tmainform.cboptionautochecklatestversion.caption","sourcebytes":[65,117,116,111,32,99,104,101,99,107,32,102,111,114,32,108,97,116,101,115,116,32,118,101,114,115,105,111,110],"value":"Auto check for latest version"}, {"hash":225003075,"name":"tmainform.gboptionfavorites.caption","sourcebytes":[70,97,118,111,114,105,116,101,115],"value":"Favorites"}, diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index e28ea6386..8b4e6ccf7 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -78,6 +78,7 @@ TMainForm = class(TForm) cbUseRegExpr: TCheckBox; cbOptionProxyType: TComboBox; cbOptionOneInstanceOnly: TCheckBox; + cbServerCreationTime: TCheckBox; ckImageMagick: TCheckBox; ckPNGSaveAsJPEG: TCheckBox; ckOptionsAlwaysStartTaskFromFailedChapters: TCheckBox; @@ -117,6 +118,7 @@ TMainForm = class(TForm) gbOptionsConnectiosMiscellaneous: TGroupBox; gbOptionsConnectionsGeneral: TGroupBox; gbImageMagick: TGroupBox; + gbImageProperties: TGroupBox; IconDLLeft: TImageList; lbImageConversionHint: TLabel; lbImageMagickSaveAs: TLabel; @@ -6300,6 +6302,7 @@ procedure TMainForm.LoadOptions; cbWebPSaveAs.ItemIndex := ReadInteger('saveto', 'ConvertWebP', OptionWebPSaveAs); cbPNGCompressionLevel.ItemIndex := ReadInteger('saveto', 'PNGCompressionLevel', OptionPNGCompressionLevel); seJPEGQuality.Value := ReadInteger('saveto', 'JPEGQuality', OptionJPEGQuality); + cbServerCreationTime.Checked := ReadBool('saveto', 'ImageServerTime', OptionImageServerTime); // imagemagick if TImageMagickManager.Instance.PathFound then @@ -6492,6 +6495,7 @@ procedure TMainForm.SaveOptions(const AShowDialog: Boolean); WriteInteger('saveto', 'ConvertWebP', cbWebPSaveAs.ItemIndex); WriteInteger('saveto', 'PNGCompressionLevel', cbPNGCompressionLevel.ItemIndex); WriteInteger('saveto', 'JPEGQuality', seJPEGQuality.Value); + WriteBool('saveto', 'ImageServerTime', cbServerCreationTime.Checked); // imagemagick WriteBool('imagemagick', 'ImageMagickEnabled', ckImageMagick.Checked); @@ -6691,6 +6695,7 @@ procedure TMainForm.ApplyOptions; OptionWebPSaveAs := cbWebPSaveAs.ItemIndex; OptionPNGCompressionLevel := cbPNGCompressionLevel.ItemIndex; OptionJPEGQuality := seJPEGQuality.Value; + OptionImageServerTime := cbServerCreationTime.Checked; // imagemagick TImageMagickManager.Instance.Enabled := ckImageMagick.Checked; From cf92b02686008e228b6b4de6a7a4db5b2f200722 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Fri, 6 Feb 2026 20:47:51 +0800 Subject: [PATCH 21/35] Fixed: Dropbox image rough edges --- mangadownloader/forms/frmDropTarget.lfm | 4236 ++++++++--------------- 1 file changed, 1445 insertions(+), 2791 deletions(-) diff --git a/mangadownloader/forms/frmDropTarget.lfm b/mangadownloader/forms/frmDropTarget.lfm index acb185348..fcced0fda 100644 --- a/mangadownloader/forms/frmDropTarget.lfm +++ b/mangadownloader/forms/frmDropTarget.lfm @@ -39,2797 +39,1451 @@ object FormDropTarget: TFormDropTarget BorderSpacing.Around = 4 Center = True Picture.Data = { - 1754506F727461626C654E6574776F726B47726170686963BE5C010089504E47 - 0D0A1A0A0000000D4948445200000320000003200806000000DB700668000000 - 017352474200AECE1CE90000200049444154785EECDD077C1CF5993FFEE975AB - 7625ABD9D8A6B800A608DB186322B0901160127288F44B2EA45CCA5D2E977609 - 3922D27BBB4BB9BBF44BE34412BAB05C585CB18DE898621B3759B6256D9DDD9D - 3EF3CB50FEF70F474092B5AB9D9DCFBE5E790161E6FB7D9EF733587A76E6FB1D - 92C0070210800004200001084000021080409504C82ACD836920000108400002 - 1080000420000108106840701140000210800004200001084000025513400352 - 356A4C0401084000021080000420000108A001C1350001084000021080000420 - 000108544D000D48D5A8311104200081EA0B747676328AA290F3E7CF27878709 - 3A99D4484511A8484427298AA25555A52C492225CB222D4B2005C122759DA128 - 8AA08B7691E46C9B741CEE357F565094E17AD91934ED523AEDD2B4EE3A8E68D3 - 11FAF9FF9FD618D7102C872933AEAE9B4E24E2D89AA6393CCFBB8AA2388D8D8D - CE73CF3DE7CE9F3FDFE9EFEFB7AB2F85192100010840A05A02AFF943A55A8160 - 1E0840000210989C40676767886118DA755D46D328DE756DD6612C8934DD30C3 - 3022C3D0826DDB0996E54314C5889AA636B01C23D30C2D089CC0E70AB9184550 - 02C9D02C45920C4D923445D3344951F4B191A3B2EB920C499034499324491224 - E1927FF93383245C827009D7F5FE4A108EE33884EB3A8EEB3A84E39ACD2DCD65 - 8AA21CF7F97F41388E6D5B8EE318BA6E94A39158DE712DD5326DCDB28C12CF0B - 59D3348B966B957986CD9AA655220852755DB268DB6E89243553D7253D1CB6EC - 542A559C9C148E8600042000815A124003524BD5402C1080406005FAFAFAA854 - EA4989086B02AB919CC3D902E738826D53A26D5B8D36E12658864B5A96318B63 - B858269F8B732C2DD124C38F8E8EC6289AE6089264188A626886E66886662892 - A619EFEF69EFFF26699AA6BD5B1B5E8FC17A7F3FD3D8A669EA5E6FE278AD89ED - 588E635BB6EDFDBD6DDAB6657A7FB52CDB78E19F6DD3340CA5B5BDA5645BAE6E - 3B56291289E60DC3C84B923C6619669661C8B44B1359D2A68B14656996C5AA14 - A56BAEEBEAE974DA181A1A32673A67CC0F01084000020476C1C24500010840A0 - D2022F341729AAB1B1911A1B1BA31445A1044188392C1B716D32C191F429A66D - 9E1A09855B54B5DCCE725C787474AC8165598965199165599EE33841108450A5 - 63F5EBF8B66D5BAAAA298661A85E63639A6679D6ACA6B4A6693951108F96D4F2 - 319AA1F7DB2E719820ED3147D38A866164C3E1B0A3288A1D0E87DDCECE4EA7AF - AFCFF1AB01E286000420E01701DC01F14BA51027042050F3025EA3F1D0430FC9 - 9A468B452B1F261D3ACE534C234138EDB66DCDE6792159282A4DC74F9C48B22C - 1B8AC8A1068663059EE39E6F32BCBB120CC3B0359FA8CF02F4EEB0589665788D - 89AE1B9A69985AA1A8A44DC3283537378DCB52E8B861E8E334CB1DA168EAB0A5 - 9B630441E5288A570842D1F0C897CF0A8E702100819A17400352F32542801080 - 402D09747474B0ADADAD6CD67178D9B2BC47A49A5D979C4592EE6CC332E7784D - 86AA96DBC646C7DA44498C49A218E238569424395C4B792096FF2BA0AAAAE2AD - 4F29AB654553B57C229938C1F3DC21433347699A3A4432F41186A44F581C3146 - 94392D1CB68D919111138F76E16A82000420303901342093F3C2D1108040C004 - 7A7B7BC562B118721CA6C9B28C16D725E63A8E759AA69BA787427253269B6D89 - 45A32DDE020B6F0D374912144591D4F3CBB6F1F1BD80B726C55B57EFDD45314D - 532B2885D1443C79A2582E8E8A3CF71C49D37B4997D867DBC411CB62D22D2D52 - 01BB78F9BEEC48000210A8B0007E40561818C3430002B52FD0DBDB4BEBDE164B - 3A13A2283BEE38E61CD725E7B9AE7D5A49D5E68882904CA7334D1CC786799E97 - 398E13799E176B3F3344584981171FE92A6BAA5A28AB6A21168F8FA8AA3A2E8B - E230C771FB49923844D3EC21C7D1B23CCF17EFBCF3CE7225E3C1D810800004FC - 228006C42F95429C1080C0B40878EB34EEBCF34E9A9B3F9F09E7B5669B74E692 - AEB390A2A8B34CD33A2397CBCD9125A921128924A765420C1258817C3E375A2C - 96C72291E82196A19F7208E7099AA49FB16DF20841A8E3DEE2F7B56BD7DA58F8 - 1ED84B04894320B0026840025B7A240E81E008788F51E9BA1EB72C72B6699A67 - BBA47BA6AE19A7E7F3F93972486EE4384EE2394E6018860B8E0A32ADA680E1ED - CC6518AAAEEBE57CBE702C168B1DE105711F49914F7134FD044198475CD72D0C - 0E0E96AA1917E682000420301302684066421D73420002151358BB76AD645996 - ECBA6C8B4B13B3699738CD25888596652DCAE5F3A74892D4204B52A462016060 - 084C42A0542E171445198D46A287189A79CA259D3D1441EE334DE7304599E3E5 - 7243B9BD9D30B0AE6412A838140210A879013420355F2204080108BC96405757 - 5794A2F8D9A6692D2169F23CC771CF29159553239148F38B2FDFA3BDF7EFBDD6 - 38F8F710982901D77D7EA9BBFDC24B196D2B9DC91D8984E5E728EFEE88433CC2 - 30CCA3E572E8C08E1DFDEA4CC58879210001084C97001A90E992C43810804055 - 04BC3B1C86614409826DF11A0E82229658A6B5A0A828A7CAB29C9464295A0B6F - F9AE0A0626A97B016FA1BBAAAA05A5584C8743A1FD8228EC255DF2499263F790 - 167D80E3CC3C16B7D7FD658004215077026840EAAEA4480802752540767676D2 - E1709853147D8EE3D8E7302CB3D47589734BE5E2E9B168AC19EB36EAAADE4866 - 8202994CF6A82C4BCF9214F9A86D3ABB298A7AC4BB43C2F363662A95B226380C - 0E83000420302302684066841D93420002AF26B062C50A91E7A3B328CA3E43D7 - AD0B1DD7394FD5CA8BC2A170A32008B2F7D670084200020461DB8EA9AA6AA9A8 - 144E88B2FC0C4D928F0902BFCBB6A9276DBB348AB7B8E32A8100046A51000D48 - 2D560531412060029D9D9D0241102193204EA31D6631C5D04B46464696C7E3B1 - 39917038C9B22C76A70AD8358174A72E90CDE64E643399C3EDEDB377DBB635E4 - BACE1E5164F7E772A1E28E1DFD1A4110EED447C799108000044E5E000DC8C91B - 62040840600A02BDBDBDDC91B1B15647B7CEA2297A2945511768AABA281E8F7B - 6F1567B08E630AA83805022F0ABCB8A8DDF1EE90284A618CE785A75CC77DD026 - 9C5D024B3EB269D3A6C3684470B94000023325800664A6E4312F040226D0D3D3 - E33D3615314DA2DD34CD732986E918191E3E3F168F9D120A85E33CCFE1CDE201 - BB26906E75050CC3D04AA552369BCB0FCF6E6BDF69B9E6C30CC93C640AF4B032 - 32921F1A1A32AB1B1166830004822A800624A89547DE10A88240676727A3EB8D - AC2429E76A9ADA4950C4859AAA9FD9D8D83817DBE256A100980202AF22E0EDB0 - 95CD664704917FC2B689ED9220DCAF0BF4D34CA9A460213B2E1D0840A0920268 - 402AA98BB1211040818E8E0E361C9E956059E74C5D3756B904B15455D5459148 - A489E33891A2282A802C481902352DA0695AA9542EE739967B9C24DCDD3CCF6F - B179FAC94D77DD358247B56ABA74080E02BE144003E2CBB2216808D496C08ADE - 5E5154D5065AB716EABAB58AA2C88BCAAABA30120937721CE72D30C7070210F0 - 8980E3BA4E2E9B3B268AE2D38E6D6D6304618B4DBB4FE859398F1721FAA48808 - 1302352E8006A4C60B84F02050CB02DDDDDD4D8E432D362C6B35CBB2175B9675 - 3ECF7122C3306C2DC78DD8200081D716F016B27B6F652F7B774678FE49DBB4B7 - 711CBD8961C8C7060606C65E7B041C01010840E09505D080E0CA800004262CB0 - 6245AF28CB6A2345D9679AA6B58A20C8A525B57C4638144AF23C2F4D78201C08 - 0108F84EC05BC45E282863922C3D4D38C42E56E0B6930EFD384D1BA3030303BA - EF1242C01080C08C09A00199317A4C0C017F08F4F6F6D2C3C304C7CBD90ED774 - BB29965D65E9C6D9E14838E18F0C10250420500981424119E779EE71CBB45314 - 456C34256E4F8B2415FAFBFBED4ACC8731210081FA114003523FB54426109856 - 81AEAEAEA86591A79324BD4C33D42ED330CE8D46A3B3BC351D24496221F9B46A - 633008F85740D7F572B158CE5214B93B24CB29CBB21E1004FAA9818181827FB3 - 42E41080402505D0805452176343C067026BD7AE95F29AD64699C4F2BCA27439 - 96B5BC21D1D02E8A62C867A9205C084060060454552B6673D9A30CC3EC920471 - 1DC153BB04921C191C1C2C6337AD192808A684408D0AA001A9D1C2202C085453 - E0AAABAE8AEBBA7D8E6599577082F83A5DD3168AA218C6BB3AAA5905CC0581FA - 11701CC7B62CCBE458E6315DB7B6100C75AFADB30FA652B7E5EA274B64020108 - 4C55000DC854E5701E047C2EE0351D16C99E4E98D68A62B974A9A9EBE746A2D1 - E7DFD5E1F3D4103E04205043028EE338996C7698A599874551DC4051D48E5289 - 7E76DBB63B941A0A13A14000025514400352456C4C05819916F0DE4CCEB29126 - C7312E1104A1EBC4E868673C1E6B6759969FE9D8303F0420100C81916323CF24 - 1B929B34535F2F72F44ED33447F1E6F560D41E5942E025013420B81620100081 - 9E9E1EDEA6A8B3F4A2710DC7B39D9AA69DE93D62C5300C1780F4912204205063 - 02A6691AAAAA16388EDB635BD6FDA2280E281CF5C4B63B7057A4C64A85702050 - 110134201561C5A010987901EF6E8724494955B557721C7BE9D8D85857229998 - 8BBB1D335F1B44000108FCA5C0D191E34FCF6A4CDE6F9AFA7A8A92B63634F0D9 - FEFE7E034E1080407D0AA001A9CFBA22AB000B788D07CF47E6BAAE7D996EE8D7 - BA0471A12808216F41394992F86F3EC0D7065287402D0BD8B66D974AA52C45D3 - 4302C7DF61DBEE868D1BEF79B69663466C1080C0D404F0CBC8D4DC7016046A4E - C05B546E18F6F996E576F33CB3B254561786C3785960CD150A01410002AF2950 - 2A957282283C6319C6669A66D6F33CFDF09D77DE99C656BEAF49870320E00B01 - 3420BE28138284C02B0B786F29CFE7F3094D732E9624B12793C95C9E6C4C9E02 - 2F08400002F520E0BAAE934EA78F3436CDBAAF5C2CDD258AF4365996C7F0B6F5 - 7AA82E7208B2001A9020571FB9FB56A0AFAF8FBAFFFE074E2719F75243D7AF74 - 1D77B924C9319665B1A8DCB75545E01080C05F13B06DDBF2EE8A300C33C48BE2 - 004D589B6459DED7DFDFAF420D0210F09F001A10FFD50C11075780ECECEC945D - 973EDBB2AC2B4459BED4348CB365598E0597049943000241132895D582244ACF - 687A79034B33F73A8EFCE8860DFDF9A039205F08F859000D889FAB87D80323D0 - D9D92918867B1E4DD36FCC170A573737CF3A95A669068BCA03730920510840E0 - 6502DE9BD673B9DCD1443231E85864BFAEE7B7A652290D50108040ED0BA001A9 - FD1A21C2000B74777737298ABE9217B9CB72D97C77434343BB20F0528049903A - 04200081BF1078A91199D5342B552EABF7328CB83912A147B14E04170A046A57 - 000D48EDD606910554C05BDFB163C78E98AA5A97EB86D14BD3F425B158B431A0 - 1C481B021080C08405344D2B5AA6791FC370BF7304EABECE65CB46FBFAFA9C09 - 0F8003210081AA08A001A90A332681C0C4042EBBECEA36C7D12F374CE35A9224 - 578442A1B8F7A8D5C4CEC6511080000420E0092805254D90C44E8663FEE0B2F4 - 606A60E028B6F0C5B50181DA114003523BB540240115F0B6D21D1B2B3512B4B5 - C632ACEB5CD75D1E8D4670C723A0D703D2860004A64F4051940C4112DB6992BE - 85E3C8FB0DC338964AA5ACE99B0123410002531140033215359C03816912E8EC - BCB299A6AD35A6EDBE8570DD65922446298AA2A669780C0301084020F002DEBB - 444CD3D475DDBC8FA1E95B18C6D9B07EFDFA91C0C3000002332880066406F131 - 7530053A3A3AD8868696B9AE6B771A86BED6B29D65D168A4093B5A05F37A40D6 - 108040F504F2F9C21849933B5996F913E9301B1DA77C147744AAE78F9920F092 - 001A105C0B10A89280B7B87CEBD607DB09C2EEB22CFBCD2EE92E97252952A5E9 - 310D0420000108BC28A0EB7AD9B4EC2D3449FD9624D98D8984781CBB66E1F280 - 40F504D08054CF1A330558A0A7A7A7DD30DC2B4DDB7AA3EB3817489214A3699A - 0E3009528700042030E3028AA2A44992DC4553F4ADAE80C5EA335E1004101801 - 342081293512ADB6C04B8BCB29CAEEB16CFB3AC771964522E164B5E3C07C1080 - 000420F0EA025E23E2B8EE369AA16FA15C763341A8C7F16816AE1A08544E000D - 48E56C31728005D6AC59D3A0EA560F4190EF205C62B92489112C2E0FF00581D4 - 2100819A177869B1BAAA69EB198AF93DCF931B070707476B3E700408011F0AA0 - 01F161D11072ED0A3CDF78A8D6E5A6695E4F50C445B1686C161697D76EBD1019 - 042000815712C8E5F2271CDBD94A73F46F4322975AB76E5D06521080C0F409A0 - 01993E4B8C145C0172EDDAB562A9A49FCB30ECDB8BA5E2DFC462B1A6E0722073 - 08400002F52190C964464272F836C7B17E93CFA7770F0D0D99F59119B280C0CC - 0AA00199597FCCEE73016F9D47A650B888B48937160AC56BA3B1680BCBB29CCF - D342F81080000420F0A2806118DAD878E660221EB99D24E93FD8B6F6782A95D2 - 000401084C5D000DC8D4ED706680057A7B7BB96CB67CAA691A6F8944C3D7A8AA - BA80E33821C024481D021080405D0B388E63D334FD6821AFFC4114A53FA6D323 - FB7147A4AE4B8EE42A288006A482B818BA3E05D6AC59D362DBD4D50445BE8322 - C9E5344DB358E7519FB54656108000045E2EA0697A89A2C8075DD2FD6F8E26EF - 1818181883120420303901342093F3C2D10116E8EC7C43CC754B975B8EF53692 - 20564622116CA91BE0EB01A9430002C116C8E70BA3AEEB6EE139E6B71C4763A1 - 7AB02F07643F490134209304C3E1C113E8E8E86043B1C60B188A785BA958BAB6 - A1A1A135780AC81802108000045E49209BCD1E0B87E45B5D97FC552673E2513C - 9685EB0402AF2D8006E4B58D70448005BABAAE5A649ADA5BF285FC75C964E33C - ACF308F0C580D421000108FC1501C330D4D1D1B17DF158F4564A646F4986C3FB - FAFBFB6D80410002AF2C8006045706045E26D0D7D7476DD9F250234118571324 - F17686612EA6699A0114042000010840E0D504344D2B5114F5A0633BBFE479EA - AE8181817182205CA84100027F298006045704045E26B07AF59A2E4DD33FCC70 - ECA59228864892A48004010840000210988880EBBA6EB158CC98A6B54912851F - AB6A74C78E1DFDEA44CEC53110088A001A90A0541A79BEAA80B7CE231E9FB5D0 - 719CBFCDE6B2AF6F69693E1D6410800004200081A90AD8B66DA5D399C3B224DF - C230F4EF6D5BDB934AA5ACA98E87F320504F026840EAA99AC8652A02647777B7 - E4524C2F4DD2EF230862194551F45406C23910800004200081970B782F322429 - EA41C334FE9374848154EA4EEFB12C7C201068013420812E7FB093EFEDED1515 - 455DCE30ECDBB2B9ECD5D168B439D822C81E02108000042A21E03D96555094F1 - B01CBA5DD7B55F685AEC213C965509698CE9170134207EA914E29C3681CECE4E - 86E7237335ADF49682527C6B4B4BF3C2691B1C0341000210800004FE8A806559 - E6F1E3279E0DC9D2EF4431D4DFD020EFC76E59B85C822880062488550F70CEBD - BDBDF458267F1DE592EFA5686A25B6D50DF0C580D421000108CC9040B9AC2AAE - 4BEC746CF3C734EDAE4BA552C5190A05D342604604D080CC083B26ADB680B7C8 - BCB1B16D91AEEB6F2B968AD7373626E7563B06CC070108400002107849C0755D - 279D490F87A4F0FFB0ACFB8B4824B2B7BFBFDF801004822080062408550E768E - 644F4F4F58D79DD79334F51E9EE32E093607B28700042000815A12304DD32029 - 72B76DDA3FE638B27F606040AFA5F8100B042A218006A412AA18B326045E78A1 - E003CB1986799B522C5E17898493D8E1AA264A83202000010840E06502E974E6 - 482C16BDC374CD5FF114F5281A115C22F52C8006A49EAB1BE0DCD6AC79638BE3 - 6857D10CFD6ECBB2CEC35A8F005F0C481D021080804F041CC7B11DD779C036ED - 9F138478DBAA55E764FBFAFA1C9F848F3021306101342013A6C2817E10F076B8 - E238F91C9665DE5F50946B43A1508224495CE77E281E62840004200001C25B1B - 522C16B3A224DE6A19D6CF366D5AB70B2C10A83701FC62566F150D703EDDDDDD - 4DAECB5C43D1D4DFD9B6EDDDF51003CC81D42100010840C0C7028661A8344D3F - EC3AEE2F49D2BA73DDBA75C77C9C0E4287C05F08A001C105E17B016F6BDD6CB6 - B884A2A8F794CAE5DE6834D2E8FBA4900004200001084080208842A130268952 - BF65593F751CFDB1542A650106027E174003E2F70A063CFEABAEBA2AAEEBCEB5 - 1443DD605BF6B93CCF4B012741FA1080000420506702DEDD1092A2865CD7F939 - 4508770D0EFE69B4CE52443A0113400312B082D74BBABDBDBD5C3A5D3897A669 - 6F87ABBF696888B7D54B6EC803021080000420F04A02D96CEE583814BAD522AD - 5F383AEE86E02AF1AF001A10FFD62EB0917B0BCD294A783BCB31EF731CA78365 - 592EB018481C02131050554DB16DDB706CDB721CDBB06CC7721CC7741DDB344C - 4BB72D5B775CDBB41DC7B46CDB245CC27609D7766CD7FB3884E3B82EE93ADE3F - 1004E1FDEFF99F1DA4FBE2060F1441122E41920449923449510449B924495204 - C9D00C43132441D324C5D234CD5034C5320CC35194F7CF14435134CB30344FD3 - 34CBB2ACC8F3BC3C8194700804022B6059964910C46E4337BF1F8908F7DC71C7 - 1D4A603190B86F05D080F8B674C10CBCBBFBAAB36CDB7957B1A45C9F48246607 - 5301590759C07B14C3B46CD3B62CC3328DB2619AAAAE1B8A61E879DDB08A8E6D - 954CCB2A2612C90249BA65DB760A922C675CCB2E38A45B6429BEE8D0864298A4 - 4910A4499294E13884659A962D49AEA5AAAA43D3B4EBFD8F6118AFD92072B917 - FEFA6A9F58CC7AFEE78965BDF057DBB649D3142959B649EFEF759DA179DEA228 - 8A6254C7E12893646891A64993106DDB8A902429320C17514AC5384391118A61 - 42E9B17484A088104DD1618665C33CC74545498C732C2BB32C27D20CC3B10CCD - 619BEDD7AA0EFE7DBD09BCF4167591177E4D0ACCCF095D3F88B521F556E5FACE - 070D487DD7B76EB25BBB76AD649ACE2ACD303F2689E2E57593181281C08B02CF - DF6B70BDBB0CC4F3AF02701CC72A954B194DD5145D370AA55239138B4746B4B2 - 3E2A86A463966E1EE779F68449DA39C6E10BB64DA8145536689A36868686CAF5 - 04BB78F1E290288A82AE53224D13118271E2B6EE36D11CD5582AAAB3044968CE - 6772AD822034F03C1F15453E2C49729C6559C1EB78BC9B312FFECFDB951B3FF7 - EAE9E208782EDE17129AAE6FE059E6DF6CDBB80F4D48C02F081FA58F3F887D54 - ACA086DAD3D3D35E52CD1B744DBB21168BB5788F7104D50279D787806D3BB6AE - 6B4555551555D5B2E57239AB69DA783416396C9AD6A82C0AC31C271F27083B63 - 59EE9824516AB95C36088230F34D4D76BBAADAA954CA7EF171A8FA40994216DE - E398A3A3A394288A8CF7B12C91E3389DD7343BC9304C54D78DC692566E61687A - 562E9B6BE505A15996C526490A2565598A8664393E8569710A046A4AC07B246B - 74746C9F2C893F6723D2EF520303C33515208281C02B08A001C16551B3023D3D - 3DBC6D93CB0541B8215F285C23CB72AC6683456010789980699ABA6559866198 - 9A61E8A54C2E3BA295B4F1582C7A5C33F413222F1CE438762FCB92C7BD9D3619 - 86296FDBB60DCF7257E84A5AB1628548D3B4502A3911D7359B2CCB9EAF9BFA19 - 02C7B765F2F91651141221496E942431C672BCE03DDAC5B22C8F3B26152A0886 - 9D768142A130EEBDBCD0B19C9F3534841FEDEFEFF7BEB4C0070235298006A426 - CB82A0BABA7AA30CA3BD99E3B80FE8867E26EE7AE09AA875014DD34AE5B29A2B - 16954CB1581C1144E95981E39ED675F3204D53C32CEB8E47A3D18CA228F6FCF9 - F39DFEFE7E6F5D8553EB79D5717C646F6F2FF5DC73CF51E170985614256E9A64 - C234AD169A65E6E8BA7ABA522C9E1692E4B66834DAE43526E170B8A18E3D909A - CF059E7F86D3762D8770765A86F52323CCDFB90D0BD47D5ED5FA0D1F0D48FDD6 - D69799798F54C8B2BCD034C9F7164B4AAFF7C8952F1341D0752BF0FC33D79A56 - 5255359FCDE68E978AA5A3A22CEE9764E9598E669F25047A843685224128E5A1 - A12135E88F49F9F542F0EE98148BB44092A6ECBA56DCB2EC534B6A714149292E - 088723A74463D1765996E3B22C45BC3B257ECD1371D79F80B7882C9BCD8E8882 - F02B8EA37E1A8D460FF7F7F77B8F6CE203819A1140035233A54020DEBB3DCA65 - E352CD303EC6D0F465344DD35081C04C093CFF6DE20BABC12D4DD3CBB95CEE68 - 3A9D392C88DC133C2B3CCCB2CC5E92E44EE4E37CFA602AA5CD549C98B7FA021D - 1D1D2DBAEE365A967D9A61E9E7689A764E24129D1B0E871BA391708377C7D65B - F4EE7DAA1F1D6684C00B029AA615554D5B2F70DCF75CD7DC8605EAB8326A4900 - 0D482D5523C0B1786F342708F6ED82207CA0582A9D46D3141B600EA43E83024A - A1902E148A63B9426E3F4BB38FB202FBB4C8F107695A38689A0525168B69A954 - 4AC79D8D192C520D4D7DDA693D7C343A2AD8361B2708ABCD34ED39BAA92F2816 - 8A67251A1B1636C41B5A24498AE20B951A2A5A8042F1D6A2B10CF798691A3F33 - 05FAD6D49D778E07287DA45AC30268406AB8384108ADAFAF8F1A1A1A3AC33489 - F7154BC5B7452291A620E48D1C6B43C0344D4DD78D52A9583C91CBE7F68523B1 - A71DD77992A3E9C7398E3CBA7DFBF6D1DA881451F84C803AF3CC1531DB2EB6C9 - 72E86CCD3096948ACAC2682C3A37120EB77A2F5B6418E6F92D827D9617C2F5A9 - 403A933D2A4BE2EF199AFB49342AECC523593E2D641D858D06A48E8AE9C7547A - 7AD6BEEECF5B047D9A6598CB1886C15D0F3F16D167311B86512E1494E3D97CEE - 394914870887D82508C2D3A2483FE7BD472F954A790BC3B138DC6775ADE170A9 - CECE4ECA344DB150D0DA4CD73A8D7489F38AA5F2B9C978ECF45038DCEC3DBA55 - C3F123B43A11F0B6EB2D958B039C207DBB9019DD3E3434E4BD511D1F08CC8800 - 1A901961C7A43D3D3D11DB26AE6358E6FD8E435C806F02714D5442C0B66D6FFD - 46B1542AA673B9DC7E39243FC1D2DC232CCB3C4292D689D1D1687EDFBE01EF71 - 2A7C20503581CECE4E415194104110495DB74FB55DFBAC62B17C6E3C165F188E - 845B454108731C27562D204C141801D3340D8AA41E360CE33F5D57FA632A755B - 2E30C923D19A1240035253E5084630575E796573B16CBCDFD08DF73634C4DB82 - 9135B2AC86C04B0BC735DD28673399E718967E88A298ED36613E2A32CCE1EDDB - B78F61ED46352A8139262BB07CF9F2886559ADBAEE2EB21CE722C7B196251A1A - 4E0F87C3098AA2187C493359511CFF6A02DE2E590CCBFE84A5C5FFDCB4E9AE11 - FCB988EBA5DA026840AA2D1EE0F97A7B7BE95CAE7436CBB21F2AA9EAF5B22446 - 02CC81D4A751C0DBED45519413E3E3E9FD1C7F55049F0000200049444154CFED - 1438F16159661E224932C3B2AC8ADD5FA6111B43555A805CB16285605956B2A8 - 590B4C5D5F522AAAE73736269644A39156AF21A97400183F18028AA2A423E1C8 - ED9AA6FD78E3C67B7707236B64592B0268406AA512751E87F7C88120842E330C - F39F299ABA088F17D479C12B9C9E6D3B66B95C52D299EC019EE31E65687AC865 - DC07458639D0DCDC9CC102CB0A1700C35755A0A3A323EA384C9B6599E791A4BB - ACAC6A4B1A9B9A16C99214C19FA5552D455D4E562A9707599EFB76292C6DDED1 - DFEFBDBB081F08545C000D48C5893181F772419A166EC8E4B2FF3CABA9E9343C - 4A806B62AA02C56229333E3E7E8862E9072887DCC8F3C2C3A552CBF09E3D675A - 04D18785E35385C5797E11A03A3A3A68829092BA5E3E5B37B58B1DDB59356B56 - D3A2582C36CB2F4920CEDA12701CC7397162F4D96422F12D8671FF676060A050 - 5B11229A7A144003528F55ADA19CD6AC59739A61B8EF2EABE5B7271289D93514 - 1A42F18180B7877DB154CA6632E97D14C5EC66287A8728CA0F4A1235964AA58A - 3E48012142A06202DEDBDABD47B594B2B1D8D2ADE5A665AE686A4A9E198BC59A - F076F68AB1D7E5C0DEFAB94C3637C2F3DC2F2481F949381C3E823BC97559EA9A - 490A0D48CD94A2EE0221BBBA7ACE1545E123B6E3BCB3EEB24342151178691179 - B95C2E8C8F8D3F4733EC0EC7B6378AA2FC7038CC8E602D4745D831689D08786F - 682F6AE622C7B03B1DC7BEA4B5ADED6C5114C22FBE991D3FEFEBA4CE954C43D3 - B4523814FA63B9AC7E7FE5CA650FF5F5E1CE7225BD833C36FE400A72F52B94BB - B7DE83E7A54ECB763E4951D445F826AE42D07536ACB720F2C4F113CF5014BD9D - 61981D1CC73F4692C6C8D0D09086F772D459B1914E4505BC3B238661C434CD3C - C730CC0B0CDB7E5D7353D3A24422815D072B2A5F1F831B86A159B6BD856398EF - D3B4BB7E60005B95D747656B2B0B3420B5550FDF4773CD35D7848B65FDBAF1F1 - F17F6A6D693D0BEB3D7C5FD28A25E0388EADEB7A2997CB1F62187A2745D2F7EB - 84B193B6ACA3434343E58A4D8C81211020016F0D5E26A336DB84799EEBD8AF23 - 087269A2A16191288A118661F8005120D5490A1C3D3AB22799487C5B96B9FFB9 - E38E3B94499E8EC321F0AA02684070814C9BC0EAD5AB1386457CC8B6AC0F46A3 - D1269224717D4D9B6E7D0D94CBE546C6C7D38F4463B1BB198ADA92CF8F3FB367 - CF9E3F2F24C71BC8EBABD2C8A68604C88E8E0E462588164A773B72857C4F3291 - 58D9DADAB2B8866244283524E03D129BCE64466892FE8F7098FF8FC1C1C1D11A - 0A0FA1F85C00BF20FABC80B5107E5F5F1FB565CB96B92EC9FC836998EFC03EF5 - B55095DA8AC17B2379B95CCE8DA7D3CFF22C733F27C91B48917D72E7C68D276A - 2B52440381400850E79E7B6EC4759979BA695EAC69EAA5CDCDCD17846439896D - 7D0351FF492599CBE54F8882F87B8220FE73E3C6813D933A190743E0AF08A001 - C1A57152025EF3B179F38E0B3443FFB4C0F3970B82209FD48038B96E045CD775 - BCC62393C90E3334F580A619770B82B4FD81075207EB26492402813A1058B66C - 59A26C38E7138EBD8670884B5B5A5BCE641886C35DEC3A28EE34A690C965FF20 - 48FC573B57AEC4E2F469740DEA506840825AF969C8DB7BB3B9A2A86B4CCBFA38 - 169B4F03681D0DA128C5F19163238FC6E30D77BB36B99D2084A7E7CF8F17B1AD - 631D1519A9D49B00B96449B7C43085392E455E941E4FAF6D6D99D5118FC75B49 - 92A4EA2D59E43379016F5B74DB71B6D324F14DD3D436A552296F83107C203025 - 0134205362C349DDDDDDB2EBB2D7F202F751C771CE870804745D2FE772D92304 - 49EF7009622347735B71B703D705047C29402E5DDA394B55731D0441AE2129EA - 758964629EC00B3245A119F16545A72968EFA58514490FE9BAF67D9A76FE3438 - 38589AA6A1314CC004D08004ACE0D391AEB7D39569BAEF4A67B31F4F3434CCC6 - 6DFAE950F5EF18A592B7B6637CAF6559F74642E13B93C9E8630303CB4DBC99DC - BF3545E4107849A0A3A383B52CEA8C62B9B09A70A8B5AD6D2DE787C3E1060805 - 57C07BBC3693C98C8443E12FAB2AFBEB6DDBB0435670AF86A9678E0664EA7681 - 3CB3A7A7A7BD5432DFAF1BDABB1289447B2011903461599691C9648F38AEB3D9 - 71888D92203DC071CE51DC92C7C50181BA1520972F5FDE562EEB1D14C5AC7609 - B733996C3C551078A96E334662AF2A90CDE58E5304F5435966B14316AE95490B - A001993459704FB8ACA7E754DA26FF9124C9BFF7162806572298997B5B327A8D - C7D8D8D83ED332072541BC351E0F3F8A5BF0C1BC1E9075B0052EB860C579C562 - E91A9A655EDFDAD2BC188BD683793D284A29CB30D42F4882FEC1A64D03CF1104 - E1065302594F56000DC864C5027AFCA5DDDD1D4649FF142F085762A7ABE05D04 - C562297BFCC4F1C72DCBBE2716896C8844C46752A954317812C81802107849A0 - B3B353C8664BA7168ACAA5844BBCBEA565D692582CD604A160099454B5502A2A - B787A4D0F753A9F54368428255FFA9668B0664AA720139CF7B8B2EC789971896 - FD2F2CC35CC2B22CDE9C1B90DA7BCFF92A8A92193E3AB22B1E8DDE2908F4861D - 3B76EC0B48FA4813021098A080B723E2B3CF0E375B96B62A9BCBBDA1ADAD7545 - 3C1E6BC69DF20902D6C161DE2624AAA60DCAA2F8CD4C6674D7D0D0D09FD701E2 - 0381BF2E80060457C75F15F0161FC61B9B2FA35DE2B32445ADA0288A06573004 - 72B9FC31C771B6EAA67E4B34246E6B6C6C1CC316BAC1A83DB284C04908786F5B - 17CB65E7A27058BA8EA4C82B1289C42927311E4EF59180619ABA633BDB688AFC - DAFAF503833E0A1DA1CE80001A901940F7C3946BD7AE95CA65EB5A41E4FFD932 - EDB3698662FD1037629CBA80B7C77B269B3DEC38EEFD14E1DC2D49FCB62D5BB6 - A4098270A63E2ACE840004822870F1C517C70B65E33CC2B27B6896B92A1E8BCF - 11041E2FAA0DC0C560DBF676D3D0BFEB38E69DD8982400059F628A6840A60857 - CFA7F5F4F4F0A649BC2D97CF7DB6A9A9695E3DE78ADC08C27B5B79369B3D6C18 - C63A4E927EC712D623DBB66D536003010840E06405BC7522C5A2BEA85C56AFE3 - 05FE8D8D8DC9531986C1175A270B5BE3E71F3B76FCE98678FC4BB6ADFD3E954A - 59351E2EC29B0101342033805ECB53F6F4F444BCE6235FC87FB2B1B1716E2DC7 - 8AD84E4EC0B22C733C9DDE6F18C65D52387C0769698FEEDCB9B37072A3E26C08 - 400002FF5760C9926E99E78B8BF34AE14A9EE7AF9DDDDE7E0E9CEA57C0DB3571 - E4D8B16712F186EF5194FDBB0D1B36E4EB375B6436150134205351ABD373BCE6 - A350D03EE4B8F63FC4E3F1963A4D33F069798B0533E9F47ED3B6066551BAD5B2 - B4C7868686CA818701000420507101EF8E483E5F3E4B55B56B79817B7D32999C - CFF3BC58F18931C18C088C8E8E1E6019F6873C1FFA752A75CFF119090293D6A4 - 001A909A2C4BF583EAEAEA8A5A16F109D3B2DF178D461AAB1F0166AC86C0F0D1 - A34F59A679BB1816FB09D37C1C3B9554431D734000022F1758BC7831C7F321EF - D1ACBF1125F1BAD6D6964550AA3F01EF4E48BE901FA308F2476458FCC1968181 - B1FACB12194D45000DC854D4EAEC9CAEAEAE3996457DC0B6ADF78623E1449DA5 - 17F8740CC3504F9C18DD673BF65D222FDC6E9A91271E7B6CB014781800400002 - 332ED0D9D9192A958C45C562F1F50CC75EDB3C6BD6692CCBE245B7335E99E90D - 209BCD8EF082F02B8A607EBC69D33D87A677748CE6470134207EACDA34C67CD9 - 6557B711A4F951DBB66F906539368D4363A81916701CC7CA643323BAAEDF4132 - DCAF1ED9BDDD7B411476B49AE1BA607A0840E0FF0A788F66298AB658D5D5B78A - 82F4C66432319BA6690656F523605996E1B8CE0F19CAFDDEBDF7DE7BB07E3243 - 26531140033215B53A39E7D24BAF584033E487755D7F6B381C6EA893B4900641 - 10994C76C4348C014D33FA432176071697E3B2800004FC20E0DD1119CDE49733 - 24751DC7F33D4D8D8D788F881F0A37C11855552B0A3CFF5BCB72BEB97EFD5D7B - 27781A0EAB430134207558D4D74AA9AFAF8FDABE7DFB19995CE9D3E170E88DA2 - 20845EEB1CFCFBDA17F09EB52D168B99234786B78622A1DFB11179D3C35BB6E0 - 79DBDA2F1D228400045E2670EEB9E7C654D5B924A7E4DE36F79439AB62D15823 - EE88D4C765E26D845254943F46A3B1AF0D0EDEFD447D64852C262B800664B262 - 75707C77F7556715CBA52F8443E1AB681A2F18AC839212BAAE978E1D3FFEA024 - 483F0D85B8F5A9546A148F5BD54365910304022D402E5EBC58761C668D699A7F - D73EBB7DA52C4B7854B80E2E09EFFD538582729B1016FAEE5BB7EEC93A480929 - 4C52000DC824C17C7E38D9D9D5B3DC54B57F0985E5AB699AA67D9E4FE0C3372D - 4B3F3A7CF4914834FA5B4AA06F6F4B2486FBFBFBEDC0C300000210A82B81F3CE - BBE814DBD62FD70DE36DADADAD1DA22884EB2AC10026A31B86AA69DAA0C0F1DE - 0B0B1FC60B0B837511A001094EBDC9CECB2FEF704DF20BB22C5E119CB4EB3353 - EFDBA374267DC434CD3FD11CFD4BD2B29EC296BAF5596B64050108FCAFC0920B - 2E58A02AEAF53CCF5FDFD6DAB680A248862449FC2EE3D38BC4711CBB5C56D731 - 34F5A54422BA135FA0F9B49053081BFFD14E01CD8FA7AC5EB366956DBAFFCAB1 - 6C27C330AC1F7340CC2F086432D9A39669DE4DD3D4EF19867870DBB66D0A6C20 - 0001080445A0A3A343B26DEA4CCBB1DE2409E275492C54F775E94DD3D475DDD8 - E83521F97C7A37BE4CF37539271C3C1A900953F9F3C0DEDE5E3A972B5E685AD6 - BF4A92B4C69F59206A4F405555E5E8D1A3BB2451FA39C745EEDDB56B631A3210 - 800004822AB062C50AB15854BBF34AF1867973E75E2249529824492AA81E7ECE - FBA52644E0B9AF1946793B1EC7F2733527163B1A908939F9F6A8CBBAAFBA8874 - EC2FB22C7B09455158F3E1C34A3A8EE38C8E8E3EA3148BBF8D4713BFD9B56BB3 - F71227BCCFC387B544C81080C0B40B90E79DB7B2259B1FEF0DC9F2DFCD9933FB - 9C699F01035645C07B1C4B55B5419A22BFE838C62E342155619FB149D080CC18 - 7DC5272657AF5973B16D10370A02D785E6A3E2DE1599209BCD0E97CBE5DB4541 - F86FD3541F1F1A1A2A5764220C0A010840C0C702DE8B0C73B9D2D98661BC2914 - 0A5D176F88B761DB5EFF15D4300CCD30ADFB7996F94A2633BA1D8F63F9AF8613 - 8D180DC844A5FC751CB97AF5151738AEF3455114BBFD153AA2F504344D2B1F39 - 72F4C1902CFF489298BBB1CE03D7C5CC09F451BDBD4F92636363A4A228A4AAAA - A46118FFDFCF0E8EE35C5114DD7038EC363636BAFDFDFD2EEED0CD5CB5823EB3 - D7889C48E72E2B154A1F5AB0E0F4D50CC37058A4EEAFABE2853B21EA7A8E65BF - 188B851EC0C2747FD56FA2D1A20199A8948F8EEBEAEAB9D0B4EDCFF11CEBFDE1 - 8B05E73EAA9DF7B8D5B1E3C79F5255F5B7D170C37FCB32750CB7A17D54C03A08 - B5A7A7871F1D55C32EAB35B22E35DB34EDB9BC28248A45A5D1B65D319BCE440D - CBE22892201DD7715C973013894481A6C9922C86C65CD7C9D03C7B9821A8A396 - 458DC932318E6BB80E2E0C9FA570E18517CE1D1FCF5FCBF1FC3B5A5B5B16731C - C7FB2C854087FBFC9A104DDF400BFC17EE1BBC6767A031EA34793420755458EF - 0DE75B77ED3A5355D42F442391D7D7516A8148259BCB8DE8BABE8EA5E99F8922 - FB602A95D2029138929C5181C58B7BB968B410B2ACC242D3B4176BBABEB85C2A - 2D8E46A3EDA1B09C1445312408823CD120354D2B7AFBFB179562A6A028C7C2B2 - BC87E1B8C7489A7A52E2A86742A150616060409FE878380E0227214075745CB8 - D4B4ED778665E9DA7024D288C7914F42B3CAA77A4D485955EF1543C2CD1B0606 - 1EAEF2F498AEC20268402A0C5CCDE1BBBAAE5A54D6D42F8743D25ABC64B09AF2 - 2737976559E691C3471E6505E1DF6481BE6BC78E1D99931B1167436022027DD4 - B265EBCF771CE7428AA65F6759D6790D0DF176EFCF8EE97A76DE7DE1E378EFAD - 5114658CE5D8476CD3DE62DBD66651649F48A552C589448A6320701202E4F2E5 - CBC3864D74ABC5F23FCC3F75FE252731164EADB2C0F36F4C2F2AB7C942E8A60D - 1BEE7EAACAD363BA0A0AA001A9206E35875EBDFACA338AA5FCBFC662F1374FD7 - 2F0FD58C3F887379BF99E572F911CB36FFA0DBC67FB1AEFB0C16DC05F14AA85E - CE9D9D9D8C61506DE5B2722949D39D96655E108FC5DB64598A56EB39796F3BE9 - 5C3E7F8C24A99D8E656F8C4484CDE3E3B38EEED9D36F544F0233055160D9B28B - CF316DE32D2CC35E9F4C26E705D1C08F39EBBA5E2E158BB78542D12FA209F163 - 055F396634207550CBCB2EBBBA8D669D4FDB96FDAEC93C2A5107A9FB3605CBB2 - 8CA34747767302F7EF1CDD70CFCE9D0305DF2683C06B5EC07B1FD0F070BA5937 - 8B57E7F2CA5B4F993DFB7CEFD1AA990EDC6B468E1C197E281A89DC228ACCBA96 - 96964358703AD355A9EFF9BDFF169EDD7FF0F56A49FBD029A7CCBE886559A1BE - 33AE8FECBC2705688AFEA96D6B5F1F1C1C3C501F59053B0B34203EAF7F7777F7 - 6CCBA1FED134CC7787C3A1069FA71388F0C7C7C70F9555F537D170F457ADADC9 - 7DF8852B10659FB12457AEBCBCB554CA5D952F14DED4DE3EFBFC50488A55EB6E - C744932E954AF99191638FC5A2D1DF3361E1F61D9B361D9DE8B9380E02931578 - E14EA0714A26577C47480EBDBDA9A9F1D4C98E81E3AB2FA0AA5A9165D89F390E - F1AD0D1BEE3A5CFD0830E3740AA001994ECD2A8FD5D5D515354DF2932EE17E20 - 1492E3559E1ED34D5240D3B4D2E1C387B78564E9273CCFACDBB97327EE7A4CD2 - 10874F5CA0BBBB5BCE66CB2B1CD77EB720089747A391E4C4CF9E99230B85C2B8 - 6E981B188AF925CF135B53A9548920086F5B5F7C2030ED024B9674CB0491BDAC - 50C8FFFDDC79735649921C9EF64930E0B40A94CBE53C41923FE218E287838383 - 47A675700C565501342055E59EBEC97A7A7A22E5B2F571DBB13E1089D4FE2F16 - D397B93F47CA64B3C3F97CEE97A178E467BBB76E3D88F724F8B38E7E89BAB3B3 - B3B9ACDBEF3075E3BDB36635CDF7D3CE3FDE3B00D2E9F4115E107ECD50CE2F53 - A9D43EBFB8234E5F0A90CB9777B6E50AE9BF8B4623EF492692737C99454082F6 - D64E2A8A922609EA871C477C7FE3C68DE980A45E7769A201F16149575E734DD8 - 49173E4491EE47A3D158930F53084CC8BA6E940F1D3AB84B96423F8EC7E575A9 - 542A1798E49168D505BC7778E472C58B1D97782FCFF3DD7EBE335A2A970B8E65 - A52CD7FD11CF10296C4B5DF5CB29501376767686D239A5AB58287E60DEBC792B - 05819FF0D6D38182AA9164BD2F29289AF921CF867F924ADD395E2361218C4908 - A0019904562D1CEAFD8261DBD40D4A51B9311E8FB7D6424C88E1FF0A785B8F7A - DFD2944AA55B2892FECFA1A11D8FC309029514E8E8E860298A7FBB61D99F6C6B - 6D5E58C9B9AA39F69123C34F3034F3758E6BB81D9B3554533E987375745C74AA - AA97FF3E1C0ABFB5A121DE4C9224154C89DACF7A7C3C3D2C89E2974491F9EDC0 - 003672A9FD8AFD658468407C54B1152B7A4541C8F6168AA5BE594D4DD842B046 - 6BE73D4272E8D0E11DA2C0FD8724F1776FDDBA355BA3A122AC3A1158BE7AF52C - B2A4BFCB729C0F3435369E5227693D9F86E3388EB771034DB13FA469E157DBB7 - 0F8ED6537EC8A5F604962F5F1E5155BBBB542E7F70EEDC3917F23C2FD65E9488 - C87B1CEBF889137BA3E1C83708C2FC452A95B2A0E21F0134203EA995F7ED662C - 967863BEA07CA9A9A9093B76D468DD72B9DC885A56EF6459F627BB766D7BB046 - C344587524D0D9D9D99E4E17FE21128BBE3B5AC7EBC1BC05EAF95CE1577222FC - 6F0FA452DE3A2A7C2050490172E9D2958B3543BD21128ABC251C09E32DEA95D4 - 3E89B10F1F3EF244480E7DA15098751BDE27741290553E150D4895C1A7329DB7 - 65A028862FA318FA4BAEE35E309531704EE50586878F3EC1B1EC771A1B63BF19 - 1818D02B3F236608BAC045177537158AE9CF3434C4DF294BD57B99E04CB91B86 - A1A6C7D3BF0A8785AF6DDEBC19EF0298A9420468DE952B5786CB65EB2ACDD03F - 366FEE29F8F95B83B5F71E792649F221D3B63FB7FEDEBBEEA9C11011D22B08A0 - 01A9F1CBC26B3E785E5EE512C4CD04415CC8300C5BE321072E3C4DD394FDFB9F - DBD0D6DAF2DD6854DE89E6237097C08C247CC925DDB3B3D9F18FC662B1BF0D47 - C2891909620626F516A7E773B9DF44C2E257366FDE8C6D3867A006419B72F1E2 - C59C24259666B3E3FFD83EBBBD5B96A558D00CFC90AFA6E99B2892F8826569DE - 16DE781CABC68B8606A4C60BD4DD7D558769995FE6797EB59FB6D2AC71D66909 - CFFBD6C57B93733E97FB31C3883FD8BD1BBF0C4D0B2C06794D818B2FBE389E2B - 943E914C243E1CC4771794CBAA323E36F6EFF178E83B5BB66C197B4D301C0081 - 6910E8E858D5A228D9F74563D11B92C9447BADBDD0731A52F4F510A669EA8661 - DCC7D0CC4D1B37DEEB3D028D7708D57045D180D470713AD7AC394D57B4AF8442 - F25A9665F91A0E3590A11D3A7478BB2808FF2E08F4BD58681EC84B604692F65E - 3098CB15DF4F52F4C7128986C0EE8497CD668FD98EFB955844FCD9E0E0A0F7C2 - 427C20507181E75F5E48677A4CDDFC587B7BDB79F8D95C71F2494DE03DA6592C - 2A7F9263E12F6D1C18780A4DC8A4F8AA7A301A90AA724F7CB2AEAEABE790A4F3 - 49DBB1DF250802F6239F385DC58F2C954A594D53EF6668F607DBB6A51EA8F884 - 9800022F0A789B519024FF668A22BF906C4CD6D56E575329F291E1E13D144D7D - BE7556F2363CFA3815419C331501EFD1E852C938CB76EC8F44A3D1378AA21899 - CA3838A73202A5B25AE059FA97344D7C6160600077482BC37CD2A3A2013969C2 - E91FE09A6BAE09E715F5133CC77D8A61186EFA67C0885315C866B323C552E9A7 - 9150C38FB76D5B7F0CDFAE4C5512E74D41805CBAF4A2556555FDFE9C39B397E0 - F10F82F01E833C72F8C8235234F24FBBB6DDBF650AA6380502531658BAB4B3B9 - 504CBF33140AFFFDACA6C6B9531E08274EBB40B158CA1224F1FDB0CC7FEFEEBB - EFC656F8D32E7CF203A2013979C3691DC17BBCC2759977E5F2F94F363626E74C - EBE0186CCA02DEB3A54747461EE238E1073419BA6B6868437ECA83E144084C41 - A0B3B3B3B9AC1ADF8EC5E2D761338AFF05B46DDB1A4F676EE118AE6FC78ED4BE - 29D0E214084C59C07B83FA78B670B95656FFF1B4D34E5B85B59A53A69CF61373 - F9FC89B01CFAA2EB1A3FC7639AD3CE7BD203A2013969C2E91BA0B7B797CE6494 - B72845E58BC9241EAF983ED9A98FE4BDE8C8B66D3397CDF5D334FDADF6F6598F - F5F7F7DB531F11674260F202DE17138582FE7E5EE06E9265293AF911EAFB0C45 - 29651DDBFC4624227D1B8F62D577AD6B35BB8E8E156793A4FB49391CB94696F0 - 4856ADD4697474F4802C856E348CD86D3B76F4ABB51217E220083420357215F4 - F5F5513B1F7CF82A86A26FB62CEB5C3C5E511B85194FA70F97CBE59F87A4C82F - 1E78002F3FAB8DAA042F8AA54B57AD364CED076D6DAD0B8297FDC4323E7EFCC4 - D3B2247E78CB96FB364EEC0C1C0581691520972D5BD69057D40F46A3D1F72713 - 89B6691D1D834D49C0711C9BA2A8471CDBBE291C1637F4F7F71B531A08274DBB - 001A9069279DFC80DE9D0F45519739AEFB5586612E99FC083863BA05BC67CB0F - 1D3EF288C071FFCEB2C41F76EEDC5998EE39301E042622D0DDDDDD942B94BE9E - 4C24DF3991E3837A8CF798643A93FD1F91973FBB6DDB86C3417540DE332BE03D - 9295C917AF3675F3A3B367B79F87C72567B61EDEEC5E1362E8468AA6A9CFAD5F - 3FB01D6B3767BE265E0468406AA00EAB7B7A169B25E3ABBC20AC61592C3A9FE9 - 9278BFC81C3878707BB2A1E1F3B367B76CC12357335D91E0CEEFED7AC530E23B - 1886FE5234166B0EAEC4C432CFE70BE36A59FDCC430F3DF05F133B03474160FA - 055ED8254B5F369EC9DCB4E08C33BAB02E64FA8D273BA2D784144BCA1D221FFA - D4FAF577ED9DECF9387EFA05D0804CBFE9A446F4BEDD2408F673DE76BB3CCF4B - 933A19074FBB40B95CCEE7F3853F3034FD6F73E7B63D8EE663DA8931E0240496 - 2DBB64DE587AF4678B162EE89CC469813E74DFBEFDF7B4B6B47D24955A8705E9 - 81BE12663EF9152B569CAD19EE47229170AF2C49D8AA77864BA2695A9161999F - 130EF38DC1C1DB8FCC7038819F1E0DC80C5E025D5D5D51D3263FE63AEE874321 - 393E83A1606A82201445192F28A59F708CF8BDDDBB53C7810281191620CF39E7 - 82F7259B1ABFCB739C30C3B1F8667AEFBF63DBB56FE268F2E7A9544AF34DE008 - B42E05962F5F3DAB58CE7C281689BC37128DCEC2FACE992D73A954CAB90EF14D - 8AB2BE964AA5AC998D26D8B3A30199A1FAAF58D12BCA72F1EDAA56FE62341A6B - 9AA13030ADF730A8EB3AA363637B4997F84E28C4DF924AA5728081C04C0B7476 - F6B40F0F1FFCD9E9679CDE855F5A265E0DEF518B7DFBF66D9C33BBE5839B366D - DA3FF1337124042A23B062C58A065D775EEF12EEC75B5A5A165766168C3A5181 - B1B1B1839170E48BB6ADFD065F524C546DFA8F430332FDA6AF39A2B7E3D5B66D - 0F5C71FCC4D857DADBDBCEC62F17AF4956B1032CCB328687871F1105E99B1C47 - DCB563C70E6CD357316D0C3C5101EFCF887BEED9F0769663BE1E8D46674DF43C - 1CF782402E971B2DE4957F7CE28987FABD35A87081C04C0B789BCD3CBDF7C0D5 - 6AA9FCD179F3E62E675916773567B0282323C79E6A6A4C7CCC30D4F5B8133233 - 8540033203EE5D5D3DE739AEF32D8EE35E47511435032160CA17050A8AF2475D - D5BEBA7BF7F621FCA282CBA256047A7A7AF8F171E547C9C68677E10B8AC957C5 - 7B39E1C8B1E3FF11921237EDD8B12E33F9117006042A21D0472D5FBEF12C8770 - 3E1A92E5BF1145315C895930E66B0B78774AD5B2BA916198CF6EDC78EF83D819 - EBB5CDA6FB083420D32DFA1AE35D71C5150B585EBA5153B5EB5996E5AB3C3DA6 - 7B51A0542A650B4AF1969024FFDB962D1BF7000602B524B0E2924BCE2EE64ABF - 993DBBFDEC5A8ACB2FB1782F103D74E8F083B39A9A3E70DF7D83DE970BF840A0 - 5604C8952B2F6FC915C6FFA1211E7F6F381C4ED44A60418B43D70D55E0F95B4C - B37CD3E0E02016A557F90240035245F0AEAEDEA8EB163EED12C4870441085571 - 6A4CF5A280F78B49A150182D2AA59F4722C2F7B76CD9720C3810A83101F2BCF3 - 96BD3F1C097F25140AC56A2C36DF84532814C62CDBB971765BD3CFB09B9D6FCA - 1698402FBEF8E2F8D858F6BD0DC9C44763D11816A7CF50E54BE572C1719CEF4A - 02F3BD75EB70B7B49A6540035225ED15BDBD62A8507A67215FF84C2291985DA5 - 6931CDCB048E1F3FB18FA4E96F3164E4B73B770EE0E582B8426A4E60C59A350D - 6656F9F76422713DDE1F30F5F2788F618D8F8DFFA4A929FE4F030303FAD447C2 - 9910A88C80F7D2C27C5EBDD676ED4FB6B5B62E2649128F645786FA55474D1A6B - D02F0000200049444154A7D3C3A224DE9CDAB4FE2733307D60A744035285D27B - 2F252249A13B9B4F7FBBB5A5754115A6C4142F13F07E1939327CF4518163BE11 - 89C8B763E70B5C22B52AB07AF5EA33C6C6737F686F6F3FAB5663F44B5CCFEEDD - BB7956E3ACF76DDB76DF337E891971064BA0B3B35348A7736B0CC3FAD429734F - E96018BC8C7826AE80C3878F0CB5B6347F3A1A9537E18E69752A8006A40ACEAB - 575FB1C421DC6FF11C7729BED1AC02F8CBA6F076BADABFFFB91D9178FCA68777 - 6FDF8AC5E6D5AF01669CB8406767F71B6CC7FAAF70389C9CF85938F29504B2B9 - EC71C2713EB863C7D63F410802B52BD0472D5D3AD8313A3E7ED3998B175D5DBB - 71D66F648EE3389AAA6D7418E6539B370C3C5CBF99D64E6668402A5C8BCB2FBF - A695E3A8CFEB86FE568EE3C40A4F87E15F26A06A5AB15C2EDF4938EEB7449179 - 14DBEDE112A9758173CF5FF6C5D696961B6B3D4E3FC4A7695AF9E8C8D11FC422 - B3BF88472EFD50B160C7B86CD9C5E71886FEC148347A7D282463FD57952F07CB - B24C8AA47E4610E657EFBDF7DE83559E3E70D3A101A960C9DFF08637C47285F2 - C74882F808B6DBAB20F45F19DA300C359BC9FE5A96235FD9BC79F040F523C08C - 10989CC035D75C137EF2C9BDBF58B0F08C374EEE4C1CFDD7049EDCB36743EBBC - D9EFDAB169D3512841A0D605962FEF6C2F970BFF1C6F88BF5396E538B6E1AE6E - C58AC552967089EF9B66FC6B3B76F4E3BD6015E447035241DCCB2FBFF23D4AB1 - 78734343BCB582D360E85710F0B6D92D15955F729CFCDDEDDB371D021204FC20 - 70D995579E323A7CFCD639B3675FE08778FD10E3F1E3C79F93C4F00D5BB76E48 - F9215EC40801AF092996F3EF8F4563EF8F46238D10A9AEC0F8D8D82141106FA4 - 28FB0F582F5A397B342015B0F5DE785A28942F6138F6EBAEE3E217890A18FFB5 - 215DD775BCE6239D4EFFB8211EFE01B6D9AD223EA63A590172D5AA4B2FD30DE3 - A7C964F294931D0CE7BF20A0EBBA7AFCD8F1BE279F7CE4EB3081805F04962EED - 6C2E14D2EF89C6A2EF492613F8F3A08A85B3BD8FE3ECD64DF35FB6DCB7FEFE2A - 4E1DA8A9D08054A0DCDDDD6B171A86F66D4114D6E04DE715007E9521C7C6C70F - B234F30D8AB27FB775EBD66C7567C76C1098BAC0E2C58B39D3743FD2DAD676A3 - 2CCBD1A98F84335F2EB0E7A9A77E71F0B967FF0E3210F093404747074B10EC3B - 699AFA6CB2B1114D48158BE7BD293D97CFDF1A09099F1E1CC423DC95A0470332 - CDAADEBA8F52C9F85792223F8CEDF4A619F75586F35E30383A3AFA8C4B52DF16 - 39F2F7DBB66D53AA373B6682C0C90B2C59B2443E7CF8C4F7962DBFE09D0CC330 - 273F22467849E0D967F7DEBA6FEF9E5E8840C06F02DDDDDDF2F878FE5AC7753F - DDDADAB2D86FF1FB395EEF258584E3FC4092B8EF0C0C0C8CF939975A8C1D0DC8 - 3456A5B7B7972B94D4F7160BA59BA2D148D3340E8DA15EBDF970C6C6C60ED014 - 7DB32832FD786613978B1F054E5BBE3C923F38F2EBA5179CBFD68FF1D772CCFB - F6EEBB7DEEDCB6B70D0E0E966A394EC406815712F01EEBDEBBF7D09B088AB8A9 - A5B9F90C2C4CAFDE7592CE648F8624E1C655AB2EFAEFBEBE3EA77A33D7FF4C68 - 40A6A9C6DECB0645317C992849DFD5346DD1340D8B61262070E4C8F0130C4D7E - 291A0DDD86E663026038A42605CE3DF7DCD8F878E1D625E79CBDBA2603F47150 - 7BF7EDBBB3AD65F15B53A9FEA28FD340E80116E8E9E9E1474E8CBF8174C99B70 - 27A47A1782B7AED471DD9D84E3DCB86EDDDDDE46166EF566AFEF99D0804C537D - D7AC597BA66119DF6219E6328661D8691A16C3BC8A80F776F36323C79EA028FA - CB8F3CB2AB1F5810F0B3C08A152B1A468E8DFFF1CC3317BFCECF79D462EC7BF7 - EEBBABAD75F15BD080D4627510D34405BC26E4C8C8892B6DD3BA71DEBC791D13 - 3D0FC79D9C80699ABA52546E13C2D26753EBD6ED3BB9D170F64B026840A6E15A - E8EAEA8A5214DB4752F487699AC6B3DBD3603A91219EDBFFDCCE4824FC995DBB - BAFFFCAD046E8D4EC40CC7D4AEC0F30DC8F1F4ED672E5E7471ED46E9CFC8F6EE - DD77775BEBE237A301F167FD10F5FF5FA08F5AB66C53A752CA7D6DDEDC79D865 - B34A1747A954CA3BAEFB3D9A0C7F2795BA2D57A569EB7A1A342027595EEF1B09 - D324FEB6542EDD1C8FC75B4E72389C3E0101C7719C83070F6D8927135FD8B1E5 - 75F7A1F998001A0EA9798165CB9625C6C6F3B72F5AB47065CD07EBB300D180F8 - AC6008F75505BCDDB11C8A5FA164735F3E63C1E9F8F3A24AD7CBD8F8F8819014 - FA6CA130DE3F3434645669DABA9D060DC8C99596BCE28AAB5FC78BC2F74CC35C - 727243E1EC890878CDC773070EEE9645E1930F3FBC7BF344CEC13110F08380D7 - 808CA70B772C5CB8E0223FC4EBA718D180F8A95A88758202E4D28B2E59A56473 - 5F9B376FEE722C4C9FA0DA491EA66BFA268AA23EB67EFD3D8F9CE450813F1D0D - C8495C02575EF9C6535896F992A697DF8447AF4E027212A71E3870E07E81E76F - 3AEDB4B9DBFAFBFBED499C8A432150D3021D1D9DC94CEEF81D8B162E5851D381 - FA30B8BD7BF7DFD3D6BAE84D7804CB87C543C87F55C0DBFC46D3AC8B0BA5E257 - E7CE396539A82A2F6018A6C6B0F42F19CAFDC25D77DD75B4F233D6EF0C6840A6 - 58DBB56BD74AE5B2F171CBB6FF4996E5F81487C1691314F0169C1F3E7CE481C6 - 64E2739B376FDA34C1D37018047C23F07C03923F7EC7A2056840A6BB686840A6 - 5B14E3D58A80D784E4F3A58B0A4AE9CB0BF0385655CA52509471D7B6BFCCB2E4 - 8FB0F3E6D4C9D1804CD1AEBBFBCACB73F9C27F259309BC9D748A869339EDE0C1 - 835B6449FA97DDBB773C401004F6E29E0C1E8EF585001A90CA9569EFBEFDF7B4 - B5E00E48E58431F20C0B90CB96ADBCB8582A7D73EEDC5396CD702C753FBDF7E2 - E3A323234FC71B1A3E76FFA68BD6611DEAD44A8E06640A6EDD575D75965136BF - C1F3FC6A9AA6B0E5EE140C277A8AB7E663FF730736CF6A4CDEBC756BEA7EECC1 - 3D51391CE73701342095ABD8B3FBF60D2C5E70EA9BEEB8E30EA572B3606408CC - 9C807727A4503057140AD9AF60617A75EA90CD666F1778E953F7DD77EF33D599 - B1BE66410332C97A7AFF91D3B4F0655EE03F31C95371F82405BCE6E3C0C1030F - 4642E14FEEDEBDC36B3EF08140DD0AA001A95C69BD06A4BD65F1F55803523963 - 8C5C1302E4D2A597AC2A96F25FF7EE8460617A656BA2695AD1DB9A9767C96FAF - 5BB72E53D9D9EA6F74342093A8A9B7E5AE65B9BDF982F2856432397712A7E2D0 - 2908EC3F70605B2C1EFFD739AD4D9BB1E07C0A8038C5570268402A57AE7DFBF6 - 0D2CC41D90CA0163E49A11F0BE242D978D4B0A05E5ABF34F9DBFB46602ABD340 - C6C7C60F0982F899CD9B37FCB64E53AC585A68402641DBD5D57321C350DFA468 - 06FB6E4FC26DB287DAB6631F3A78F0A14824F6AFBB766DF9F3F395F840A0FE05 - D08054AEC668402A678B916B4FC06B4274DD7E5D3697FFD2FCF9F3B03B56854B - 5456D5F5A44B7EE2BEFBD63D86C7C4278E8D066482566BD7AE4D1A86FB79C775 - 6E6059969BE069386C0A02C347861F91A4F0271E78A0F3CFBB5DE10DE75320C4 - 293E14400352B9A2A101A99C2D46AE55813E6AF9F2C1AEB2AA7F6BF6ECF6B36A - 35CA7A884B55358565A89F1A127F73EA36BC257DA2354503320129EFDB048E93 - DF5D282A9F6B88C75B27700A0E998280EBBACE9123C37B4882FCFCE38F0FFD01 - BB5D4D0111A7F856000D48E54A8706A472B618B97605162FEEE538F1D0958E65 - 7FBEBDBDFDECDA8DD4FF916532D91141E46F241CF3F7D89A7762F544033201A7 - D5ABAF58CA70ECF7688AC20BC226E0359543BC6DEDC6C7D3074CCBBEE991871E - F8CD54C6C03910F0B3001A90CA556FDFBEE7EE5DB860DEF5D805AB72C618B936 - 057A7B7BE967F61DE8A508EAE69696E6D3B130BD3275F236CD711C679B4DDA1F - DB78EFBDBB2B334B7D8D8A06E435EA79E5955736BB2E73B3611A6FE7795EAAAF - F2D74E36274E8C3DCB72F457048EBE35954A156B2732440281EA08A001A99C33 - 1A90CAD962E4DA17F036D039766CFC3A8A266F6E6E6E39B5F623F66784A669EA - 0CCDFC9224ADCFDD73CF3DC7FD9945F5A24603F22AD61D1D1D6C22D1FC9EB2AA - 7E3E120927AB5796E0CCE43D7695CD6487755DFF0A45D9BF1A1A1A2A07277B64 - 0A81FF15F01A905CFEC49D0B169C71215CA65760EFBEFDEB162D98DF8B3B20D3 - EB8AD1FC23D0D9D929144ADA9B4982FCCCACA6A6D3FD13B9BF22CD6432C3D148 - F4F3AE6BFC767070B0E4AFE8AB1B2D1A9057F17E7ED72B96F90E4551F885A042 - D765B158CC58B673B36D0ABFD8B973A050A169302C046A5E000D48E54A8406A4 - 72B618D93F02DEE358FB0F0CBF87E7D9BE782CDEEC9FC8FD13A9F738B9E33ABB - 6CD3FAF8860DF76EF54FE4D58F140DC85F31BFFAEAABDB1C82EE3374E3ED1CC7 - 09D52F4DFDCF582E977363A3E3FF1189347DFDFFB177DEF15155691F9FB977EE - F43E935E082109C506869690C010203160B06DD6577765ED1557454477D53562 - 63D575ED6D151BD8B2AB6B02840402034908A0590B8A9400E9C9F4DEDBFB19C0 - 5D452033937B67EEBDF3F0C71673CEF33CBFEF7306E7977BCF399D9D70890FFD - 3B0E0ACF46605A79798A7558DF004F40F05F276040F0670A11A94960D6AC6AB1 - C53678874226FFA3442A011342401BBD5EAF9B85626F87429EBFC0058567060C - 06E4346CEAEAEA905DBBBEBCD1E1743E2691885309589F491F32FC0135992D6B - B96CE6131D1D1D43490F0400243D013020C42D013020C4B185C8D423A052A994 - 5ABD75558A527E93402090524F01F92B36994C4302BEF0210C0B7DD8D4D4E421 - 7FC5F1AF100CC8AF9933172EBC680E0BC39E613299B3E0C408FC17A5DBED76D8 - EDB6CFD818AFAEBDBDF528FE19202210A01E013020C4F50C0C08716C21323509 - CC9D3B37C76C71AD4C4F4FBD8DC56261D45441DEAA83C16080110AEE0E044277 - 6FD9B2E92BF2569AB8CAC0809CC25E75E9A5528ECBFF642018B896CD66F312D7 - 1A7A660E04027EBBCDD688A2D8833B776EFD919E2A411510889E40D8805846F4 - 8D938A8AE0E6E2E8F19D750618109C8142385A10983B7751A1D7EB5D2D120B2E - 870B96F16FA9DFEFF70543A1973134F4545353930EFF0CD48E0806E467FDABAD - AD65EB74E6DF7A7CDE67645229BC1B49C0DAEEE9EDFD522691DCDBD1B123BC39 - 2B44400A0809042849A0BCBC3C6578C4D0585454080604E70E1EE93ED2327162 - FE6FE0142C9CC14238AA13605E386BD6791683EDF989130BE7535D0CD9EA0F6F - 483799CC4342B1F0619958F07E7D7D7D806C3526B21E30203FA3BF68F1E2A921 - 3FE34514414A51144513D9183AE6EEEBEBFF8E2F14AC0A789DDBBABABA7C74D4 - 089A8040AC04C080C44A6EF479478E1C6999580406647452302219099494942F - B0DB1DCF6465679D8F20087CF7C17911783C1E350B65DDDDDCBCE15B9C43533A - 1C189093ED53A9542C14E5FE95C3E5ACA0744749587CF8B7000683A12710623C - 9A3F2E731DFC1680844D8292124E000C08712D0003421C5B884C7D02E13BCFBC - 01C6122E9BF3424A4A4A2EF515914B81C7E3713242CCD7F87CD69AC6C6463DB9 - AA4B5C356040180C46F8C3C7E58A2F737B5C6BD2D2D2C627AE1DF4CC6CB15875 - 5EBFE7711633F48FCECE4E173D55822A203036026040C6C6EF6CB3C18010C716 - 22D383404949092F1040966118AB4E02AFA0E3DE54A3C1D8C7E70B1ED8B66DF3 - 47B807A7684030200C0623BC118B81845E130A040B28DA47D296ED743A2D06A3 - 61AD42265EAD56ABCDA42D140A0302092670D2806C282A2A9C99E05268971E0C - 08ED5A0A820820B070E142C9F0B061853235E56E019F27262045528774D8ED1B - D86CDE8A2D5B361C4E6A1027C527BD01A9ACAC1478BD8C075818BA122E1CC4FF - 2361309AD63282C8237BF6A807F08F0E1181007D081C37201AC386A242302078 - 77150C08DE44211E5D0984FF1EB2D9DD8FCAE5F2655C2E5740579D89D065B73B - 4CFE80FF6F0A99E8EF8D8D8DCE44D440A69CC96E40988B1655CFD5E90DAF6664 - A44F863B3FF05B9A7EBFDFEB767B36632CD6C3ADAD9BBFC32F32440202F42400 - 0684B8BE761F39B2655251FE15700A16718C21327D08CC9D3B77BCDBE37F42A9 - 4CB98A3EAAC8A1A4BF7FE0BB14A5E2CE6DDB5A7692A3A2C45591D40624FCF483 - C964FF1D65A13725AE05F4CB1CDE743E3838F4359F27FAE3EEDDDB3BE8A71014 - 0101FC098001C19FE94F11C18010C71622D3934069E9BC12ABCDFA724E4ECE54 - 269389D05365FC5585EF426384186F8442DED52D2D2DDAF857409E8C496B40C2 - 777E18CCD62B5D0ED71A994C96499E9650BF128D567B04419147F272323F8613 - AFA8DF4F50101F02604088E30C068438B610999E04C22783EA4DD6A528823E95 - 959959444F958951A53718FA0442C1C34A99787D327F474A5A03525555734E20 - E87F0545D139288AB212B30CE997D56EB71BDC2ED7A352A9706D4B4B8B837E0A - 411110208600181062B886A38201218E2D44A62F81B00971BBFDB7232CD69FA5 - 12491A7D95C65F99CD6EDFCCE3A0F7B4B4B41C887F7672644C5A03A2AAA87C9C - C3663F00170EE2B7105D2E97CD62B5BCCDC1A48F7576361BF18B0C918000FD09 - 9C3020C60D458505700A16CEED0603823350089734044A4AAAE4168BE681EC9C - ACBB592C169634C20916EA703AADA150E839A998FF5CB2EE4D4B3A03525B5B8B - 9ACD369546A77F293B2B6B32C16B2CA9C21BF4FA753C1EF6B05AADEE492AE120 - 1608E040206C404634C68D85850533700807217E46000C082C0720103B81B2B2 - 05F95EBFFB31B14872399B8D71638F04337F4E606464E4A05221BFA7A5A5A929 - 19C9249D0159B060699ADB6D7D4522955C918C0D27427328140A1E3B76EC4BB1 - 4874CFDEBDBB3A89C801318100DD09800121AEC3DD478E6E9954341E4EC1220E - 3144A6398159B3CAA7E8F4BA178A8A8A2A100436A5E3D56EAD46FBBE44C25FD5 - DADAAAC12B2655E2249501096F3C375A6CD7F83CFE678442818C2A4D227B9D83 - 83433F0805C25518166A51ABD57EB2D70BF5010132120003425C57C08010C716 - 22270F8119B3CB16BA1CCEE7727373CE4B1ED5C42A35184C835C3EEFE154C5F1 - 0DE95E62B3912B7A521990CACA25E7FA838117D918360F411038560E87B56834 - 1A87FC3EFF934221E70D301F38008510494BA0B4B43455A7B76C8057B0F05F02 - 478F1CDD5A5434FEF2647DD71A7FA210311909A8542AAED3E9BB1241D127E472 - 595632322042B3D7E3D9CE62B1EFDEBCB921A9EE4C4B1A03525C5C8C0944B2BF - A00872178FC71311B188922DA6DFEFF70D0C0FBF2011A43C059BCE93ADFBA017 - 6F026040F026FABF78604088630B91938B4071710DDFE71F59AD54CA6F859BD2 - F1E9BDD7EB757BBCDE276512C1F3C9F44B92A4312015954B4A0D5AED9B595999 - E7E0B364923B4AF8A673A7DBB50109F91FD8B973E7E1E4A601EA81C0D8098001 - 193BC333450003421C5B889C7C044A54AA8280DBFF845C26BB02411034F908E0 - AB387C7973F88674456ACA3D3B5A9BD50C0623846F0672464B0A03525353A3F4 - FB998FF9FCBE3FB0D96C1E395B41ADAA060606BFE70985B7EDE950B753AB72A8 - 16089093001810E2FA02068438B610393909CC2E2B9BE5B0385FCBCEC90EDF94 - 9E14DF2589EEB4DBE57E4D2060AF6C6C6C74129D8B0CF19362D1A81654FE9FDB - E97E16DE59C467C959AD369DD3E17888C9F4BFD3D5D5E5C3272A440102C94D00 - 0C0871FD0703421C5B889C9C04C297143A1CEE2B9828EB69A542919B9C14F055 - 6D3418FA783CE13D56ABAE3119BE5BD1DE8054545C9CE5F1395E9188C597E0BB - 5492339ADBEDB69B2DE6B7C442DE136AB55A9F9C14403510C09F001810FC99FE - 14110C08716C2172F21238FFFC4A81CB33787F4E76F6BD5C2E979FBC24F0511E - DE576BB5D91AC442EE7D2D2D2DC7F0894ADE28B43620E1131B381CE1B54E97F3 - 319148A4246F1BA85399C56CFE1C4539F7EEDC49FF0F0775BA0295D281001810 - E2BA08068438B61039B9099496568CF307BD4F4B25924B592C163BB9698C5DBD - D56AD5632CECC1EDDB5BDE1C7B347247A0B50159BCF892F38241FF6B08CA9A43 - EE3690BFBAF06583030343FF118B04AB3A3A7624CD2629F277062AA40B013020 - C475120C08716C213210282E2E9BE570585ECA9F903F03688C9D80C3E1D88CB1 - 382BB66EDDF8E3D8A39137026D0D884A552B64302CF7B339D82A70E5635F802E - 97CBEA72BAEEDABDBBEDDDB14783084000089C4A000C08716B020C08716C2132 - 10603018C8D4A933FF0F63636B944A45366C4A1FDB9A70381CE65090F12C82C8 - 5E50ABEBED638B46DED9743520CC8B2EBA781E87CB7DD1EBF59E0B1F86B12DC0 - F0BE0F8D56F3568A420AFB3EC686126603813312081B10BDC1B2B1A0A0603A60 - C2970018107C79423420702A81F0FD206EEFC003599999F7C32F7DC7BE3E9808 - B32BE0F3DFB979F386CEB1472367045A1A90CACA4A0183C17E32180ADCCC66B3 - B9E4444F9DAA0E1FEEDE98969ABEA2BDBDF51075AA864A8100B5089C3020D68D - 050513C080E0DC3A30203803857040E034042EBCB0A440A3D33C77CE94C917B1 - 582C0C20C54E207CD79AD7E77B8685049FD9BA75AB25F648E49D494B035255B5 - A4DC64367FA0542AC791173D352AD3687487C422FE1FB76FDFDA922C97E350A3 - 335025DD08800121AEA3604088630B9181C0CF0830A74E9D5EEAF17A5F1E3F7E - FC5420133B81F0E584C3C3233FA6A5A6DCD5DCBCB1958EDFBF68674054AA1A25 - 87137A2A180A2EC3300C4E64887DFD33CC66B32618083EC164FADFEAECEC748D - 21144C0502406014026040885B22604088630B9181C0CF094C993285CDE189AF - 1709854F0A850219D0899D80CFE7F3204C642D8B157A70E3C68DA6D823917326 - ED0CC8FCF955BFF57ADD2F48A4D2747222A74655C16030A8D7EB3E6463E27B77 - ED6AD152A36AA812085097001810E27A07068438B61019089C4A60C182050AB3 - D5F1944C2ABB065E831FDBFAD06A754745C2E36FA16CA2DB53105A1990F0D30F - 9FCFF6BA442AB9626C2D4FEED9E1477F038383DF48C5E27BDADAB6EFA4DBA24F - EEEE827AB2120003425C67C08010C716220381D311289E5D7EA1C3627E353F3F - 7F16108A9D402010F01B8CC67A9944B072CB962D43B14722DF4CDA1890DADA5A - B6C160BDD2E3713F0D4F3FC6B6D0EC7687C9E3763FCCE3B1DE56ABD5EEB14583 - D94000084442000C482494621B030624366E300B08C44AA0B6B6163D766CE05A - 8C8D3D2693C932628D03F3180C8BC5AC6563D83DDBB76FFD904E3C68634054AA - C5E94186F75D019FBF88C96422746A523CB584DF3934998CF5F0EA553CA9432E - 20C0608001216E158001218E2D4406026722107E15CB60B2AF4E4B4DB9194551 - 16908A9D80D964FA4424E2DDD3DCDC3C1C7B1472CDA4850151A9542C0CE35FEB - F678FE2A1209E5E4424CAD6AFAFB07BAC422E13D8B16CDEFA8ABAB0B52AB7AA8 - 16085097001810E27A07068438B61019089C8DC0D419A5539D16CB2B058505A5 - 402A760246A36990CBE7DECF08783F51ABD5FED8239167262D0CC8E2C58BC7B9 - 3C8137386CF6220441E0E9478CEBCB66B319BC1EEF237BF6B4BF126308980604 - 80408C04C080C4082E8269604022800443800001048A8B8B3106835D8BB2D0F0 - 2DE93904A4489A90169BA591CFC16EA5CB5E10CA1B90F0D30F365B7093D3E55A - 2D168B9449B3127116EAF3F9DC7ABDFE438998FF885AAD1EC0393C8403024060 - 14026040885B22604088630B9181C068046A6A6AF80303DAD51999E9F78E3616 - 7E7E660276BBC38C62C8BD4A99645D7D7DBD97EAAC286F40162C5892EF0B785E - 150A0455546F4622EBEFEBEBFF322D35F58ED6D6CD5F26B20EC80D0492950018 - 10E23A0F068438B6101908444260FAF4D2738D46E32B45130BE7200882463207 - C6FC9240F87A0497CBB549C067DFBB69D3A64354E7436903A252A9B8088B738D - CFE37B4A241629A8DE8C44D56F369BB55E8F777528E47DB3ABABCB97A83A202F - 10486602604088EB3E1810E2D8426420102101E6D4A9332FE10B78AF4BA5D2B4 - 08E7C0B0530858AD569D802F78542CE6BD5E5F5F1FA032204A1B90CACACA493E - 3FF365361B53A1280A8E3A8695183E637A44A77D4FC895FCA5A3835E674CC780 - 03A6008184110003421C7A3020C4B185C840205202C5C50B255EBFF191B4D4B4 - 5BD96C362FD27930EE97041C0E67131BE3DCB565CB86C35466436503C2ACAC5E - 72ABD7ED7D8ACFE74BA8DC8444D51EBE70707868681F5F22B975D78ED6CE44D5 - 0179810010806378895C03604088A40BB18140E40454AACA491AEDC8DABCBCBC - D94C2693CADF4123178DF3C8F081412C94B52A14F27E48E5BBDA28DBFCF0DE8F - 40D0FB2A9FCF87BD1F312EEEF0A3BC5030B41AC3186F517911C7281FA6010152 - 11802720C4B5030C08716C213210888640F882C21F0F755F2DE48B9E91CB65F0 - 2A5634F04E8E0D06830187D3D5CCE2B1566CDFBCF9600C214831859206A4BABA - 9AE3F606FEE0F5F81E9748C429A42049C122B45ADD3A8998B7B2B5B55543C1F2 - A16420402B026040886B271810E2D8426420102D81B2B23299DDE95B939AA2BC - 96C562B1A39D0FE3190CBBDD6EE472B8AB5A5A36BE4D551E943420959535E37D - 3ECF9B5C1E77013CC28B6DE90D8F0C1FE260FC3B76EF566F8D2D02CC02024000 - 4F026040F0A4F9CB58604088630B9181402C0466959515DB4CF6D7F2F2C6CD88 - 653ECC61304C66F3673C8EE88FDBB66D18A4220FCA1990F0BD1F1C8EF03A97DB - FD57A15020A322F444D7EC7038CC3EAFF7F15028EDD5CECE7A57A2EB81FC4000 - 08C01E1022D700181022E9426C20103D81E31714229C9B8402FE93028100F6F1 - 468F9061301887D818FB7E140D7C4CC5DBD1296740162EBC38D7E7F7BCCEE371 - ABE0D6F3E8576C28140A5A6D8E461E87F9C7AD5BB7F6451F0166000120400401 - 78024204D51331C18010C71622038158099497976778BC81BF4924D22B300C83 - 57B1620069B658FECD16F36F536FDA3412C3F4844EA19401096F5ED2E92CD77A - FD9E27A512696A42C95134B946A33DCA617357ECAA9CD7C8A8AB0B525406940D - 046847000C08712D0503421C5B880C046225505757876CD9B27D9EDDE57E352B - 237D52AC7192795E782F080BC5966FDBB6F923AA71A0940159B0E03285DB6B7E - 5B22165F4235D064A837E00FFA8646865FE267A63CBAA7A9C94A869AA0062000 - 044E10000342DC4A0003421C5B880C04C64220FC2A96CB1378343323E31E369B - CD1D4BAC649C1B3E11CB6034D50B78A2FBD4EAA6012A31A09801A9BCD2EDF1BE - 209148E0E8B61856595F5F7F9752A1B851ADDEF24D0CD3610A10000204120003 - 421C5C3020C4B185C84060AC0466CE2C2B32980C6F141614CC8557EBA3A7A9D7 - 1B06510CBDAFB37DFE270C0675DE6CA18C0159B074699AC7687B552014D6A028 - 8245DFA2E49E61B198B5FE25AD9F00002000494441548150F0919CCCF4B5F5F5 - F5DEE4A601EA8100F908800121AE27604088630B9181C05809840F17329B1DBF - 170885CF482462E558E325E37CCD8866BD542AB8ABB5B5D54015FD9431201515 - 8B2EF378BCAF4AA4D274AAC0254B9DE18DE79A11DD7A8180756F5B5B9B8E2C75 - 411D400008FC8F001810E256031810E2D8426420800781AAAA2AB9D9627F4126 - 935F0D4F41A227AAD56A8F7205FC3BDAD5ADCD0C0623147D84F8CFA08401A9AC - AC140483ACA7D91CECF6F823A27E46BD5EDF83B1D03B3A3A766EA2BE1A500004 - E849000C08717D0503421C5B880C04F020707243FA1C9BDDFE4A7676F67978C4 - 4CA6185EAFD78522CC37198CC0EAE6E6662315B453C18030172DAA2ED5E90DFF - C8CCCC984C05A864AAD1E3F1384D46F31B7CBEE2B1F6F68D2632D506B5000120 - F03F02E5E5E5291AAD695341C184E9C0055F026040F0E509D180001104542A15 - 776844F7A7DCDC71F7B3318C43440E3AC71C1E1EFE313525E58EE6E68DDBA9A0 - 93F40664E9D2A522BBD3FB174628741B97CB1550012A996AEC3E7C64B74221BF - B9B373E73E32D505B5000120F04B026040885B11604088630B9181009E04CACA - 1614E90DFA77F2F3F34AF18C9B0CB1C22762395DAE355C36F2544B4B8B83EC9A - 496F402A2A97941AB4DA37B3B232CF213B4CB2D567B158342EA7EB31B198F706 - 156FC9241B4FA80708104920FC0A96D660D9585450004F4070060D060467A010 - 0E081044E0F80DE928BB9685A07F552814D904A5A16DD863C77AF6A628536EDD - B973EBD76417496A03525353C3379B9D2BB93CCE83704B66744B29EC84AD365B - 3D978DACDCB66DDB6074B36134100002F1261036203ABD65436161C18C78E7A6 - 7BBEEE2347B74C2A1A7F454343838DEE5A411F10A03A8199331728FC7EFBB3A9 - 69A9CB60437A74DD74381C669F37F05428A47CA9B3B3DE15DDECF88E26B501A9 - ACAC99146206FFC142D1394C2693D4B5C6B76DA367D3EBF5FD188BBDBCA3637B - C3E8A361041000028926107E056B4463DC080604FF4E8001C19F294404020412 - 609697CFAF70385DAFA5A7A71512988796A1DD1E4F2B9BC5B863F3E6CD07C92C - 90B45FEA6B6B6B518BC5798BDBE3795C2814C8C80C916CB5F9FD7EAF56A37D5F - 28E4AC6A6F6F878DE7646B10D403044E43000C0871CB020C08716C2132102082 - 407575B558A3333E9AA24CBD03EE7E8B8EB0CD66D3632CF67D0A85E883FAFAFA - 4074B3E3379AB406A4AAEAF20C97DBFABA5028581A3F1CF4C8343434F81D1B13 - 2CDFBB77471B3D14810A20407F02604088EB311810E2D8426420401481192525 - A56E87F7CD9C9C6CD8031C05E4F02BF826A3F19F3C9E78A55ADD3410C5D4B80E - 25A501093FFDD01ACC4BDD4EF70B0A853C27AE44289E2C7C16B4CFEF5FE3754B - 9F21FBFB7F14470DE503015C09C02958B8E2FC4530D8844E1C5B880C04882250 - 5C5CC3C730F3728CCD794024823761A2E1ACD1EA7A385CF67D950B549FD5D5D5 - 05A3991BAFB1A43420E11B311184F3943FE0FF0306674147BC1642A150686060 - E06B65BAF2E6ED2D2D5D114F8481400008249C003C0121AE05F0048438B61019 - 081049A0AC6C41FEB066E8CD8945450B88CC43C7D86E8FFB6597C3BAAAB3B393 - 949BD1496940162DAA996734E9DF4A4B4B2DA0E3A2204A93C3E1B0B89CCED581 - 80E2F5AEAE46275179202E100002F8130003823FD39F22C21310E2D842642040 - 3481D2D279B773B89CA7783C9E98E85C748A3F3830F06D5A5AFAED2D2D1B7791 - 5117E90C884AA562F983489D58247A908CC0C85CD3A1EEC33B32D39437EDDCB9 - F33099EB84DA800010F835013020C4AD0A3020C4B185C8408068022AD5457943 - 43FD6BF327E4CF451004253A1F5DE2BB5C6E9B3FE07F46C867BFD0D4D464259B - 2ED21990C58B1717F903CCB7582C5639D96091B91EABD5A6F305BC75B959196F - 90F9D403323384DA804022098001218E3E1810E2D8426420100702CCA9538BAF - 1288C42F4AC462451CF2D12245F8B57CAFCFD7C60C31976FDDBA691FD94491CA - 805457577382417499C3E978422C16A7900D1659EB090683419BC3F60587C5BF - 67DBB64DBD64AD13EA020240E0CC04C08010B73AC08010C7162203817810282D - AD4C0D86DC2FCBE5B2DA78E4A34B0E87D3696561E87DAD2D9BDF249B26521990 - 050B96A679FDF6B74442D1C5640345E67A8C46D388DBE35DF9CD7F76AF27739D - 501B100002604012B106C08024823AE40402F811A8ABAB43366EDE528B32D1BF - C9E5B22CFC22D33F92C968FE54A110ADD8B061C32099D492CA809495555CC664 - 86FE2182476C11AF119FCFE7319ACDFFE473D0FBDADADA86239E080381001020 - 15017802425C3BC08010C7162203817811A8ACAC4C35991D4F2B14F2DFC35E90 - C8A9EB74FAA322A1E06E8542B2894CAFE893C6802C5CB850C264B2572328723B - 8AA2ACC8D126F748AD4ED7CDE772EE4A4B5336936961257757403D10889E0018 - 90E899453A030C48A4A4601C10203781D2D2F94B18CCE05AA9549A4AEE4AC953 - 5DF87E384628F80686218F9069333A690C4855D5C5178C6834EB323333CE6132 - 99A4A98B3C4BE8F4956875DAD7D352E47FDEB871A389ECB5427D4000089C9900 - 1810E256071810E2D8426420104F02252555729FCFF2AC4C2EBF1AEE898B9CFC - B19EDEEFE452E90D1D1DEAAF229F45EC48527CD10F1FBD1B08A0F7611CEC412E - 87232056327DA26B349A632882DDB9776FDB46FAA8022540203909800121AEEF - 604088630B9181403C0984F782B4EEE898EFB05A5F4E4F4F9F14CFDC54CE157E - 5DDF6EB3DF9F9D9DF65A7D7DBD970C5A486140AAABABB35D2EFF9B7C01BF9A0C - 50A85083D7EB756B75DA0FE452D19FD56AB59E0A35438D400008C0139044AC01 - 302089A00E3981003104542A95D06A773F959A927A3B82301162B2D02BEAF1D3 - 52ADB64681807D674B4B4B3F19D491C280CC9B577199C7EB7F094E36887C4984 - F77EA02CD61D7B76556C6530EA8291CF8491400008909140F809C8B0C6B8A1A8 - B0602619EBA3724D6040A8DC3DA81D08FC9A40996AC142B7C3F9466A6A6A3EF0 - 898C80DE60E813F084F7CC9B37FBDF757589FFDE987003A252A9A40C047B0C45 - D01B381C0E2F328CC93D2A1008FACC16CB07985CB4B21DF67E24F76200F5B421 - 70C28018361415168201C1B9AB604070060AE180408209949595C9AC56D793A9 - 69A9D7B2D96C6E82CBA1447A9FCFE7668418AFDAA582873AEBEB5D892E3AE106 - E4E4E6F3F59999195360F37964CB41ABD51EE3F0B8772FAA98B7810C2E36B2AA - 61141000026723000684B8F501068438B6101908248A404949F93C8FD7FB8FF4 - F4F4C244D540B5BCC78EF5ECCECACCBE7EEBD68D3F26BAF6841B90458B16DF12 - 0806FEC6E57261F37904AB211008F8878686DF1109390FEDDAB54B1BC1141802 - 0480000508800121AE49DD478E6E995434FE8A8686061B71592032100002F124 - 505D5D2DD6EB2DCFC8E4B2EB582C1616CFDC54CD65B5D98C8C60E83EA351B96E - FFFEC46E464FA80151D5D4287D46FBAB12A9B896AACD8C77DD0683A117613296 - 7776B66F88776EC8070480007104C08010C7160C08716C2132104820016649C9 - FC4AAFDFFD7A5A6A6A5E02EBA04C6ABFDFEFB358AC9F8945DC155BB66C194A64 - E1093320E1A3D4DADA3AE798CC96B7D3D3D3E0F15904ABE0F8316A76DBA72221 - 6F654B4B0B3CFD8880190C01025421000684B84E8101218E2D440602892450AC - 5229FD56C733E9A969D7A0288A26B216AAE4D6683447E432D9ED5BB634B524B2 - E6841990F0316AC120723F0BC3EE81D7AF225B02E1BD1F6C2EF79EAC74E506B8 - F53C3266300A085085C071033262D85054049BD0F1EE191810BC89423C20401E - 02E5E5AA4B194CE42D9148A4204F55E4AEC4E174AEB65B8D8F777575F9125569 - C20C486565CDA42023F0261BC3CA13259E6A79355ADD7A0E265CB16B173CFDA0 - 5AEFA05E20301A819306A4B1A8A870D66863E1E7D1110003121D2F180D04A844 - A0B2B232D5E50EBC2912092FA152DD89ACD5E9766F4139E8F2D64D9B0E25AA8E - 841990850BAB9779BC9EE7C0B146D67A87C361B2D8ACF77CD3B5F7BDC866C028 - 200004A844000C0871DD0203421C5B880C04124D40A552B11C0EEFEF596CEC29 - 99549A9EE87AA890DF68340E611CEEFDE929D24F1375337A420CC892254B647A - BDED79A94C7C358AA22C2A342B91358642A190D3E9DCC86123B793E506CB44F2 - 80DC40808E04C08010D7553020C4B185C840800C04CACBAB320201F7AB5299F4 - 5232D443F61AC27B8AF506E3C7A94AC98AE6E6666322EA4D8401612E5C583DCB - 6034AE4D4F4F9B04777F8CDE76BBDD610AF8FDAB308CF1AE5AADF68F3E034600 - 0120403502604088EB181810E2D84264204016023367CEB9952F103CCDE7F344 - 64A989CC75F40F0CEC97CAE537B76DDFD291883AE36E40C28FCA381CE11D5E9F - F7311E0F1649244D3FD27D64475656EA0DDBB66D3B12C9781803048000F50880 - 0121AE67604088630B91810059089494A826194DFAB7C78F1F3F1B4110842C75 - 91B50EAFD7EBF607FD77A7C8A56F25E260A3B81B90050B2E5338DDC6376552E9 - E5646D0A99EA72381C1687D3F584908FFD1D9E7E90A933500B10C097C0B4F2F2 - 14EBB0BE61E2C4A2D9F84686686040600D0081A420C09C3D7BDE721E9FF3388F - C7132785E231880C06830193D1B45E2249B9AFA5E5F3B85FED10770332776E45 - A9D5667F273333A3680CDC92626A78EF47CFB19E2F150AC5CDEDEDDBBF4D0AD1 - 201208242981E26295D26CD1348201C17F018001C19F294404026424A052554E - D219F41F8ECBCD9946C6FAC856D3C8C8C881D49494DB366FDEB083C16084E259 - 5F5C0D484949098FC160DDCDE6721F10F0F9E04E47E9742010F40D0E0D3E337E - 5CD6138D8D8DCE782E0CC8050480407C098001218E371810E2D8426420402602 - C5C5C598D3E57B62DCB871F7C26B58A377C6E572D9BC3EDF1A0C0D3D1DEFB76C - E26A40162D5A9AE9F3BBD672B9DC850882C08D95A3AC0D9D4E7F94C3E7DDD0AE - DEAA1E7D19C108200004A84C000C0871DD0303421C5B880C04C846A0B8785699 - 3F187C3B2B3313DEB489A03946A3E13344C4BF6D574B7CEF988BAB01A9AA5AB2 - D062B1BC2D572872236092D443FC7EBF4F6F30BE23970A566DDDBAD592D43040 - 3C104802026040886B72F791235B32D3275FAE56D7DB89CB0291810010200381 - 3973E6889CEEC0D3A929CA1BE1AA87D13B32383474482816DFD8B1A3B56DF4D1 - F88D88AB0199AB5A58C7E7F11E86C762A3375033A2ED61B198B7ECD9B3AB65F4 - D13002080001AA130003425C07C18010C7162203013212983F7FE11297DBFB86 - 5C2ECB22637D64AAC9E572D93D6EF7E30A85E4A578BEEE1F3703A2522D4EF707 - 5C6F89C5E22564024FD65AB45ACD3A1E175BD1D6D6A6236B8D5017100002F811 - 0003821FCB5323855FC1CA4C9F044F4088430C918100A9089457556504EC9E97 - 4422E125F014E4ECAD0904820197CBB949C067DFDED4D43410AF46C6CD80CC9D - 5B31D7E170BD97969E9A172F7154CDE37038CD1EB7FBBEDDBBDBDEA2AA06A81B - 080081E8088001898E5734A3E1094834B4602C10A03E81F06674BF9F798D4028 - 5C23954A52A8AF8858057ABDFE984C2ABDB9B979E3566233FD2F7A5C0C487171 - 0D9FC3B1AC6273D82BF87C01DC50394A77070606FFA3902B966DDFDEFC43BC16 - 02E401024020B104C08010C71F0C08716C213210202B81D2D28A0923DAE1B593 - 2616CD256B8D64A92BBCEFD8EDF1FC65A77AEB9A78D5141703525171715628E4 - 7D97C7E72D8C9730AAE6F1783C4EA3C9F45A7AAA7C7553539395AA3AA06E2000 - 04A22370D280842F222C896E268C1E8D001890D108C1CF81003D094C289CBC7A - 427EFE9F582C168B9E0AF15365329A3F63B1B8CBDBDA9A87F18B7AE648713120 - 175D74F102B3D9BC164EBF1ABDA5C3C3C387397CFECDBBDBD570F4EEE8B86004 - 10A00D81B001315A461A264F9C080604E7AE8201C1192884030214213073CEBC - F2A0D7FB5E6A6AEA788A949CB032C3DF3FF962F1F51DEAADEDF128827003525B - 5BCBD66A8DF773B8DC87582C163B1EA2A89C636464783D9FC7BEB3BDBDDD4465 - 1D503B100002D1110003121DAF684683018986168C0502F421B064C91299C160 - FDBB4422BD1A6521187D94E1AFC4EE7058DC4EF753281A78B1B3B3D3857F865F - 4624DC802C5AB428D3ED09BE2910F0ABE1F8DDB3B7D366B3E9DD2EF79FF3F2B2 - D6D6D7D707886E3EC4070240803C04C08010D70B3020C4B185C84080EC042E9C - 31FBB73C0EF765890436A38FD62BABCDD6C8C18437B5B63668461B3BD69F136D - 4098E5F3175538EDF6B7D252E1F4ABB3352B140A057BFBFADA5395A9B7A8D52D - 07C6DA58980F048000B508800121AE5F604088630B918100D9091417CFC9D51B - B56BCF99326501D96B4D747D5A9DEEA85CAAB8A9A5A5711BD1B5106A40C2C7A0 - B1B9C287785CEE4A2E97CB275A0C95E3FBFD7EAFDBE37944C0C3FEDED4D4E4A1 - B216A81D080081E8098001899E59A433C080444A0AC60101FA1150A9542CA733 - B0422215ADC6308C433F85F829F2F97C1EA7C3F1A7CCCCD417897E1387500352 - 5353A3B4581C6B8522510D7E78E819696464E4281BC36ED8BDBB1D369FD3B3C5 - A00A089C95001810E216085C44481C5B880C04A840A0BCBC62A6C3E978373D3D - 7D3215EA4D548DC16030A0D3EB3FE160A27B76ED6AD1125907A106A4B27249A9 - C16078372D3DAD904811548F1D0804FC7A9DAE9ECD46967776761AA9AE07EA07 - 0240207A026040A26716E98CB001C9CBCDB8ACA5A5C511E91C18070480007D08 - A854974A5D2EFDDF6472D91F100441E9A30C7F257D7DFD3FF279BC5BF6EEED08 - 9F8615C23FC38988841910954AC50D0691BB9828EBCF023E4F4C94003AC40D6F - 3EB7DB1CF72388FF83AEAE2E1F1D348106200004A2230006243A5ED18C060312 - 0D2D180B04E84960C6ECD26B4542F12B5C0E07B6049CA5C50EBBC3EA74BA570B - 04AC17D46AB59FA8D5409801A9AEAE4EB13B7D6F09F8BC25E036CFDEBE9EBEBE - 4EA54CF9879D3BB71C26AAD1101708000172130003425C7FC08010C716220301 - AA10B8F0C292029BC3F67161C18462AAD49CA83AF506E37B0A99F01622F72413 - 6640AAAA2EBE40AFD7D7C3EB57A32F9FE111ED9AAFBB3AFF34FA481801048000 - 5D09840D88C93CF2C5A449134BE9AA3151BAC080248A3CE40502E42170FEF995 - 02A773E0D1DC7139B7C1C148A3FC62BCB777EFB89C8CEB9A9A9AF613D541C20C - C8FCF995D70782C1BF0985022951C5D321AED96C1E6673B9D7AB5B9B37D3410F - 68000240203602604062E316C92C3020915082314080FE04A64E9DAD4250C63B - E9E96979F4571BBB42ABD5AAC338ECE5DBB7367F1A7B94B3CF24C4809494D4F2 - 4422E7B32C8C753B5185D3216EF8B48183870F6F1B979D7EBD5AAD1EA08326D0 - 000480406C04C080C4C62D9259604022A104638000FD09949757A7F4F577BF7E - CE39532EA7BFDAD8157ABD5E1783C97C9D83311FDBB871A329F648679E498801 - 59B4E8E2C2C1A1810FF2F2C6CD22A268BAC474B95C56B3C5FA707AAAEC0D22DF - B3A30B2FD00104E84C000C0871DD0503421C5B880C04A846A0BCBCE24E8150F0 - 77D89F7CF6CEF5F4F6ECCECECCBDAEA5A59190CBB1713720B5B5B5A84E67ACF1 - 787DAFC864B24CAA2DCC78D63B32A2F99185A2CBF6EEEDF82A9E792117100002 - E423000684B89E8001218E2D440602542330678E6ABADBED5A9F969E5E44B5DA - E359AFC9681A66A0CCBB3ADB77D4139117770352595929F0FB918718CCD0722E - 972B24A268BAC4B4982DEB308C71935AAD76D34513E8000240203602604062E3 - 16C9AC1317112A96C2DFB591D082314080DE044AAAAAE43E83E505855279158A - A27027C859DA6DB7D91E4590E0E3441CC78BBB01A9AEAE4DF178ADEB391CCE42 - 2693897B7CBA7C2C1C0E8729E0F73F9C9191F23AD1D7DDD38519E80002742670 - FC185ED3F0BF274F9E3487CE3A13A12D6C400E1DD8579988DC9013080001D211 - 604E9B36F31AA148FCBC48249091AE3A121564329BEAF95CE99DADAD0D1ABCCB - C2DD202C5C785199C96C79272D2DB500EF62E914AFB7BFEF9B14B9F23AB57ACB - 3774D2055A800010888DC0CC9933153ABDE50B3020B1F13BDB2C3020F8338588 - 4080CA04E6CC9F3FD1AC33AF1B372E773A9575105D7BFFC0C0B74AB9E286EDDB - 5BBAF0CE458001A9BE9EC164BCC266B3B978174B97788140C03F343CF2369F9B - B26ACF9E262B5D74810E20000462270006247676A3CD0403321A21F83910482E - 02B5B5B5EC9EBEC197940AE58D4C2613492EF591ABB598CD235C2E67A5D96CF8 - B4ABABCB17F9CCD147E26A40AAABABC5C120FA2483C9B8054551D6E8E9937384 - D7EB75EB75FADBBEF9E6CB77939300A8060240E054026040885B13478E1C6D39 - 78605F15711920321000025422505757876CDEDCBA8C8561CF88C52225956A8F - 67AD1E8FC7C964206FF0F9AC471A1A1A6C78E6C6D5805C74D1A579BD7DC73E0A - 1FBF0BFB3FCEDCA69E9EDE6F4542D1B23D7BDABEC3B399100B080001EA120003 - 425CEF8E1C39D27CF0C0F717119701220301204035022A55E5249D5EF75E6E6E - CE0CF8CE7AE6EE1D3B7AAC3D2767DCB29696C66378F6184F03C22C532DA8F2BA - DC6F2995CA2C3C8BA4532C9FCFE7D1E875EFF330E54A78FD8A4E9D052D40606C - 04C0808C8DDFD9668301218E2D4406025425103EB57568D8F0545656C66DF0D6 - CE99BB683018FA8502F1CDADAD9B36E3D96BDC0C487171312610481E647338F7 - C3FE8F33B7C862B16ABD3ECFBD79B9591FC1E957782E65880504A84D000C0871 - FD0303421C5B880C04A84CE0BCF32EFC9D54267D492412C16958676864F817E7 - 0EBBFD418FC7F1229EFB407033203535357C93C5B64E2C925C46E5C54874EDBD - 7DBD7B5214A9D7AAD52D84DC2C4974FD101F0800016208800121866B386AF7D1 - EEA6433FFEB098B80C10190800012A12983D7BEE64B3C5BC2E3F7FFC8554AC3F - 1E35070281804EABFB402CE6DDA756ABF578E5C4CD805456D64C1AD10C7F989D - 9D350DAFE2E818676878E495C209B92BEAEBEBBD74D4079A800010888D40D880 - E80DD68649932696C61601669D8940777777D3A18360406085000120F04B022A - 954A68343BFE9A969A720386611CE0F36B02A1502874F4E8B1AF940AE5751D1D - DB7FC08B116E06645EC5A2CB023EFF1B62B13805AFE2E816C766B3195D4ED73D - 5F7DD5F93EDDB4811E200004C646E0F81310A3B571F2C48925638B04B34F25D0 - DD7D64D3A183DF2F013240000800819F13A8ADAD457BFA87AE60A3AC17245269 - 3AD0393D01BDC13088A1C88A8E4515FF64D4D505F1E0848B012929A9E57138A6 - 075116EB1E0E87C3C7A3303AC63879FAD5D57BF6B4EDA7A33ED004048040EC04 - C237A19B2D9AC689138B66C71E05669E8E40F791231B0F1DF8FE62A003048000 - 103895404545F584E191A177C78FCF2B033AA727E076BBED7E5FE06F08E27F5C - AD56FBF1E0848B01A9ACAC4C757902EF09F8FC450882A0781446B718E14D3C7A - BD613D9723BDAFB3B3D948377DA007080081B111081B108B55BBA1A8A870D6D8 - 22C1EC53091C3EDCBDE1F0A11F6A800C10000240E05402D5D5D59C9111E3D319 - 99E97F043A67266032993F924AF8B73635E17381362E06A47CC1822976B3AD21 - 233D630234EFF4041C0E87C9E5F6DEB377F7CEF7801110000240E05402E5E5E5 - 29231AE3C6C2C2821940075F0287BBBB1B0F1FFC6129BE51211A100002742130 - 6DFAAC6BC442D14B02814042174D78EBE8EF1FE8CA48CFFC7D4B4B232E8728E1 - 6240E6CE5D706588C178552412CAF1164C97784343C3DF2915CADF6FDDBA691F - 5D34810E200004F0230006043F96BF7A0272A8BBE1F0E11F2E212E0344060240 - 80CA0466CD2A9FE2703A3EC9CDCD3997CA3A88ACDD6AB56A992CF4E6B6ED5BBF - C0230F2E06A4A2E2A2C7B83CCE43781444D71816B3F9430C63DEA056ABDD74D5 - 08BA800010889D40D8800C6B0C1B8A0A0B67C61E05669E8EC0613020B0308000 - 10380B01954A25B53B7D2F2815F2DFC15682D383F2783C0E9FD7FB2C82049F55 - ABD5F6B12EA8311B90850B6B256EAF61AD5824BA7CACC5D075BECBE5B20582A1 - 271086EF6F786DDEA12B2BD005049295C07103326268843D20F8AF0078050B7F - A6101108D08C0073E6CC39B7F005FC357C3E1F5EC33A4D73C3C7F15A2DD606A1 - 90735B7373F3F058FB3F660372D1454B270E0F0F7E92959D7DC1588BA1EB7CCD - 88B607C3D09B76EF6E6F65301821BAEA045D400008C44E60D6AC056946B36663 - 61C184E2D8A3C0CCD33E01E9EE6E9C7AFE94DFC0FD4BB03E800010381381B973 - 2B4ADD1ECF3AA552391E289D9EC0C0C0C00F4A8572D9B66DCDFF192BA3311910 - 954AC56232394B3C5EF76B52A93463ACC5D0717ED831EEDFFFE3CED414E9355F - 7EF9653F1D358226620984CF29D7E9744C9BCD76F2F37AE2FB697EBEE9AC9F5F - BBDD3EA6CF371EAA5CAE342683D1733C94C79312793DD978648F2EC69952BADD - EEC8EB8E2EE5492E1EA6C1C009C9648109239A918F737373A6C41006A69C85C0 - D123C7B6E5E74FB84D2060FDF7EFE00182899DBA9E6259475C2EF7BFBFB0FA6F - BD03030CA552797C4D0E0D31180A8527AAF5E9F57AA31A4F30A6D38667B3D967 - FD455DF8F37262E2D0F1FF0C8FE77038216D4A4A3055A70BAAD5EA00FCB22F11 - 9DA376CEC58B17A71FED195C9F3F3EAF82DA4A88ABDE62B51A82FEE09D9D9D3B - 3E1A6B9631FD4514BEFF03C50CAB3016EB5E1E8F271A6B31749C1F0804FC870E - 1EFEFBB871197F86D7AFE8D86162349D341D321F8351E0B17B2E60B1B1742E97 - C36386108CCD4651261345180C26C244190833C4643251268230907031C7FF83 - C9649EF86C230CE6F17FC06032424C0693190A314F0C09FFBF13B53319C8FFFE - 1E6086FFFFC9B9CCF0E3BA13FF3B9CE3643CC6891827FE8498CCFF7E51608642 - C7FFF74F371485C7E98D06AEDFEF4799A1E3694ECCFB295808619EA8F667F14F - 167F3AAABFFECBEA7F75FC7AFCC9C027049E503FCA9FFF323BCDB89F389C0476 - 22E4CFFEFC34F7B8CE53FE8498279E7A867F19F1D38FC2E38F8F0DFF378AB0FC - 5E9F27180A065828AB9CC7E30A46AB157E1E1D81F02984288BF56530E8F78602 - E1363019C193EBF8747D3FF5DBEF7F9BFAD3E7EAE7BD3FCDDA0A7F247FB6027F - 516CE8971FB1D3AECBF0472FFC39FAE93315623043E17F12FEEF80DFC7181E1E - E1843FFDA1601061843FBF274530FFFB890AAFADE39FED139FF5937F7EA6F574 - FFECF41FBB137F279CFAB3513F4F67EB5088110A9DF22EC049E4273F24FF6BC0 - FF069E98149E171E140C85E10442C1102318080683FEA03FE84D4D4BD17179BC - 5E16C23AC466633F8642DE213E9F6F6B6C6C7446B76260743212282EBE196320 - DF3D9B969A06C7F19E6501D8ECF6D56D3B5A1F19EB1A0D4E7164000020004944 - 415419D35F2265654B64FE80ED6DB95C76D9580BA1EB7C97CB6DD3EBF4B7EEDB - D7F5215D3582AEB113282E2EC658AC541E87139020487082CBE59A3EACD194CB - E5B28962912495C7E38A5014658D3D13440002400008D09B80C3E1B0586D369D - DDE618E2F3B8FB2512C96E2693B19FCB651D118BC57678158FDEFD8F555D5D5D - 1DB27163CB320E97F38C582C56C61A87EEF3CC16F3C70A99F8CEC6C646FD58B4 - 8EC980CC993367A2D1ECF8747CDEB8F3C752049DE70E0F8FEC934AA4D76CDFDE - FC2D9D7582B6D809A854AA02ABD555C160324A3C1ECF54B95C3E8ECBE50AC286 - 03419033FD2235F684301308000120900404C24F1D83C160301008F84C66CB08 - C6627D1D0C84DAD86CD6B640C07DA8B3B3D395041840621404A64F2F3DD7E170 - AE1F9F0FDF6BCF84ADB7AF774F565ECEB52D8D63BB0F644C066476994A15F07A - 3F48494949C01BDB51ACA8040D0DBF7E65B3D93F6163D2E56AF5BFCD092A03D2 - 928CC09429B56C99CC94CE6004A6DB9D8ECA80DF5F229349B3F97CBE189E7290 - AC59500E100002B422E0B03BAD468B7180C544DB7842FE561693BD479F26D1EC - AFAFF7D24A2888898940595999CC6A773F9F919EFE3B1445D19882D07C925EAF - 3FA690CBAF6B6A6ADC3116A9633220151555D72128F22A9BCDE68EA508BACE75 - 381C668FDBF3979C9CF437E0912F5DBB1CB9AE93FB3A72EC76CF121E8FBB38C4 - 60CC84C7BC91F3839140000800013C09D8AC36038311DAE3F4781B796C6E4B46 - 86BCB7BEBE3EBC811DFE24318119B34AEE924A647FC5308C93C418CE28DD66B3 - E9795CCEFD128970DD58BEDBC66C406A6B6B794693ED51168ADD8DB2100C9AF4 - 6B029A114D0F83855ED3B5A7A31DF824378192928A2CBFDF7D099BCB59823091 - D97C3E4F02BF5D49EE3501EA810010483C81402018703A9D160441BA1C76FB17 - 4221E70BB55A4DF4216989170E159C91C0BC790B1679FDFE776552692660FA35 - 018FC7E30C8598AF0503AEBAB15C4818B301A9BCECB2548FC9F6368FC75B0CEF - A99F7E897EB7EFFB6D0A59EAB26FBFED1C84459C9404982A954AE0F406E68502 - C16BD8186BBE44224D4D4A12201A08000120407202168B45E7F5FB5B1114F980 - C508B4757474846F7B86BBBB48DE37BCCBBBE8A24BF37AFB7BD68FCF1B578A77 - 6CBAC4B35AAC1B793CD6CD5BB66C397116760C7F623620555535E768759A4F33 - 3232E0CCFA33803F74F0D0F3DDDD3FAE80BFC062589934985252A22A083183BF - F3F9FCD72A958A1C1441E07D521AF41524000120405F02E13DEB3ABDBE9FC3E1 - AC638698EB3A3AB61FA4AF5A50763A022A55ADD0E11C7C5A2A955E0FAF619D7E - 8D0C0E0C1D502A15D7B7B66EEE8C7515C56440C24795B5B7EFFD8DCBE57C4122 - 95A4C79A9CCEF3C28FA834239A3F7EFFFDD76FD3592768FB3581F05E8F818191 - 850C84790BC662CF170A0552E004048000100002D421E0703AAD01BFBF2DE00F - BDEE558AB675C15D22D469DE182BADADAD650F0C68AE4159AC3562B1088EE33D - 0D4F9BCD66F2B8BDCBF7EE6D8FF98A89980C48F8CE029148F1670465DE173E2E - 748CBDA6E5749D4E7F2CC8642C83FD1FB46CEF1945A9542AA9CDE6FE8DCFEFBB - 3B3B3BFB9CE4520F6A8100100002F422303034F8231BC59EC730F13F3B3B9B8D - F452076ACE4460D69C39B33D4EEF7B9999994540E9D704FC7EBFD7EE703CA690 - 899E8BF5A2CF980C884AA5E2BA5C81B50AA5FC2A68CCE909F4F4F6EE4C5566FC - 4EAD6E82CD6C49B248542A55BAD71BBC9189A27789844239EC8D4A92C6834C20 - 0004684B207C8F88CD66333042CC97391CE6DBDBB66D833D9DB4EDF6FF84CD98 - 31237D7048FB8FA953A75E9C0472A396187E55D16832AF4B4B91AE8CF542C298 - 0CC82C952A5B3FA8FD7062516179D45527C104AFD7EB3619CD6F6465A53CDCD0 - D0604B02C9492FB1B4B46282CB6DBF4F2412FF562814C8921E08000002400008 - D08880DDEE30D96CD64F4542F12B6969B2FD705C2F8D9A7B0629F9F913FF3A69 - F2A455F4571A9BC2633DBDBB268C9F70ED860DFF3A1C4B84980CC8B46933A7FB - FCFEF773737326C79294EE736C36BBD1EBF1DEB1674FDBC774D70AFA188C1295 - AAC0E7F4FC452A91D6C29D38B0228000100002F424E0F5FA3C16ABF5730E86AD - 696FDFFE1D1C3043CF3EFFA4EA9CF3A72D53C8E42F088542D8C7799A566BB4DA - C3A94AE5AD4D4D8DDB63F92CC46440669694D5B210F415A9549A42EFE5179BBA - E191E1431C8C73D5EEDD6DFF892D02CCA20A01954A55E0747AFF2214892E87FD - 5054E91AD40904800010888D40F8801987D3D188A1EC27D3D3E53FC09390D838 - 5261D6F492F29941AF6F7D7A7A5A0115EA8D778D56AB5527100A1E140B796B63 - F91C446D406A6A6AF80683ED3E0E97BD92C7E309E32D980AF9BEDFF7434B4686 - 62D99E3D7B3454A8176A8C8DC06C952ACFE770D74925D2DF72381C5E6C516016 - 100002400008508940F8356B8BC5FA198B8F3DD2A9567753A976A8357202E555 - 55199A9E810F264C9850C16432A3FEBE1C79266A8E3C712161E8258B59FF7057 - 57972F5A1551035DB0E03285D3657C5D28142CC5308C1D6DC264187FF458CF4B - 08C3B772FFFEFDDE64D09B8C1A552A95D264713DAC54C86EE47038FC6464009A - 8100100002C94AC0E3F1B88C26E35B72A9E889D6D656F865230D17426565A540 - AB373FA2902B9673386CF825E3697AACD7EB3EE2F3D8B7ABD56A73B44B206A03 - B270E1C5B9239AA1CF7373732E8C3659328CB7DA6C46BBC3F170617EEE1BB13C - 924A064654D75852552567D83D37B31064A5482C52505D0FD40F048000100002 - D113B0D96CFA6020F01C97CB7AB3B5B5D5107D0498417602D367965DC5E3B25F - 1289E0DFF5A7EBD58F3F1E68532A52AEFDF2CBF6A3D1F6320603523DDB62B5AC - 4F4949C98F3659328C1F19D174231876ED57BBDB3A92416F326A9C397BCE8D3C - 2EEF598140204946FDA0190800012000044E10D0EBF5FDBE40F0512EC6F8B0B3 - B3D3055CE84560E6CC39D3DD6ECFFBD9395970E8D2695ADBDFDFFF235720BCF1 - CBCE9DBBA2ED7CD406A4A2E2A25AAFCFF3B2582C4E8D3619DDC78742A1D0E1EE - 6E7566BAF20F3B77EEECA7BBDE24D4C72C2B532D305B6DCFE464675D00EF8426 - E10A00C940000800819F11088542C1DEBEFE6FC412F143BB17CD6F66D4D50501 - 107D08845FB7EEE91B5E3F65F2A44AFAA8C24F89D96CD1FB7DFEBBF87CD6A76A - B5DA1F4DE4A80DC8DCB915F70B45A235D1244996B18140C0AFD5E95ECDCE4CFD - 53AC3743260B2B2AEA54A95479FE00F277B158742915EB879A81001000024080 - 180216B3F50B1465DDB773E79698EE4420A62A883A560253A64C61FB83E8DF26 - E48FBF037EE9F86B9A2E97CBEE76799E4310FFB31D1D1D51DD7B17950109DF80 - EE70785F48494DB979AC4DA5E37C9FCFE771BBDCF7B4B56D7B8D8EFA9259934A - A5127ABDC1BB300E679580CF1727330BD00E048000100002BF2460B3394CC150 - E0796688FF527BFB4613F0A10781DADA5AF4F0E19E5B4462D1E32291082E193E - A5AD3E9FCF6BB65A3F130BE477B7B636447518435406A4BABA3AC56AF7FE4322 - 165E428FA585AF0AA7D369663218BFDBBE7DCB267C2343B44413983B77FE62B7 - C7FBAA52A91C97E85A203F100002400008908FC0C8C8C861A180BF72E7CEED0D - E4AB0E2A8A910073E6CCD2F98140E8EDB4F4D4BC1863D07A9AC7E351632CEE75 - 9B37FFBB271AA1511990B98B1615EA06B51F8C1F9F372B9A24C932766464E4A0 - 582EFE3FF5962DDF248BE664D0B960C18234A7D3F7A24C2EFB6D32E8058D4000 - 08000120103D81F07E10A3C9F4898027B96FDBB60D83D147801964245052A22A - B058CD1FE6E58D9B41C6FA125DD3D0D0F0FECC8C8CEB376DFA624F34B5446540 - E6CC51CD76B99DEBD2D3332644932459C61E3C746847DAF89CDFEE6A69D1268B - 66BAEB2C2E2EC6984CF6756C0EFB31A9540A072FD0BDE1A00F08000120300602 - 26B369C4EFF5FF4520607FA056ABDD630805534942A0AC6C896C60F0F0EB9326 - 4DBC02411094246591A60CA3D134A8904B6FDFB8B121AA277F111B90F017312E - 57747920187C5E2E97A5934639490A09FFE6637070F04DB94C749F5AADB693A4 - 2C28638C0454AAEA6C040DBECFE572E78F31144C07024000080081242060B739 - 9A318CFDC7D6D64D8792406E52489C7AE1CCC7D352D356A128822585E028443A - 9D4E0B8FCBFB5353534354FB9F2336203535357C83C1B20263B357C2FD07BFEE - 8CD56A333AECB6873C9EBCB7F7EFAF871BD0A358BC641E5A5A3AEF360E97B386 - C7E3C1C67332370A6A0302400008908480C3E1347B3D9E07A452C1BB4D4D4D1E - 929405658C814059D9FC655C1EF70D369BCD1D4318DA4E757B3C6B827EF7A3D1 - 3CF58BD8802C5CB85062B43A5E524865576218C6A62DC5188569B4DA3E463078 - 6D57D79EED31868069242350595999E372FB5F1608041723088290AC3C280708 - 0001200004484820180C066D36DB17188BBB42ADDE1CD5C65C12CA8192180CC6 - BC790BCA5D6EF7FB4AA51236A29F6645180DC6750281F2EED6D6CF0D912E9888 - 0D48F8042C9727B09ECFE32D8A3478328DEBE9EDDBC7E7F26BBFFAAAE36032E9 - A6ADD6BA3AA4B4557D79C81F7851269767D056270803024000080001DC09E874 - FA3E8C83DDBBAB4DF51983019713E20E38CE01E7CEADCCD119B49F8DCF1B373D - CEA92991CEE1746EE288F9B7B67CF145C49770476C40AAAA6ACE191E1E5A979D - 933D951234E25CE4BE7DFB1A535372AFEFEA52EBE39C1AD21140605675B5D8AB - 353D97919E760301E12124100002400008D09840F87E048D56F3168F93FAA73D - 7B9AAC34969A14D24E6C44EF7E6FCA9449354921384A91FDFD035F6766645CD7 - DCBCE1DB48A7466C40E6CF5F34C76AB3BF9F96969A1F69F0641AD7DBD3F7DC0F - 3F7C7D6F3269A6B3D6D252D554ABCDFA7E6E6ECE7974D609DA80001000024080 - 1802C78EF57C2D95486EE8ECDCF9353119206ABC08949494F0F446EB2339D9D9 - 7772B95C7EBCF252258F46A33D2614F06FD8B1A335E26D085118908557B8BDBE - 976552299C8075CA8AF0783C0EBBCDBE62CF9EF637A9B258A0CE3313A8AEAEE6 - 180CF6DB797CCE2370E002AC14200004800010888580DD6E373BEC8E3FA7A6CA - D6C266F4580892678E4AA562E9F5D6FF134B44CF49A5D214F254468E4A4C46D3 - 308AA12B5D0E6B7D5757972F92AA223220757575C8D6AD3B96F3F8BCA7310CE3 - 44123899C6984CA60136865DBF6347EB9664D24D57AD959595A90EA7E735A150 - B4144551165D75822E200004800010208E80DFEFF759AC968F857CF97DADAD0D - 1AE23241E4781038FFFCE259088AACCFCCCC84BBF04E016EB33B4C1E97670D8A - FA5FEAECEC7445D28F880C486565A5201864FE094159AB582C169C817C0AD9A1 - E1E1EFA54A69ADBAA5E54024D0610CB9095454545D68B6983F4C4F4F9F48EE4A - A13A200004800010203381A1C1C1EFE472C54DDBB635EF25739D50DBE804A64D - 2B1D67B59BD64D2C2A2A1B7D74728D70BBDDCE4030F8BADFCBABEBE868B045A2 - 3E22035255552BB75A479E174B2457A3280AB7409E42B6FBC891EDE372327EBF - 65CB96A148A0C318721398376FD155280BF90797CB1590BB52A80E0800012000 - 04C84CC0E572DB42CCD09DEAD696F7C85C27D4363A81A95355528DEED83FA64D - 9DFA9BD14727DF08A3D9F42F0157714BA447F1466840AA328EF50CADCBCFCF53 - C17D08BF5C543E9FCFA3D7EBDF4D4F53AC6A6A82932E68F091634E3967DAB379 - 79B92B68A00524000120000480408209F4F6F53EFFC3BE6FC2FF4E0925B81448 - 3F4602E79E7FE133B939392BC7188696D38F1D3BB6373323FB9AD6D64D872211 - 18910151A9AA0A0C26FD3F73B2B32F882468328D71389D5697C3F1D0B87159AF - D6D7D70792493B1DB59E53522237F40EBD77E1B4A917D3511F68020240000800 - 81F812F8FA9B6F3765A62B6EECEAEA1A8E6F66C8863781D2D279B7F305FC67D9 - 6C360FEFD8548F3738347440919AF6876DCD1B227ADD302203525E5131D36975 - 7E989696061B6F4E592166B34567B7D96FFCEEBBAF1AA8BE78A07E0663EAD459 - 856EB7BB3E7F421E986D5810400008000120306602478F1CFD5A2010FEA1ABAB - 73DF988341808412983D7BEEE5189BF5BA48248293B04EE984CEA0EF9308A537 - 6FDDBAB1399226456040EA903973B65D1A0C325E96C9657023F42954B55A5D5F - C0EFBFE2EBAFF77E15097018436E0217CE9C53CE0C04DE4B4B4F1B4FEE4AA13A - 200004800010A00281F0F7041461DCB467CFAE162AD40B359E99804AB570B6C3 - E55A9FA254C29D78A760B2582C1A0E9B7BCFB66D9B3F8A640D8D6A406A6B6BD1 - A347FB960B84C23AA150288D2468328D397CB87B2F8F2BF8BFEFBEDB7B2C9974 - D3516BF89C6FABD57D258FCFFDBB442281DF6ED0B1C9A0090800012010670256 - AB55EF76B9EF0F85BC1F447A47429C4B84741112A8ACAC1C3F3C62F8574E4EF6 - B408A724CDB0F09E6897C7B58AC50CBDAA56ABFDA3091FD580141717636CAEF0 - 513E8F773787C38177DE4E21FADD77FB9A72B2D3AE88F4DCE3D11A023F4F1C81 - F005842693ED0E0E8FF78880CF1727AE12C80C0480001000027421E074BA6C6E - AF670D17633EA756ABDD74D1958C3A54AA1AE5D0D0B10F2714E42F643299A37E - 874E2646E17B6FFCBEC093C1A0E859B5BADE3E9AF651E185BF948D684D6F64A4 - A7FD61B460C9F8F3FE818177033ED72DFBF7EFF726A37E3A69AEA9A9E1F7F68F - 3C919AA2BC95CD6673E9A40DB40001200004804062080482C1804EAB7D432CE2 - DDAF56AB47FD6296982A216B2404542A95D062753DAB542AAE858BB97F492C10 - 08F8CD26F33B5269C603CDCDF5C6D1788E6A404A4A4A78FDFD9A4FCFBFE03C38 - 15E8149AC16030303038F81C07633E088F55475B6AE4FFF9D2A54B451A9DE915 - 855C7E0DF9AB850A810010000240802A04CC66CB277C5ECA2D5BB7D65BA85233 - D4F96B02B5B5B5EC7DFB0F3D90999EBE0AEE0AFB259F6030183C74F8C8C60953 - 0A6EDDD2D030EABD78A31A907367CD4AB30CE93F3EEFFC7355B0187F49C0E974 - 9A5D6ECF43B9D969AFC311BCD45F1D0B17D64A7A7A7FF8A0A8A8B086FA6A4001 - 1000024000089085C091EEA3AD53A6145CF9F9E79F1BC85213D4111B8169D366 - 5E25100A5F168B45F2D822D0735628140AF51CEBEDCCCBCB5CD6D4D474643495 - A31A901933CAF2CD66E3C785458533460B966C3F379B4CFD1C0EFBA6EDDBB786 - 4FB6800B8628BE00962C5922EBEEEEAB9F5090BF80E252A07C20000480001020 - 1181633DBDBBF2720B2F6D6AAAD791A82C28250602C5C573CA5016F363A55291 - 15C3745A4F191C18F8363D3DE30FCDCD1BBE1D4D680406A474AACBED5E9F9B9B - 3365B460C9F673CD88F607A55279657373E30FC9A69D8E7AABAA6AE5BD7D07FE - 959F9F0F4FFBE8D860D00404800010481081DEBEDE3D4505E3977EFEF9E7DA04 - 9500697122307DFA9C897687EDA3FCFCF17012D6294C474634876552C9EDADAD - CDADA3FD627E54035252525EC56030DF813B407EBD727B7B7BDB7373F2AF6A6A - FA6C00A7750D611248E0B801E93FF8CFFCF1E3E727B00C480D04800010000234 - 23D0DFD7BBA7000C082DBA3A6DDA9C4C9359BB7ECA9429F0CBCA533A6A341A87 - D8187BD5CE8AF28F187575C1B335FCAC06A4AEAE0ED9B4B9F57A2E87F3B45028 - 90D162E5E024E2F8669B4387FF5D5870DE4D91ECF6C7292D842190C0A5975E2A - DD7FA0FBD38209131611980642030120000480409211E8E9EDED1C97537809BC - 8245FDC6AB542AEEC1EE9E8FA65D70C1A5D45783AF029BCD6172BA9C4F8804EC - 1746BB0BE4AC06A4A4A49687A28615189BF5008FC713E25B26B5A3858F1BD3EA - F4AF6667A6FCA9B1B1D1496D35507D98407575B5F8D0E19EF7264E2C82BF5460 - 49000120000480006E048E1C39BA6DCAE482DFC22674DC90262CD09429B56C36 - BBE7A5CCACCC9B1356044913BB5C6E87D7E37DC1EDB6D68D763AEC590D48F80B - 99566F795626955C03F722FCB2DBE10B5786474656EFFBB6EB7192AE03282B4A - 0295959502B3D5F1BC52A1BC31CAA9301C08000120000480C01909582CD64F79 - 5CE5CD700C2FF51749F8826E8F2FF8686646E6BD2C168B4D7D45F82AE8EBEF7B - 2B272B7D79535393E76C91CF6A40AAAAAAE40EA7EF6D3E9FB784C56261F89648 - ED683E9FCF6DB7D9EFE8ECDCB996DA4AA0FA9F08D4D6D6F28E1CE9AF932B6477 - B2D96C1E9001024000080001203056025EAFD76D365BDF1E9F97F9407DFDE837 - 448F351FCC2796406D6D2DDAD3377C0B9FC77D4220104889CD46BDE81AADB65E - 24E02C53ABD5EE980DC8E2C5B5E93D3D873FCB1B3FAE847A0888ADD86AB5E999 - 2CE4DAB6ED5B37129B09A2C78B40F882A1FE41ED0D1C36F624FCA5122FEA9007 - 08000120406F024EA7D312F0FB9F40D1D04BA37D29A33709DAA863CEABA8BCD8 - EBF6BC2E93493369A30A27213FECFF71EBF8719957A9D56A7DCC06E4E28B2FCE - 1D1CD46CC8C8CC3C0FA7BA681346ABD5F5214CE6EFF7EEED68A38DA82417123E - 74A16153F3251C8CFDAA4C2A4D4F721C201F080001200004702060B198B51E5F - 6065C8EFFA78B4F7E271480721E240A0A2A26AA6D566FB203535A5280EE92895 - E2C703073AD3526457EFDEBDBB27660372D1454B27EA0CBAC6B4D4D4424AA98F - 43B17D7DFD07386CCE6FBBBA3AF7C5211DA488138159B3CA8A3D5EEF47999919 - B0E6E3C41CD20001200004E84C40A3D5F660287ADDEEDDED6A3AEB4C266D5555 - 4B0B46B4431F676566152793EE48B41EE93EF68D4821BCE6AB5DBBBE8FD9802C - 5A543DC762B3AD572A14E322499A4C630E1D3ADC2512CA967EFD75C75032E9A6 - BBD659B36665EB8CD68F26151595D15D2BE803024000080001E2091C3D7AEC3F - 32A9E0779D9D9D0788CF0619E24160F1E2C5E9C77A06D7E5E58DAB603299A3DE - A9178F9AC892636878F8288FC3BDA6B373E7AE980DC8BC8ACA1AAFC7F3864C2A - CD208B30B2D4F1CDB7DF6E13F215571E3AD475D677DCC8522FD4111981E2E262 - FED19EC1D74B66CFBA26B219300A08000120000480C09909FCE7EB6F1BB33214 - D77775C1F705BAAC93F0BD61FBF61D7CB3B0A8E072044150BAE8C24387C964D6 - 3042CC1B3B3BD51B623620AA0595BF0BF8022F884442051E45D129466F6FDF07 - 42017BF99E3D7BAC74D2055A188CDCDCFCFBCF3DEFBC35C00208000120000480 - C058091C3A7878CDB469E73C545F5F1F186B2C984F0E02E163FB8D46DB5F154A - C52D288AB2C8511539AAB0D96C468489DECD64FA3E3ADB6584677D6C545A3AF7 - 5E1E9FFF1887C38123497FD657AFD7EBEAEBEF7B5D24E03ED4D5D50597109263 - CDE356C5AC5973E63311649D5C2E87D32D70A30A818000100002C947C06AB56A - 8381D01DBB76A9FF997CEAE9ADF8FCA9D31F4F4F4B5B05D754FCB2CF4EA7CBE6 - F5F81E5728842F9FEDA2EEB31A10956AE1E37C81E0417A2FA1E8D5858FD4B359 - 6DAB535365AF8C76D14AF4D16146A209CC9D5B99A3D18FAC9F307E7C79A26B81 - FC400008000120405D02434343DF8AE4E2ABDB5A5BF7535705547E3A0273E6A8 - 96F305FC67310CE300A1FF11F0783C4E2683F12A83E17F7CEBD6AD9633B139A3 - 0109DFF4E8F7335FCECACE82ABE64FA167B3D9F4769BFD5E04097C0447EAD1EF - 6317BE0FE4E0E1637F49512AEFE170387CFA2904454000080001204034019FCF - E7B1D96C1F7339D2956A7523EC17251A789CE3CF9855FA7B8958F2265C5CFC4B - F03E9FCF6BB5D93E49554A5734369E79DD9FD180CC9A552D0E06CDAFA5A4A65E - 1DE79E923E9DC9641E44D9AC1BDBD5AD9B495F2C141813811933662F4459D83B - 72B93C3BA6003009080001200004929A80C3E130BB3DBEFBE552FE7BF0B604FD - 96C2CC9925554C94F58E422E87839A7ED6DE4020E077BA9C1B6412E1AD0D0D0D - 9AA89F80945455C98356E7DB0AB9FC52FA2D9BB129D2EB0DC7386CEC9AB6B6ED - 1D638B04B3C94A40A552497BFA86D64E993CF932B2D608750101200004800079 - 090C0E0E7D2F120AAF6D6FDFDE45DE2AA1B258094C9F3E7B4E28C4F8202D3D6D - 7CAC31E83ACFED766F110A38D73634349CF1AA8A333E0151A954CADE81A10F27 - 4F9CBC88AE8062D5A5D1687F140945BF55AB5BCE7AC94AACF1615EE209D4D6D6 - A2BBBFFCE6A69CACCCD552A93425F1154105400008000120401502E1DF027FF7 - EDF71F4E98907D777B7BBB892A75439D9113282E2E39CFE3F57C929B9B3339F2 - 59C931B2BFAF774F6161FE959F7DF659EF99149F6D0F4886DE68FBF49C2993E1 - 42B653E8F50FF47F99A248BB6ADBB6A623C9B194925365717171EE88D6F8F279 - E79EBB044110243929806A200004800010889640F83236B7D3BDEAC081EF3E67 - 3018C168E7C378F213B8E08299456E8FEBD30913F22F207FB5F1AD707070E8DB - 71B979BF6968A8EF8EDA80CC983137C768D27D3A7162D1ECF8964DFE6C3DC77A - 776465E55EBD65CB991F2D915F05541809810B2F9CFD3B8180FF82482C82BB70 - 220106638000100002494E201008FA060607DF904B05ABDBDADA74498E83B6F2 - A74C9991EE72DBFE3D79F2C459B41519A3B0A1E1E1EF73B3D37FD3D0D070306A - 03525C5A3AC165767C9E373EEFBC18F3D3765A77F7D1CDE3F326FDAEB9B9DE48 - 5B9120EC3881E3AF22F60FBF3D69E2C48B994C263C0581750104800010000267 - 25303C3C724028E0DFDAD6B67D07A0A22F818269D3525C3AF3A7175C70BE8ABE - 2A6353363232F2637A5ADAB24D9B1ABE8ADA809494CC3DCFEE707C9293930DEF - B69D42EFC0C183FF3A774AD1750D0D0DB6D85A03B3A843A00EB9E0824D9770B8 - EC17954A059C88459DC641A54000080081B81370B95C36AD46F7424A8AE4AF6A - B5DA1EF7022061DC089C77DE79B2C111C307B367CE5812B7A41449A4D5E98EC8 - 95D2EB5B366DDA19B501292D2D9DEA707A3FCECACA9A4811BD712B53AFD3BFB5 - 776FC74D714B0889124A60EA5495744477ECC50BA74EBD26A185407220000480 - 00102035811F0F1C542BE58AE55F7ED9F103A90B85E2C64C60E2C4392284E578 - 797CDEB865630E46B3007ABDBE472695DED4DCBC716B0C0664DE0CA7CBB93E33 - 33B390665CC62C47ABD1BDF4D557BBFE38E64010803204A64F9F5D8DB058AF2B - 158A5CCA140D8502012000048040DC08381C0E93CBE9FAD3DEBD1D6F32188C50 - DC1243A2841038FFFCF3056E6F604D6E4EEE4D6C361B6E43FF59170C2663BF52 - 26BB6DE3C6868D511A903A64D6AC2D0BFCFEC09B69E9697909E92C89936A4686 - FFDAD5B5F701129708A5E14C60E1C2859211ADF9C1D454E51D5CB81D1D67BA10 - 0E08000120406D02E16377BB8F1C69C9CBCDBCB3B5B5F528B5D540F591102829 - 29E16934A687C7E5E5FE91C7E3092299932C632C16CB08C661DFAD6E6DF9242A - 03525C5C8CB1D9BC2A7F20F46A4A8A3227598045AAD3E1B4DFBF637BEBD3918E - 8771F250C2C70000200049444154F42070EEB9179EEFF579DF2E2898309D1E8A - 4005100002400008E041C060300CB95DCEE5DF7EFB9FF0B1BBF0270908545757 - 73B45ACB2D42117FB54020902481E48825DA6C363D1B63AF6C6DDDFC5E540664 - 4A6D2D5B32ACBD24E80F3EAF50C83323CE982403AD76FB5DED3B5A5F4C12B920 - F32401954AF5FFEC9D777C9455F6FFA7F73EC9CC249346E8A1088496020C2406 - 020B5F71CDBA6B5D3BD8D6AE5863D95D5D5DBBA858B0EFBAD95D575A48243084 - 8410302208849040FAF4DEFBFC5ECF777FBEBE8A81CC24539E72FC977BCFF97C - DEE722739EE7B9F7D2CEF50DDF57909FF7288FC783FFD9C0CA00024000080001 - 522010F06AB4BAF7C442CEE3ADADAD70380D41D64451511183CEE45F23E071FE - C21708E0A8FE9FD4DDE5725B990CC6A66FBED9F56E5C0D884AA562B9DD811B19 - 4CE6D342A12083206B29269BC809178160E0BED603EAF7639A0083704560F1E2 - C5053ABDE5EDE9D3A755C1B1BCB82A2D980102400008C44D201A8D46914BD7E8 - 2CE65D1DEDADADB0F7236E84989D803C94B45ADD9773789CD7C522911CB34692 - 20DCEFF77B027E7FED8103FB5E8CAB012929A9619348FA3BE80CC6633C1E5794 - 046D980DE9743A2D342A65E3BE7D7BFE815913207C3C04C8F317955EC9A4335F - 130A05B2F10482B9400008000120806D02A1502860301A9FB96CDDEA3FD7D6D6 - C28DE7D82E67DCEA172D5AB63C4A0E7F0407D4FC129DDDE178AAF5C0BE67E26A - 40D6AE5DCBB1D95CF75368B407B81C8E20EE8AE07882CD66D393A9945B5B9BF7 - 6DC3B14DB07611020B16A814434367FF3A73D6AC2BE8743A0360010120000480 - 00310974779F6DCE52483634373777129300B15D97962E2B0904839FCA649913 - 894DE297EE5D4EF773CDCD7B9E88AB0151A96A782492FD31328574279BCDE601 - D4FF2360B158346412F5A6B636F56EE0425C0253A75EB29CC566BCA354664F21 - 2E05700E04800010202E01E4A41FA7CBF94828E0FDDBA953A702C425415CE7E5 - E5CB8BBD3EDFE772B90CEECC3B6F19F8BC9E17F6EEFD66D3853E4B248FB46CAA - ABAB0546B3ED65A140781593C964137769FDD2B9D1681AA49069D7B7B7EFDF07 - 5C884B0039FD6270D8F8645EAEF251E25200E74000080001E212387DBAEBEF93 - 26E6FDA1B1B1D1405C0AC476BE6449C56C8FD7FD77B95C3E9DD8247EE95E33AC - 795B24E23EA456AB5D23B119B101A9ACAC11BABDFACD7C1EBF8646A3D101EAFF - 11D06AB53D6C16FBAA8307F71F012EC426B078F1927976BBFDDDFC82FC79140A - 85426C1AE01E08000120401C027AA3B18F1C21DDF3EDB707BF268E6B707A3E01 - 956AE5249BDDFACFECECAC4B80CECF090C6BB41FB218D27BDBDBEB1D3137206B - D6AC11DB5DDE2D021EFF0A00FA73024343C3A7195C5ECDB707D527800DE10950 - F2264CBEA3202FEF59389697F06B0100000120401002C8B1BB5A8D764B66A6A8 - 56AD56DB08621B6C8E4040B56A5581556FFE97323B7B1E00FA39018D46FB7186 - 54F0873D7BF6D8E36A405C2EFF875C1EF73200FA7302FD030327593CD6151D6D - 6DA7810D10282B2BCB1E1E36BC5D34A3681DD000024000080001FC13D068868F - 33E88C0D870F1F6CC3BF5B70783102555555B91AADE9EF7979B9A540EAE704B4 - 5ADDA75209FFAEB81A90952B6B24FEA0F5630E9BFB2B00FA730267CFF57ECF13 - F3AEE83878F02CB0010224522D65DEBC86FFA131A8AF4A25925C32993CE2678D - 400A080001200004B04FC0EDF13AAC56CB2B746AF48F1D1D1D41EC3B0207E321 - 5051B14EAED1F67D3961C28465E38983C7B93ABDFE33018F75D785DE128EF863 - 69FDFAF5529BC3F5319BC559834728E3F1D4DD73B6432AE65D71E8D0A1BEF1C4 - 81B9F821505E5E2E3E75FAEC0B0BE617DF40A55269F871064E800010000240E0 - 470291482472E64CF77E855C71F741F80C1B160689445ABB766D46F7D9812F0B - 2714AC00203F27A03718BE6033A977B6B4B45847623362038200F578839F3199 - CC9500F4E704CE74F77C2BE48B7EDDD1D13A006C80C08F04A614CDAE60D2E86F - E5E6E6C0517CB02C80001000023824E072B96C4E87F301BF3FFFD353A7EAE0D8 - 5D1CD6385E4B1515EBA5C39A737F2B2C2CB834DEB9781F6F3419BF64D2291BE3 - 6A40D6AF5F2FEB3A73EE9F0505054BF00E285E7FA7CF9C699767887EDDD6D636 - 1CEF5C188F5F02B3675771BDFEE14DCAECACBB391C2E1FBF4EC1191000024080 - 98044E9C3AB5B3305F79B35AADD6119300B83E9FC065975D26EA3C7DF66F1327 - 16AE023A3F2770E2C4C91D9327E5FFBEA9A9C91CF31B9075EBD6C97B7B87BECE - CDCB5D04407F4EA0F374579B4820BDE2E8D1560DB001023F25B0A0AC6C86C3EC - 7C77E2C409654006080001200004F043C068349D8B84238FF0F9CCAFD46A7508 - 3FCEC0C9780820F7E6F59C1DFCDBE4C913578F270E1EE71E3DFAFDEEECAC8C6B - 3B3A3A4C313720AB57D72806877AB7E7E62AE7E311CA783C75769E6E95886535 - 1D1D07B4E3890373F14960EAF4D97F28C8CF7B09F682E0B3BEE00A080001E211 - 40F67EE8758637391CF9E3ADADDB9CC423008E2F44E0BF0DC8C0E793274F8243 - 9BCE83F4FDD1630D5959D26BE26A402EBFFCF2AC9EB3FDDB7372728A61D9FD9C - C0C9CECE1699545873E4C81178050B8BE31704162F5E5C30A431BD51347DEA4A - B8C41316081000024000FB048606873B391CD6ED870EB5A8B1EF061C2492C0BA - 75EBF8A73A7B3E9B3265321CC59FB8066460474E8E122E56390FE88993A79A45 - 82CC9AE3C70F1A12B98821167E08CC9EB7602D8B467F232333331F3FAEC00910 - 0002408078047C3E9F6B58A379254B2EFD8B5AAD76118F0038BE1801554D0D6F - F0FB139F4C9D32653D90FA398131BF01397B6E60A752A99C0B40CF7B0372E2E4 - 7EA150F61B684060655C884049490D3B181C7A512697DD019480001000024000 - BB047A7B7BF7CB658A0D6A75235C3E8CDD32264D79555515F76CEFE0A7D080FC - 12F1981A9075EBD665F70F68772A95D9739256358C063E090D08462B9752D9E4 - 59B3E62E0D47A2AFE5E7E7CD86CB0953CA1E9201012000041242C064360F0543 - E1A7264DC8F9B8AEAE2E9C90A010045704FEB701393BF8C9D469532EC795B104 - 98F9FED8F14679A6E89AA3478F1A470A37E23D20D0805C983C34200958950408 - 515252C236986CF715E4173CCE64325804B00C168100100002B821100E87433A - BDEE63018FBDE9C0810323FE80C28D5930326602D0805C181D3420635E56234F - 840624C140711CAEBCBCA2D060D4BF3F69D2C4E538B609D68000100002B82380 - 1CBBCBA0B336B4B6367D833B7360286104A001810624618B69B440D0808C4608 - FEFC4702C5C5C5F47098F21B269BF5A25422C90232400008000120807E025EAF - D7653498DE160A739E856377D15FAF742A843D20C96940762895D9B009FD3CB6 - D080A4F3AF3AF6729794AC94F4F59F7E63EEDC3957614F3D280602400008108F - 40CFD9B3ADD98A6C64E3F909E2B907C7F1108006E4220DC8D1630D72B9F8DAB8 - F68020F780C0295823433D79F2E47EA1004EC18AE72F28D1C74E99327D3587CB - 7F3D3B3B6B22D159807F20000480009A0978BD5EA7C56C79F4D8B16FDF44B34E - D0860E02353535BCEF8E9EF874EAD42997A143117A547C7FF4D8EEAC2C697C37 - A1430372E10222F78064C925BF696F6FD7A3A7CCA004CD049027241A8DE131B9 - 42713793C9E4A2592B680302400008109540341A8D9C3D77AE29275B76CBDEBD - 7BFB89CA017CC74EE07F1B9063273E9B3A79CAFFC43E8B18238F1E3DB63B3BDE - 0664F5EA1AC5D0702F721121DC847EDE3AE93CD5D92A91F06B3A3A3AB4C45842 - E03211044A4A96CEB2DAED1F144E28589088781003080001200004124BC06CB6 - 0C924991077373B3FF09C7EE26962D5EA35557570BBA7BFA3E9F3265CAAFF0EA - 71ACBE8E7EFF7D7DB622E3BA8E8E0ED34831463C8617694006877AB7E7E62AE7 - 8F35315EE775769E6E958879D080E0B5C049F2A552A968FD83DA7B7394CA4D7C - 3E5F9CA4341016080001200004C64020140A050D06C3C76C96E4E1B6B606CB18 - 42C0140212A8ACAC11F60F767E3179D2C4D504B47F51CBDF7DF7FDAEBC5CF975 - 870F1F36C7DC80AC5BB74E7EAE6F705B5E6EDE4200FA7302A73A4F1F140B336A - 8E1E6DD5001B20100F81B9A5A5F9168D71F3F4E9D3565128144A3C73612C1000 - 02400008248F804EA73F4DA352EE387CF8E03E1289144D5E26888C27026BD6AC - 119FE9E9FFDBE4491357E2C95722BC7C77F4E8CEBC1CC5F5713520EBD7AF9775 - 9DE9FD5741417E792244E02946E7E9AE36814C5C73ACAD6D184FBEC04B6A08CC - 9F5FF23B169BF59A4020C84C4D46C8020480001000021723100A85027A83E185 - BC1CC5F3DBB76FF7002D20102B81952B6B24FDFD9D5F164E9C5819EB1CA28C3B - 7CA4E33FF2CCDC9B4E9E6C1BF18DE2889F60AD5DBB36C3EB0D7ECE6032AB8802 - 2A569F67CE741F160AC4351D1DAD03B1CE817140E04702E5E5E5E2DEFEE17767 - CD9CF96B780B02EB0208000120905E02D16834DADBDBD72ECB94DDDADCBCE787 - F4AA81EC5823505D5D9DD9DFAFF9B26042015C387C5EF1745AEDE71C0EE3AE96 - 9616EB48751DB10159BF7EBDD4EEF07CCA62B1AAB1B61892ADB7BBBBE7088F2B - AC397AF4209C90916CD8F88C4F993163B68A42A1BF919B9753844F8BE00A0800 - 0120800D02369BCDE0F3FA1F97CBC59FD4D7D7FBB1A11A54A285C0EAD5AB157D - FDDA7F1414E42D418B26B4E8D0E9F59F0978ACBBD46AB52DAE06C4E6707DCC66 - 71D6A0C5085A7474F79CED100944BF3972A4E51C5A34810E6C1150A9542C8BC5 - F9A4224B713F8D4663604B3DA80502400008E087C0C99327FFA390E76F686F6F - 82A3F5F153D69439B9F4D275D9C3DAC17F16E4E795A42C294612E9B4864F0502 - E6DD713520C8376D7EBFED230E97B316233E5326F3DCD9BE633C1EEFCA6FBF6D - ED4A595248843B028BCA97177B1D8EF7737273E6E0CE1C180202400008608080 - CD66D3783DBE3F1C3DDAFE4F0CC805892824B06AD5AA02ADCEFC9552990DFF96 - 9F571FAD4EF78990CFFE435C0D08B2ABDFEEF2BE2FE0F12F4761BDD32A69A07F - F00497CBBDB2BDFDC0A9B40A81E49826505D5DCDECEFD7DC9129973DC9E57084 - 983603E281001000021823E0F7FB3D56ABFD3D0E5BF2744BCBCE11BF51C79825 - 909B06022B57AE9C64305AFF959595353B0DE9519D52A3D57D9421E1DFB367CF - 1EFB484247DC0372D96597894C26DBDB7C81E04A32993CE21854BB4EA2B8C1C1 - A14E168F79FD9183078F24310D84260081E2E2B23CA351BF65C6CCA22AF87B46 - 808283452000045043A0BF7FE0388BC7BDB5E3504B3B6A448110CC1158BE6AD5 - 54BBC1F64F45967C26E6C42759F0B046FB218B21BDB7BDBDDE11730382DCEC68 - B1B85FE10BB85731180C569235622ABC46AB3B47A7526E3C72A46D3FA6848358 - 3412A0CC9E3DFF4A1687F5628654AA44A340D00404800010C01B019FCFE71A18 - 1C7C29275BF6825AADF6E1CD1FF8491D81252B56CCF338BC5FC8E5B2A9A9CB8A - 8D4C830383EF0A04EC075B5B5B9D3137202A550D8F42753C4E2291EE64B1585C - 6C584D8D4AA3D1384021936E696F3FD8989A8C9005CF04CACBD788FB074EBF52 - 5434FD6A2A954AC3B357F00604800010483701E4D8DDBEDEFEFD72B978A35AAD - 3E9D6E3D901FDB04CA54AAC5014FF0B3CCCC8C89D8769278F56E97FB453239F4 - E4859AFC0BDD03C271383C0F902894FBB91C8E20F1B2B01BD16CB66828E4E86D - 6D6D2D3BB0EB0294A389C09CF98B2EA544499B150AC52434E9022D4000080001 - BC110804023EB7CB79475B5BCB56B8F11C6FD54DBD9FA54B572CF505FC1F6748 - 330A529F1DDD193D6EF7736AF59E272EA472C406A4A4A4864D269BEEA2D1A99B - 783CAE08DD1653AB0E39339C42A6DED9D2B2B72EB599211B5E09CC9E5DC5F5F9 - 340F642BB3EFE770D87CBCFA045F400008008174120887C3A113274FD6672B72 - EF3872A479309D5A20370E08D4D6529634EDBF34180ABD2F91487270E028A116 - 1C4E676D4BF3DEA7E36A4090137ACC36D72D4C3ABD96CFE74B13AA08E3C1DC6E - B7CDEBF13E70F870EB0718B702F2514460E9D2AADC61CDE0BB53A74E81CB3F51 - 541790020480007E08582C9601AFC77DAF582CD8A656AB43F871064ED241A0B8 - B8981EA5D07FC366325F160A45B27468406BCE68341AB1D91D8FB5B5AA9F8FAB - 01A9A9A96168F4A6CB22C1F0AB6289380BAD06D3A10B7982E2747BEE3B7860EF - 1BE9C80F39F14B60C182B2AB592CE66B7C0134FDF8AD3238030240205D04F47A - FD1B0C7AEEC36D6D75DE746980BCF821505454C460B305377179BC3FF2785C31 - 7E9C8DDF89DBEDB1B198CCC71B1A76BC155703A252A9687E7F6855281CD99C99 - 99993B7E29F88AE071BB37A9D57B2ED8D5E1CB2DB8491581D9B34B653AC3C05B - 73E7CCB90C36A4A78A3AE4010240800804FEF7087D2663239C6049846AA7C6A3 - 4AA562793C81BBD95CEE63B05FFAE7CC5D2E9799C5643CD4D858FF615C0D484D - 4D0D756060B822148ABC2B57C86163CD79F4F43AED0B1D1D871F49CD12872C04 - 22409E39734E259DC1DC9C95051BD2095477B00A048040120920C7EEF6F5F7BF - C8CA51BC7C4AAD7625311584261081E2E2628EDDE97D262F3777238BC5E210C8 - FAA8561D0E8781CE64DCBB6F4FC317713520C8E0D2D2650B3C5EEFE7D9D95993 - 47CD44B00106A3E1CD6F0FB7DD4530DB60370504CACACAF83687FB99ECACEC8D - 743A9D998294900208000120806B02E7CEF5EEE772B81B3A3ADAE0D85D5C573A - B5E6A69695F16936D72B39B9B9D7C3570B3F676FB55A878502D1EDBB776FDB36 - 86064435C7E5727E91939B333DB525457F368BD9FCC1A1432DB7C0117EE8AF15 - 161596942C9DEBF1B8B7662B95B3E186742C5610340301208016024EA7D3140E - 851F552A651FD6D5D585D1A20B74609F407171B1304AA2BFA750C86BB0EF26B1 - 0E4C6673BF542CBEB5BE7EFB05EFCC1BF1185E44C6820565337C3EDF97B97939 - 33122B0BFBD14E9FEEFA77E1845937EED95367C7BE1B70803602C8C91A4EA7F7 - 81FC82825A3A9DCE409B3ED00304800010C002814824123979E2D47F0A0A26DD - 79E04083160B9A412376082C5CB850AAD599BE98356B56157654A746A9D1683C - 2B118B6F6868D879600C6F404A271ACDF62F264F9AB4303572B193A5BBA7A761 - 42FE94EB1A1BBF3260473528C51281929292692693FDBD899326965028142A96 - B4835620000480001A08582C56BDDDE6D8D0D9F9FD7FD0A00734E08BC0C4D9B3 - 6541BBE73F3367CE28C197B3F1BBD1E9749D7299FCEAFAFA6D47E36E40162D5A - 946330DAFE367DFAB4F2F14BC15784DEDEFEE6DC9CFC6B1A1BBF868B8CF0555A - D4B8292AAA61B07983BF6331987F81F3C551531610020480004608F8FD7EB7DE - A07F87CB563CD3DE5EEFC0886C90892102975C7289D2ED096E9B3265F23C0CC9 - 4E8954CDF0F0F19C9CFC2B76ECF85777DC0D4871717196D164FF7CE6CC19CB53 - A21643498686863B323364573535ED3A8321D920156304CACBCBC5BDFDC36F5F - 327BF69518930E7281001000026925D0DBDBDB9E9921BBA5B979CF0F691502C9 - 714B60C6DCB945117FE41F132614C05685F3AA3C3838D451909F5DB37DFBF6DE - B13420191A8DE9E3B9F3E6ACC6EDEA19A3319D5EDF29168A7EDBD4B4FBF81843 - C034201013811933E6AD6573596FC9E03E9E9878C12020000480007261F0B9B3 - 671FEDEEEE7C116800816411282E5E3C2F140E7DA9542A27252B0756E3F6F6F6 - B54C995C70D5D75F5FF84BA10B6E42479EBEFA7C91B765F24C78FA7ADE0A309B - CDBD2C26F3FAFDFB9B2EB8B906AB8B0674A38B406565A5D060303F912953DCCE - 6432D8E852076A8000100002E82280341F5D5D5D4D7259D65DEDEDCD17FCFC03 - 5DAA410D1609CC9B57BA824A237F929999A1C4A2FE646AF678DD3B382CF12DBB - 76D5E9E27E03B26851B5C01FB4BC969DA5F87D32456231B6CD661BA652E8B71D - 38B067171CC58BC50A624B73C9D2A5739D56D796BCBCDCF9D8520E6A81001000 - 02A92560B15A064381F07DD1A8FFEB8E8E8E606AB343362211285FB6623D83CE - F88CC564C225843F297C28140A3ADDAEAF447CD99DF5F575C6B81B90AAAA2AAE - 46637C312F3F6F239116542C5E9D4E97C9ED723F4826073F87FFC1C5420CC68C - 8700722CAFC3E57F4899AD7898C3E1F2C7130BE60201200004F04C40ABD3BE9D - 932D7F60FBF6ED1E3CFB046FE927B078F1920D7C01FF55B834F8E7B50806837E - 9BCDF6A92C53FCD0CE9D3BAD713720C884929265CF8825A227D25F667429F078 - BC768FD7F38C54CC7FABBEBEDE8F2E75A0068F044A4B574CD46807DF9A366DDA - A5140A8582478FE00908000120305602D168343A343C7C5C2C14DEDDDCBC17F9 - 3C3A3AD658300F08C442A06CC9F24D5C0EA79646A3C17D5D3F01E6F3F9DCD108 - E9E56854F017B5BACE35A606A4B474E9FD7426F3492E872388A5184419130804 - BCC3C3C36F72D8F4DA8E8E0E78CA4294C2A7D9E7F419737F2B9749B7C05B9034 - 1702D2030120803A028140D0D7D7DBFF67A190F512FCBB8CBAF2E04ED0DAB56B - 391A8DFEF98C4CD9462A954AC39DC1711872BB3DF64030F8B848C07EEF620FE9 - 2FB8091DC9AD525D7A4D301C7A592810648E430B2EA70E0C0E7DC265D3EE6A6F - 6F87F3C5715961F4992A2DAD920D0E9F7D6DFAB46997C31317F4D50714010120 - 903E027D7D7D078402E11D6D6DCD70EC6EFACA4098CCD5D5D5028BC5FD865822 - BC1A2E0BFE79D9ED0E87914AA36E68DEB7E7DF175B10176D40962EBF745DC0E7 - DF2C91886187FF79147F38FEC31E994CFCBB8E8E0E1361FEC681D1F412A8ADA5 - CCF9CFEEA5E148F08DDCDC9C99E91503D98100100002E82060B3DBF59150F8F1 - DC5CC5277575750174A802157826B076EDDA8CD3A7CF7D3669F2C44BC964327C - 16FD93625BAD562D8D4ABDF6C0817D4D636E40AAAA562FB5DAEC1F67666614E0 - 79218DC55B67E7E9230C3AE7B2AEAEA39AB1CC873940608C04288593A63D3C6D - EAD43F8D713E4C0302400008E08AC0D163C7BE56642A6F3F7AB415FE3DC65565 - D16BA6BABA3A677050F7AFBCFCBC85E855991E65C3439AD37C3EEF9A96967D1D - 636E4056AD5A37DB6832D4C9E5F229E9B181DEAC7D7DFD9D540AF5CA1F7EE880 - D7BDE82D132E952D2C2F9F62D159DE9E3479E23278F58BCB1283292000046224 - 801CBB6B77381EEC3C71ECCB18A7C03020306E02D5D5FF53A437E8EB140A79D1 - B883E12CC0B973BD47A512E9EF5A5BF7758DB90159B3E6F2C261EDD0D7D95959 - F0B9C77914B55A5D5F241CBAF6D8B18E169CAD1DB0830102F3162CBE92CD64BF - 2114C2FE2C0C940B24020120900402C88130569B752B43227CA2ADA1C1928414 - 1012088C44805C51B152E5F678B64A24927C40F473029DA7BBDA3224B22B8F1C - 691E1C7303F2AB5FD528CFF575D715E4E79700E09F13305BCCDA70307AD3B7DF - B6D6031B20906A02B366958BF5C6BE2DF38B8BAF48756EC80704800010400381 - C1C1A1936C16F396C3870FB6A1410F68200681DADA5A4A4BCBE1F53EBFEF6D81 - 800F87349D57F663C77FF826273BF38AD10E69BAE826F4AAF5EB655E8BE35D36 - 8BB58646A3D189B1B462731908047C3687F3D66FDB5B3E8D6D068C0202092540 - 9E3163F65A168BF3AA5C219F90D0C8100C080001208072028160D0D7D7D7F7B2 - 90CF468EC3871BCF515E2F3CC9ABA9A9A16A74E6BB1874DAD36C361BAEA938AF - B806A3F19F3C0EE35AB55AED1BF31B90CB2EBB4C34AC31BC28140AAF6130182C - 3C2DA0F17A09854201AD46F3E40F3F1C7D61BCB1603E10180B8145D5D502AFD6 - F874964271279C433E168230070800012C128846A391BEBEFE8312B164436BEB - BE9358F4009AB14BA0B8B8981E08919FCF5166DF4B26932FFA201FBB2EC7AE7C - 7858B3353B2B63E36817755FFC0D485515D7EB0DDF47A3D31E62B359BCB1CBC1 - DFCC70381C329A8C6F92A3973CD4D1B1059EBEE0AFC49870B46851D962B7C7BB - 252F2F77162604834820000480C03809B8DC6E9BCFE7DD140EFA3E80B71FE384 - 09D3E326505454C3607387B6C865B2EBE39E8CF309C16030100CF85F713A6D4F - 8CF677F3A20D484D4D0D6370D870139341FF1397CB15E19C5B5CF6229148A4AB - EBCCBF8BA64FBA75E7CE9DD6B826C360209020022525256C8BCDF58042A67880 - CBE3C0ABE004718530400008A09300F2F6E3CC999E6F0AF2B3AE6F6A6AD2A353 - 25A8C23381E2E2B51C8BB5FB1FD3A74F5D83679F63F1863C1C08FAFD7F6232A9 - AFA8D5EAD0C5628CFAEA68E9D2E5EBC291C87B42A148361631789E73EE5CEFFE - DC9C82ABBEF9661B9C3D8EE742A3DCDBDCD2D27C93C6F0F6AC1933AA512E15E4 - 0101200004C645C060300E7AFDDE7B8BA64EFA4F5D5D5D785CC1603210180381 - B973CBB26D0ED3DFA74F9BB6640CD3713DC562B1EA6854EAFD2D2DCBFE4E22D5 - 46C6D5802C5F5EB5C8E172FE4D2E93C146D7F3486A349AEF15F2ACDFEEDEBDED - A2671DE37AB58139541098B760F1D542BEF01DF8541215E50011400008248140 - 381C096A8635EF0804ACC75A5B5B9D4948012181C0A804E6CD5B3CDD17F0FDA3 - 203F1FAEA8388F964EA7EF110AF837EFDBF74D3389448A8EAB01292FAF986232 - 1BBF282C9C503C6A550836C06CB1F4F1389C1B9B9A1AD4A38126181AB09B6202 - A5A555B2616DEFE6A953A6AC8313EB520C1FD20101209012025AADAE93C366DD - D6DABAFF404A1242122030028139F317ABE854DAE79919D26C00F47302834383 - C732249957EFDBD730EAE110A37E82555252A2D4EACC7F2B2A9A0EAF9ACE5B69 - 6EB7DB1C0C871EA8AA507D525B7BF1574DB0488140B209CC98317B0595C6D89C - 93A39C9AEC5C101F08000120904A021E8FD7A9D7E95FE470F2FEDAD1B1DD93CA - DC900B08FC48003982B7A7A7FFF73C3EEF453E9F2F06323F2770AEB7B7B5202F - FB9ADDBB77F78DC626960684DD37A0FDD7DC3997C0F7E5E7D1446E61D5E9F52F - 6448047F1C6DB3CD6885803F0702E325801C0DE8F5869EC9CDCF7B904AA150C7 - 1B0FE60301200004D042E07467577366A6F0E6F6F6F66EB468021DC42350BC76 - 2DC7DB3BFCB4429E793B8BC5E2108FC0851D238733F574F7EC9A3265C22DBB76 - EDD28DC666D406A4BABA9A39AC31BE9793A3BC76B46044FC738D56B3994A8EDC - 33DA71634464039E534FA0BC7CF92536BBED83BCBC3CF86432F5F82123100002 - 4920E074BACC5E8FE7D10913723E808DE749000C2163265059592974B8BC9B85 - 42D115741A8D11F344020C44AEA7B0586D5B6519C28763391D76D4060479AACA - E389FFC862B3EE85CBCE7EB982BE3FF6C3572241DE75A74EA95D04585F6011E5 - 0490A3B37FF8E1CC5D59D9F25A369B0D77F7A0BC5E200F0800818B13884422E1 - D35D5DDB0A0BA6DCB577EF8E61E00504D24940A55AADD0EA07EA26164E2C4FA7 - 0E34E60E8542C15030F8028D467AF90536E20000200049444154BEB1B1D13D9A - C6511B10954A45737B83F7B059ACC7783C1EDC05721ED1D3A7BB5A8502F6D547 - 8F1EED1F0D36FC39104805814B2E2951DA1CE68F67144DAF48453EC801048000 - 1048160193C93C1CF07BEFFDFEFB8E7FC2612FC9A20C71632570E9A5974E369A - EDFFCECECA8213B0CE83160C86FC3EAFF7910307F6BE1A0BCF511B1012A99652 - 56A6AE8944A3AF89C522792C418934667858D31D8D447E7BFC78C77744F20D5E - D14B0079686077792F63D019AF4825921CF42A056540000800810B130806833E - 83DEF09158CCDBA456AB6DC00A08A49BC0B26515CBFDFEC04712A9242FDD5AD0 - 96DFE3F1D86954CAED7BF6347C118BB6181A101259A5AA2C73BADC1FCBE5B2C2 - 588212698CCD66335A6CD69B4E9F3CBE9D48BEC12BBA09A8542A5E4F4FFFABB3 - 66CFBA814C2653D0AD16D401012000047E4940ABD39DA23128B71C696B3B087C - 80001A082C2E5B7A3D93CE7885CBE5C20958E715C462B10C0905821B1A1A76EE - 89A556B13420A4E5CB574D359A8D7FCFCBCD99134B50228DF178DC4E87DDF128 - 991C7E1736A213A9F2E8F7BA7061E98A7038F2B65C219F827EB5A01008000120 - F07F04FC7EBFC76AB1BC387162FE9FEAEAEA02C00608A081C09265159BF83CDE - 9FD0A0056D1A745A5D576666E6550D0D3B62FA2228A60664C58A5F2907067BB7 - 4E9A545841A150E069EA4FAA1E0804FC4683F1FDECECCC47EBEBEB1D685B10A0 - 87B8048A8B8B3956BBFB81BCDCDC07391C0E6C4827EE5200E740005304908DE7 - 677BCEB649145977B41F683A8E29F12016B70490CF9B5D1EFF9BB24CD96DB835 - 390E63E77AFB8E28B3727EDBD4B4F35C2C61626A4056AE5C29B1D9BCAF8825C2 - AB2970BFC0CFB846A3D1E899AEEEA6C2C29CEBBFF9E61B4D2CD0610C10481581 - C58B1717184C8E0FA74D9DBC3C5539210F10000240603C049C2E97D964B2DCD7 - 79F2E867241229329E58301708248AC0A28A0AB9B14FB375DAB429702FDE0850 - 2D16EBBF8502F62D0D0D0D965898C7D48054555571C361EAA3541AE5411A8D46 - 8F253091C60C0D0F1F978AA557C572F53C91B880D7F413406E6DED1B18BE8EC9 - 603E2F100864E957040A8000100002172770BAEBF47F14B2FCDB0E1E6C34002B - 20801602F3E7974D75B99D9F17164E807BB6CE2B8ACFE7734749A477F95C66ED - B66DDB9CB1D42CA6060409B464C98A7B586CD6F3743A9D194B60228DB15AADC3 - 2C26E3A67DFBF63410C93778C50681050B548A61EDC0E6D9B366AC833798D8A8 - 19A804024424807C5160309AFAC951D203BFFA55D557B5B5B5F0F683880B01A5 - 9EE7CC59AC2251A31F642B147020D3793572B9DC567F20F0270A49FE565B5B9D - 379612C6DC802CAF5C757928107897CFE767C41298486342A150C0E972DEDDD6 - DAFC2E917C8357EC10983163F65A3687F7964C96998B1DD5A014080001221140 - 2E32EB1F18785922E23DDDD6D616D38F1822F101AFE923505454C4A0D3393770 - 79BCE7442221FC0E3EAF14668B4543A3D0EEF5F91C5FC57A2053CC0D486565F5 - 62ABD5FA895C219F9CBE2580DECC9A61CD4B9327173C5257571746AF4A504654 - 026565657CB7DBF76CA64CBE01DE62127515806F20806E0203FD7D870402F1C6 - 8307D5DFA35B29A8231A01E4687B83D1FEE7AC2CF9CD4C26934534FFA3F9D5E9 - B467D97CC1EF5BD57B5A461BFBE39FC7DC802C456E7FD4E8BF985030617EACC1 - 8934EE87E327FE9D9323BBA5ADAD2DA6CD374462035ED141A0A464E95C9BCDB6 - 654221FC1D46474540051000023F1270381CA64028FCB854C4FDA8BEBEDE0F64 - 80009A082C5C5821D51906BE9839A3A80A4DBAD0A2A5F75CEF6189427A63EBBE - 7D2763D51473035251B15EEA0FDAB70AF8FCB5B10627D2B89EB3E7DA857CE155 - 478EB4C474FC1891D880577410282E2EA65BAD9EFB0A26E43DC962B138E85005 - 2A800010000224D2F1633FFC272B2BE7EE23479A07810710401B81B2B2E5336C - 4EDB67F9B979701FDE08C571389CFFE172E8B73734346863AD5DCC0D487575B5 - 60586F7A4926CDB896C160C0EBA7F3086BB4DA731412F9EAEFBE6B3F142B7C18 - 0704524DA0B4B434DF60B67D3C79E2A4A5643239E6BFFFA9D609F9800010200E - 01ABC5A2757ADCF79E38F6DD97C4710D4EB144A05C555119F0F93FC8904AF3B0 - A43B555A91FBF0323284F7C7731F5ECC3F40542A15CBEB0DDEC964B31FE771B9 - C25499C24A1E9BCD6E72D8EDF74D9F3EE90BD8078295AA114F27722CEF99B37D - 57F038DC3784426126F1088063200004D04420180CFAF506FDA7423EE7D10307 - 0E18D1A40DB400811F092C2A59762B97C3FA2B8BC5824B7D4758162EA7FB89E6 - E63DCFC5B362626E40901F2E831AFD9A6838FAB6542AC98E270911C62237A20F - 0E0CBEC1E3319FEAE8E8F010C13378C426818A8A0A69F7D9FEB7A64F9BF66B2A - 954AC3A60B500D0480001E08E80D866E269D7DF3C1837B9BF1E0073CE08F0072 - 179EC5627F4E9A21BB834AA5C05D78E795D8E57299594CD6FD8D8D3B3F8EA7FA - 31372048D0C54B56CCF33A9D5F2895D953E3494294B1274F9CDC3D6142CEB56A - B5DA4414CFE0139304C8B3672F5849A3D3DE522864709E39264B08A28100F609 - F8FD7E8FC1687C23275BF6146C3CC77E3DF1EAA0BABA3AF34CCFC0D6C9930AAB - 29140A05AF3EC7EACB6432F78B84925B1A1BB77D134F8CB81A90D2D215F97A83 - F6A3A953A7A8E2494294B17D03033F88F8C2AB0E1E549F208A67F0894D02C5C5 - C51CAF2FF46C4E4ECE5D341A0D9EE860B38CA01A08609640341A8D749DE96EC9 - 5048EF3EDCD2720CB3464038EE092C5FBE7286D96AFE2247A99C8D7BB3633038 - 343C7C3C5B917DEDEEDDDB8EC7333DAE06A4BC7C8DD81FB2BD9929CDB82A9E24 - 44196BB15887A90CFA0DADFB9BE2EA0289C2077CA28B4069E9B2056E8F67AB52 - 993D035DCA400D1000027827E0F7FBDD36ABED9E8E8E43EFE3DD2BF8C33081DA - 5ACA92A6FD6B03C1F05B52A95889612749911E8D46A33EBFBF89C5E0DE505FFF - EFA17892C4D58020FB40BABBFB5ECA5666DF134F12A28C4536D379DCAE3B5A5B - 9B3F208A67F0895D022525256C9BD37B9F3C53F63087C3E663D7092807024000 - 6B04BACF74EF522AF36F53ABEBE3FAD182359FA017DB04542A15CDE78B3EC462 - D31FE170B8F0EFE479E5447EF7DAEDF62FE532C9FDDBB76F8F6BFB415C0D0892 - B7B47CF9DD3C2EE7451A8DC6C0F6B24ABCFA70381C329A8CAF087879CFA8D575 - AEC46780884020B104662F5A9463D59ADE9F356BE6CAC4468668400008008191 - 09E874FAB39170E4019188B343AD5687801310402B81EAEA6AA6C160D9225728 - AE43ABC674EAF278BC4E7FC0FF673E97F97A6363A33B1E2D713720CB97AF5CE3 - 0BF8B68845223809EB3CD2C837ADDD677A1A7272F26F85A73AF12C43189B4E02 - 73E62CB89A2FE0BFCEE7F325E9D401B981001020068173BDFD2FCD9A31F91138 - B29E18F5C6B2CBB2B2B23CADD6FCE9B4E9539762D947B2B4DB6C7623294ADE78 - F0E0BE7FC59B23EE06A4A262D56C8BCDFAF72C85627ABCC988305EA7D5763118 - CC9B0E1D3AD04A04BFE011FB0490133E4E9DEAD93C75DA94FF810DE9D8AF2738 - 00026826A0D3EA4FB058CC5B0F1EDCDF86669DA00D0820044A4A962CF307421F - C2899123AF078D46DBC36232AE3974A8A53DDE15137703B272E5CAACDEFEE1BF - 4F2C2C5C023729FF12B7D3E130DB5DEE878F1F3DBC95442245E22D088C0702E9 - 20307BF6BC150C266BAB4C9609B7BCA6A300901308108080DBE371E8F5FAE727 - 4FCC7F6DFBF6ED705F16016A8E718BE445A5CB36B218F43F72B95C11C6BD2445 - FEE9D35DAD5249C675478EB49C8B3741DC0D487575B5406FB4BD28118BAE6330 - 18AC7813E27D3CB20FA47F60E8552E9BFA6847474710EF7EC11F3E08201BD2CD - 56E7E3394AE53D2C168B830F57E0020800013411E8EAEADA9B9BA3B84DAD56F7 - A049176801022311A8ACAC14DA6CEEBF8AC4A2ABE1F7EEC86B44A7D5D7B1D9D4 - 9B5A5B5B9DF1AEA2B81B90E2E2623A9DCEDEC864B39FE572388278131261FCB1 - 63C7776466E45FFBFDF76A1B11FC82477C10983FBF6CAADD69DD3A69E2A4C5F0 - 76131F35051740002D04EC76BBDE62B63C3673E6D48F60EF075AAA023A2E4660 - D5AA5505FD039A2F264C985002A47E490079E0EEF3075F376608369DAAAB0BC4 - CB28EE060449B078F1B26A3225BA552C16CBE34D4884F1BDE7FA8F3318B4DF1F - 3BF6ED5122F8058FB821409E3E7DCE1F7272B39FA7D3E94CDCB80223400008A4 - 95402412099FE9EAFE4AA9CCBCFBC08103DAB48A81E440204602CB96552CF7FA - 7C5B333232F2639C42A8612E97CBCC66B19F1208D8EF8CE5A1C2981A90458B96 - CC76BA5D9F15E4E7CD2214ED18CD22FB405C2ECF9D9326E5D58DA52831A68161 - 4020E104CACB2B0A359AA137274F997C29954AA5253C0104040240807004CC66 - CB20294ABAABBDFDC0D784330F86314B60C182F2DB0542DE4B4C26938D591349 - 146E32997AA512C986FAFAEDC8E5DBD178538DA90159B06081426FB47E3E73C6 - 8C15F12624C2F84020E0351A4C9B79F9594FB76EDB16F777714460041ED14900 - B974496FB6FD8AC364BF2A97CBE0A90F3ACB04AA8000660820379E1BF4BA2D02 - 01F7A9B17C278E19A320146F04C83367CE7B332F3FF776BC194B841FE406F4C1 - 81C123050585D7ECD8F1AFEEB1C41C5303825CCC32A4316ECECD51DE3896A478 - 9F13894423E77ACFED2DC8CBBEB1B1B17110EF7EC11FBE08201BD23D9EE00BCA - 1CE55DF872066E800010483501E4470A83C1D8D0D17108F92439EEA7A4A9D60B - F980004260D1A245391AAD69EBAC59332B81C82F09209F55DA6DB62F148A8C7B - BFFAEA2BF358188DA901419E92FA83A407584CC6A36C361BAEA61F81BCD1683C - CBA0B36F686D6D3A3096C2C01C20904E024B962C2F73BADC5BB2B3B38AD2A903 - 72030120805D02C160D06734989EFAFEFBC37FC1AE0B504E4002E44B8A8BCBC8 - 61CA47D9CAEC8904F43FAAE5502814F079FDCF70B9F497EAEBEBFDA34E1861C0 - 981A90DADA5A8AFAC0C175019F7FB34824CA1A4B62BCCFF1783C76BBD37EFFD1 - 6F0F7F8077AFE00F7F0490B720268BE3811CA5F221369BCDC39F437004048040 - B209F4F4F41C50C8A5373537378FE9138D64EB83F8406024023535358CBEBEE1 - 9B992CD6B302015F02947E4900D96A100E456EDEB7AFE18BB1F21953038224AB - AA5A3B4D6FD0FD5DA9CCBE64ACC9F13EAFE7ECB9576894F023A74E9D8AFB7832 - BCB3017FE827505A5A9AAFD35BB64E9B367539FAD58242200004D044C0EE7098 - 9D2EF77D744AF86F7027169A2A035A462380DC776732395F154B84D7D06834FA - 68E389F8E71A8DA65B24145EA756EF393456FF636E40D6AF5F2F35986CEFF279 - BCF5140A85325601789E77F4E8B1DD0AB9F8A6A3478F6AF0EC13BCE194406D2D - 65C1CEC6EB982CE65F040241264E5D822D200004124C201A8D464E9D3CB52D2F - 2FEBD603070E18131C1EC20181A412A8AEAECE191CD4FD2B2F3F6F6152136138 - B8CBE56E643129D73636361AC66A63CC0D484D4D0DD56CB63F4DA3D31F820E71 - 64FC4343C35D741AEDFA8E8E43ED632D10CC0302E92450515121EFEEE97FABA8 - 68FA65140A859A4E2D901B0800016C1030994C7DA468E4BED5AB577E5D5B5B1B - C1866A500904FE4B40A5AA58E5F307DE93482439C0E4970482C1A09F4CA2BCCB - 62511EDF368E935EC7DC8020922AAA565D4F8E92DF812BEA475EA27687DD6CB7 - BB1E8E843C9FC26758F0D718AB04E6CE5FBC8ECD646E11894470F128568B08BA - 81408A0884C391A0D160788DCD963FD3DA0AC7D0A7083BA4491001E4E1BA4E67 - BA8FC5E63C47A7D318090A8BAB302E97CBC262B23609859C8FEAC67003FA8F30 - C6D580AC5851B5D4E5F67C969121CDC515DD0499415E436B75FAF7B3E49207EB - EBEB1D090A0B6180404A09949595F11D2EEF9F6499B29BE042A694A287644000 - 73040607874EB078BC1B8F1CDC7F0473E24130E109A854AA0CB727F89A542AB9 - 12DEFA8FBC1C2C66F3805028FC7D43C3CE7DE35930E36A404A4B574CB4584D75 - 858513E68E47049EE72267A0672865D7EEDBBDBB0BCF3EC11BBE092C5EBC649E - CBED7E2F2F2F771EBE9D823B200004C64AC0EDF6D886B59AE7332582D7DBDADA - BC638D03F38040BA08CC9F5F32D7EDF57E34A1207F76BA34A03DEFD0D0D077D9 - 59CAAB76EFDE36AEDFB5E36A40CACBCBC51E4FE83DB9427639994C1E572CB403 - 1FAB3E87D3A90F07031BDBDA5ABE1A6B0C980704D04060F6EC059BB2B2E5CF50 - A9541A1AF48006200004D045A0A7E7EC2E853C7B4373335CC08BAECA809A5808 - 209F5F9D3AD57D835024FCB34824CA88650E11C7D81DF62F4502EEC69D3B775A - C7E37F5C4D03725740944CBF9FC5643DC4E1C08584231502F91EB6BFAFFF8FA1 - 90F2F99E9EB15DD6329E02C35C2090280225252593F47ACB96C953262FA552A9 - B0213D5160210E10C001019BDDAE0FFA837F3872A4F54B1CD8010B042480DCFF - D1DDDDF7AA5C21BF051EB45D780178BCDE5AF5DEC6A7C7BB44C6D580FC77B38E - 656D281CDC2C168BE142C211AA81EC0339FADDF73BC4E2CC0D9D9D1DDAF1160C - E60381741150A95434A3C57E059FCB7B45229128D2A503F2020120802E02FFBD - F1DCF89948C4DDA456AB4DE852076A80406C0490E377CFF50E7D3C7162E18AD8 - 66106F94D3E9B2D0A8B48DFBF635FC63BCEEC7D58020C957AD5A37756878E8B3 - BCBCDCF9E31583D7F90303835D9170E8FA53A78EC371BC782D32417C55555571 - CF9CE9FBB068C6F4DF10C432D80402406014020683A12B18086C3C76AC635C9B - 52013410482781E5CB2F5DE6F5FB3E95882570B0D2050A31ACD5748905E22BD4 - EAC613E3ADD5B81B90CB2EBB4C643058378BC4A2DF8D570C5EE73B1C0E8BDBE5 - 7E6CD2A4FCF7EAEAEAC278F509BE0841803C6FDE82955112E58DAC2CC5244238 - 06934000085C9080CFE7739BCCE6D7E8D4682DDC780E0B05AB0490CFAFF47ACB - 5D642AF5492E872DC0AA8F64EA8E442261BBC3B98BC3A2DED2D4D4A41F6FAE71 - 37208800D58AAAA7386C76ED78C5E079BED160DCC2E532FEA056AB7D78F609DE - F04F60F6EC2A6E20A47B3A3727E72E3A9D0EE7A4E3BFE4E010088C48201A8D46 - CF7477B7664A85B71E3A74A813300101AC12A8AAAA92B9DCBECD3C1E7F1D5CAE - 3D7215FD7EBF271808BC281472FFB27DFB76CF786B9D900664E9F2CADF9049E4 - F7B81C0E748D17A8C8E0E0607B9642F9FBC6C6EDA7C75B34980F04D24D60E1C2 - B2F95EAF774B6E5E2E1CC19DEE62407E20902602C885640E97FB61119FF5915A - AD0EA54906A40502E326505ABA6C81DBEDFE4499A39C36EE60380DE0743A4D64 - 52F4A6E6E67DDB126131210D4865E5EA59468BF91FCA2C0514EE025571B95CE6 - 50307C675595EA1FB5B5B59144140F6200817411A8AEAE669EEB1BBE5B21976D - E272B9E274E980BC400008A48740381C0EF59CED6D50C8B26E6F6DDD33901E15 - 9015082486C0DCE2C51B8502DE0B1C0E979F9888F88BA2D7EBBA4442C9E54D4D - F5A712E12E210D087273A4D71B7C572416AF83A3CB462E0B724A88D56AFD80C5 - 943CD1D232BEB393135178880104C64B40A552E5F40D6ADF2D9A366DF57863C1 - 7C200004B045C062B60C44A3A4BBDBDB0F204F43A3D8520F6A81C0FF11A8AEAE - 16E88DD6571572F90DC0E5C2045C6EF7D72C06E5EAC6C64677223825A40141EE - 03219399F7B3D8CC47582C163711C2F018A3B7AFF75BB15072C3C183EA719F1E - 80473EE0097B0466CE9C77A540287843241266624F3D2806024060AC04060787 - 5F954A784FA8D56AD75863C03C20800602C8573C3ABDEEA3BCBCDC7968D08346 - 0DA15028188D905EB758949B3A3AB60413A131210D0822A4BC7CC5DA2829FA81 - 5028801F2217A88CD3E9B6DAAC96BB7EF8E1BBCF13513C880104D24D40A55289 - 2C16E71F6572D98D0C0683956E3D901F080081E41240369E6B34DA330C3AFDD6 - 23470E3627371B440702C925809C7E35A8D15D47A3D0FE2410C0EFD70BD17638 - 9C262683F1C092258B3F4DD436828435201515ABA718CD86BA1CA5727672970B - B6A30F0D0EBCCEE5B21E696B6BF362DB09A80702FF25806CDE73795CEFE72873 - E0EF3E2C0A208073023E9FCFA5D7195E1189382FB6B6B63A716E17ECE19C4065 - 65A5D0E9F4BD2E128BAE822D04172EF6E0E0D0890C69C635FBF6351C4BD49248 - 5803A252A958C108F913215F50932871788C73EE5CDF416576C60D4D4D4D67F0 - E80F3C118F007243BACE687D549995F50893C964138F00380602C42170B6E7DC - 818CEC8C5B5AF7EDEB228E6B708A57024B96AC986773D83FCCCDC9B904AF1EC7 - EB0BB9FFC36432D70905EC3B9B9A9ACCE38DF7E3FC443620341289F6089546DB - C4643239891288B73876BB431F0A86EE61B3A9FF84630BF1565DE2FA292E2D9D - 68D699B74C9B3A4545A15028C42501CE81007E09381D0EB3C7E37DA2B030770B - 5CAA8BDF3A13C9D9BC798B6E158945AFB0582CF8DD7A81C28742A180DDE17CAA - BDADF985441E3891B006844422912BAA5657BA1CAEAD52A95849A4051C8F57A4 - 9026B3E53D363373536BEB36787D1D0F3C188B6A020B1694DEC0E670FECAE3C1 - B1BCA82E14880302632010894422274F9EDA9197ABB8ABB5B5158EDD1D034398 - 822E02C81E469BCDFDB25C21BF163EBFBA706D9C4EA799C3665FDFD0B0736722 - 2B98C8068454565999671CD07D397152E12232999CD0D889349DEE58BDBD7D1D - 12B1E4FAD6D67D27D3AD05F203814411408EE3EE1FD47D346DEA946A32990C6F - 41120516E200011410B058AC43A1A0FF9E6FBF6DFF170AE4800420306E02E5E5 - CB2FB1D9ED9FE6E5E5CE1A77301C07181818FC2E2F57F1BB5DBB762574EB4042 - 9B04954AC5A3D198CF5269F43BA19BBCF06A74B9DD76B3C5BCE1E4F1A37FC7F1 - 9A056BC4234099356BEE4A0693F9965C2E9F403CFBE01808E09380DF1FF09A4C - C60F1572E9930D0D0D167CBA04574422505353431D1AD26FA033E8CFF0783C09 - 91BCC7E335180CFA6974DA87A448F091FAFA7A473C73471B9BD0060449B67CF9 - CAEB48E4E89B6C361B6E93BC007DE406D981C1C137043C566D7B7B7B420B3A5A - C1E1CF814032091417AFE50442C3CF656765DF050F2192491A620381D411E8EB - EB3F4663B16E3BDE71A83D7559211310481E01E481B9DF1FDE2C9648AE4D5E16 - EC47463EBF62B3D80F0B859C4FEBEAEA02897494F00664C58A950B6D36EB278A - ACACA989148AA758C839EA677BCF1D910825BF3F74A8B9134FDEC00B10985F52 - B230E80D6C552A738A8006100002D827D075FACCE367CF76FE99442245B0EF06 - 1C000112A9AA6ACD4CAD4EF7716E6E0E5C3E789105A1D71B7A4419D2EB9A76EF - 684BF4BA49780352515121F5FAC3EF8B84C2CB122D164FF16C36BBD1E7F53DF4 - DD77AB3E21916AE17FEA782A2EC1BD2047729BADCE7B32A4D24D6C365B40701C - 601F0860960072FCE6C0E0609B4820DA78F0A0FA04668D807020F01302C8D1F1 - 5E6FE846268BF53C1C9A72F1A561B3DBFF23127036EEDAB54B97E84594F006A4 - A4A686CD3058EEA550A98FC06758172F17F24D2D95A2BCB3ADAD0E2E254CF4CA - 86786925B070E9D209C661C387D3A74D55A555082407024060CC0490DB8F43C1 - E083B9B98A2F12FDF9C59845C14420304E02C881296E77E80DB14478398D4663 - 8C331C6EA747A3D188C7ED7E6EFFFEA6A7926132E10D08721CAF4A55B1D2E3F3 - BF9B2195E62543345E626AB4DAE37C2EEF860307F67E87174FE003082004900D - 7EA74E755F2314895E128984194005080001EC11F8EEFBEFFF9DA794DF7AF8F0 - E1845D3E863D0AA0186F04162D2A2B0F04431F66652926E3CD5B22FDD86C763D - 954EBDF380BAE99F898CFB63AC643420A4CACACABCDE7ECD0753A74CAE4C8668 - BCC4F47ABD0E97D3B589CB656C814B09F15255F0F123819292959261EDD9778A - A64FBF9C42A150810C100002D821603299FAEC2EE7835D278FFF1BF67E60A76E - A074740225254B1FE07039CF30994CF6E8A3893BE25C6FDF912CB9E4867DFB92 - 736544521A10E42DC8B26515CF7179BC47895BBAD19D239BD17F38717257AE52 - 765B5B5BDBF0E833600410C01681F9F317AFA3D2199BA512B89C145B9503B544 - 26809CD4683419DF9488F8B57BF6ECB113990578C71781AAAA2AD9D9DEC10FA7 - 4E99B2065FCE12EB261008784964D2BBA100F369B5FA3FB6C446FF6FB4643520 - A4A54B2B7F138D4636F3057C693284E325A6C9641E2293A2B7B5B7B7EEC28B27 - F001047E24505656C6B73B7C7F542864B730180C169001024000FD040607874E - 72D8AC0DEDEDAD2DE8570B0A81408C046A6B29254DFB2F0DFB03EF666466E4C7 - 388B90C390E3771974C69D1209BFAEAEAE2E9C0C08496B40CA2B2AA638CDB6AF - E028CED1CB36ACD13CBFFE7FD63C565B0BA7618D4E0B46608DC0C285E597787D - DE4F72737366634D3BE805024423E0F67A1DDA21CD2B5229FF85B6B636382085 - 680B00C77E91BB3F0C46FB9F1559F29B58F0F9D5452B3D3C34744CA1C8BEBAA1 - 61FBC9642D89A435202B57AE94D8EDBEB70442DEAF69341A3D5906F010776060 - E090449C715D73F337DD78F0031E80C04F0920471E1A4CB607B3148AC7994C26 - 07E8000120805E023D67CF7D2355486F6F53AB7BD0AB12940181F8095CB260C1 - 0C8FC3FBF1E449138BE39F4DAC19569BED1F4CBAEC26B5BACE952CE7496B408A - 8B8BE94C8E700383467D96C3E1089365000F711D0E87C1E976DD4F2347BEECE8 - E808E2C1137800023F25B068D1D2C906A3FEEDA953A7A860433AAC0D20804E02 - 3E9FCFE5727BEF3C7CA8F963742A045540606C046A6B6B29F5F57B6EE60BF8AF - C1E7C01767180C06035E9FEF591A25F27C320F484A5A0382D85B5E55556C37DB - 3F532814D3C6B66488310B396B596F307E2EE031EF56ABD549D9EC430C92E012 - C504C8B366CD59C7E30BDE158BC57214EB046940809004908DE73DDD3DBB0A0B - 73377EF3CD371A424200D3B825A052ADCDF0782CAF4AA492DFC243B08B9759AF - D79F1509851B9A9A1A9A48245234598B22A90D486565A5D0E78FBC2F10F0AF48 - 9601BCC41D1ED69CA1D3A8377EFBEDA156BC78021F40E0A7048A8B2B85FEA0F5 - F92C85FC463A9D0E973FC1F200022822A0D5E97A3D3EEF3DB38BA6EE4CD6A653 - 14D90529C422405EB66CA5CAE5B6BF2397CBA710CB7A7C6E9107E216AB793B8D - C2B9BDB535B90F2292DA8020DF7E87C3E4076974FA26B8157DF4575E16ABF9B1 - 8E23ED7F4D66C719DF5284D14020B1044A4A962CF4787D5BB3B3B3A693C9E4A4 - FEFF27B1CA211A10C02F81482412EE1FE87F831C0D3D7CEAD4A9007E9D823322 - 12A8A9A961188DD64D541AED412693C9252283583D8742A180C3E57A9A4527BF - AC56AB7DB1CE1BCBB8A4FF0050A92ACB1D4EF7C70A85AC702C02893207B913E4 - DCB93E759622EB56B5BA0136FF11A5F004F389FC4370B2B37B5398C57F210000 - 2000494441548E52F9288D4683B72004AB3FD84527818181C1EF32A4D2DBD4EA - 6FBE45A742500504C64E60E9D2A593355AE3962953A6A8C61E851833AD56EB30 - 97C3BF69CF9E9D0DC9769C820644A5F0FBC3EF0845A2B5140A85926C43588EEF - 743A8DC150E4A15555AA4FE0485E2C5712B45F8CC092254B8AF446EB0793264E - 5C0CA4800010482F01AFD7EBD268B5CF1516E4BC5A5F5FEF4FAF1AC80E04124B - A0A6A686DAD9D973BD40247C4124146624363AFEA2F9FCFE460E8B76CB8E1D3B - 0692ED2EE90D0872D96169A9EA511E9FFB243CF1BC783991B7204683F9D3CC4C - C1ADF00F41B2973EC44F1781A29A1A06AF5F731D83C9F8B34020807F10D25508 - C80B044824D2E9D35DFB32A4191B0E1F6E3903408000DE082CA9AECEF45B9D6F - 0A0582CB60EFE1C5AB8B9C82170E455E1608582F6CDFBEDD93ECB5908A068454 - 5555BDC2E5F67C261289B2926D08EBF1351A6D378D4AB90136A363BD92A0FF62 - 04907B82CE74F76D993E7DDAAF8114100002E921807C6EE10F061E1670595F26 - F3B8CDF4B883AC4080445ABEBC72A5D3EDD92CCBCC846D00A32C08BDDED0CB15 - F06F5EB1B4549D8AAF7052D28054575767FA02914F594C66156C3C1DB503F568 - B4DA171532C94B6AB53A6917C0C0FF988040BA09CC99B3F032068BF1668654AA - 4CB716C80F048846201289444C26D3FB2C99E491969D3BAD44F30F7E8940A096 - 327BCEF6177294390F10C1ED783DDA6CB66D540A6BC381030DDAF1C68A657E4A - 1A9092921A368D667A8046A73F08A7615DBC2CC81168FD03FD87E5998A9BF7ED - 6B38194B11610C10C02281E2CA4A61406FAA952BB236C0C55058AC2068C63201 - E46D3B9D46B9FDC891437BB0EC03B403810B1158B4684991DD61FFA4B07002DC - 7C1EC332B1D9ED8F2BB3329F4FD531DC29694010DF4B962C2F73BA5C5BB3B3B3 - 27C7C081D043BC5EAFC3E7F5DCDBD6D6F221A1418079DC13282F5F5EEC72BB3F - CECECE9A817BB3601008A08480CFEF776B87B56F4A24BC3FB6B6B63A51220B64 - 0081841150A9542CA7D3772B9BCB794AC0E74B121618A7812C66CB804824BC71 - F7EE1DC8E58329F92F650D884AA5CAF0FAC2EF48A512F8E63B86D21A8C864F29 - 7CCEBD879B9ACC310C872140009304FEF758DE93DD9B1459F207592C169CCF8E - C92A8268AC1118E81F3894992983B7EC582B1CE88D994045C53A7928E4F990C3 - E554C3A7FFA363F3FA7C0D2C06F7E6FAFA7F0F8D3E3A312352D680207217952C - 7D442A11FF3931D2F11D45ABD39E613198B7B7B555EC23916A23F8760BEE884C - 60E9D24B276B74C3EF4E9E346919994C86A3BA89BC18C07BD209783C1E7B2812 - 7A92468E6E868DE749C70D09D24460C58A4B6BFCC1D05B428120334D12309316 - 39FD2A1A89FC99C763BD9A8AD3AF7E0493D20664C58AAAA56E8FE733A9549A8B - 99CAA449A8DFEFF76A75DAF7F95CD6E3EDEDED8E34C980B44020250466CC9873 - BD4C2E7B8BCD66C35B90941087244424806C3CEFECEA6A5016E46C3CB8776F3F - 11198067FC13A8A8582F75BA4D7F158B44D750A9142AFE1D8FCFA1D96C1EE20A - 0457EF6DDCD53CBE48F1CD4E6903B27AF56A85DB13788FC562ADA252A9B4F8A4 - 126FF4D0F0702787C5BFE5D0A17DADC4730F8E894440A55229FAFA87B7141515 - AD25926FF00A045249C06EB3EBCC36DBFDB38A267F99AA8DA6A9F407B9800072 - F75C59D98A55FE80F74D994C0647EFC6B024EC0EC72E7294734D4B4B6A4FC34B - 6903525D5DCD74B97C77D3E8F427E034ACD1574528140A6875BAE71834D2F31D - 1D1DC1D167C00820804D02C86DB567FB862E2545A2AF2B147238A8029B6504D5 - 2826100A858236BBFD13068DF4604B4B0B1CBB8BE25A81B4B113282E5ECB0984 - 86FF929B937BC7D8A3106726F23BD3E3F5FEC5EBB63F93EADF99296D4090922E - 5B56B1C0E6707CA2CCCE9E469C128FCD2972337AFF407F7B8624F3C6E6E63D9D - 638B02B380003608204DC8F11367FE34B1B0E0216C28069540003B04907D850C - 16E7A6F656750B7654835220101F81254B2A669B2DE68F0A0AF2E7C6379398A3 - 0D06E359A158B4B1A97117721C7734951452DE802C5A542D08856DEFC8E5B2DF - A5D228567379BC5EA7DBE97CA2A020E74D78658ED52A82EE58092C5C5836DFE3 - F57E9897973B2BD639300E0800818B13080402DEBEFEFEBFE464CB9E57ABD53E - E00504F04800397A37188CDE4B63301EE17238023C7A4CA4A748241276B89CFF - 14F139F7ECDAB54B97C8D8B1C44A7903823CE5B4589C370743C1E7793C9E2816 - 91441FD3D9D9B5274B21B9F9E0C183B06990E88B01E7FE91CF340706F47F90C9 - 331E87CF34715E6CB0971202FF7D933E7848C8E7DFD6D6D6FC434A9242122090 - 06022A55D53483C9F859417E1E5C3C18037FE4C10495427DB0A161C75B310C4F - F8909437208883A54B2BE7DA1DF64F95CA6CB87C2C8692DAED3683CF1BB89744 - 0AD4A5FA1BBD18E4C11020905002C886F4C161FD6753A74CA948686008060408 - 48C0E5725902C1D02341BFEB23F8F783800B804096172D2ABB872F10FC99C160 - B008647BCC56B53A5DB74424BAA9A9A9E1C098838C63625A1A9075EBD6F1757A - D3AB62B1E47A2A950A47A48D52C070281274BB9D5F53388CFB9A1B1B07C7516F - 980A043040A096327BF68E2BD91CD64B52A9341B0382412210402D81E33F9CDC - 91ABCCDBD0D6B67718B522411810182781AAAAAA09BE40E46D1E97BB729CA108 - 313D1C0E87AC164B9D58CCBFB3A1A1C1920ED369694010A3AA8A55BF0D05026F - 0804FC8C7418C75A4EBBDDAE7739DD7F3876ECC89758D30E7A8140BC04CACBD7 - 887D01CB4B5289141E52C40B0FC60381FF4FC060340EFA3CBE074F9CF8AE8E44 - 22C185B6B032704900F974D76A75DD48A5D19E160AE1E2C1588A6CB3D9F40C3A - F3E1CC4CE1DFEAEAEA02B1CC49F498B435202BAAAB275242A4F7190C862AD1A6 - F01A4F33ACD9CA6452EE818B09F15A61F0F55302F3E695ACA431A85B32A4D23C - 20030480407C0490279C8343836FC365B6F17183D1D823A052AD2A0847026FF1 - F9FCD5D8539F1EC51E8FAF894C22DFB16FDFEEAEF4282091D2D680AC5DBB96E3 - 74FA1F225348F7C166D3D8CAAFD7EB7B6954EA6DEDEDADDFC43603460101EC12 - A8AAAAE2EA0D9627A552E9ED2C168B875D27A01C08A49E804EA73BCD66B16E6D - 6DDD9F96EFBB53EF1832129400B9B272E5EFBC3EFFCB42A1504E500671D98E44 - 22119FD7FF27B5BAF189B826267870DA1A10E4B6CAE5CB2F2DB5D91D5BB3B214 - 70F1580C85452E9232194D1F0904EC87D46AB52D8629300408609A4049896A92 - DEA0DB326DDAD4E5983602E281400A0978BD5EA7C1687C559995F9426363A33B - 85A9211510482981152B56283DDEC0CB4291F8D7540A05F614C740DF62360F88 - 44C25B77EFDED910C3F0A40D4967034252A95422B737F8466646C635497388B3 - C02693A90F79AAB57F7F13BC05C1596DC1CEC804E6CE5D789358227E9DC56271 - 8011100002A31338D5797A6F965C72475B5BDBE9D147C30820805502B594B2B2 - BD35C150E4A58C0C690E565DA452F77FEFFE706F67093977EEDDB123AD0753A4 - B50141A0575655DF180C865E814B63625B82C877BD1AADEE6D219FF5544B4B8B - 35B659300A086097C092252BB334BA81F7274D9C5845A55269D87502CA8140F2 - 09B8DD6EABD3E17AF8BBEF0EBD9FEA9B8D93EF0E320081FF23B0644975A6CFEF - 78552A95FC9642A15080CDE8045C2EB79546A73ECCA4533EA9AFAFF78F3E2379 - 23D2DE805455AD99A9D5EB3ECBCDC9B9247936F115797858738646A5DCD5D1D1 - 8EBC0589E2CB1DB80102BF243067CEC235541AF575B95C56087C800010189900 - F280AAE7ECD9865C65C106B5BA7E08380101BC1250A954343299B9C6E571BD9A - 99915180579F89F6353030785C22965CD3DCBC27ED9792A6BD01A9AEAE16F87C - 91A72854F2462693C94E346CBCC61BD668DFE1B0A8F7B5B5B579F1EA117C0181 - 1F09141515314814FA4B79B979B753E03B5F58184060440266B345E30BF8EF3C - F6DDE1AF001110C033818A8A0AB9CB1D785520E05F4EA7D31978F69A286FD168 - 34120947DE1608D8F7A5EBE8DD9F7A497B03826C462F2957AD2145A2EF8BC522 - 38C120C69566349ACEB2B89C9B0EECFB667F8C53601810C03481C58BCB1779BC - BEF773729433316D04C4038124100804023EAD46F7BE48C479B4B5B5D5998414 - 101208A0864059D9F2CB43E1E0EB52A954891A51281762B55A87396CCE034B96 - 2CFE476D6D6DDAEF0542430342423AD94090F4019FCF5B83F2FAA1465E3018F4 - E9F5C62D5C8EE4E9B6B6F4DC62891A1820841004542A15CB68B63FA890CB1F61 - 3299B0219D10550793B1108846A351AD56F30397C3BDB3B5757F0B7C9A1B0B35 - 188355021515EBA57697E1655946C67558F5906ADDC8FF237C7E7F239B49BD6D - D7AE5DFDA9CE3F523E543420C8B77CE130F53E0A9DFA1897CD16A0010C163468 - 75DAB3340A63C391232D7BB0A017340281F112983FBF6CAAD566FD60EAD4C965 - E38D05F381005E088442A18056A3FBE3B469857FACABAB0BE3C517F80002E713 - 407E2F46C8F4D53E8FF7F58C0C693E108A8D4030180CB85DDE270E1EDCF7225A - 1E50A0A20141F0AD5AB56EF69066686B6E4ECE5C32998C1A5DB195367DA3743A - C36B023EF371B55AED4A9F0AC80C045243A0B8B8981E89D07ECBE230FF221689 - 15A9C90A598000BA09747575B70AA4FC5B8FB6B79F42B752500704C64700B9F7 - C3ED0EBC281409AFA0D168F4F14523CEEC81FEC1137CB1E8A6B6037B0FA3C535 - 6A7EE823B71E4722D45A2A8DF6072A95028B2AC61562301A7A781CEE2D6AF51E - 758C53601810C03401E4FEA09E9EBECDB32FB9E477983602E281400208381C0E - A3CD6A7B84C9A47CDAD1D1114C4048080104D04A805CB674794D24147E552C16 - 67A15524DA7421FBC3FC3EFF7B9188FF3134ED0F434D0382146CD9B2AAB581A0 - EF5D5858B12F5FE47674ABD5FA3193217EA8A56527DC0B123B3A188961020B17 - 96AEA1D068EF4AC462D88088E13A82F4F11338DDD9F54F8522EF8E83071B0DE3 - 8F061180007A09945556E6855CFE97C562D165701A62EC75329B2D83741AE3F6 - CACA25BBD0B0F9FC47E5A86A40904B658241F7BB4291601D954AA5C68E97D823 - CD66F390DF17BCF3FBEFABB79348E93FD980D8D500F7A920A052A97866B3E359 - 995C761B1CDF9D0AE290038D044C26533F854CBAFBD0A1D66D68D4079A8040A2 - 08D4D4D450070775B7D0E8F46705027E46A2E212218EC3EEF8078DC6BB43ADDE - 6E42935F5435203535350CBDD152130A86FE2A12C191BCB12E9470381C361A4D - 7FA7F2590F1C51AB75B1CE83714000CB04E6CF2F99EBF17AB71614E4C325A658 - 2E24681F1301BFDFEFD168346F09F8CAE7DADBEB1D630A029380004608AC5AB5 - AAC0E78FBCCDE1B0576144322A64BADC6E2B93CE78E89B6F76BD8F0A413F1181 - AA0604D15555B57642201C789BC362AD441B2C34EBB15AAD9A7028B2293F3FEB - 73380505CD95026D8922809C866234DA1F5564C91F623299DC44C5853840000B - 040687868E72589CDFB7B71F388E05BDA011088C9540757535D366736FA03318 - 4FF1785CF158E3106D5E2412090743A1567294B261CF9E9D9D68F38FBA060401 - B47469E5631C2EFB69F8C62FBEE5D2D5DDB55B9199735B6BEB9E81F866C26820 - 804D02E5E5158506937EEBC4C2C225707A1E366B08AAE327E0F6781D56B3E905 - 8944F017B55A1D8A3F02CC0002D821B074E9D2E946A3ED93098513E6634775FA - 95FA7C3E5730147A91CDA4FEB5B1B1D19D7E453F5780CA06A44CA59AEFB2BA3F - 55E6644F431B3034EBB1DB1D268FDBFD884221FDACBEBEDE8F66ADA00D082482 - 00F25D704F4FEF551C2EFF65A15000DF0527022AC440358148241239D3DDDD24 - CF54DCDDD6A63E8D6AB1200E082480C09225CB1F65B1D94FD2E9746602C21126 - 844EA7EB14098537EFDDDB78108DA651D9805456560AA351FAD3640AE9560683 - C1462338B46AEAEA3AB33F332373E3A143CDA87BDD865666A00BDB0416565448 - B53D7D5B8AA64F470EAFA061DB0DA807021727803C6872395DF71E3B76E43360 - 0504704E80ACBAF4D24B8C5AD396FCFCBC0538F79A507BE170384421533E2491 - 8277A3F581342A1B10A40AE5AA8A55D16068AB502482CBC6E25896C8A273793C - 9B5A9BF7BE14C734180A04304D60EE82920A2A89BC4526CB2CC4B411100F042E - 4220180CFA2D56DBDFF85CC6836AB51A5527DA40E18040A2095457570B3C9ED0 - 23640AF94E0E87CD4F747C3CC7339BADC34C06E3A1152BCAFF8EA6A3777FCA1C - B50DC8CA952B252EB7EF6DA150F41B3C2F9264781B181C38CC66B2EF3C72A4AA - 038EE54D0661888936022A958AA5D59B1FCD512A1F806379D1561DD09328021A - ADB693CFE5DE5551B16C1F5A7F5424CA2BC401022525AA5581A07FB35C2E9B00 - 346227807CA6E97038B7B3989C3FECDDBBAB3FF699A91D89DA06A4B6B696D2DA - 7AE82AAFCFFF578140204B2D166C67438E67341A4C5BE874516D47C71E3BB6DD - 807A20101B81D2D21513CD66C3A785130B17C386F4D898C128EC10404EB4D16A - 742FE6E5299EDDBE7DBB073BCA412910889F40696995CCE3B33F2F97655E0B9F - D6C6C7CFEFF7BB23E1C87DFBF6356E896F666A47A3B60141305454AC290C8503 - EFB0D9AC0A0A8542492D1A6C67D368B4DD540AF9CE8E8EF6466C3B01F5402036 - 02C8B1BC168BF36AA150F057FEFF63EFCCC3E3A8AEBC5D7B5557EF6AB576CB3B - 60B363839125DB2DCB961160208B934C26996408614920EC841D11C2BE853D90 - 000993C9903109134830922CA9B16C0B1B448080C1066CC9DA5BBDAFB5D79782 - F00C5F2660A9D552D772F43CFECBF79EF33BEFB96AF5A9BAF75C97CB37B95930 - 0A081883C081FD07767BBD25E7EDDC197CD3188A412510C88F80F6007ADBB657 - BF92CDA6EF29F1F96AF3B362DD59922CF7208AFA83F6F63FBFA3670ABA2E40B4 - 8B0947464297B3767B2B4992949E41EA4D9B7639E17868FC198FCB7E6D102E27 - D45B7A40CF0C1158D9DC5C36F261FFCF972E59F2A51972016681C0AC13C86432 - B1442A75BDC7697B2A180C72B32E001C02815924B076EDA973393E7BAFC7E3FE - CA2CBA35852BAD453786A83F2349F42E3DB6DEFD2C645D17209AD0B56B379C14 - 8D457E555555BDC414AB63168348241263A2205E3F776ED5AFE072C259040FAE - 8A46407B72F6D24B5BCF4471F4415F49494DD1848063205040021F7CF8515B65 - 79D5F7B76D6B1F2CA0593005047447403BCF97CE8AE7D868AA15DE644F3D3D83 - 43436F9596979FD7DDFED2AEA9CF9EDD19BA2F4002818003C1A8EB081CBF185A - F24E7D71BCBF77DF369FB7E407AFBDB6E3DDA9CF861940C0780456ACD03AA78C - DF565555751E4E405B5EE36510147F96403812195465E5DA79F3AAFF0B1E24C1 - DA303B814060FDF2B189D0A3F36A6B4F80CBA8A79EED6C267B27CF7B6EEEEDDD - 9C9BFAECD99DA1FB0244C3D1D474CA8991A8F616A46AE9ECE231BE378EE3B283 - 4343F796786AEFD9B56B4BD2F811410440E0D0044E3E79557D8EE77E595D0597 - 991E9A168CD02B01ADADFAC8E8D8530ED6774D6F6F5B54AF3A411710280401ED - 62D97DFB0EDC5D5D537D6921EC59CDC6F8F8F887255ECFF91D1D2F771A217643 - 14202D2D2D342FAAB733340D8B328F55353E3EBE8FB5D97ED0D3D36D88459947 - 88300508FC7F04366EDCC81E383078A5BFACEC729B0DFAC7C3F23026818989F0 - 7E1C23CF7BF5D5E056634600AA81C0E408684D44D26971BD248B0F5455552E9E - DC2C18F529015114390CC39E9444F2A6CECEE72346206388024403595FDF78AA - 24CB4FF87CDE6A2380D59BC6D191D15F3A1CF4B53D3D3D137AD3067A80C04C10 - 38F1C48605E3E3638F1D75F491CD33611F6C02819924A05D3A381E0A3D58E271 - FC24180CA667D217D80602C526B07A75F31C41C8DDEF72BB361204014D87A698 - 90482C3AC8D2F405DDDD5BFF3CC5A9451B6E980224B07163A9184D3E6A7738CE - 2208822C1A31833A8E44A3A31C97FB3181A9CFF6F5F589060D03640381A91040 - 8F3966F9B7DD1ED7CF9C4EA7772A13612C10283681BD7BF7EDF47ABCE7BDFEFA - 4E5DB7D22C3627F06F0E022B57AEF91163636E6318C66E8E8866378A6824FAAC - CB653B47EF9DAF3E4BC5300588B63770229AD8C865730F9540779BBC56F647FB - 3FDA5E55E13FBFBBBB1B0EA4E7451026198DC0AA551B2A8787FB1F5D7CD861A7 - E138060F2E8C96408BEACDE5B8542299BCF68DD77B1FB6280208DB3A04D0FAFA - C0B24834FAF0FCF9F34E824B64A79EF84824324C12E455DBD7AD7916696D55A6 - 6EA138330C5380687802818DA582947CCCED727F0516E9D4178C2C29E2F0E8E8 - DDF66AFF9DBBB6C081F4A9138419462470C209751B480AFFA5CFE783B6BC464C - A0C534ABAAAA7CB47F7F576D4DC5F7B66EDD7AD062E143B81623505757674B67 - C53BE7D4545F64B1D00B12AEA22872229E7CDEE1A02EEEE8E8182988D1593262 - A80244EBF11FECD9B989CF71F77BBDDECA5962641A37AAAAAAE3E3A10F591B73 - D9F67581978C54299B260910C8AC13686E6EB68F8F476FF197F92FA0288A9975 - 01E010084C814034123D8820E89573E694FF1EDAEE4E011C0C351C01EDE0B924 - A92D395E7CB0BCCC3FCF7001E8407032999C2070E2B240A0FEB7AD067AFBA1A1 - 335401F2C95B9040458E131FF67A4BCE821ED1F9ADFE6824B299A2B0CBB76DDB - 06975AE5871066198CC08927AE3C319DC9FC7CDEBCB9C7C3DB538325CF427225 - 491243E3A1A73D1EFB8F83C160DC42A143A81624D0D0D4741822CAF7B036FB29 - 70B677EA0B407BFB91CDE6FE4C91CC455BB7FEC9706F4B0D57806845D39A35EB - BF2129D2036E97CB3FF594C18C743A1D1525F92644F13F6984CB6A20634060FA - 045AB1238E78FEAA39B5D5379324091D56A60F142CCC0081E1A1E1F7298A3AEF - B5D7766E9B01F3601208E88A407DFD9A6B1C4EE74F701C2E8CCD273189787C8C - A699AB1289B0219B0B19B10041D69E7E7AB590C83E6CB7B3A7C3C2CD67D922C8 - D0D0F05FDD2EE7453D3DDDAFE46701660101631158BD7AFDE291B1919F1FB678 - D15A632907B55620A0BDFD181E1EBE8BA1E7DCD6D7F762D60A31438CD624A035 - 151A1909AD4DA6D2F7CD9953739435294C3FEA4824FC7B3B4B5FDCD5D5353C7D - 6BB36FC1900588B66F5051882FF3A2709FAF04EE05C977D98C8E8E3EE576B1DA - ABFE70BE36601E10300A8165CB9691B28C6FB2D9E87BBC25257086CC2889B380 - 4EED7CDEC0C0C1D7CBCBCABFDFDDDDF696054286102D4C40EB4E28CAB9874ABC - DEAF5818C3B4424FA5D21102C7AFEAEE6E7F6A5A868A38D9900588C64B3B0B92 - C98A0FF8FDA55F2B223F43BB8EC562A39228DD346F5EF5AF376FDE2C183A1810 - 0F042641E098E6667BF89D0F1E3FEEF863FE7512C3610810981502894422CCE5 - B81BCBCABC4F6DD9B2859F15A7E004081481404B4B0B1D8D66CE676CD4CD76BB - DD5D0409867729CBB2C4F17C3BCE103FEADAB2E523A30664D8024403BE66CDFA - 7F9164E901B71BCE82E4BB0007060EBEE62F2DFD4130D8F17ABE36601E103012 - 81E5CB4F6E4131FC11BFBF74BE91748356F31278E7DD775FA85C38F7DC5D9D9D - E3E68D122203028876E7C78A682CFAC8BC79F3A021489E0B221E8F87688ABE86 - 61F0FF34F2030B4317208196961A29CB3F6467ECA7E1045C3296CF5A96244918 - 1D1B7DC2467B5B77EFEE8CE46303E6000123110804028E7034716D7959F9C534 - 4DB346D20E5ACD47201E4F8C0A3C7FF9EBAFF7FE97F9A2838880C0FF1258B5AA - C5CFF1F1BB7DBED26F4117D3FC57463A95DE8230F80FB7B5B71FC8DF4AF1671A - BB00F9B88734F6255112EEF7F97CD5C5C7694C05E1706458E085EB162F9EFB1B - E83B6FCC1C82EAA91138F1C486059148F8E923961CBE7A6A33613410281C0151 - 14F9F044F8576E77F9F5C1E08B7016AF7068C192CE08685BAFC2E1C4D90445DE - E8F5782A7426CF3072128964C8CEB2AD6E37FB84D1BFAF19BA00D1564C535353 - 793A233C5252E2FD32F4F7CFFF77A8BFBF7F47A9CF7FC1B66D5BFF9ABF159809 - 048C4140EBC2B27F60E4DF599ABEC3E972FA8CA11A549A8DC0E0E0D07B24819F - F7C61BBB7BCC161BC403043E4B60457DE0E47422F1F8DCB9B5C70099FC08288A - A2E438EE6586B25DDCD6F6C287F959D1CF2CC31720486B2BD6B075DBD76559BA - D75B02B7A3E7BBB47841C8C5A2D1A74B7DEE9BDBDBDB43F9DA817940C0280456 - AD5A55797078F4D125872F3903C330CC28BA41A73908F03C9F191C1A7CC86967 - 6EE9EBEB83B6BBE6482B44F14F082C5B162895A4F45DE515E5DF820B07F35F22 - A9542AC2D898AB453EFBAB603028E56F491F338D5F807CDC11EBD40A5EC83CE4 - 76BBBE04FB0AF35F588944622297CD5D8FA2D2D37D7D7D62FE96602610300681 - 152B567D85A488C75C70A9A931126612955ADBDDFE8183BD2E87F3825DBB7ADE - 364958100610F83F04EAEA36D95034740E8A63D7BB5DAE3240941F0159D66E3D - CFBE6C63D88BDADB5F34F4D98F4F0998A200D16E476F6A3AE5EBBCC03F085F24 - F25BDC9FCEDA7FE0C02EAFDBFDA3DEDE9EDDD3B304B38180FE090402014F2C9E - B9D3EF2FFD378AA218FD2B06856620208A2297C9652E6B6E6A7CBCB5B5553143 - 4C100310F8670456AE5CBD3A93CD3E5A5555B514B6C9E7BF4662F1D81845D357 - 95F93CBF33CBB50966294090F5EBD757A5B3C2434E876323BCE2CB7F916B8722 - 1389E4EF589BF3BA6070CB50FE9660261030028156ECA495ED2BB229EEB1DADA - 39C71A413168343601AD87FFDEBDFBB6CE9B5B75413018EC377634A01E087C3E - 81BABAB5D59C90B9ADCCEFFF268EE304B0CA9F4034127DD6ED662F6B6B6B1BCD - DF8ABE669AA600D16E471715F40C49101FF0F97C35FAC26C2C358220708978EA - F2D74E5BF773049ECE192B79A0362F02C71CB7BCB5AAB2F27AD8C299173E9834 - 0502D15874309DCC5C515AEAFA8319F6714F2174186A21029B366DA24646423F - C470E27AA7D35162A1D00B1E6A2291182769EA926067FBB305375E4483A62940 - 348681C0C6D26C2E725F69A9FFDB45646A78D7DAFEE4A1C1A137DD6ED765DBB7 - 075F411044357C50100010F8020275758123C291895F2C5EBCA8014001819924 - 30361EBABFBAB2F4FA175F7C110E9ECF2468B05D54020D0D81403AA36DBDAA5C - 5254210677AEDDD5168F277EEFF5D82F37D3DB0F2D2DA62A40B4801A1BD79D96 - C9728F9496FAE61A7CDD155D7E281C7EC661232F0F0683D09FBEE8D900013349 - 60D9B265A42063FFEAB4B3777A3C1E38283993B02D6A5B6BA1D97FA0BFCFEBF7 - 5FD8DBD30567EC2CBA0EAC10F6EAD5CDF305217BA7D3E53A932449CA0A31CF54 - 8CE3A1503F4D3217EEDCD9FDE799F2512CBBA62B40D6AD5BE75614FC0614437F - 40D3B4AD5860CDE037954A477941F829CBE0BF0806836933C404310081CF2350 - 5F5FEF1C1E9DB112CC6A00002000494441547866E9922567012520506802994C - 269E4EA5AE733A6D4F058341AED0F6C11E10D00B81FA558DD7D859C7CD048191 - 7AD164541DBC203C904D3BAEE9EDDD9C336A0C9FA7DB74058816684343E3B244 - 32F9F49C3935479B2D61B31DCFD8E8E85EBBDDFEE39E9EEE3FCEB66FF0070466 - 9900BA7CF9C91B510CFD99DF5F367F967D833B9313F8E0C38FDAAA2BE79C03CD - 3D4C9E680B87A79DC51564F4B44C3A7D477555D511164631EDD03FDE0A3F3CFC - 765945E9459D6D6DDBCDB815DE940588F64B20CBF83504895F69B3D99CD35E09 - 1637F0E1071F755454945CBC6DDBB6F72C8E02C2373901ED2D4822C9DD5A5D5D - 7901746D3179B26731BC582C3EAAC8F275B5B595CF6CDEBC599E45D7E00A08CC - 1A81952B03C74522A147172E5A5C376B4E4DEA486B0624F0FC1D0C43DCD3DEDE - 9E316398A62C40B444AD5B77EAD128863C4410C42A1445E196E369AC5EAD67FD - E8D8F8531E97EDFAEDDBB7C7A6610AA60201DD1338B1AE6EA5C0494FC2133CDD - A7CA1002655996272626FEC3EB715CDDD9D9396E08D12012084C914073737359 - 2492FC69A9DFFF5D1C87AD5753C4F77F86CB8AD2AB48F28F3A3A5E7A7DBAB6F4 - 3ADFB40588D6026E74347C3E4991B7D86C36975E1360145DF1446282E3B23770 - D9B94FEFD9B359308A6ED00904A64A60D9B28D6C263370657945F9A5763BEB9E - EA7C180F043E4B606C6CF4239A622FECED0DBE0C64808019090402014614D50B - 301CBFCEE974FACC18E36CC6944AA523088ADCE571B10F9BB95B9E690B106DB1 - 689713729CFC0BA7CB79EA6C2E1E33FAD2F6230E8F8CECB13B9D97F7F674B79B - 713FA219F30631E54740EBE2323636FCE4A2C58B1AF3B300B3800082F03C9F99 - 088DFFDC565DF1935D5BB624810910302381152BEA1B731CFF504D4DF591668C - 6FB663CA64B22FE218716957D7968F66DBF76CFA337501A29D054110FCAC1C27 - DCEFF395C0E584055859C974EA4F988A5DB56DDB56380F52009E6042BF04962F - AF3BDB6E77DC6F77B0F00655BF69D2B5B2FE0307769496965DB06DDBD6BFEA5A - 28880302791258B932701482217738ECF6668220A0EB559E1C3F9DA6751FA518 - F2B2CEF6977F3D4D53BA9F6EEA0244A37FDA69A7792391E4FDDE12EFB7E12CC8 - F4D723CFF3D97024F6CB72BFFBD6F6F6F6D0F42D820520A04F022B5736970D0D - EF7F72E9D225A7621806E7C8F49926DDAA9265598AC4E297BCBE6BFB23BA1509 - C280C03408343434785329EEE6EA9AEA8BA66106A6FE9D80288A7C3C967C9E61 - EC97F5F4B48D9A1D8CE90B102D81F5F56B5B3821F7707959D902B3277436E2CB - 66B3896C2E7BF5EE5777FC7C36FC810F20501C02ADD8F1C7FF69038A130F5694 - 972F2A8E06F06A44025AF1B1F7830F3A6BABCB2FD8B66DDB0123C6009A81C017 - 11D0CE7DA452DCB904455EED2B29A9045AD327109A087D4811CC25D5D5A52F5B - A15B9E450A90339C2499B90EC3890B1986B14F7F998085FE81836F3858DB9573 - E756BF62855F14C8B8350968CD2CDEDFB7FF27E56565175314C5589302443D55 - 02B1586C98E784CB5C2EE60FC160509AEA7C180F04F44C60D3A64DF8F058F894 - 5C367B7F6545C5623D6B358A36EDED07A22A8F10047AF3168B9C17B34401A22D - C0C6C60DC7862361ED72C2E38DB220F5AC535114259BC976A82A72594F4FE71E - 3D6B056D40603A04962FAF3F3C168B3C7ED8E187414BEFE980B4D0DC5068E289 - CA0ADFA566EE6063A17442A8FF40A0B1B1F14859C5EF656DB6F5B03DB530CBA3 - 7F60E02DB7B7E4DCDE9EAEDD85B1A87F2B962940FE7E39E16504895F0F971316 - 6661CA92228642E38F3B1CDEDBACB05FB130D4C08AD1082C5BB68C5431FABB0E - D67697C3E1F0184D3FE89D5D02830787F6300CF583D75EEBDD06DD0267973D78 - 9B79024D4D4DE5F144E6568FC7F34D9AA66D33EFD1FC1E32996C3C97CDDE86E3 - CAC3BDBDBD39F347FC4984962940B4609B9B9BE773BCFC08CBB21BA06A2FCC12 - 4F2492139228DE9A4A553E06F78314862958D11F01ED92ADFDFB877EB5F8B045 - 1BA09985FEF2A31745DA368A8183076FF7799D7759E98B845EF8838E9925505F - 7F8653C5521790387EADDD6E873B920A805B55552593CD6DC168EC92605BDB87 - 0530691813962A40B47D8B1313894DA2C8DFEFF6782A0C93259D0B1D1D1BDB67 - B7D92E8F56FADBF76C864B0A759E2E9097178156EC9863FE743AC5900F96F9CB - E6E6650226999EC08181819D15FE8AB3BBBB5FDE6BFA602140CB11A85FDDF475 - 91CBDD59EAF7C3676081B21F0E47062986BABCB2CCF707AB9DA7B55401A2AD97 - 0D1B3694C4E3E97BDD1ECF370982A00AB4862C6D46EBF8F2D1FE03BBDC5ECFD5 - 7DBB766CB7340C08DEB404EAEBEB9DF178F6B69A39D5E7E3384E983650082C2F - 02B1583CC4E572D7F2FCDCFF80B7C1792184493A25F0F1A1F3E1F1FA582C7EF7 - FC05F34FD2A94CC3C99225591A0B859E74DAA96BB66FDF1E335C00D3146CB902 - 44E3D5D87CEA8AE8F8F8E3D53535C74E931F4CFF3B014551E46834F63CA26257 - EDDE0D6D2761619893C0F2E527D70B82F48B9A39D54BCC192144952F81B7DEFE - EB1F16CCAB3EBFA7A767225F1B300F08E891407D7DE3911886DE6577D84F81ED - EB85CBD0D0F0F07B1E97EBFC6DDBBAB4F36296FBB16401D2D2D242C712A94B6C - 0CAB1D4877582EEB331430C77199582CF674A9CF7D7B4747C7C80CB901B340A0 - 6804EAEAEA6CC934774599BFEC4A9B8D71164D0838D61581682C3A188BC42FDF - BBF7AF9B75250CC40081691258B56A43652A1DBBA1ACCC7F0EDC743E4D989F99 - AEDDA7260AC29D2525AE07ACDA2DCF920588B606D6AD5B57CB0BC8630E077B0A - 1C2A2DDC2F95760833934E5F87A29E2776EC78215538CB600908E883405D20B0 - 686224F4E4618B17AFD6872250514C028220E4E2B1C42F1D0EEAC66030182FA6 - 16F00D040A4940BB6C3097532EA168E24AA7D3595248DB56B6F5C9C1F3EC1686 - C22E6A6F6FB7EC45A5962D40B43D8DE170ECF4543A7B5F59991F6E482FD0A781 - AAAA6A2834714045D19F2E9C57FD8CD50E5515082398D13101EDB3E3FD0FFACF - F6381DB73B5D2E9F8EA582B45920303838F40EEB64BEBF6BC78E5767C11DB800 - 02B342407BDB2BCBD837550CB9D1EF2BAD9D15A71671321E9AE877DA6DD70402 - ABFEBBB5B555B148D8FF274CCB16207F7F0BE25651E2460CC57E4892246DD545 - 3013711F1C1C7AD3EB765D81E3EA2B7013F04C10069BC524505FBFBEEAE050FF - C3472E3DE20C0CC3F0626A01DFC5232008023770F0E0BD2E0773735F5F9F583C - 25E01908148E80F690656068B42597CDDD39A7A66669E12C8325EDFE3459161E - C171E496B6B6B6A8958958BA00D112BF7AF5BAE3A3B1E8D3B5B573E0407A017F - 13144555B85CAE134190AB82C18E370B681A4C01013D10404F3CB1FE4B38893F - 58E2F556EB411068985D02DA368AFEFE811D2E9FEBFC5D3D3D7B66D73B780302 - 334760D5DAB52710087917C3D08DB045BDB09C474646DFF597FACEEBE8D8B2A3 - B0968D67CDF2058876203D91C85C4852F40D763B0B17EB14700D6B4F0753C9E4 - B3A483B9657B67E7FE029A065340A0E804D6AD5BE70E8562B79595979D4D5114 - 53744120605609643299B8C00B570B42E62978FB31ABE8C1D90C1258BD7ADD12 - 51166EB6B3F68DF0B95658D0A9542AAAC8F23D563E78FE59A2962F4034181FDF - 90CEC90FB176B6055ACC15F6172E97CBA5C2E1E89336BFFBA7BB3B3B2385B50E - D6804071099C7452FDF22C977BAA76CE9CA38BAB04BCCF2601EDEDC7BB7BDEEB - A8A99AFF6F3B77B68766D337F80202334560FDFAF555E168E27A7F2974BC9A09 - C6F178E28F0CCD5EDCD5F5D2C04CD8379A4D28403ECE582B5657B7B53993E5EE - AFA9A93EC26849D4BB5EADEA1778FE7604713DB16BD796A4DEF5823E20305902 - CB962D233941B9BAA2BCFC6A9AA6D9C9CE8371C6263031313198E57297BEFBF6 - 5F9E4710C4B287488D9D4550FF59020DA79DE645D3DC45AAA25CE872B9FC40A7 - B004B456DD0C65BB2C186C7FAEB0968D6B0D0A90BFE74E6B372749D8158C8DBE - 96A2289B7153AA4FE59148745056D556878DF86D3018E4F4A912540181A91308 - 0402470C0F4F3CB670D1825570207DEAFC8C3643966529140AFD9CB5555C0BAD - C68D963DD0FBCF0868DF7F5229EEBB288E5D5DE6F7CF054A8525A0ED045164F9 - 219244EFDABA756BA2B0D68D6B0D0A90CFE4AEA9A9698128210FDB6CB6F5388E - 13C64DAB3E950F0F0FBFEBB03BAFE2B86407EC99D6678E40555E04D0134E38F9 - 6BACDDF6B0CBE52ACDCB024C320C81F1B1D0072CCB7CBFA7A7FB15C38806A140 - E00B08D435ACD9C465B9DB2A2ACA17A2280ADF0B0BBC5AD2994C1B4DA2177574 - 747C5060D38636070BED33E90B04028484E0A7E4D299FBCBCBCB17193AB33A14 - AF3D393CD03FF07A89C77DCDABAF6E0FEA50224802027911A8ABAB2B397070F4 - D1138E3BF6EB79198049862090CB71E9D044E8BE05F36AEEB4EAEDC586481488 - 9C1401ED3B8F28AA8DD158FCA7F3E7CF3B69529360D094084C4C840FD8ECB6AB - D7AE6978CECA777EFC33685080FC03156D4F3745B1D7530C73899D655D535A69 - 3078520452A9F49F710CBF3A186C7F174110755293601010D03701F4E8A3979F - 4250F88315E5F01451DFA9CA5FDDDE7DFBB6FBBCBEEFEDDEBD7D5FFE56602610 - D0050174D5AAB527E2047E1BCBB24DBA50643211A228728AAADC4F11E81D5BB6 - C0F9D77F4C2F1420FF64C16B6DE85444BDDB6E674F813DDD85FF441045914F67 - D22F100CD9DAD3D909FDF30B8F182C168180B68F3A1C4FDF50555E7E25411064 - 112480CB192490482443995CE6BAC50BE63EBD79F36679065D81692030D304D0 - A6A6538ECE6673D7D91DEC19D06E7766707339AE532591CBBBDBDADE9A190FC6 - B60A05C8E7E42F1068FEAA280A0FB93DEE0A63A7589FEAB5ED58D148F4574E27 - 73475757D747FA5409AA80C0D4083434341E1B8DC59E9E376FEEF1539B09A3F5 - 4CE0E3CFAB58FC3FEC36EF55C1E08B613D6B056D40E05004D6AE5DBB3091E2AE - 77BB9C9B1886B11F6A3CFCFFD4094C4C4CEC77D8D96B92C9D8F370E6F59FF383 - 02E473D69576C998246157A318F2439BCDE69CFAF28319872290CBE592E148F8 - 498FCB7E7B4F4FCFC4A1C6C3FF0301BD13D0DE821C1C1ABBA4A6BAE66A87C30E - 179BEA3D6193D4373E1EDA4FE0D4F9BB76BDD231C929300C08E8924073737359 - 289CB8C9E3767F9B65E1BBCD4C258917F8DB6591BB31180C4A33E5C3E876A100 - F9820C0602CD47C88A7C8FD3E938CDE889D6ABFE583C3EA6CACAFD04A1FE62FB - F6ED31BDEA045D4060B2040281C0BCA1E1F1C70F3BECB0E6C9CE8171FA25C0F3 - 7C766474F4E1128FE3A73B76EC48E957292803025F4CA0A1E1342F8A7217A118 - 7A89C361F702AFC213D0DE960AA2182430FCCA8E8E97DE2CBC07F3588402E410 - B95CB366FD268ECFDDEBF3F9E69827EDFA8A24114F8C4992F4539B8D781C9E16 - E82B37A0263F02CB97D7FD0B45533FF3783C65F95980597A21D0DF3FB0BDD457 - 7AEEB66D5BDFD38B26D00104A64AA0A5A5C51589A5BF87E3E8555E8F17B6964F - 15E024C747A2B1618A202FC966E37F84AD575F0C0D0A90432CAA0D1B3694F0BC - 7A2586A317C15EC949FE06E6316C6C2CB41F4191BB681279A6B7B73797870998 - 02047443E0A4939A7C3C9FB8CD5FE6FF0E4551B46E8481902911C86432896C8E - BB765E6DE5E370F07C4AE860B08E0868C5472C96FE0E8AA1D778BDDE4A1D4933 - 9514EDC24114411FA569EC36E87A75E8D442017268464863E329872BAAF43386 - 61B40B0AF1494C812179100887C3072445FE89CBCE3C0BB7A5E70110A6E88A40 - 5DDDEA953CCF3F55515971B8AE84819849115014457EFB9D773ACA4B2BCFFFCB - 5F760E4C6A120C02023A231008041CA90CF76D1CC57E5C0AB79CCF5876545555 - 389EEF4208E40AE87A3539CC50804C82536B6B2BD6F5CAF6B37299CC3D7E7FD9 - FC494C812179105055551D1B1BFB4855E49B162F5EF03B78E298074498A21B02 - 2D2D2DF4F070E8267F99FF629AA659DD0803219322904C2643C944EA076FBFFD - FA1FE0BEA2492183413A23505757679314F41B188AFFC4E72BA9D1993C53C909 - 87238334455FD5D3D3F93BF8BC985C6AA100991C27A4FE8C339C649AFB314592 - 5A8F7F6A92D360581E040E1E1CFCAB9DB5DF5052E27879CB962D7C1E26600A10 - D00581C6C60D478E8C8C3CB660E1FC7A1445315D8802118724204992104FC49F - A108F42A688E71485C30408704B40720E9B4F0A5543A71634545E56170A7D9CC - 2589E3B8B4244B8FD86D146CBD9A02662840A6002B10683E0AC5D09F310CDD08 - 5F26A6002E8FA1434343EF385CAEAB9B9BD66C696D6D55F230015380802E081C - 7BC2F2737D5EDFFD0CC3C05B105D64E48B45686F6247C7C6DE77DAED17F5F474 - 77C1D34C03240D24FE7F04B4E22396CC6C4825523F993BB7F658C033B304721C - D78628E8C5DDDD2FEF9D594FE6B20E05C814F2B969D3267C7422DA9249A6EFAE - ACAC38620A5361681E040E1CE8EF7379DD374A5CA603BA49E40110A6E8824020 - 10A8E93F38FAF8D225479CAA0B4120E20B09686F3F060E1EBCABB2DC772B9C45 - 83C56234025AF1914C721BE2C9446B4D75D5D1388E13468BC1487AA3D1E8908D - 612FEFEE6EFB6F23E9D683562840A69885BABA4D36828A5E4A91E475B0AF7B8A - F0F2187EF0E0E05B2EA7FB3A9E4FB643119207409852740281408048A785D310 - 0CB9A7CCEF5F54744120E00B09F40F0CF49678BC176CDFDEFD16A002024622B0 - 74E926CAE50A6D88C7A337CC9B3F6F198661B0ED73061398C964E28AAC3E44D3 - E8BD5BB76E4DCCA02B539A8602248FB4AE5BB7AE3693E1EF75BA5C67C079903C - 004E618AB61DE2E0C1C1B7EDACE3BADDBB9BB620086CC79A023E18AA1302DADB - D33DEFEFBF6B6E6DCD653A910432FE0981643235A1C8F2756E37FB0C9C3F8325 - 6224024B376DA2DC43638D8944F2D6DAB9B5C743F131F3D94BA752CF632C7559 - F0E597FB67DE9BF93C400192674ED7AE6D5E3911893C3AA7A606F657E6C9702A - D3FA070EF679DDCE1B63B1F2AD7BF66C16A63217C602013D1038E184FA937921 - FBF8DCB9B5C7E8410F68F8BF04DE7EFBAF7F985BBBF0A21D3B3A46800F10300A - 01EDCD87D339D6924826AE9F3BB7F638D87635B399D31E8C0E0E0DBDE3F3975E - FE4A67FB563827961F6F2840F2E386684F34070646CEC109FC268FC75381A228 - B0CC93E564A70D0C1C7CCBE660AF79FDD5F56DF02664B2D4609C5E08682D3163 - 89ECC515E56557B32CEBD68B2ED0F1098168343A964E652E79E79D37B4369AF0 - 03040C41403BF3118FE71AE3C9E82DF3E7CD5F6E08D10617A975BD4A26923738 - 1CF4CFE19C58FEC9842FCDF9B3439A9A9A7CA28C5FC1D0E465B0156B1A20A730 - F5C0C0C0EB2EB7EB2638983E0568305437041A1A9A168C8D8FFDFCB0C316ADD7 - 8D28108288A2C8472291675C4EDBB5C160300C488080110868C54738966A4E25 - 9237C29B8FD9C918C771199AA2FF4351F89FB4B5B58DCE8E57737A8102649A79 - D5FAFC2BAA7A0FC350EBE0B5E734614E72FA8103FD6FDA18F6068E4BB4EFD9B3 - 07B6634D921B0CD3038156ECB8E35EFA366363EE2829F156E84111684090F189 - D0872CCD9CD3D3D3FD0AF000024620A0151FA954B639128D5D3F77EEDCE570E6 - 6376B296CDE53A5015BDB2BBBB0D9A544C13391420D3048820085A5FBFE6148E - 171E2E2F2F5B307D7360E15004B4FD9723C3C36F3B1CAE1B77EC58F327D88E75 - 2862F0FF7A22B06AD52AFF47FD438F1C73D4515F86CBC18A9F199EE773A363A1 - 47E6CE29BF1E0E9E173F1FA0E0D004B4E2231249AF4BA593DA3D1FC741F17168 - 668518118D440FD23479C52BAF743D07E73EA64F140A90E93344B4BDDD2A4AFE - 88A6E96BED2CEB2A80493031090207070FBEE9767A6E51146E4B6F6F6F6E1253 - 600810D00581A38E3AE14B7687FD619FAFA44A17822C2A425555E5A38FF6F796 - FA4A2FDCB933F8A6453140D80622F0F1F70D95DC984826AEAEAD9D03F77CCC52 - EEB2D96C0251D5BB11447A20180CA667C9ADA9DD400152A0F40602818A4C4EB8 - DBE3F67C952449A64066C1CC21088C8C8C7E80A8EACD8B17CF7B76F3E6CD3200 - 03024620D0D2D2E21A9F88DF55E62F3D07DE82142F633CCF6763D1E8656FBCB1 - FBF1E2A900CF406072049A9B9BEDE1587293244857D4D4541F39B959306ABA04 - 14459113F1C4EF9D4EE68AF6F6F6C1E9DA83F99F108002A4702B015DB7AEE538 - 1443EF2749724DE1CC82A5431118191DDD4B60F85D2489FC17BC0939142DF87F - 9D10404F3EB9E1A4543AF3736D0B854E34594EC6071F7ED4367F6ED5F7E14B85 - E5526FB88057AC68714952EC9B38415C5752E2AD840717B39342455114499677 - A0AA7A4D47C7969DB0F5AA70DCA100291C4BA4B5B5157BE595ED5F4DA533B7FB - FDFEF9D09AB780700F616A7C3C744055D4DB51D4FF9F7D7D2F6667CF33780202 - F91358B870C90DF317CEBF8E22493A7F2B30331F02E31313FD88AC5EE574D2CF - 078341291F1B300708CC0601ED8D692492FC370441AE28F597CE9D0D9FE0E313 - 02F1787C94B63157947A5DCF6DDE0C779015725D400152489A0882D4D79FE1C4 - B0CC258C8DBE9E2449AAC0E6C1DCE710D00EA64722918308AADEEB72B0CF6CDD - BA3501B08080DE09D4D505164563915F2F5CB860A5DEB59A4D5FFF81FE07CBCA - BC9743F161B6CC9A2B9E4020E0C9E5A4EF6038F663AFD75B69AEE8F41D4D3A9D - 8929AA725F89C7F1C00B2FBC90D2B75AE3A98302640672D6DCBC717E329DBCCD - 6167CFA2280ACE83CC00E3CF33391E9AE8C771FC319C25FFB3B7AB6B78165D83 - 2B20306502CB962D235194FA2A4E1077F97C253553360013F222303E1EDA8B51 - E4B9AFEDDCB62D2F03300908CC028195CDCD656886FF9EA2AA1741F1310BC03F - E342BB1B281A8B3EEB71D97FDCD9D9393EBBDEADE10D0A9019CA7360FDFAE370 - 15BF8FA6E9C6197201663F87402A958EC6A2D1A7DD6EF6C11D3B761C04504040 - CF04B4969AA3A3E1C72A2A2BBE03ED34673E53DA456213E1F0BD95E5BEBBDADB - DB3333EF113C008129134057AE5DBB20134B5EEC72BABEE9743A7D53B60013F2 - 26A075C75315B95710A4CBBABADA76E76D08267E210128406668816CDAB4090F - 876367A633B97BFDFED27933E406CC7E6E11928AA633D9E7693B75EFABDBB6BD - 07A080808E09A07575AB56E704FE89AA8ACAC374ACD314D2F6EEDBB7DDEB2E39 - E7F5D777EC3545401084D908A0AB57AF3E2A9DE62F71BA5D5F85D6FEB39FDED1 - D1B10F6D8CED1A9E4FFDB1AFAF4F9C7D05D6F00805C80CE6596B99974CE6CE45 - 71EC2AAFC703B71ECF20EB7F665A961531120D3FCB50CCBDDBB777BF0DDD2B66 - 3901E06ED204366EDCC8F61F1CB9A1B2A2E2728220C8494F84815322904CA626 - B299F40D0B17CEFD25B4ED9E123A183C0B0402810081A2D4B1D95CF60A96654F - B7D96C8E59700B2E3E432091488CCB8A74BFC8E7EE83E263669706142033CB17 - D18A1045216E5154E55C86A1ED33EC0ECCFF03015996A51CC7B589BC705B6FEF - 36AD851EFC00015D1258B93270542C1EFBF5FCF9F34ED0A540838BD2DA697EF0 - C1872F2E5A587B415B5BDBA8C1C301F92624505FBF663D4690975114B986A628 - 9B0943D475489224898A2C3F4092E85D5BB66C99D0B55813888302641692D8D4 - D4B25490F85BEDAC7D23F4EE9E05E0FFE042FB5019E81F78DD5DE2B99BA5892D - C160909B7D15E011087C3181A54B375136DBE0D98C8DF989DBEDF603AFC21288 - 4663C392285DFCFAEB3B7F5F58CB600D084C8F4020106064193F7D223C71F982 - 05F34F9E9E35989D0F01499284743AB38522A9AB83C1F6F7F3B10173A646000A - 90A9F1CA7BF4DAE6D35646C6C71EADAAAE3E1A45512C6F4330316F02838343EF - E2187EB7C7C3FE3E180CA6F336041381C00C1158B9B2B96C70F8A3C78F3EEAA8 - B366C88525CD721C9F0D47C24F38ED5537EED801ED342DB908741AB4D6663793 - 11FE4556E4CB2A2A2A16E954A6E9658D0C0FBFEDF57A7FD0DDDDB1C3F4C1EA24 - 402840662911DADE4E9E974FCF66B9DBAB6BAA8E9825B7E0E63304144591E3F1 - F8B88AA2F7D928ECD7C160300C808080DE082C5FBEF22B344D3EEC867363054B - CDFEFDFB77793DDEEFF7F66E7B07CE82150C2B189A2681FAFAF5558AC27D4F94 - E5EFF94B4B6BE1F2E26902CD737A2C161B76D8D9EBA3D189FF84731F7942CC63 - 1A14207940CB778AF69A95E7E5F36986696559D69DAF1D98373D02F1783C944E - A59FB197381FEF0D06F62348AB323D8B301B08148E4043C369DE4C66E2565FA9 - EFBB14EC039F3658AD9FFFF0E868EB9EBFFEE58E691B030340A040040281C011 - F144E64776BBFDABB0E5B24050F3309348242750447D8461889FC105C679009C - C6142840A6012F9FA9CDCDCD6592825D89A8EA050CC3C0A1F47C2016604E2E97 - 4BA5D2E9FF6119F6FE6DDBB6FEA50026C1041028188165CB1A560842EEC939B5 - 354716CCA8450DF51F38B0A3B2D27F766767E73E8B2280B07544406BD13F3E1E - 3B8617F81FBBDDAE2F43D7BBE22587E7F90C8663FF8128E22D1D1D1D23C55362 - 4DCF50801421EF0D4D4D0B644EBADBE9709C4E1004550409E01241109EE77382 - 207629B2F2A8CBC5746ED9B285073040400F04B41BD2B39C78535565D5A5344D - B37AD064440D91486458E0C56B78BEF6777BF66C168C180368360F81BABA4D36 - 1C8FACC349FC4282205641A7ABE2E556DB929DCD645EC268FCC66047C75BB035 - 73F6730105C8EC33D73CA24D4D1B1AC627C20FCEA9A93E16F67D1627099F7A1D - 1A1E7E8F22C87B3C1EFBEFE1156C717301DEFF97407D63E3E1D1F1C8D3F3E6CD - 3B193E23A6BE32B4B6BBA189895FD3A4FB8ADEDEB6E8D42DC00C205038027575 - 75364925BE2570DCC55555954BA0194DE1D84ED59276D3F9E0F0D05FCB4BFD97 - 7676B6754F753E8C2F0C0128400AC371CA56B4279C8CDDF3652E97BDBDBCAC6C - FE940DC08482115055559D084FF4D324F54B86219EECECEC1C2F9871300404F2 - 24A035AE4865B9EFB28CE32EA7D3EECDD38C65A78D8D8DBDEFB0DB7FB86D5B97 - F60543B52C0808BCE8040281400D27AAFF268BD2797E7F696DD105595CC0F858 - E80387DB71533A117D0E0E9D176F314001523CF688F63A564543DF5715F90A9F - CF37A78852C03582201F1F4ECFA4FFCB69773DB66347F75E8002048A4D60C58A - 40CDC8D8D0134B971CB11EC771A2D87A8CE29FE7F9ECE8D8D8DD0BE7CFB9EBC5 - 175FCC1A4537E8341981D6566C75D7F6C393C9C40F9D2EE7379C4EA7CF64111A - 2E9C4C269B1044E1D6D212D723F0D950DCF44101525CFE88F626847578AEC131 - FC0A96B5398B2CC7F2EEB54B0B13C9E41F3104B99BA6F13782C1A064792800A0 - 9804D0134E38F97482C21F2EF5C193D3C92662EFBE7D3D7E9FFBBC575F7DF5BD - C9CE817140A0D004EAEBD7AC4210F4729AA163BFC0CF00002000494441549B18 - 867114DA3ED89B1A018EE3D228A23E86E3C83DEDEDEDA1A9CD86D18526000548 - A189E6616FEDDAB573E389CC755EAFF75B344DDBF23001530A48406BDBD9DF7F - 70576979E9FD4E1BD5D1DEDE9E29A079300504A64460E3C68DEC8181E19B2B2B - 2A2E2249929ED2640B0E8EC5E2C3BCC85FEEB233DA85A3F000C1826BA0D82137 - 3737DB331971433812BE7CFEFC792B300CC38BADC9EAFE0541C8699D2FED36E7 - 355D5D2F0D589D871EE28702440F594010A4BEBEF17059956FF5B8DD67C18795 - 3E92323A3AF6018E610F381CB4766921DC9CAE8FB45852455DDDEAE363C9C4E3 - F3E7CE5D0E07D23F7F09C8B22CBDB7E7FD87172CA8B9017E672DF9AB52F4A057 - AD5AE5CFF2F2371449BEA8B2B26271D105810044FB5CE038BE03A3D01BBADBDB - DF803361FA58145080E8230F9A0AB4B1F9D4933045F92949926B310CC3F423CD - BA4A62F1D858369DFD3DEB661FEFDDB6EDAFD625019117938076203D148A7FDD - ED71DFEFF57AFCC5D4A257DF922409EFBFBFF7C5450B6B7FDCD5D5F5915E7582 - 2E7312D0EEF7181B8B1E9E4A252F74BA9C5FB73B1C1E0C45E1EFB80ED2ADC8F2 - CEBF6DAFBECEEB75F66CDEBC59D6812490A07DE9050AFA22B0664DF3C678327A - 6B6545E5527813A28FDC701C9FE105BE534190071189DBD9DBDB9BD387325061 - 2502CB96AD730F0DEDBDF398638FFE2E6CC5FABF99EF1F18E82571E292B7DE7A - 7DB795D605C45A7C025A8B5D1925D612187E0143D301B864B8F839F954C1F0F0 - C8BB9E12CFCD653ECF1F376F86BB80F493192840F4948B8FB50402010641A8B3 - B2B9CC1DA5A5A5737527D0A282B44B8B46C7C6F65234F930E176FEAEB70DEE15 - B0E852286AD80D0D0D878D8C4E3C7AD8618735C25BD2FF4DC5F878E8431447AF - 995F5BFD3C3CE12CEA12B59CF3A6A6265F3299FB5751967E50515EBE081E1CEA - 670944A3D1218AA46F2A2FF7FE1A3E17F493974F95C01B10FDE504D10E9D8642 - B1EFE3047EADC7E329D3A1444B4AD2EE0B8927E2E3D974F639B7DBF32886491F - C021574B2E85A206BD64C97167B176DBCFCACBCBE001C527EDB347B81C77338A - 96FDA6AF0F5AEE1675715ACCF9AA554DC7245389736D36F64B2525DE2A8B85AF - EB7063B1F8288EE10FA8258E4777BCF0424AD7622D2A0E0A109D263E10087824 - 09BB1827B04BEC76BB47A7322D294BEB9225F0C22B8220DF47D36A271421965C - 06450B5ADBEE118EA57E58565A7A85DBED2E2F9A101D384E2693138964F2619F - D7791F1C3AD741422C2241FB1D441066354E2017B95CAED32C12B661C2CC64B3 - 4914459FC051F98ECECECE8861845B4C2814203A4E782010288D25D2B794784B - BE65B3D9A087B88E72A575D5D06E5AA629FA71A793D90CB7A7EB28391690A2B5 - F93C30307C694579E56556BD253D91488627C2E187FC3ED7FD3B76EC80279C16 - 58F77A0871E5CAE632494A7F3DC7F3E75656541C4E1004A9075DA0E11302DADF - E6782CF6ACCDE3B839D8D6F62170D12F012840F49B9B8F95D50502474859E17A - 97CBFD659AA6E08E109DE54BBB3D3D954EFFCEED743DB97D7BF7DBD0DE4F6709 - 32B19C8686066F389AB8A4C45B72BED5B66A462291C17822F97889A7F2B1DE5E - 388F65E265AE9BD0B44E7492841E994CA7CF73D8D9AF58ED774E3789F80221A2 - 280A3CC777E0387E5377777B9F11345B59231420FACF3EBA7AF5BAA35455FE29 - 63B36D80EE37FA4A98762E447BE2B27FFFFE1D65FED27B5455EA822E59FACA91 - 99D52C5BB68C4D26F91F96F8BC97F87C2596D8833E3A3AF621A222B7BBDDB6DF - 068341CECCF985D8F443E0E493D76C0C4726AE983BB7F644B830583F79F9AC92 - 4C2ED78EA9C48DDDDD2F699DF0547DAA04559F128002C4006B41EB2F1E0E2796 - 2308F2531B6B5B6700C9969328CBB21C0E87FB698AFA05C310BFE95ABD7A1469 - 6D552C0702029E7502DA76ACB189E84659947F5C5D5D75A459B784FCAD8FBF38 - 3434FC178AA4EEC1F1F23FC381F3595F6A9674180804E6F1BCBC299BCB7DA7BA - BAFA484B42D079D0DA4340155177A9B27C5347C7CB9D3A970BF2FE4E000A1003 - 2D85FAD58DA7A612A93BB42F19285C70A4CBCC65B2B964369B7D89C4B1C7280A - DB0907D4759926D389D21E52BCF7E1C0F1F18970EB91472EDD80133861A6203F - BEE1FCFDBD5D251ECFCD1E8F7D37FC5E9929BBFA8C65D9B26524493AEB15553A - D7E3717FD5AC85BD3EE94F5E95AAAACAE0E0D01ED661BF219DA87869CF1EB8EB - 63F2F48A3B120A90E2F29F92F74D9B3651E3E3B1D313C9F8CDD5D5D5474D6932 - 0C9E35025A97ACD1D1B1F7599BFDD734CD3EDBD3D3363A6BCEC191A5091C77DC - 8AC5038303172D3DE2884D6E8FBBC20C3052A974646060E0F9F232EFCF5E7BED - B577CD1013C4A06F026BD7AEAD4EA5B8AF08A2785E59997F216C7DD667BEB42D - D0636363EFD918F6768A429E832D99FACCD3E7A98202C458F942B4279D43A3E3 - FFCA65B91B2A2A2A16A2280A39D4690E13897828C7F17F2671FCA99212D76B5B - B66CE1752A15649988C08A152B5C82809C99CD652E983367CEF1144531460C4F - 14253E140ABD97C9657F5DE673FF76E7CE9D2123C6019A8D4340BB0838971397 - 0BA2F4EF2C6BDBE876BBFDC6516F3DA5B1586CD4CEDAAFB7D988675F7C11EE00 - 32DA0A802FAF46CBD827B7A53B7239E97B38415CE3F158FB1E00BDA74FDB3A72 - 70F0E09B769BFD97348DFD16DA85EA3D63A6D1879D7CF2C987EFDF3FFCC3B9F3 - E66CF4FBFDB5468A2C93C9C43EFCE0833F5555553F64B7537F812D5746CA9E31 - B5D66DD8502246929B389EBF40DBE68CE3E6DAC668CCAC7CBEEA442231260AE2 - 5D2489FC12FEAE1A33BB508018336FC8AA552D7E51CC7E5F45E41FF87CBE6A83 - 866119D9B1587C3C9BC93CCFBA5C4FF7F6AC7E1D41E080BA65925FC440B5B721 - 394139313C3171F6DC39B58DDE126F6511E51CD2752693890F1E1CDAEDF1789E - 2108E5E5DDBB77C3256287A40603A643A0A5A5854E71DC71A978E6DF598639C3 - E3F554C0CE82E9109DF9B9DA05A42886FD0C47E54783C1607CE63D8287992000 - 05C84C509D259B0D0DA779312C77B18AA017391C762F7C68CE12F869B8D9BFFF - C0ABAC8D7D98658997B66FDF1E9B8629980A04264DE0E88606AF9C48AF4B2652 - DF59BC68E11A9AA6590CC3B0491B98C181DA2152AD7FFFC8C8C8DBBCC03DE771 - 95FEAEAF6FC7C1197409A681C0C7049A9A9A7C8944F6AB39813BBFBAD2BC1DE4 - CC94EE743A1D5115E5118AC21E845BCE8D9D5928408C9D3F64EDDAD3AB2585BB - 0045900BED76BBDBE0E1985EBEA228722A958A2653C9DFB12EEF2F6CB8BC07B6 - 97983EEDBA08503B3FD6DF3FE1CF6613F5E168E4AC9A9AEA86D2125F4DB13A66 - 69BF0B897822343236D687A2E84B3EAFAF3D91700F7DF8219C95D2C58231B108 - EDAD47362B9C904AA7CFA519FA14AFC76B8A860D264ED9C7A1A552A9084950BF - 5014EEDE603018367BBC668F0F0A101364582B42304CBE4245D4EFD3346D3741 - 48A60F411084DCD0D0F09BAC8D7D82A6DD2FC06DCEA64FB9AE02D46E514F6685 - A386FA0F9EE9F1784E2CAF283B5C7B8031D307D6655911B3D96C32140AED8F45 - E36F949495B43B6DD4CED75E7B6D4C5780408C29096845F8C4C4843F9DE6BF92 - C964BE3B77DEDCE3310CC34D19ACC982CAE5722902279E9265ECEEAEAE3F0D9B - 2C3C4B8603058849D21E089C322F9349B496F87CFF0A87E78C9154AD85602291 - 08F11CFF271CC79EF4F9DC6F40A72C63E4CE2C2AB5BB0E701C77C562D993C7C6 - C79A7CBE92E5E5E565F37C3EDF9C42C6188D468792C9E4C8E8E8D89BA53E7F9B - DDEE78431092237BF6EC11E1C6E24292065B5F4460E5CAD5CDA2ACFCBB8DA14F - D10A6ED8B66C8CF5C2F37C36954AFEDE612FB9068A0F63E46C322AA100990C25 - 838C696E6E3E221ECF5DEF74D9BFA4EDF136886CCBCB942449181C1E7AC7CED8 - 7E83A2D473F3E6958F6CDEBC59B63C180030AB04962E5DEA2049D2AD28586D22 - 913C3A9D4E2F2508B29AB5B3651E8FA7C2C6322E8A625892C0498AA26C9F15A7 - BDD1D33ABE098290CD6673C954261D4A2593213EC70D3BDDEEF74A3CEEB75595 - E897A4547CCF9E3DE9590D0C9C599A4020102044145D8808CA9793A9F4372A2A - CA0F877B3D8CB324789ECF2593A93FB85D9E5B1B1A4EDCDBDA0A0D5C8C93BD2F - 560A05885932F9F738021B362CE2D3B9DB5C4ED797711C8757CB06CA6F369B4D - 701CDF8E22F89389446937DCE86AA0E49954EAA2452B5C763BE79465DC272862 - 752A91AA2571A27C747CAC8CC4093B8222A82C2B39A7CB1522083CC432543FCB - 3A07719C8E641825F5E1AE5D4993A281B0F44F005DB671A38D89A6D72198F23D - 87DD792AEC0ED07FD2FEF1C1462E977B99A199D6CECE97DF36967A507B280250 - 801C8A9001FFBFB171C3B1BC28B6DA59A6059EF4182B81DADB9070383C200AE2 - 9F1C5EC7D34226F37E5F5F9FB64D057E8040D109684F9343A11096CD66314992 - 3EFEFB411084CAB2AC525656A6404385A2A70804FC9DC09A354D27C693A97FA3 - 48E274AFD75B4D100409708C434014458EE7F8B6BF3D48BDA5B4D4FD26EC0A30 - 4EEE26AB140A90C99232D838AD081124E166D6663B058A1083250F41105114F9 - C1C1A1375907FBA49D21FFA7A7A7E96FF721C0AB67E3651214030120305B04FE - 7EC8BC3295E236663299EF2C58B860C56CF9063F8523F049F1C1751004714757 - 577B2F9C132B1C5B3D598202444FD928B0964060FD718A22FF84B5DB4F854E1F - 05863B4BE652C9544410C5AD188A3CED74DAB6B7B7B76766C935B80102400008 - 188680567C0C0D8DAD9364E56C87C37E2AC3302C8AA2BAB8EBC630107520542B - 3E0451ECC251ECE6AEAEB6D7A0F8D0415266480214203304562F661B1B9B9749 - 8AD44A53F4BA996EB1A99798CDA6435114251C0EF7F302FF478FCBF3ACC341BF - 05DDB2CC966588070800817C080402014692D023A3F1C437288AD8E82F2D9D4F - 9224958F2D98535C025AF191C9722F331479BBCFE7EA836D57C5CDC74C7B8702 - 64A609EBC07E53D329C788A2F0537813A283644C43822449E2F0F0C8BBACCDF6 - 0B86C19F6F6A6A1A878E20D3000A53810010302E81D6562C100C966432C2D7D2 - E9F477E62F987F92718301E55AF1210A62F7DF5A23DFDCDDDDBE0B88989F0014 - 20E6CFF1C711AE5DBBE10451146E626CB60D7026C4D849D76E521704B11B2789 - FF5225AA1B2E3134763E413D1000025323D0D4D4E4E344658D28885FA749AAC9 - EEB07B609BF1D418EA69F4A7673E709CB8B5B4D4FD3ABCF9D05376664E0B1420 - 33C7567796B53721592E77939D654F85ED58BA4BCF9404A9AAAA44C2E1414112 - DB6C34F3DF18A6ECDEB163476A4A46603010000240C040049A9B9BED890C7F12 - 97CD7D8D208853CACBFCF30C241FA4FE1302DA1D423C2FB45324796767E7CBAF - C2990FEB2C132840AC93EB8F236D6C6C3C32C78937BADD1EED9E10C262E19B2E - 5CEDF2B7898989034E87E33914957F8B20C8FBD00AD5746986808080E509AC5A - B56AA920215FC965735FABACAC3802FE7E197F4968970C6673B92D369AB9B5AB - ABED2F507C183FA75389000A90A9D032C9D875EBD62D89277357BB9C8EAF300C - 63374958960E83E7F96C683CB4D7EE74FC8E22A897B66D6B7817DAF65A7A4940 - F040C0F004962EDD44B95CE30B45516849A6525FAAAAAA3CDA6EB7BB0D1F1804 - 80701C974EA592BF77D85D77AF5953F71E9C67B4DEA28002C47A39FF38E275EB - D6D5C6E2991B7DBE926F1304011D434CB20EB442647864E42F36D6FEB4DB41FF - 39180C84A010314972210C206011029FB4D48D540842F68C5426F39DDA3935C7 - C2B661F3243F93CD265389E4735EAFEFCECECE97F699273288642A04A000990A - 2D938D6D6E6E9E2F29D80F645939D7CEDA5C260BCFB2E1686D7B33994C5C9694 - 6DD96CF67F9C4EBABDA7A767D4B24020702000048C42005DBB766D553ACDB750 - 36FA4C0CC1EA1D0EBBD728E241E7A1092493A9304591BF1609E4DE9EB6B631D8 - 76756866661D01058859333BC9B8D6AF5F5F2549C885BC209CED76BBCBFED602 - 0FD6C424D91961582C1E1B9304B10BC7C9DF290AB963F7EE553178236284CC81 - 4620601D029FDC609EF14B2A572770DC269C201A3D6E4F39FC3D32D71A48A552 - 619C207E2E93E8A33D6D6DF050CC5CE99D7234F06573CAC8CC37A1A9A9A95C92 - 90F36445BDC8E572969A2F426B47A4288AACB5EECDE5727FA629EA599AC67704 - 83C1B4B5A940F4400008E881405D5D9D0DC3984641E2FF05C788B56EB7AB1CC7 - 715C0FDA4043E1082493C990AA280F330CF168676767A47096C1925109400162 - D4CC1558B75684709CF23D5116CE2BF595D616D83C98D30981F1F1D00159923A - 1886FD1FBB9DD80D7F087492189001042C44407BE39148247CB99CB03293C96D - 44712CE02B29A981F388E65C04B1587C14C7D007EC76FA176D6D6D5173460951 - 4D95001420532566E2F1F5F5673825257EB6AAC897FA7CBE5A78FD6DDE644722 - B1619ECBFD99B6B3CF3A6DE41B5BB76E4DC25E5CF3E61B2203027A20D0FAB7DB - CB83C120258ACA5A8E17BF8EE3786369A96F8E1EB48186C2135055558DC7E3A3 - 9228DDE976B3BFDEBA756BA2F05EC0A25109400162D4CCCD906EEDA2278E53CE - 8C27E2D7D4D4541F35436EC0AC0E080882C045A3B12114415E6118DB0BAA9D7C - 75677BFBDFBA66C10F10000240A0A004D0A6A6A6324190EB3259EE4C0C43D778 - BDDE6A9224A103634131EBC7987659EEF0F0F09E126FC9BD08223E07DB7EF593 - 1BBD288102442F99D0910EEDF5F8D858F44B9158F49ADA3935C7611886E9481E - 48990102E189F00082A8DB689AFE234561DB65598EC0858633001A4C02010B11 - 58B66C19E9749695CB32B722C77367AA08BACAEFF3D5C2DF14732F025956C4A1 - A1C1773D6ECF1D8AC2BFD0DBDB9B3377C4105D3E04A000C9879A05E66845C8F0 - F07813C530579304B1922449DA02615B3A44EDB0FAC7ED7B15A54710F917BD2E - C7CB1D1D1D23968602C1030120901781D5AB9BE7E472E95348923C154591931D - 4EA71F0E97E785D270934451DCC673B93BED76A673CB962DBCE10200C1B34200 - 0A9059C16C4C2781408040516A598EE32EB7DBD9D3699AB6193312503D550289 - 443C8461E4EB022FB45314D98DE3F2BE6030C84DD50E8C070240C03A045A5A5A - E86834BD5092E4750C4B36A90AB2C2E974FA701C27AC43C1BA918AA2C8F31CBF - 95A6A9BBA3D1D0CEBEBE3ED1BA3420F243118002E45084E0FF9140A0F9A86C2E - 7BADC3613F8361183B20B10E01ED66F5D1B1B1771CACF3599224DA63B1D20FF6 - ECD92C588700440A0480C02108A04B972E259D4EDF2249124E4D67B25F9B33A7 - E668B8B9DC5AEB4696652993C9FE8922C95BBABADADEB056F4106D3E04A000C9 - 879AC5E6FCBD73C982783277A9D361FF86D3E92CB118024B87AB1D26CCE672E9 - 68347A4051E46E9661FEAC288ED7FAFAA0A389A51706046F79020D0D0D5E8E13 - 976772B9D310155D53E6F72FB03BEC2ECB83B118804C369B4C25537F6068E681 - 9D3B836F4147458B2D803CC38502244F70569C1608042A0409390751D50B3D1E - 4FB91519583D664551945028D42F4B72376563FE48E1B63E8E8B4EC0AB76ABAF - 0C88DF2A04B483E538EE712928B782E7F833710C5BABB5D2A5280ACE095A6511 - 7C26CE582C36CCDA6CBFE179E989EDDB3BF75B1001849C27012840F20467D569 - 2D2D2DAE6834F56D59952F29F3972DB22A07ABC7ADBD6E4F2653111441760982 - D04ED3CCD61D3BBAF75A9D0BC40F044C4C005DB162F5229EE7D69014D98C6158 - BDC7E32E83F31D26CEF821428B442203B2A23EC050E8AFB66FDF1EB32E09883C - 1F025080E443CDE273966DDCC8D2F1D419F158E2CA39353547E338465A1C89A5 - C34FA733B15028B40FC7B0571C0EB613773BDE84FB442CBD2420789310F8A41B - 62C227AAD913D2C954A32A2B6B7CA5BE052E97CB87A228B46737499EF30963F0 - E0E05F7CBED2BB280A79B1BDBD3D938F0D98636D025080583BFF7947BF69D326 - 6A783CD24012C48F198A5A0B4FC1F24669AA89E17064485594ED8A22BD4CD38E - ED3C9F3808DBB34C956208C6FC04D04020802B8A322799119A48126F56157545 - 99DF5F6BFED021C24311902449D45AB5A7D2E9BB76F736752048AB72A839F0FF - 40E09F11800204D6C57408A08D8DCD27FCED80F2151E8FFBAB50844C07A579E6 - 6ADBB3B2D95C32141ADF5BE2F575A8AADC4D92E8BB3D3D3D13E68912220102E6 - 2350B76143899AE04F40717555241C59575E5EB6C4E17078501485EF0AE64BF7 - 9423D2BA22721CD74632B6BB1029F73A5C563B658430E13304E0430596C3B409 - 3436361E9948E62EB6B1B6B3DC2E977FDA06C18069084892244422D1219CC0FB - 1449EE2449FA159A468682C160DA3441422040C0B0045AB1FAFA0E3B8631F3B3 - 3CB712439055B22CAFF07A3D5570EF9361933A23C273B95C32914C3C67B739EE - 6D6A5AF57E6B2BBCF99811D016320A058885923D93A16A1DB24411FD3E82AA17 - B9DD6E28426612B6016D6BDDB3B44BAA42A1890F3114DDE670B02F490CD9B7AB - B373DC80E18064206078022B57AE2C9324EC244EE04F551565557979D9228220 - 480CC370C307070114948076CE0F519107691A7DA2A3A363A4A0C6C198650940 - 0162D9D4173E70EDF5BD184B7F5314851F5657551D51780F60D10C04B42D5AF1 - 787C3C1C89BC5F5656D68921C8AB18C6BED3D3B3250CFDE3CD906188418F04B4 - F6B92CCB96E604E5280245578C8C4FAC2AF7972E71BB5D7EB834508F192BBE26 - ED0EA8D1B1B1BD0C453FE676B3FFD9D6D6162DBE2A5060160250809825933A89 - 43EB9A323E1E3E33164B5C5F5D537D0C3C4DD34962742A437B33128D46071114 - DDA548721B4190BD5EAF7DFF962D2B4438DCA8D3A4812CC310D03E8F2726266C - 3CAFCC1704A991A488802CCBCBFCFE5238506E982C1647A8A228727FFFC05FBC - 1ED76D344D6C0906835C71948057B3128002C4AC992D625CDA9336A7D3BB8213 - 844B6C0CD36CB3D99C459403AE0D4040FB6397CBE552914874902488D71004D9 - 89DB885D348A0EECD8B123658010402210D00D81152B5A5C08929E2708FC4A04 - 43EB44413CDEE72BA96518C60ECD42749326DD0AC9E572698EE7B6D024751F82 - 4870D85CB79932B63028408C9D3FDDAA6F6D6DC582C1E0020421CF9115F91CBB - DDEEC5300CFAC6EB3663FA11A6AAAA9A4EA7E3914874802488DDAA8AECA069BA - 0FC3A4C1DADADACCE6CD9B65FDA8052540A0F804B4873E08E265313A3B9FCF4A - CB15445EA188F2729FCF57EB743A4A8AAF1014188540229118676DECB3AA2A3C - BE75EBD6F78CA21B741A8F001420C6CB99A1146BE742A444F6EBB2205C5C5159 - 71B8A1C483D8A213906559E6382E3D110EF76308FA1A86E13D4E27BD8B24C901 - D81250F4F480802213686E6EB62772B9B9B944762582610DAAA22C2F2BF32F20 - 0882C2711C0E9317393F46731F8E4406689A790447A5C7A053A1D1B2673CBD50 - 80182F6786535C575767C3716ADDF844E4B2850BE6AF827321864BA12E046B17 - 60696F461289E4284192AF1318DA47D3CC6B38CEF6C301765DA40844CC3001ED - 4D87C7E3299124644126C32D93146919CF71C79494786B1D0E87178A8E194E80 - 49CD6B1D0A8787475EF395F81EC071F965283E4C9A689D85050588CE12626639 - 0D0D0DC7E638F9C74EA7E3549665DD668E15629B7902DA01F6F1F1D07E8AA2DE - 4254E5550421FA300CDF9748F826F6EC39528243EC339F03F030D3045AB1A54B - DF254A4B13E582903D5C55B1E5088EAE10F9DCD11E4F4925C3D0EC4C2B00FBE6 - 26A0DDD5944CA5FF60B7D96EEFEC7CF96D73470BD1E9890014207ACA86F9B5A0 - 2B57AEADC571F43B922C9EEFF57A2BCD1F324438D304B44284E7852CC76987D8 - 23076CACED3D12A7DF6418EA3596250FB4B7B787665A03D807020523D0DA8AD5 - F5F67AC85C6E6E362B9E2428D2B25C3ABBA4A4A46401CBDA5C369BCD51305F60 - C8D204E2F1F8284950BFC271F9C9AEAEAE8F2C0D03829F75025080CC3A7270B8 - 6EDD3A773299FB8620F2179795957F7CF915500102852490CD6652894472CCC6 - D8DE4530B40F43D4B748D2B60FC7A531AFD79BDBBC79B350487F600B08E44B60 - E9D24D545555CC2649845714B34B6515395A91A463399E3FC6E3F1563B1C764F - BEB6611E10F86704B4FB3D464647F7D134F384D34E3DD3D9D91901524060B609 - 400132DBC4C1DFC704B4BDCC0CE308E02479B98DB1ADC371B87D179646E10968 - 7F68B583ECB96C2E198BC787681BF30E8EE17D0486BE4551D8BE6030385478AF - 6011081C9200BA7A75730DCFF38B14453C5A51D565BCC01D53E22D9947D30CAB - 7D1EC259B9433284017910D0CE7B2008F26A2E9BBD872010EDBCC7DFB6ABC20F - 10987D025080CC3E73F0F81902AB9A9A8EC9267397B23666A3D3E9F4011C2030 - D30432D96C329DC944E3F1F8A09DB5BFCF30CC7B248EEE25496C1F4110139224 - 65E08FF24C67C13AF65B5A5AE8540A6355325B26E794050A222F114569693693 - 59E270382AB516E5361BE380FB39ACB3268A15693A9D8EA653E9FFB1DBED8FE0 - B8F2367CCE152B13E05723000508AC83A213686A6A2ACFF1E2772541BAC0575A - 3A074551B82FA4E859B19680783C3E1E8BC6066D36DB3B388EBD89E3F85B38CE - EC77B9C87187C3216DDEBC59411044B5161588360F02682010C06D361B9E4C8A - E592943B5C41D06314593C269BE58EF478DDD50EBBC34B92249D876D980204F2 - 22A09D93D3EEF7C050FC6155257FB973279C8BCB0B244C2A280128400A8A138C - E54B40EB679F13E4F524465C88E1583D45514CBEB6601E10C897802CCB122F08 - 399EE3D2D168ACDFCEB21F1204F53E4A20FB5005D92F8AC8288264137D7D7DD9 - 7C7DC03C731108040284200825AAAA968B22BA8020B02304493E329D4C2DF6F9 - BC73199BCDA1151CDADD1CE68A1CA231020145F97817EA7681E71E4151650BB4 - D83542D6ACA1110A106BE4D92851A26BD76E383E994A5D68B3D9CE841B7C8D92 - 3673EB144491CB6632C94C3A1B8DC4A2C376BB6D1FCB3ADEC751FC031C978671 - 1C1F4BA71D19928C087D7D7DA2B96958373AEDDC9AD3E9A47339DC8E20824F55 - A53982AC2CE439FEB04C267384C3E1A872391D7E97CBE583C61AD65D277A8A3C - 93C9C433D9CC8B8C9D79647B77F72E3D69032D40000A1058037A23A06D61F0F1 - 3CF22D9ECF9D0FB7A7EB2D3DD6D6A36AA7DA3FF991799ECFC662F1B1642239C4 - B2EC5E92A6F6E028B29724E94104A123BB7743671923AF964FDF6CC8325E2A49 - 428D24C98709A27824C7F14B5D2E67B9DDCE7AED76BB5B3B2CAEFD435114FE9E - 1A39E126D31E9A98F888656C8F9124F29BCECE4EAD15396C2135598E8D1E0E7C - 601A3D8326D5BF6CE346968AA5D612187E0E8E6301B8B8D0A4893649585A5D92 - 4EA713D96C2E99CBE5E2A9747AC4E3760FD958DB882408A304410DD334352E6A - 0E5A00001C0049444154A2D0589851D58C2CCB3C6C85286EF2B5020341100641 - 9C0C82880E5916CA2449AC1264710E43DB2AB3D96C75341CAD723A9D1536D6E6 - B6D918274DD32C4992B095AAB8A903EF5F4080E3B8B420894155421E2D29B1BF - F2E28B2FC276515831BA240005882ED302A23E2510080416A92A79B62009FFEE - 71BBCBE12923AC0DA311D0CE95643399442A938965B3B988C7E31EE1B2B97192 - A63F2471E2039442065189884A3634CDCA722614F22B6565134A2010505A5B5B - B5A796F0E472EA494791D65674D3BBEFA2EFBE8BE06565135A630B4210301F8E - 233EADC840646531C70B8B6D369B3F1E8BD5D81D0E1F6B63DC4E970BBAF14D9D - 37CC283201EDEDAC567C9004FE24C7894F6CDBB6F57DF8EC287252C0FD171280 - 02041688EE09B4B4B4B8C2E1C4D7731CF7C3CACA8A25F00452F7290381872020 - 8AA22049922808628E17F84C3A950E0B82902C2D2D8DF03C17B5B3EC284D3323 - 922446701C1F47513C86E3724A55D50C67B70BCA042DF5F66ECE591DF4A76F31 - 689AA6780C63514EB5ABAAE4E565A982C2302FCF0B55199E9B4311A437128996 - 3234ED763A9D651445D9288AB4699F25705EC3EAABC81CF10F0E0EBD61B3DB9F - F03899E7DBDBA1CB9539B26AEE28A00031777E4D139D7600D4E1F02C4FE5B217 - 3859FB4696655DD0AED734E98540FE8180F634339BCBA52451E44541C8E6383E - C5F37CD25BE20DC9A21873389C215191E3344D8665414950141E952425ADAA48 - 4251900C8611228264259AA63F6E81234992EC743A95542AA5F8FD7E65FFFEFD - AAD3E95483C1A05CCCA7A49B366DC2272626D050C88F696F299C4E27168DFEBF - F6EEC43BAEABBE03F8BBCB5B671F2D23D9710C5989035950A8318EC3244A0226 - A440419CD05068A1ED39F4AFD07F514E4BCB9642A95A28A4C1B53166F0929082 - 2001E2EC8BB3581E8DA4D12C6FBFF7DDF24C424359629F8C46B37CE71C4713FB - CDBDBFDFE7F712F9A7F7EEBB84D9B64719634C085397B2ADA7572FA4A4658D33 - 5BC5498919B424C2688673A3E8BADD8A6E18858DE6FA8CCE8DBC699A59D334B2 - 3A37AC4CD6C9E3E482C0280B74BBDDF5308A8E646CFBF3C78E1D393ECAB922B7 - D1124003325AF51CF56CD205EA153F94F74451F4B9D99999AB463D61E40781D7 - 0BA46B4DD2E6E4D5D7F9F749A21221E2D00F82761C45611C0B3F8E22776A7AAA - 2D93C413B1F00AF9FC4624A42B65DC310C735349E9091185499278BA6EB4A54C - BC288A03CDD07C2A78A49426188B22C6980AC33049BFA6BFFE7F3538E74A08F1 - 9BEF235164522925711C49D2AF4A293D4A176913C2694CAC249106E7CC0884C8 - 11A2D93AE72627C4F2C3B8A4339AD37533EFFADD2983EB596E70BBB1BA56E25C - CFE95CB7B8C12D83EBA693710AE90F1FD257FAF5D5DB32CFFF06CE16088C93C0 - 6A63F579D3B4BE60EAE4CBC78E1D3BBB9D3F4C182777E4DA1B013420BD71C428 - 7D14B8FBEEBB9D8D0DF7BD8A687FAB735ACD6432C53E4E8FA920307402511405 - E7F7034812994829D2F7894ADF2752C432964AC6E7DF4B19AB2411E99FA9F41F - 42F849A21421DAAF7B9D3FB81C85684469E47C4B4028A78C1AE9BB571B044A28 - A18C324E29E1E913A318E53AE38C334A984628E39C71CAD27FA7DC344D1B6BBD - 86EE1443C07D14F07DBF23A5AC2552FE03E75A0D0FB4E8233EA6EA99001A909E - 5162A07E0BDC72CB9D6F4D92E8DE308A3F3B3151DE95FEC5A6DF31603E084000 - 021080403F04D21F02AC6FACBF6C9BD67D8CA97F3E76ECD8B3FD98177340602B - 04D0806C852AC6EC9B407A35A4D974E715517F6D99E61DE94F4FFB3639268200 - 0420000108F441E0FC550FA51EA42AF9429CCF1C3EF59DEF74FA302DA680C096 - 09A001D9325A0CDC4F819B6F9EBF8A30ED936EB77B4FA552B91C0BD4FBA98FB9 - 2000010840602B04D267486CB65AE76CD3BE8F1072DF0F7E70F834D67A6C8534 - C6ECB7001A907E8B63BE2D1358585830CED6D7DE4F29FB9CCED801CBB2325B36 - 1906860004200001086CB180E77987A54A3E9FC499EF9F3A85AB1E5BCC8DE1FB - 288006A48FD8986AEB05D27D01A4645711463EEEB9DE5F4C4C942F658CA53B1E - E305010840000210180A817ABDFE543E97FB57A5C852AD76E4974311348284C0 - 4508A001B9082C1C3A3C0277DE7967C60DE2F732CAFECE348C3BD2CDC6F0649D - E1A91F2285000420308E02E913EBA490353F0AFE7ED78ECA034B4B4BE95E3D78 - 4160E404D0808C5C4991D0EB04C8FE5B6FBD8AC464C10FFDBFAC4C4F5F0E1D08 - 4000021080C0200AAC361ACF66ECCCD7384FEE93523E57ABD5C420C6899820D0 - 0B013420BD50C418032D50AD562D21D41D52A9BF320C6B3EE3D8D81D79A02B86 - E0200001088C8F40B7EB36954A4E304ABE1863ADC7F8147ECC33450332E627C0 - F8A4BF486FBBEDF8AC17C87BA330FC9B9999CA15E3933B328500042000814113 - 48F7F558ADD79F316DFBAB9641BF7ACB2DB7BCB4B8B8980C5A9C8807025B2180 - 06642B5431E6C00AA46B433A9DF86621A34F19867147A1909F1AD86011180420 - 0001088CA440BBDD6E8441F87D66E85FB1747202BB998F649991D41F11400382 - D3632C05E6E7E72BAD96F761D7733FB36BD7AE1B186358A43E96670292860004 - 20D03F012144FCF2CBAFFCD2B6AC2F398EBE74E2C48995FECD8E992030380268 - 4006A71688A4CF02E9BE21F57AF36A4D4B3EEABAEE272A333357F539044C0701 - 08400002632090DE6E55AFAF3E9F71EC7F13422EB55A95C74E9F5E8AC62075A4 - 0881DF2B80060427C6D80BECDFFFA739425AD548CA4F9ABA717B2E972B8F3D0A - 002000010840A02702AEEBB6442C6A49A2BE9CC9E8C78E1E3DDAEAC9C0180402 - 432C800664888B87D07B27B0B8B8486BB55AB9DB8DEFF103EFB3BB775F7A43EF - 46C7481080000420308E022B2BE79E3074FE4FA699F9C6F1E3EF7945D3B0C87C - 1CCF03E4FCBB026840705640E07502BF7E642FB97EB3D5BED7B6ADBBA6A6262F - 0310042000010840E04205D2DBAD9ACDE65921C477F3A5F29793C8FD69AD560B - 2EF4F3380E02E3208006641CAA8C1C2F5A60616181ADAC340E4AA53E635BD69D - A6693AD849FDA219F101084000026325E0FB7E5B29EDC1200AFE316B1BDFC7ED - 5663557E247B110268402E020B878E9740DA84341A8DD98E177FD0ED743EB573 - E78EEBD34664BC14902D0420000108BC91401CC761BDBEFA7836E3DCC7B3D637 - 2B85C28B4B4B4BF28D3E873F87C0B80AA00119D7CA23EF8B12D8BBF7C0758C91 - 3F0BC3F013E58989DDBAAE9B1735000E8600042000819113888588D6D7D69ECF - E70ADFD234F50DDBE68F1F3A74281CB9449110047A2C8006A4C7A0186E7405F6 - EC5930329957DE2DA4F8B463DB1F28148B33A39B2D328300042000813F26D0E9 - 74D67C2FFCAE65E95FF4FDCEA9E5E5E518621080C08509A001B930271C0581DF - 0854ABD54921D48148C87B0CDDB82D9FCF4D82070210800004C643A0DDEE3492 - 441C6786F175A6C40F6BB5DABAA6696A3CB2479610E88D001A90DE3862943114 - 989F9F9FD8DC743F92CFE7EEE5BABE8F736E60A1FA189E0848190210187901A5 - 944AD779504A7FDCED74BFCE98F59F274E1CC62EE6235F7924B855026840B64A - 16E38E85407A5B56A9B4F6D6380EEFEA74DD3FDFB163768F699AF658248F2421 - 0001088C89C04B2FBEF4B37C3EFF6FC462DF9C2D975F585AC22EE663527AA4B9 - 45026840B60816C38E97C0DCDC9C6E1899B7691AF958D7EB7EAC323D7D996118 - D67829205B08400002A32320D205E6EB1B2FE673B96F699AF61F4A458F623F8F - D1A92F32D95E013420DBEB8FD9474C206D4418336F0AE3E8D38E93F950090BD5 - 47ACC24807021018078156AB550F7CFF30E7D6976C9B3C84C6631CAA8E1CFB29 - 8006A49FDA986B6C04F6ED7B5F594A6F9F10D1C718E7B74D4D4D5E3A36C92351 - 084000024328206522DBED565DC4B2C64DFEEF2627276AB5DADA10A682902130 - F002684006BE4408709805F6EFDF9F131A3B9044F25ECBB6DE97C938454A291B - E69C103B042000815112489244BAAEDBD434728A33FD2B4A05C76AB5DAE628E5 - 885C20306802684006AD228867040516E9FCFC89521425378771F471CEF45B8B - C5C2EC08268A94200001080C95406B73F35CDA78E896B1242376ECC48943E915 - 0F3C5277A8AA88608751000DC830560D310FADC0FCFC7C4508754B18C71FA584 - 55D33D4470456468CB89C0210081211490528A6EA7B34628FB11E5F45B9293A3 - A7BEF7BDB343980A4286C0D00AA00119DAD221F0A115585CA4FB0E3F54642CDE - 2FA4F824E7ECB67C3E8FCD0C87B6A0081C02101816814EA7936E1A788A68E46B - 4AF1E3F3F3FBEA8B8B8BC9B0C48F3821302A02684046A592C863180548B55AAD - C409794F1C861FD6345A9D9C9CD8358C89206608400002832A90AEF168B5DAAB - 1A5127755DFFB666B0E3348A566AB59A18D498111704465D000DC8A85718F90D - 85C0C18307F3ED76B83F8E834FE8A6F9FE5C365BC6AD5943513A040901080CA8 - 40DA78743ADD0DA591538C907F711C7EECF0E1C31B031A2EC282C05809A00119 - AB7223D94116585C5CA4478FFEB8203577AFEFF91F619CDD59999A7ACB20C78C - D8200001080CA2C0FAFAC6CB49921CB74CE39B8CA91FD66AB5F4D62B2C2E1FC4 - 6221A6B114400332966547D2832E70FBEDB7173A5E9436221F229A569D9828EF - B62C2B33E871233E08400002DB2510C771B8B9D93C9B2875DC36CD6F73ECE3B1 - 5DA5C0BC1078430134206F48840320B06D0264CFC2829E3D73F63A6EE81F6CB7 - DA1FB9E4929DD7E2D6AC6DAB07268600040654A07E6EF5E95229FF4010C86F4B - 597AF8A18796025CF118D062212C08689A860604A701048640606EEE6E87D9CD - 2BB52879DFE666EB439599CA35994C268F6664088A87102100812D11705DAFD5 - 585B7D66A2547E8073FDBB96C51E3F74E8507B4B26C3A01080404F05D080F494 - 13834160EB056EBA69FFD55246B7E54BA50FCA387E57160BD6B71E1D33400002 - 0321902E2C8FA2C8A78CFDD8EB761F304DFBBF2727F34F2F2D2D450311208280 - 00042E48000DC80531E120080C96C09E3D0BC6E464ABA269C9BBFCD07B7F2254 - B532337DE56045896820000108F44640CA246E369B67352D39EED8D9EF729E3C - 582A95CEA1F1E88D2F468140BF05D080F45B1CF341A0C702D56AB5E8C7EA4683 - D2DBD7379AB74F4F4F5D6DDB769E1082FFBE7B6C8DE1200081FE09A4573BC230 - F4D6D7D79F9D9C98FA4114054708B1974F9C38D4E85F1498090210D80A01FC05 - 652B54312604FA2F40F6EC59D0272636AE08C3E0B64C36737714C537140AF9E9 - FE87821921000108BC39816ED76D729DFFD4F5BC4326378EB86EF389E5E5E574 - E3403C4AF7CDD1E2D3101808013420035106040181DE0954AB559E18C6AC8AE4 - DEAEEBBE4F93EAE672B9B4CB344D3CC6B777CC18090210E8B140BAB6A3D56AD5 - 89C64E998EF15F26270FEABA5E3F74E850D8E3A9301C0420B0CD026840B6B900 - 981E025B29B077EFC13CA5EEDB19A3776C3437EFDAB173C73B386306A5946EE5 - BC181B021080C0850828A59410223A57AF3F35599EFC9E1BFA0FE41D63F9E8D1 - A3AD0BF93C8E8100048653000DC870D60D5143E0A204F6EDDB673B8EB3ABD5F1 - 0E30C2EF504ABEBB502CCEE8BA6E5ED4403818021080400F04924425CDE6E68A - AEB347C2203C92C9648F1986F6FC9123473CDC66D503600C01810117400332E0 - 05427810E8B5C0810307A7A4746FD475BDBA72AE7E606A6AEAEA4CC62970CE8D - 5ECF85F120000108BC26902E2AF73CBF7D6EE5DC9395CAF443918C7F482DFD27 - 0F1D3B76164D07CE13088C97001A90F1AA37B285C06B02646E6E8E6732133342 - 447BC3C8BF3B49B47DB3B33378942FCE110840A0A702499224EBEB1B6788467E - 6C9AE6FD84D0875D77E3052C2AEF29330683C05009A00119AA72215808F45E60 - 6161816D6C6C14C330B9228CE39B4DC3A8C6B1B8319FCF4EE216ADDE7B634408 - 8C83809452B4DAED55C3307E212271C230F8F7354D3C53ABD5D671B5631CCE00 - E408813F2E80060467080420F05B027BF7CE57148B6EF2DAEE0712A20ECC562A - 5770AE1B8C51062A084000027F48404A29E358846B6B8DE708650F676CF37ECE - C94F8F1F3FFE12D420000108BC5E000D08CE070840E0F7082CD26AB5E6F8BEBC - 9452724318C7B74819BFA75C9A788B6D5B399041000210784DC0F7FDF6E6E6E6 - CB866E9C324DBDA669EC1752FA2F9C3A75AA032508400002BF4F000D08CE0B08 - 40E00D05F6EFDF9F534ABF5C4AF15E8D907D6114BEA35828ECB42C2B4B29AE8C - BC21200E80C08809A44D87EBBAEB9CE9FF4388F62329E571CB62CFD56AB5CD11 - 4B15E94000025B208006640B503124044655205D2FD26834745FCAAB222F7E8F - 6599B74561F4CE8989F22E3C456B54AB8EBC20F07F028DC6DA738669FC52C6E2 - A8EEE8A792307C7AC78E1DDED2D2928413042000810B15400372A152380E0210 - F82D81B9B939DD71A68B84C4978461708BC6C8BE288C6ECCE7F3958CE314C005 - 01080CBF407AA5A3D56AD74DD37C5425C98396653E24A5FEACE7AD6E2E2F2FC7 - C39F2132800004B643000DC876A8634E088CA0C0CD37DF5522C47FAB1706FB75 - C66F1522BEA1542AED608C71DCA6358205474A232990EED5913EC1AADDEEAC1A - A6FEA88CE50F749D9F90D27AE6E4C9079A23993492820004FA2E8006A4EFE498 - 1002A32DB067CF825128B4B39486970551F4274AA9770B11DF34512E5F62DB36 - 16B08F76F991DD900AB8AED76AB59A67B96EFC8428ED478E63FF8C73ED29C330 - BA870E1D0A87342D840D01080CA8001A90012D0CC282C0A808BCB6803D08FCFD - 4A9177F981776DB95CBAD4B6EDAC699ACEA8E4893C20304C025114F9BE1F74D7 - D6D65E7032F6E354E3CBBAC34E72A59E3F79F224AE740C5331112B048650000D - C810160D2143601805D205EC8F3DA6B162717D368EFD6B28E7FBD656D76E9D98 - 2C5F363939B973187342CC10182681245149ABB559DFD868BE50999EFA6192C8 - 073927BFB06D7B259BCD0A2C241FA66A2256080CB7001A90E1AE1FA287C0D00A - CCCDDDED50DA9A502ABA5CD3B41B854CAE0F02FFEDB97C613697CD142CCBCA0C - 6D72081C0203201086A1EFF97ECBEDBAEBBAAEFF9C51F20821DA239C3B4F0465 - 7B6DF9FEFBBD0108132140000263288006640C8B8E9421308802D56A35DBEDC6 - 3B1392BC9512B277BDB176A05C2E5F5E9E28CF524AD385EC941082FF670D62F1 - 10D34008BCB680BCD3E936571B8DA766672A0F26523EAC1479328E0B679697D1 - 700C44A110040420A0E19B394E02084060E004AAD5AA25A5CCC5B1BA4C08797D - 24C4F571145D97CFE77767324E29DD0071E082464010D80681388EC37443C04E - BBF38A65598F525DFF1927E4E742B0A785703ACBCB7381A62D26DB101AA68400 - 0420F00705D080E0E4800004065EE0BAEBEECC50A73D4542798565593746425C - EB79DE9585427E976D39455DE72636421CF83222C03729905EE188E2380883B0 - DBDADC3C93CD679F36B8FE7810478F32933FE11AC6CACF8F1C71DFE434F83804 - 2000812D174003B2E5C498000210E8A540BA98BDDBEDF2D576BBA2FCF80ADDD4 - AF9352BDD375BD6B8A85FC8E5C2E37C539D77B3927C682C0760A743A9DB576BB - 7DCEC9669E5089FC0951E4115DB79FA2345AD1344DD46AB5741772B59D31626E - 0840000217238006E462B4702C04203070026943B2B2B292D734B31486E16549 - 22AE495472ADDB75AFCAE5B23B2DDB2E989695B54C138BDA07AE7A08E8F50251 - 140541107482206C77BA9DD56C36FB94A95BA709D77EA904795229BD592C5217 - FB72E0BC810004865D000DC8B05710F1430002BF23303737A7F35CAE42C3644A - D3C85B98CEAE4F44727DD7EF5E5DCC17672CCBCCA4BBB36387769C3CDB21A07E - FD4A5E5B34BEB6DE7C3197CD3CA3A9E49184904734A69E55216D4451ABB9BCBC - 8C27556D479130270420B0A5026840B69417834300028320B06FDF3E3B9FCFDB - 51A4CDC67170591425578451F036CFF3AEC966B333D98C53CEE5F31383102B62 - 184D0129A5705DB7E9FB7EABD56ED71D27F3B865998F33C29FB22CEBE93866AB - 9CBB7EAD5A8DB4452C1A1FCDB30059410002AF09A001C1B90001088CA540DA94 - D8B65D0EC3649610729522DAD551185DB1D16CEE2A16F297589695334DD3669C - EB3AE7C6582221E98B12482F6B0821A2F45718865ED775373AEDCED97C3EFFA2 - 6199CF198C3F4D0879867355D7346DB356AB752F6A021C0C010840604404D080 - 8C482191060420F066041669B55AA3B66DA70BDCCB4290194D53BBA54CAE0CA2 - E8CA7C3E77C9C646B3625B66C9B1EDBC93C9141863FCCDCC88CF8E8640B7EB36 - 03DF6FB73B9DF562B170B6D56E9F310CF34983B3A7358DBE645974757D7DA635 - 3DDD486AB5EAAF1E878BAB1BA3517964010108BC190134206F460F9F85000446 - 5AE0E0C183661CC79652CAD2342D1304B29C246A5724E2CBC220DC6DD9C66CB3 - B93993C964A66CCBCE99A6E1E8BA6EA6574E461A668C924B77138F63114651E4 - 7A9ED775BBEE6A69A2540FBC60D574AC170D437F4E23EC0C915ADD3092F411B8 - BFDA77430B6AB59A182326A40A010840E0A204D0805C14170E86000420F06B81 - 6AB5CA196305DF57454A555188784714C5979AB6B5D3F7835DEB8DB54B3259A7 - 9C71B2F97CE1FCA381392124DDD0FDFC8EEEE97B586EAF40BA0A3C7D7CAD525A - BA1EFCFCA2F04EA7D3E8BA5E3BF0BDCD62A974D6308C1702CF7F51D7F97384B0 - 155D574D4248E7E4C993CDED8D1EB343000210185E013420C35B3B440E01080C - 94C022DDB3E7316EDB012F957C7D75D5332D4B14A999994A4231254458D1757D - DAF5BDD9D57A63D6B6AC7447F79C699939C7C9A4574F6CC77172684C7A5F5421 - 441C46911F4791EF05811B8591EBBB5ED70F838DA9C9C9B38E6DAD0821CF1986 - B542A9762E66499D0BE186A1136A5A33F67D5F9C3E7D3AC65E1BBDAF0D468400 - 04C653000DC878D61D59430002DB2450AD56B38D466870AED99A29335A92146D - D3B9248EA39D856CBED2E9BA15C3300AF57A3DCF39B3196726E7BAE3D8768931 - 6630CE0D4629A78C714A084DD7A28C53D3923E4D2A7D846DFA4BA6972DA41452 - CA484A19FB7EB019C7B12744ECC5B170A7A6A75B228EDB8E6DAD4651BC6A18FC - 95288A5F2184B7A2A8E32589E33B4E12349BCDF0F4E9D3D1369D129816021080 - C0D809A00119BB922361084060F00416E9C2C263A4D16890D5D529BA7B77976C - 6E6E522144210C89AD94CCEA3A2B726E148412933A3526FCC09DE5BA5132743D - D768ACE638E33665D4208C1906633A65DC608CEA8C338351C609A5FC7CE34229 - E3BA6EEA9C9B83E0906EBCF7EAFD4F3291899049F26A4391C48912B188652485 - 0C62294299C4DEF4C4743B96B21B45613B97C9AC0A21D738A76B49A25A52269B - 9A46DBBE1FBBB91C6D178BC5E4CC99336A7A7A3A999A9A524B4BD7FE6AB7702C - 021F84BA2306084060BC05D0808C77FD913D0420308402E9E278DFF7F54E8733 - C37019E79C0501639C872C208413A5743DE10635F4AC0C4556D7358B52EAB841 - 90E584598430D334B9B5D96EA7B77C59941243D3286784304514211AE5F5D555 - 53494114A1AF7E9F50846AE7DFFFB1EF1B2AD11245D22B1494CA99A9E950D3B4 - 44239A4C94A60839BFF95E2CA516940A3937D188AFA40CE338F62DCBEA2689F0 - 84203EE7A423846C13426342A29810120B2164FA945BC77124E75C514A451445 - B256ABA58BBEF1820004200081211240033244C542A810800004FA21B0B0B0C0 - 5AAD96F5F2CB2FFFCEF708294BBFF37B8C357F7565E1B75FB66D87CBCBCBE9BA - 09BC20000108400002BF25800604270404200001084000021080000420D03701 - 34207DA3C64410800004200001084000021080001A109C031080000420000108 - 400002108040DF04D080F48D1A1341000210800004200001084000026840700E - 40000210800004200001084000027D134003D2376A4C04010840000210800004 - 20000108FC2F6CEDD0B06C74B3B90000000049454E44AE426082 + 1754506F727461626C654E6574776F726B4772617068696373B4000089504E47 + 0D0A1A0A0000000D494844520000042B0000042B0806000000A5CB265100000A + 3A69434350735247422049454336313936362D322E31000048899D5377585377 + 173EF7DEECC14A88808CB0976C81002223EC215396A8C4244018218604DC0311 + 15AC282AB21445AA0216AC962175228A8382A8E0B6204544ADC52A2E1C7DA2CF + D3DA3EFDBEAF5FDF3FEE7D9FF33BE7DEDF79DF7300680121227116AA02902996 + 4923FDBDD971F1096C620FA0400602D801F0F8D992D028BF680080405F2E3B3B + D2DF1BFE8497038028DE57AD02C2D96CF8FFA0CA97486500483800380884D97C + 00241F0032726512457C1C00980BD2151CC529B8342E3E0100D550F094CF7CDA + A79CCFDC53C10599620100AAB8B344902950F04E00589F23170A00B0100028C8 + 11097301B06B00609421CF140160AF15B599425E36008EA688CB84FC54009C2D + 00D0A4D1915C00DC0C00122DE50BBEE00B2E132E92299AE26649164B4529A932 + B619DF9C6DE7E2C2610708733384329955388F9FCE930AD8DCAC4C094FBC18E0 + 73CF9FA0A6D0961DE8CB75B2737172B2B2B7B6FB42A8FF7AF80FA1F0F6337B1E + F1C93384D5FD47ECEFF2B26A00381300D8E63F620BCA015AD70268DCFA2366B4 + 1B40391FA0A5F78B7E588A794995C924AE3636B9B9B9D62221DF5A21E8EFF89F + 09FF005FFCCF5AF1B9DFE561FB089379F20C195BA11B3F2B234B2E65674B787C + 21DBEAAF43FCAF0BFFFE1ED32285C942A950CC17B26344C25C913885CDCD120B + 44325196982D12FF2713FF65D95FF079AE018051FB0198F3AD41A59709D8CFDD + 806350014BDCA570FD77DF42C831A0D8BC58BDD1CF73FF099FB6F9CF408B158F + 6C51CAA73A6E64349B2F97E67C3E53AC25E08102CAC0044DD0054330032BB007 + 6770034FF08520088368888779C08754C80429E4C232580D0550049B613B5440 + 35D4421D34C261688563701ACEC125B80CFD701B0661041EC338BC8449044188 + 081D61209A881E628C5822F608079989F822214824128F24212988189123CB90 + 354811528254207B903AE45BE428721AB980F421379121640CF915798B62280D + 65A23AA8096A8372502F34188D46E7A229E84274099A8F6E42CBD01AF420DA82 + 9E462FA1FDE820FA189DC000A3622C4C1FB3C23818170BC312B0644C8AADC00A + B152AC066BC4DAB12EEC2A36883DC1DEE00838068E8DB3C2B9E10270B3717CDC + 42DC0ADC465C05EE00AE05D789BB8A1BC28DE33EE0E9786DBC25DE151F888FC3 + A7E073F105F852FC3E7C33FE2CBE1F3F827F49201058045382332180104F4823 + 2C256C24EC2434114E11FA08C384092291A849B424BA13C3883CA28C58402C27 + 1E249E245E218E105F93A8243D923DC98F94401293F248A5A47AD209D215D228 + 6992AC423626BB92C3C802F2627231B996DC4EEE258F902729AA14538A3B259A + 9246594D29A33452CE52EE509E53A95403AA0B35822AA2AEA296510F51CF5387 + A86F686A340B1A97964893D336D1F6D34ED16ED29ED3E97413BA273D812EA36F + A2D7D1CFD0EFD15F2B3194AC950295044A2B952A955A94AE283D55262B1B2B7B + 29CF535EA25CAA7C44B957F9890A59C54485ABC25359A152A97254E5BACA842A + 43D54E354C355375A36ABDEA05D5876A443513355F35815ABEDA5EB5336AC30C + 8C61C8E032F88C358C5AC659C60893C034650632D39845CC6F983DCC717535F5 + E9EA31EA8BD42BD58FAB0FB23096092B9095C12A661D660DB0DE4ED199E23545 + 3865C394C62957A6BCD298AAE1A921D428D468D2E8D778ABC9D6F4D54CD7DCA2 + D9AA79570BA765A115A195ABB54BEBACD693A9CCA96E53F9530BA71E9E7A4B1B + D5B6D08ED45EAABD57BB5B7B424757C75F47A253AE7346E7892E4BD753374D77 + 9BEE09DD313D86DE4C3D91DE36BD937A8FD8EA6C2F7606BB8CDDC91ED7D7D60F + D097EBEFD1EFD19F343035986D9067D06470D79062C8314C36DC66D861386EA4 + 67146AB4CCA8C1E89631D998639C6ABCC3B8CBF89589A949ACC93A93569387A6 + 1AA681A64B4C1B4CEF98D1CD3CCC169AD5985D33279873CCD3CD779A5FB6402D + 1C2D522D2A2D7A2D514B274B91E54ECBBE69F8692ED3C4D36AA65DB7A2597959 + E55835580D59B3AC43ACF3AC5BAD9FDA18D924D86CB1E9B2F960EB689B615B6B + 7BDB4ECD2EC82ECFAEDDEE577B0B7BBE7DA5FD3507BA839FC34A87368767D32D + A70BA7EF9A7EC391E118EAB8CEB1C3F1BD93B393D4A9D169CCD9C839C9B9CAF9 + 3A87C909E76CE49C77C1BB78BBAC7439E6F2C6D5C955E67AD8F517372BB774B7 + 7AB787334C670867D4CE18763770E7B9EF711F9CC99E993473F7CC410F7D0F9E + 478DC77D4F434F81E73ECF512F73AF34AF835E4FBD6DBDA5DECDDEAFB8AEDCE5 + DC533E988FBF4FA14F8FAF9AEF6CDF0ADF7B7E067E297E0D7EE3FE8EFE4BFD4F + 05E0038203B6045C0FD409E407D6058E0739072D0FEA0CA60547055704DF0FB1 + 089186B487A2A141A15B43EFCC329E259ED51A066181615BC3EE869B862F0CFF + 3E8210111E5119F120D22E7259645714236A7E547DD4CB68EFE8E2E8DBB3CD66 + CB6777C428C724C6D4C5BC8AF5892D891D8CB3895B1E77295E2B5E14DF96404C + 8849D8973031C777CEF63923898E89058903734DE72E9A7B619ED6BC8C79C7E7 + 2BCFE7CD3F92844F8A4DAA4F7AC70BE3D5F02616042EA85A30CEE7F277F01F0B + 3C05DB0463427761897034D93DB924F9618A7BCAD694B1548FD4D2D42722AEA8 + 42F42C2D20AD3AED557A58FAFEF48F19B1194D99A4CCA4CCA3623571BAB8334B + 376B51569FC4525220195CE8BA70FBC27169B0745F36923D37BB4DC6944964DD + 7233F95AF950CECC9CCA9CD7B931B94716A92E122FEA5E6CB178C3E2D1257E4B + BE5E8A5BCA5FDAB14C7FD9EA6543CBBD96EF5981AC58B0A263A5E1CAFC9523AB + FC571D584D599DBEFA873CDBBC92BC176B62D7B4E7EBE4AFCA1F5EEBBFB6A140 + A9405A707D9DDBBAEAF5B8F5A2F53D1B1C36946FF8502828BC58645B545AF46E + 237FE3C5AFECBE2AFBEAE3A6E44D3DC54EC5BB3613368B370F6CF1D872A044B5 + 6449C9F0D6D0AD2DDBD8DB0AB7BDD83E7FFB85D2E9A5D53B283BE43B06CB42CA + DACA8DCA3797BFAB48ADE8AFF4AE6CAAD2AEDA50F56AA760E7955D9EBB1AAB75 + AA8BAADFEE16EDBEB1C77F4F4B8D494DE95EC2DE9CBD0F6A636ABBBEE67C5DB7 + 4F6B5FD1BEF7FBC5FB070F441EE8AC73AEABABD7AE2F6E401BE40D6307130F5E + FEC6E79BB646ABC63D4DACA6A24370487EE8D1B749DF0E1C0E3EDC718473A4F1 + 3BE3EFAA9A19CD852D48CBE296F1D6D4D6C1B6F8B6BEA341473BDADDDA9BBFB7 + FE7EFF31FD6395C7D58F179FA09CC83FF1F1E4929313A724A79E9C4E393DDC31 + BFE3F699B833D73A233A7BCE069F3D7FCEEFDC992EAFAE93E7DDCF1FBBE07AE1 + E845CEC5D64B4E975ABA1DBB9B7F70FCA1B9C7A9A7A5D7B9B7EDB2CBE5F6BE19 + 7D27AE785C397DD5E7EAB96B81D72EF5CFEAEF1B983D70E37AE2F5C11B821B0F + 6F66DC7C762BE7D6E4ED5577F0770AEFAADC2DBDA77DAFE647F31F9B069D068F + 0FF90C75DF8FBA7F7B983FFCF8A7EC9FDE8DE43FA03F281DD51BAD7B68FFF0D8 + 98DFD8E547731E8D3C963C9E7C52F0B3EACF554FCD9E7EF78BE72FDDE371E323 + CFA4CF3EFEBAF1B9E6F3FD2FA6BFE898089FB8F732F3E5E4ABC2D79AAF0FBCE1 + BCE97A1BFB767432F71DF15DD97BF3F7ED1F823FDCF998F9F1E36FF784F3FBC5 + A88942000000097048597300002E2300002E230178A53F760000A9DF49444154 + 789CECDD09DCA563FDC7F1CF98B1EF3B214568232AADF65D11424264977F8B25 + 4B511115DA14490BA1B2B7D82949D142F67DDF22FBBE8D6566FC5F97AED12CCF + 729E73EEFBFCEEE5F37EBDCE6B06CF3CCFB7E679CEB9CFF7BEAEDF35EAD5575F + 459224499224A92AA6890E2049922449923429CB0A4992244992542996159224 + 499224A9522C2B244992244952A558564892244992A44AB1AC90244992244995 + 62592149922449922A65CC701FF0D1F536EC4F124992146D76605E60EE491EF3 + E47F9FCC30C9C7CE38C4E7190FBC3CC93FBF04BC9A7F3F36FFFEA5FCFBE4C5FC + FB17F3E3E5FCEB73F9DF3F9F7F9F7E9524490D71CED9A7775F564892A45A9A6B + 92B261D25F27FE7ECA7F9EBB26D70563737131B1C878363F9ECABF3E937F3FF1 + F164FEF509E0B1FC7825FA7F8424491A5A1D2E4A24496AB35153AC749874E5C3 + 50054453B77ACE981FE9FF876E3D334971F1F814BF7F6892C7C3F9D77105E697 + 24491DB0AC9024A97F460FB2D261CA7F9E722B868A355B7E2CD6E1C73F9A4B8B + 077381F100701FF01FE0DFC0FDC02325679624A9552C2B2449EACEB453940C73 + 0DB2D261D27262CEE8D0EACABCF9B1F4101FF3522E30EE9FA4C0B81BB827FF7A + AF2B342449EA9C65852449C34BDB0EDE03BC373F9607968C0EA54A991E784B7E + 0CE4D55C66DC95CB8BBB7291917EBD3DAFDE902449996585244953AF9878777E + 2C9F1FEF8C0EA546CC1E79637EAC32C07F7F1AB8231717B702B7E5C7AD7970A8 + 2449AD625921496AFBEBE032B99898B86262D9060FA75475CD9E57EFA4C794D2 + AC8C1BF3E3A6FCB8390F049524A9912C2B24496D2C26266EE948C584AF85AABA + 05F3638D29FEFD43B9B89858625C0F5C9B8F759524A9D6BC4093243591C584DA + 6081FC586D8A7F9FE6605C938B8B6B738971779E9B2149522D78D126496AC271 + A0936EE5B09850DB2D961F1F9FE4DF3D035C075C39C9236D25B1C09024559217 + 7292A43A99261F1F3971C5C4C41913D34507932A6E366085FC98E8855C5A5C91 + 7FBD0AB8C50243925405961592A42A9F9EF0B6BC52626231917EB598908A3113 + B0627E4CF43C7019F04FE0F2FC782030A324A9A52C2B244955F1C649B671BC1F + 781F304B7428A96566CE3330269D83F16FE06FB9C0B82CAFC0181F985192D402 + 961592A408734D514CA4C7FCD1A1240D5A246E911FC94BC03F808B272931D28A + 0C49920A63592149EAC700CC65F34A890F021F02168F0E25A96BD303ABE60779 + C6C5959394177F071E09CE2849AA39CB0A4952D1D20A890F4C524CBC2FBFB991 + D4DCF93213574AED91FF5D1AD479217011F057E0B1E08C92A49AB1AC9024F5FA + 26E5EDB99C48A70C7C1858223A94A4706FCD8FCFE67F4EC7A6FE09F84B2E2FD2 + 51AA92240DCAB2429234D22D1DEFC9A5C44AF91481B9A34349AABC65F263E2CA + 8B74CAC805B9C0B80418179C4F925431961592A4E1CA89B48D63E5BC3F3D9513 + 33468792547BCBE7C7BEC08BB9B4F843FEF5D63C074392D462961592A4494D93 + 574EAC928F2E4CAB27668A0E25A9D16600D6CB8F8947A59E9F575EA402E3D9E0 + 7C92A400961592A4B7E455136BE6C71CD18124D1F6A35277CA8F57F390CEB372 + 81E1AA0B496A09CB0A496A9F997229B136B00EF0E6E8409234C410DFB4CA2B3D + 0E03EE02CE04CECBC33A5F8E0E28492A87658524B5E362FF9DB9A0F848DEE291 + 66514852DD2C06EC961F2FE6D2E274E05C8F4795A466B1AC90A4669A36971269 + 0FF8867959B524356DD6C546F9413E55E4F779CBC81DC1D924493DB2AC90A4E6 + 981D581FF818F05107634A6A9915F3E3FBC075C06FF29691F47BE75C4852CD58 + 564852BDCD97CB894D80B5F2960F496ABB65F2E340E076E0E4BCEAE21A8B0B49 + AA07CB0A49AA9F05818D814DF3D1A292A4C12D017C353FD2F6905380DF01575B + 5C485275595648523DCC9B0B8ACD2D2824A9A7A39AF7CB8F3B737191B68BB8E2 + 42922A669AE80092A441CD066C0D9C0F3C021C6551214985591CD817B80AB801 + F852FE7792A40AB0AC90A46A992E9FDE711AF004703CB0767428496AB8B70307 + E76D2297029F05E68F0E25496D66592149D5782E4E2B267E023C9687C0A58199 + A3A38349520BBD1FF811F010F047602B4F5792A4FEB3AC90A4D83B790701F700 + 7F057606668D0E25497ADD9AC02FF34AB76381D52C9225A93F1CB02949FD3547 + 3EC563FB7CF74E92547DD303DBE4C77F805F002702B7440793A4A67265852495 + 2FDD855B0738396FF3F899458524D5D642F918D49BF37C8B1DF340644952812C + 2B24A93C4B01DFCC77E1CE033673F9B02435CAFB7301FD58DE2EB28AD7D79254 + 0C9F4C25A95833E6616C97E4E5C1E9583C27CA4B52B34D9B9FFB2F026E07F6F6 + B95F927A63592149BD1B052C0B1C0E3C9AEFAEAD101D4A92146231E050E041E0 + 37F9F86957D549D20859564852F76600B6062E03AE063E0FCC1C1D4A92549922 + 7B63E0FCBCDA620F60EEE85092541796159234726F03BE9757511C0F2C1F1D48 + 9254696FCEAF1B0FE7D5771FCE6586246910961592D4F97EE44DF37EE49BF21D + B259A24349926A65749E6DF137E05A60275F4B24696096159234B40581AF010F + 00A7E649EF9224F56A69E0A7C023C0F78125A203495295585648D2D446E525BA + 27E66347BF0ECC131D4A92D4D853A476076E03CE01D67220A724595648D2A4A6 + 073E0D5C9997E86EEE9E6249521F7D04F843DE6EB88B439B25B599658524FD77 + ABC781C043C071C072D1812449ADB624F0E3BC45E43BC0A2D18124A9DF2C2B24 + B5D97BF2691E69ABC7578139A2034992348999803D817B8093800FB8E24F525B + 5856486A9BB40F783DE02FC015C0D65EF849926AE093C03F814B800D9C6B21A9 + E92C2B24B5C50CC00EC0CDC059C0CAD1812449EA421A007D7A7E3DDB21BFBE49 + 52E35856486ABAB980FDF2D1A33FF768384952432C915FD7D256C6BD81D9A303 + 4952912C2B2435551A4676581E9AF90D60CEE84092249554CA1F9A5FEF0EC943 + A325A9F62C2B2435CDD2C02FF330B2DD8069A3034992D407693BC83EC0FDF924 + 91C5A20349522F2C2B2435411A90F921E00CE03A60ABE8409224055EDFEF02DC + 09FC1A7847742049EA866585A4BA97146B007F06FE0E7C2C3A90244915B22570 + 03701AF0EEE830923412961592EAFADCB55E3EC2ED026095E840922455D826C0 + 95F934ACF7458791A44E585648AADB73D6FAC0BFF205D7FBA30349925423A9E8 + BF0C38C7D7504955675921A90E46031BE4BB426702EF890E2449528D7D04B834 + 9716EF8D0E234903B1AC9054F5926223E02AE07460D9E840922435ACB4B81CF8 + 1DF0AEE830923429CB0A49557D6E4A2B29AECE1750CB44079224A9C1D28D816B + 809381B7458791A4C4B24252D59E93D6C93329D24A8AA5A3034992D4229B0137 + 01BF0496880E23A9DD2C2B2455E508D2D5804B80F39C49214952A8AD80DB80A3 + 8085A2C3486A27CB0A49D13E045C981FE9F79224A91A3E03DC0B1C0ACC191D46 + 52BB5856488AF2CEBCD5E3EFC0AAD1612449D2A0C3AEF7061E00F601668A0E24 + A91D2C2B24F5DB1B815F00D7E7219A9224A9FA66000E01EE01B607A68D0E24A9 + D92C2B24F5CB3CC07781BB816DA3C34892A4AECC0B1C0DDC00ACE7FB094965F1 + C94552D9D272D12F03F7035FF4794792A4465812380BB8C0C1D892CAE09B0649 + 6519036C93978B7E0B983E3A9024492A5C3ACDEB0AE07860E1E830929AC3B242 + 5219C790AE0D5C0D1C9B978B4A92A466DB3ADFA03808982D3A8CA4FAB3AC9054 + A477017F00CECFA77D4892A4769D1CF2953C9F6A3B87704AEA856585A422CC0F + FC14B80658333A8C24490A3517700C7019B072741849F5645921A91733E6B3D7 + EF05768A0E2349922A6539E02FC0C9C0A2D16124D58B6585A46E9F3B36026E06 + 0E7578A624491AC266C09DC0D78099A3C348AA07CB0A4923B52C7011F03BEF92 + 4892A411CCB3F87A2E2D3EE1FB1049C3F14942D248F69F1E994FF958293A8C24 + 49AAED9CAB53800B1DC62D692896159286932679EF9CE752FC5F74184992D408 + AB00D703DFF3A8534903B1AC90349415812B819F00B344879124498DB3077017 + B079DE2A2249AFB1AC90349005805F0317034B47879124498D36377022F02760 + A9E83092AAC1B242D2945B3E3E07DC0D6C191D469224B56E6B483A69EC0060A6 + E83092625956489AE883C0E5C011C00CD1612449522B8D02F6076E02D6CEFF2C + A9852C2B24CD956752FC03785774184992A47C3CFAF9795B6A3A414452CB5856 + 48ED9586586D0DDC934FFB902449AA9A2DF2F6D49D8031D16124F58F6585D44E + 4B001700C703B346879124491AC28CC04F818B1CC029B5876585D42E6916C5BE + C02DC0AAD1612449924660853CCBE2CBC0F4D1612495CBB2426A8F15816B806F + FAB32F49926A2A5DC37C0BB80A787F741849E5F10D8BD47CB303470117BB7452 + 922435C4DB814B81EF03B3448791543CCB0AA9B9D2515F1B0077009F890E2349 + 925482DD819B81D5A283482A966585D44CF3022700A703F344879124492AD1C2 + C085C0910E0E979AC3B2426ADECF743AE2EB4E60F3E8309224497DF47FAEB290 + 9AC3B2426A8E370067E41515DE559024496DB4D024AB2C668B0E23A97B961552 + 337E8EB7CEB329D68B0E23499254915516E9A87657594835655921D5DB827935 + C5F1C08CD1612449922A769D9456591C06CC1C1D46D2C8585648F5FDD9FD94AB + 2924499286B51B702DB07C7410499DB3AC90EA677EE077C0AF8099A2C3489224 + D5C0E2C0BF80FD81E9A3C3481A9E6585541FA3808D81DB810DA2C3489224D5D0 + 01C03F81B74507913434CB0AA91EE6008E057EE3491F9224493D590EB801F81C + 303A3A8CA481595648D5B75A3E33FCD3D1412449921AF43EE808E0ACBCC55652 + C58C890E206950691EC541C01ED1412435DA78E099291ECF4EF2FBC781C70678 + 3C0A3C3DC5E79A748ECE8C79FBDAE8BC3F7CA6497E9FA6F2CF907F9D293F26FE + 7E1660F6FCFB19F23F4FFCF733E7C7ACF9E1BE7349BD5A17B80DD812383B3A8C + A4FFB1AC90AA6969E03460A9E820926A5B384C5A3A3C3E48D9F0D80085432F5E + 18E4F7654985C8DCC03CF9CEE87C933CD23FCF99FFFBDC93FCDE6B1F49539A2D + AFB03812D807783E3A90245FB0A52AFE4CFE5F3E0FDC6D5A52BB8C9B6245C370 + 85C3C4B2A1E8C2A14EC602F7E747A752B1F1066061E08DC09B80852629382696 + 1DEE6397DAE7B3C05AC0A6F9A85349812C2BA4EA58200FD15C273A88A452BD0A + DC9B4FF6B92D1FA5971EB744076B898905CF75C37CDC22C09BF363A95C6CA492 + 63C15C6E38EC586AA62580AB805D81A3F2CA3549012C2BA46A581FF8755E8628 + A9399ECCA5447A5C035C065C0EBC181D4CC3BA2F3F2E1EE4BFA7D5176FCD8FB7 + E75263D1FC48273849AAFFF0CD3580EDF3CA36497D665921C54A43E3BE9D971D + 4AAAF7168E3B722971F324AB25D29B5D35D323F9315099316F9E3DF4CEFC5834 + 6F3759CC6B2FA95636003E086C025C121D466A1B5F30A538E96EDC6FF31D3949 + F5F1E024AB25AECCAB25D2AA8909D1C15419699EC89FF363CABBB5A9C4780FF0 + EEBCDC7CB1BC2AC319195235CD974BC9AF0187022F470792DAC2B242EABF74B1 + FA69E067FE0C4A95F6522E246E05AECFA5445A2DF1447430D5D6843CB42F3D7E + 31C9BF4F45C5BB80F703CBE7323BCDC9982B30ABA4C91D08AC0E6C9E4B6B4925 + F38D92D45F6926C58FF359DE92AAE3A129065E5E9A0B8A340C532ADBF83CD0EF + AA3CD06FA2B47DE4437919FADB7281914E31191598556AB395819B808D075839 + 25A960961552FFA465BFBFCB13E525C5BD29BC339FBC3171B5C4A579D9BE5435 + F7E6C749531CBD9ADE30AD022C93B712A67F27A93FD200DD0BF3B690438057A2 + 03494D655921952F2DEFDD0538DCBB61525FBD924B895BF21DEB4BF2AA092F2C + 55678FE57947E931D1E2B9BC581178472E31A60BCC28B5655BC84AC01616DE52 + 392C2BA4F2DBF7349B62D3E820520B564CDC9A4FE2B83C0F434BAB261C7AA936 + B8333F8E996436522A2ED606DE97E761B8FA422ADE1A795BC846C0DFA2C3484D + 635921956759E0ACBCBF5852B1EE076ECCA771FC39AF9A7042BBF45FA9A4FB6B + 7E4C94665EAC95EF042F9B4F2071B59FD4BB79F26BD05EC061B93C975400CB0A + A978E98ED6F6C04FF2EF25F5661C70433E412115131738895D1AB19BF3E387F9 + 9FDF007C24DF197E4FDE4A62792175EF3BF9449F740DF84C7418A9092C2BA462 + CD021C096C1D1D44AAB1E7F38C89B48DE30FF9EEB07326A4623D001C9D1F13CB + 8BF5F3EA8BF73A0C5AEACA26C072C07A795E92A41E585648C54977A5CECC93D9 + 2575EEB9BC9DE39FC039C0DF3D32540A292F7E9A1FC992F978C655F3DDE274F4 + B6A4CEAE07AFCBC7D49F161D46AA33CB0AA918E96ED4A9C00CD141A49A6CEBB8 + 369713BF072EB29C902AE736E0E0FC209F36F209E043C0D26E739486346DBE2E + 4C5B43BE0ABC141D48AA23CB0AA937E968B8AFE417224983BB2FAF98383DAF40 + 1A1B1D48D288FC253F923973719196BA7F38FFB3A4A9ED954FE449A7C279BCA9 + 34429615526FD39F4FC8FB7B254D2E4D43BF22BFB939312F8995D40C4F4EB165 + 24ADBAD83C9F34B294833AA5C9AC9C5F03D705AE890E23D5896585D49D7466FD + F9C002D141A40A199BCF994F5B3B7E956751486AD7AA8B7424EAA78075F21D65 + AF35A5FF5E2F5E9107B09FE4D647A933EE37944626DD2DDA220F03B4A890FE7B + 3CDBE9F9AEEA6C79A5D1511615526BDD0D1C34C9F690CFE4537D5E880E26051B + 9D57E41E92B7114B1A866585D4B9F4C272687EA1492F38525BBD90E74EA43DEB + 73001B0127E7C1999234D17379ABC83AB9CC4CA5E619B9E494DA6AEFFC1A3A57 + 7410A9EA2C2BA4CECC0D9C9D0725496D9D41914EEDD82117141BE423D95CCA2A + A9D3E790546A6E3849C999B68C3D1B1D4C0AB0769E5FF1D6E8205295595648C3 + 7B477E4159333A8814E0E6BCA43B6D7B5A0D380678253A94A45A7B356F1FFB78 + 2E2E3E996F08B855446DB248BEBE4C8337250DC0B2421A5ABA7B7C35B0707410 + A98F5EC8AB265600DE0E7C0D782C3A94A4469A009C02AC0FCC0E7C3ACFB87829 + 3A98D407D303E702BBF9BE4C9A9A3F14D2C0D24C8A2FE53B3FD3468791FA74A7 + F3FABCD569CE3C8FE2EFD1A124B54A9A7BF3CB3CE32215175F00FE990B0DA9C9 + 0E037E02CC181D44AA12CB0A696A3303C70207470791FA74DCE86F800F01CB00 + DF055E8E0E25A9F5D2CA8A23F273D32279C0F52DCEC95183ED985715CD131D44 + AA0ACB0A69720BE6B3E2B78A0E2295ECF6BCBD234D23DF14B8343A90240DE281 + BCDAF16DC0FB80E38047A24349255811B8D6C19BD27F595648FFB31C701DF0DE + E82052894BACCFCF4BAC97CC83335F8C0E2549237005B02D303FB01970A1C726 + AB61DE90E7A5AD111D448A665921FD573A42ED7297DEA9A11E050E0716CA53C7 + D3325349AABB53F31BBAF4E6EE10E08EE840524166002E00760646458791A258 + 56A8EDD220CDBD81DFE5DF4B4DF16ABE33B353BE03B9ABCBA62535B890FD32B0 + 04B02AF0FB3C8F47AABB3474F3DB0E7B575B5956A8EDADF54FF2D02EA9295E01 + CEC843E9DE0DFCDC8174925A24CD9DFA789EC7930A8C9BA203493DDA13380998 + 253A88D46F96156AAB7434E3D9C00ED141A4823C91B77AA421B11B3A305352CB + BD98B786BC0358291F45EE4947AAAB8D818B80F9A28348FD6459A1367A237019 + B07A7410A900E928BFDD8179F3568FC7A3034952C55C926753CD9B0B8C7BA303 + 495D4803E0AF04DE121D44EA17CB0AB5CDB2C035795FAB545713808B818FE6A3 + FC7E90FF9D246970CFE4AD216FCA4736FFCDE74ED5CCC2F93AF683D141A47EB0 + AC509BA4E31AFF95B78048759D47F1BB5CBAAD0C9C1B1D48926AEA37C08A799B + C809C00BD181A40ECD9C8BB6349B456A34CB0AB5C1A83C9BE23CA729ABC67703 + 7F9A8FE74BFB56AF8F0E24490DDA4AF7A97C74F93780FBA303491DBE87FB2DF0 + 398F3655935956A8E9C6005FCF27224875F3207060BE88FE0CF0587420496AA8 + 74D4E957814580ADF3D1CF9EA4A4AA3B0238385FEF4A8D6359A1A61F4DFAF37C + F121D5C9EDC0E7818580FDF3F60F49527FFC2A1FFD9C0671FF19181F1D481AC2 + 3EC031F9BA576A14CB0A35D5AC796FFF36D141A40EA53B7857019B034B023FF2 + AE9E2485BA2817164BE719171E7DAAAA4AAB817E0FCC161D442A9265859A68DE + 7C2764DDE82052075221F14FE023C07B8093A30349922673733E3D24CD0DFA49 + 9E2324557190FC9FF375B0D40896156A9A370297E5B3A8A52A4BC7E5FD155805 + F810707E742049D2901E077601E603BE9DFF59AA9274D3E3D23C7B45AA3DCB0A + 35C93BF340AC374707918629292E00DE978B8A8BA303499246E4A53C2760FE3C + 57E8A1E840D22416CBDB4ADF1A1D44EA9565859A6205E07260AEE820D220C6E7 + D5136968DB5AC095D18124493D3FAF1F98B7877C11B8373A9094A553C4AE70A5 + B1EACEB2424D90F6FAFFC529C8AAF0C5ECB9C072798ECAB5D181244985CF1EFA + 3EF0266067E0CEE840123033F08FBC8A53AA25CB0AD5DD16C039C0E8E820D220 + 2B2996013E0A5C1F1D489254BA9F016F017604EE880EA3D69B16B810F8587410 + A91B9615AAAB51C0E78013A2834803CCA4F813B07C5E49715374204952DF1D0D + 2C01EC04DC1D1D46B4FDFDDE19C056D141A491B2AC505DBF6FF7038E880E224D + 5152A4ED481F04D6CCC35E2549EDF6F33CF0F0F3C0FDD161D46ABFCCDF87E986 + 9F540B9615AA9B31F9B8B083A2834893EC554EC7E5AE9A1FFF8A0E2449AA9C1F + E5E324D329228F4487516B1D0EECEB7B40D585DFA8AADBBEBBC3F3C46DA90A6E + 0036043EE011A492A40E7C3B9F1EF22DE0A9E8306AA56F0007F83E5075E037A9 + EA62FABC947297E820127017F0696069E0CCE83092A4DA0D604EDB5917007E0C + 8C8D0EA4D6F92A70685EB12C55966585EA60C6BCCF2EBD3994223D0AEC052C9E + BF272549EAD64BC067F3F690938157A203A955F6047E90572E4B956459A13A9C + 117D2AF089E8206AB5E781EF010B02DF8D0E23496A94C781CD81770017E481CD + 523FA4B2EC2860BAE820D2402C2B5465B3E5A396D68B0EA2D67A25AFA05830DF + 81484B7725492AC3EDC05AC01A9E28A53EDA1E380E98213A883425CB0A55B9A8 + 3807583D3A885A6942BEBBB554DE7EF46C742049526B5C04BC1BD8C1E34ED527 + 9BE79B331616AA14CB0A55D1ECC0F9C00AD141D44AD7E5BB5AE9EED6DDD16124 + 49AD750CF046E060E0B9E8306ABC4D8113F2AC38A9122C2B543573007F043E18 + 1D44ADF320B023F0AE7C574B92A468AF02FB020B03BF713BA24AF671E0440B0B + 55856585AA644EE04FC0FBA283A855C6E6E199E942F0E8E83092240DE0E97CE7 + FBC3CEB350C936044E02668A0E225956A82AE602FE0CBC273A885A637C1EE0FA + A63C3CD3E9EB92A4AABB2CCFB3D8251FA72D9561837C9CAE8585425956A82A2B + 2A5251B16C7410B5C635C02AF9EEC123D16124491AA19F000BE55F5F8A0EA346 + 5A1F38D5C242912C2B548519157FCA7302A4B23D01EC0A2C07FC2D3A8C24493D + 1EAF9D5658BC0DF86B9E6F2115E9A3CEB05024CB0A556198665ACE28957D4177 + 5CBE0B7578741849920A74775E2DF8A93C2C5A2A7A4BC8AF3DD65411C6847C55 + E97FC7932E1F1D448D77693EABFEC6E82052438C021604E603E6CECFE76999F0 + ACC0F4791ECC8BC033F9F174DE5BFF10F06C7478A9C1D21DF0538023816D81E9 + A203A951A7841C0F6CEDB623F593658522CC069C03BC3F3A881AEDB17CDCDBCF + A3834835F766E0EDC00AC0CAC07B8169BBFC5C0FE4E5EA9700D70137E7ED5992 + 8A91CAC2CFE45584C77AC29A0AF409601CB09D8585FAC5B242FD360B70563E7A + 4B2AC3B87C7769275F4CA5AE4C9757BDAD076C032C50E0E77E03B0797E4C742D + 701A701170555E9521A93737E59B429F070ECA2BA0A45E6D91AFB376045E8E0E + A3E6B3AC503FA565C2BF01568A0EA2C6BA3A6FF9486F78248DCC7BF385E8E7FB + 7C7DF0AE49862CBF9AA7CF9F90575F3CD5C71C52131D9197EFFF329FEEE0BC3A + F56AEB5C2A7F36171752697CC252BFCC9087F3AC1D1D448DF41CB04F1ED66A51 + 21756EC6BCB4F71EE07260F7E01B19691EC666C099C09379C5C5EA3D6C3B91F4 + DFD9311BE64189FF890EA34648AB57BF0D8C8E0EA266B3AC50BF96141F0D6C14 + 1D448D3301380F5834BF684AEAFC34A63DF39B9853F2CF50156D928FB74E39BF + 0A2C161D48AAB1B3F3CFFA31F9942CA917A9DC3EC0F7932A93DF5C2ADB983C95 + 7ACBE8206A9C743CDBA6C0471CD0278D683BDEDEF967E63B35DA0E9A56E71D08 + DC99575D38A059EA7E0067DA2EB922705B7418D5DE57802FE5557152E12C2B54 + A6B434EC7BF945512ACAB83CE17C11E077D161A49A1895875AA6AD1587D6FCC2 + 72FD7C24F115F9741249237719B01470988312D5A36F02BB468750335956A82C + E942F8EBC017A283A8516ECF6F4EB6CB7787240D6FB97C07F5C4BC2DAF29DE03 + FC05F817F081E830524DED9187EBDE101D44B5964A2F6F4EAA7096152ACB1781 + FDA243A831D211A4DF079604FE111D46AA89E9F3568F3474F62D34573A66F59F + C0E9C09BA3C34835743DB0749EFDE42A0B75EBE779CE905418CB0A9561FB7C81 + 2C15E15A60D95C8049EACCFB8007F210CDB648271DDC05EC55A3591C5295EC93 + 5759DC141D44B5958E9E5E233A849AC3B24245DB389FFC2115B19AE21BB9A8B8 + 253A8C54A32D787BE5FDE87345870992EE0EDF97575C481AF92A8B77003FF0C4 + 1075F91A745E2ECCA59E5956A848AB03A7458750235C9397A4A6A30A257566F6 + BC4DCA637C61813CCBE26B79D8B3A4911F4BB90A706F7410D5CE983C4FE8EDD1 + 41547F96152A4A5A36787ECD27CC2BDE8B7935C5727998A6A4CE2C9DB77D3868 + 727269D0F38DF9F420492393CACFC5815F3BD45A2334237031F0A6E820AA37CB + 0A15210D3DBCC83DC22A60E969DAF2E16A0A6964D603AE03668A0E52514BE5BB + C36B4607916A2895145BE56DBE8F468751ADCC0D5C02CC171D44F56559A15EBD + 2137A7B34407516DA5C9E3DF0596016E8D0E23D5485AC9B61B705674909AFC7F + F5C7BCB4DD1580D2C89D91EF929F0BBC1A1D46B5B130F087BC4D511A31CB0AF5 + 62CEBCA262FEE820AAAD3B810FE58180923A372ACFA64867DBAB73DFCF43A0BD + FE9146EE05E0A3B9244DBF973AB16C3E25C4D57F1A315FACD5AD998133F31610 + A99B65A5C7E5EF9F2BA3C348357CED3EB665C79216693BB72E4A3D393CCFC9B9 + 213A886A632DE0E7C0B4D141542F9615EAC674C0F1C00AD141544B69CFEB46C0 + B6C084E830520D5FB74F013E1D1DA4E65602AECAAF679246EEAE5C58FC141817 + 1D46B5B005F01DDF7F6A24FC665137DF33DFCE8396A49178359F18F366F7D84B + 5D6FFDF815B049749086486FB4AEF04E9FD493CF001B028F4507512DEC0AEC13 + 1D42F56159A191DA3D3FD14823F142DEE3BA2EF07C7418A9A645C5E1F9CE948A + 2D2CD2B4FAD1D141A41A3B27DF88F86B7410D5C2B780ADA343A81E2C2B34129B + E5531BA491B829BF21486FB424755F147F2E3A4443BD1FF8BDA784483D790E58 + 05381878253A8C2A2F6D275F2D3A84AACFB2429D5A1138293A846A3744334DDD + 7F67DEDB2AA9FBC164DF8B0ED170EB03FB5B58483DDB373F673D121D44957736 + F0D6E810AA36CB0A7562C97C46B21771EAD413795FFD8E9EC72EF56491FCFCAB + F2A5B2629DE8105203FC05583CFF2A0D66C6FC3DB26074105597658586331F70 + 617E42913AF14FE02DC0E9D141A49A4B831F6F8C0ED132E7E6D73D49BD6F0B59 + 35CF27705B8806333FF04760F6E820AA26CB0A0D65E6BC446BE1E820AA8557F2 + 52F50F014F4687916A6E543EA274D6E8202D74B50337A5C2EC97572C795A8806 + 93B60B9F0ACC101D44D56359A1A1EEE8A57903CB4707512D3C0A7C14D8333A88 + D410E98EE446D1215AEA0DC061D121A406F933B004F0AFE820AAAC34E7E48716 + C59A92658506BBA37700F0C9E820AA85BFE5BDA9174407911A22DD5DFA537488 + 96FBBC83DFA4423D954FDEF9491EC02D4D69276F7A694A96151AC8A7F3346769 + 28E3801FE493629E8D0E2335A82C3EC181C69570B977F9A4C2ED02EC00BC101D + 449574481ED02EBDC6B242535A1938363A842AEFE9FC62B27B7410A961DE047C + 3C3A845E330BB06B7408A9818E03DE0DDC131D449574B2DBD035916585269596 + F29F171D4295776D3ECEF68CE82052035F932F890EA1C9A4A1C1334587901AE8 + 566029B7BC6900A3F3D6E245A383289E6585269A231F1DE411A51ACC84BC3C7D + 39E091E8305203A53B8D0B4587D0548E890E2035D4CBC09A79A0AD732C34A974 + 94A9479ACAB242AF990E3809582C3A882AEB456037E053C0ABD161A486BE1E5F + 181D4203FA642EF42595630F606BE0F9E820AA94B48AF7D7F97D8A5ACAB24269 + 88DBC1F90C6C69200F021F068E880E2235FC9CF9D9A2436850E9286F49E53911 + 781FF040741055CA7AC0371D3ADD5E9615DA2E37DAD240FE91CF46BF2A3A88D4 + 60E922ECDCE8101AD2C6CEAE904A7753BE9B7E697410554A3ACE74DBE8108A61 + 59D16EE96EB9778B34D87C8AA3F3F788CB32A572CDEDAC8A5AF8527400A905D2 + 35C707F3F27FB79D6AD2D9412B468750FF5956B4D71BBD93A721E6537C01D831 + 3A88D4124746075047BE0A4C1B1D426A89AD80FDF2104E89FCBE251DEFAD16B1 + AC68A7998133DD1FAD013C0AACEA9B27A96FD29BDF4F448750C7DE1A1D406A91 + 34536D53E0B9E820AA845980F37CFFD22E9615ED3CBBF8C7C0BBA283A8726EC8 + 17E2EE1595FA3B5853F5E1D649A9BFD2CDB5F73A785359BA4EFD0530263A88FA + C3B2A27DBE908F87922675562EB09E880E22B54CBAE8527DA4D30A3C464FEAAF + 5BF39BD46BA283A832038FF78D0EA1FEB0AC6897D581EF478750A58C03BE037C + 2C0FD594D43FE94DEFB2D121D4D5CC2749FDF52CF06EE09CE820AA84AF031B45 + 8750F92C2BDA230DA4393D3A842A652CB003B0777410A9A57CD35BDF8B6449FD + 974E07590FF8A93758049C02BC3D3A84CA6559D1AE819A69308D44DEEE910669 + 1E1F1D446AB103A203A82B9B7BFD2485FA0CF015E095E8200A1F507D3E305774 + 1095C717DB76FC1D1F012C1D1D44957107F00EE0B2E82052CB9F9BB7880EA1AE + 8C02A68F0E21B55C3A29E4D3C00BD141146A11E004670935976545F3ED086C1B + 1D4295F1B75C543C141D446AB9E9F39B5ED5D39BA30348E22460358783B7DE3A + C057A343A81C9615CDB63C7054740855669F677A515F1178393A8C24168B0EA0 + 9E6C171D40D26B2ECBA799DD1F1D44A1D2B620076E3690654573CD0B9CED9D3B + 01E381EFBAE45CAA945DA203A8275B450790F4BAFBF3AAD19BA38328D4C9C092 + D121542CCB8A669A2EDF459F2F3A88C2BD04ECEA891F52E5581ED65B7A7D1D13 + 1D42D2EB9EC92B2CFE111D44A1EF7FD2D1B6B3450751712C2B9A29EDDB5A3D3A + 84C23D076C021C191D44D25413CCE78C0EA142FE1E2555473A1D6405E0ACE820 + 0AF316E01796C9CD6159D13CEBE67D5B6AB7C7810FE7AD4092AAC537B9CD3043 + 74004903CEE8FA18706CFEBDDA67E3BCAA580D6059D1BCE37B4E8B0EA170F7E5 + A590D745079134A0D9A303A8101F880E2069C821B8DF012644075188EFE6A1F2 + AA39CB8A66DDE14945C5CCD14114EAC63C64EA3FD141240D6ACDE8002A443A32 + 515275ED03EC078C8B0EA210A703F34787506F2C2B9AE320E0FDD12114EAEFC0 + B2C0B3D141240DC9B2A219D2563B49D57608B05B9E67A176990B3805983E3A88 + BA6759D10C696FDE9ED12114EA9C3C54CABB0752F5AD141D4085786F7400491D + 4983C6B7CF27A4A95D5606F68F0EA1EE5956D4DFC2F99852B5531A1E7522B05E + 7410491DBFEEBE313A840A1B943A3A3A84A48EFC0AF804F0427410F5DD9781F5 + A343A83B9615F53F4FF86460A6E8200A2B2A8E02B68C0E22A963BEB96D16FF3E + A5FA3813F8483EDA5DED92DE2F79A3A0862C2BEA2D0D0D72CF6C3B8D070E063E + 1B1D44D288F8E6B659BC8E92EAE5AFC0AAC033D141D45733E583083C72BA667C + 91ADF714F2AF458750883497E22BB9AC92542FBEEE368BE593543F57E4632D9F + 8A0EA2BE7A1FF08DE8101A192F9AEA69DEDC0EAA7DD234EB2FE6E9D692EAC737 + B7CDE27594544FD7011F029E880EA2BEFA623E984035E18B6CFD8C018ECFC7F1 + A85D5E06FE0F383C3A88A4AECD171D40859A393A80A4AEDD0CBC1F782C3A88FA + 2A1D4CE0FC8A9AB0ACA89F34A360DDE810EABB17816D80A3A38348EAC9E2D101 + 54F8895C92EAEB8E7C0CF123D141D4D7F915A702D34707D1F02C2BEA6569E0B0 + E8100A292AD2891F1E512BD5DFA2D10154A837440790D4B37B81F7000F470751 + DFA41535FB4787D0F02C2BEAB5D4F437C0A8E820EAABB1C066C0EFA283482A84 + 6545B32C141D405221EE0796071E8D0EA2BEF932B05674080DCDB2A23ED240C5 + 25A343A8EF45C526F95C7049CDB060740015CAB2426A8EFB7261E10C8BF63805 + 983F3A84066759510FEB019F8B0EA1BE7A01D81038373A88A4423960B359E68E + 0E20A9F02D211F001E8F0EA2BE9803382E1F60A00AB2ACA8BED4F69D101D427D + 35B1A8F863741049A51C3DADE6982D3A80A4C2DD990B0B8F356D877580CF4787 + D0C02C2BAA6D34708C1743AD2B2A36022E880E22A914B3470750A17C7D969A7B + 4AC8878027A383A82FBE07BC3B3A84A66659516DDB011F8D0EA1BECEA8D8D815 + 1552E3979CAA392C2BA4E6BA15580978263A884A970E30380D98253A88266759 + 515D8B03474687505F8F27DD1C383F3A88A452CD191D40859A353A80A452DD90 + 4F8C783E3A884AB718F05D4F5EAC16CB8A6A9A0EF835306D7410F5C54BC0A781 + 33A283482ADDF4D10154A819A203482ADD657996585A01AB66DB19F8587408FD + 8F654535ED9107FBA8F95EC94F8CA7460791543AEFD6348F2B2BA476F813B045 + BEC1A466FB15B0407408FD976545F52C0B1C1C1D427D310ED80D383E3A88A4BE + B0AC90A4FA3A1DD81178393A884A2FA18FF538D36AB0ACA896198193A243A82F + C6035F027E1C1D449224491DDF75DF2DDF705273A5E34C77890E21CB8AAAD90F + 786B7408956E0270503E26499254EF195392DAE52860FF7C3DA7E63A0C785B74 + 88B6B3ACA88EE57359A1667B15381CF87A74104952CF1CB029B5D3B780EFE7EB + 3A35D368E0440763C7B2ACA8CEF68F13A243A82FD27C8ADDA34348920AE19D55 + A9BDF6027E111D42A5CF12FC72748836B3ACA886AF014B448750E97E0F6C1B1D + 425218076C36CF73D1012485DAC1A3E71B2F6DF9797F7488B6B2AC88F7813C68 + 51CDF667E0E3D12124499254A80D81BF458750A9D201083347876823CB8A5833 + E5A9C26AB66B8035A343489224A914AB003746875069DE0C1C1C1DA28D2C2B62 + ED0BBC253A844A7517F041F7354B52233D1D1D4052658EA4FF10F09FE8202ACD + E78135A243B48D65459CE53CFDA3F11ECE45C58BD14124499254AA6780152D31 + 1B2DAD889F2D3A449B5856C44847E01C171D42A54A2F542B038F44079154191E + 712749CD7637B03E30363A884AB100F0DDE8106D625911231D5DB94C74089566 + 6C7EA1BA353A8824A954AE9C9334A54B809D8057A283A8143B02EB4487680BCB + 8AFE5B0AF866740895E695FC02955EA82449CDF67274004995F46BE000679635 + D6F1C01CD121DAC0B2A2BFC600BFF0FFF7C69A905F98D20B9424A9F99E8D0E20 + A9B2BE05FC2C3A844A311FF03D60547490A6F34D737FED902705AB998EC92F4C + 92A4767099B7A4A1EC029C171D42A5D8CEED20E5B3ACE89F0581C3A243A8347F + CCDB3F2449EDF14274004995B71E704374089522AD98F77490125956F4475A22 + 74383043741095E24660DDE81092A490A30A2569B86DC21FCE47DAAB79A783B8 + AABA449615FD6B5437890EA1523C9CB7F638404992DA675C740049B529365705 + 9E8F0EA2C27D1658393A44535956946F5687EB34567AC159C53B6B92D45ABEF1 + 90D4A99B812D9C75D3D8D341668A0ED1449615E53B202F1152B3A4179ACD815B + A2834892C258564B1A893381FD8157A383A8508BE6F77C2A986545B9DE03EC11 + 1D42857B353F219D151D449214CA6D209246EA60E0C4E8102ADC5EC0F2D1219A + C6B2A23C63809F448750294E70988EA42E7827AD793C0D4452373E05FC2B3A84 + 0A7734305D748826B1AC28CFB6C07BA343A870FF04B68A0E2149AA04B78148EA + D66AC003D12154A86580CF45876812CB8A72CC031C161D4285BB1F58233A8424 + A9325E8E0E20A9D6037AD774506FE31C02BC313A4453585694E3DBC0CCD12154 + A8F442B2BA4B7E254993F03541522F6E027670FE4DA34C0B1CE5FBEC62F87F62 + F156CC5B40D41CE3F20BC96DD141244995F25C740049B57732F0BDE8102AD447 + 808DA24334816545B1D24015876A36CF61F9854492A449B9B2425211BE049C1F + 1D4285FA912BED7B675951AC9D81B7478750A1CE03F68E0E21A9113C0DA4795E + 8A0E20A931D607EE8C0EA1C22C007C393A44DD595614675EE0D0E8102AD41DF9 + 854392A481B80D445291DB8ED37CB467A383A830FB024B4487A833CB8AE27C0B + 98313A840AF36C3EF9637C7410499224B5C2BD0EDC6C9451C011BEE7EE9EFFC7 + 15E37DF98945CD1AA8995E3024491A8C5B7B2415EDD43CEF40CDB036F0B1E810 + 756559D1BB31C091D12154A823F30B8524494371B9B6A432EC0E5C1C1D4285F9 + 21304374883AB2ACE8DDA780F746875061FE0AEC161D42922449B4FDF8CB87A3 + 43A8106F043E1F1DA28E2C2B7A335B3ED652CDF020B06E7408499224B5DEF3C0 + C73D75A831BE01CC1F1DA26E2C2B7A938EA399233A840A915E083604C6460791 + 24D5C633D1012435DA3F80AF3B1FA711A6030E8A0E51379615DD5B0CD83B3A84 + 0A915E00F607FE151D449224499AC4C1C0D9D12154881D81774587A813CB8AEE + 8FA1F98EFFFF35467A0138343A842449923480B41DE4EEE8102AC4A1F9BDA43A + E09BEDEEAC9A9F34547FE989DFBF4B49922455D5B83C70D3EDCACD38CA748DE8 + 107561593172D33A54B331D213FE7AF90540922449AAAA5BF2BC3CE757D4DFB7 + 8131D121EAC0B262E4B60696890EA19EA527FA7D819BA283489224491DF82170 + 667408F56C59E013D121EAC0B2626466C94D98EAEF2CE007D121244992A411D8 + 14B82F3A840A995D31437488AAB3AC1899DD81B9A243A867FF0636890E214992 + 248DD02BC086C04BD141D49385811DA243549D6545E71600BE1A1D423D7B293F + C1A7277A499224A96EAE020E8C0EA19E1D9857EE6B1096159DFB7A1EAEA97AFB + 2670757408499224A907DF022E880EA19ECC097C363A4495595674E61DC04ED1 + 21D4B38B8083A2434892244905F838F0687408F5E46BB9B4D0002C2B8637CAA1 + 9A8DF018B0417408499224A920CF01DB02E3A283A86B33015F8C0E51559615C3 + 5B15F8487408F5643CB01DF06C7410499224A940E700BF880EA19EEC0DCC171D + A28A2C2B86361A38243A847A765C3EAA549224496A9ACF0037478750D7D25CC4 + BDA243549165C5D03E062C1F1D423DB91DD8313A84244992549257818D80B1D1 + 41D4B5DD8105A343548D65C5D00D97AB2AEA7F4CE9C7F313B8244992D454B702 + FB4787504F2BFAD376104DC2B262705B024B4687504F52D974437408499224A9 + 0FBE03FC253A84BAF67957574CCEB262603302074787504FFE091C101D429224 + 49EAA38D81A7A343A8EBD515CEAE988465C5C0760116880EA1AE3D9BF7ED4992 + 24496DF2449E7FE036E8FAAEAE983F3A445558564C6D36E0EBD121D4B5F4C4FC + 65E0E1E82092244952806381B3A343A82B6380DDA243548565C5D4760566890E + A1AEFD0938323A84244992146833E0D1E810EACA1EC0DCD121AAC0B2627273E6 + BBF2AAA727814DA24348922449C1D231A63B02E3A38368C4A6CBDB415ACFB262 + EA162B0DD754FD4CC8AB629E890E2249922455C019C069D121D495BD81D96939 + CB8AFF99C7B36D6BED3CE057D121244992A40AF934F05074088DD88CC0676839 + CB8AFFD93B2FB9513DA71EA77D7992244992FEE7656027B783D4D297DABEEADF + B2E2BF16CC5B4054CFD33FD2C4DCE7A38348922449157416F0DBE8101AB13980 + 6D6831CB8AFFDA07181D1D425D39DFED1F922449D290B6061E8E0EA111DBAFCD + ABFF2D2BFEBBAAE273D121D4F5E91F6EFF9024499286F612B04B1E4AAFFA5808 + F8042D6559017BBAAAA2B6DB3FF6029E8D0E22499224D5C0EF81D3A343A8ABD5 + 15A369A1B69715F3E7E32E553F1701C74487902449926A642BE0F1E8101A91B7 + 02EBD2426D2F2BBED8D696AAE6D230CD2DA2434892244935F3425E599E5629AB + 5E331647D1326D2E2BE603768F0EA1AE1CE48020499224A92BC701174687D088 + AC007C8096697359918E2A1D131D4223760570687408499224A9C6B6CCAB9555 + 1F7BD2326D2D2BE6CA6585EAE565E053D121244992A49A7B04F85674088DC8C7 + F3FC8AD6686B59918E2A9D363A8446ECA7C0ADD121244992A4064865C535D121 + 3422BBD1226D2C2B6605F68E0EA111BBB76D3F9C92244952C9B6015E890EA18E + 6D0FCC434BB4B1ACF80C307374088DC8046097FCAB244992A4625C0B1C1B1D42 + 1D1B93DFCFB642DBCA8A19812F4587D0889D099C171D429224496AA0CF020F44 + 8750C7F6C8EF6B1BAF6D65C5B679B8A6EAE319E0D3D121244992A4861A97B75B + BF1A1D441D9913D88216685359311DB06F74087535F827151692244992CA711A + F0E7E810EAD8DEC0681AAE4D65C5278085A2436844AE030E8D0E21499224B540 + 5ACDFC627408756449606D1AAE2D6545FADFB94F74088D7839DA0ED121244992 + A496F80F704474088D687645A3B5A5AC580B786774088DC829C0E5D121244992 + A416493778EF8D0EA18EAC0EBC8B066B435931CA13406AE72960A7E810922449 + 52CBA4219BBB3A6CB3363E4783B5A1AC581E58393A84463C54F385E810922449 + 520B9D01FC293A843A3EED721E1AAA0D65C59ED10134223701DF890E21499224 + B5D8F6C04BD12134ACD14D9EF3D7F4B2627160D3E810EAD804E00BD121244992 + A496BB0FF8597408753C68733A1AA8E96545A3F7F034D0F9C085D12124499224 + B13BF07074080D6BDEA6DEA06F7259311BB04B740875ECC5BCDC4C92244952BC + F1C07ED121D4912FE683251AA5C965457AE33B7D740875ECC7C043D121244992 + 24BDEE18E08AE8101AD672C04A344C53CB8A6981BDA343A8630F007B45879024 + 49923495CFE65516AAB6DD6898A696151F0716880EA18EA4339CF7C9C3352549 + 922455CBBFF271A6AAB60D81B7D0204D2C2BD25E1D8F2BAD8FCB805F47879024 + 499234A89D81B1D12134ACCFD0204D2C2B5600DE1B1D421D1907EC141D429224 + 49D2901E037E121D42C3FA3F60161AA2896585C795D6C7EF80EBA34348922449 + 1A569A09E851A6D53623F0691AA26965C522C027A243A8232F78B4AC24499254 + AB55D1DF8C0EA161ED018CA601A669E05E2AD5C351C013D1212449922475EC08 + E096E8101AD262C0DA344093CA8AE9F3B13AAABE87F3092092244992EA65AF7C + A29FAABDBAA2F69A54566C06CC111D421D39D0B39A254992A45A3A1BF87B7408 + 0D6975E01DD4DC340D3AAEF40BD121D491B46CECC7D12124499224756D376F3E + 56DEE7A8B9A69415EF07DE131D42C34ACBC5BE1C1D42922449524FAE04CE8D0E + A1216D5FF79D074D292B3C55A21E2E054E8F0E21499224A967695EE02BD12134 + A869811DA9B126941573035B4687D0B0D232B1DDA343489224492AC47DC029D1 + 2134A4342A610C35D584B2E2D34D3947B6E1FE005C161D4292244952A16F86C7 + 4687D0A0160636A4A6EA5E568C6EC2E0901648CBC33E1F1D4292244952A19E04 + 8E890EA16187A1A603296A679A061CC9F2E6E8101AD6EF81BBA243489224492A + DC5EC033D12134A80F03EFA586EA5E56EC1C1D40C37AC955159224495263BD08 + 1C151D42C36ED7A99D3A97150B021F8F0EA1619D003C121D429224495269BE02 + 3C1E1D4283DA02989F9AA97359B14D74000DEB3960D7E810922449924A350E38 + 3C3A84867CDFBF0B35334D8D076B7E263A8486F5B35C58489224496AB66F000F + 4787D0A0D24DE4E9A991696A3C58F38DD12134A4A7817DA34348922449EA8B09 + C00FA243685073E4ED20B551D7B26287E8001AD64FF2704D49922449ED7028F0 + 6074080D6AF73A7500B5093A8979814DA24368484FE4213B92244992DAE355E0 + 87D12134A8A58155A9893A96159F02464587D0908ECC437624499224B5CBB75D + 5D51699FA726EA5656A49262C7E8101AD2A3C001D1212449922485707545B56D + 002C4E0DD4ADACF800F0B6E8101AD28FF2701D49922449ED5D5DF14874080DAA + 16C798D6ADACD82A3A80865D55918E2C92244992D4EED515474587D0A03E03CC + 44C5D5A9AC4867C26E1D1D4243FAB1AB2A244992240107E5C1FBAA9E99EBB010 + A04E65C586F9FF5455D363F9094992244992C603474787D0A076AB7A1F50E970 + 53D8363A808674547E4292244992A4E46BC033D12134A0B702AB516175292B16 + 02D68E0EA141A5E55D5F8F0E21499224A9525E028E8B0EA141ED4C85D5A5ACD8 + 323A8086949677B9AA42922449D294F6035E880EA1016D0C2C4045D5A1AC1805 + 6C171D42837A362FEF92244992A4293D079C1A1D42F57BAF5D87B2E2BDC052D1 + 2134A85FE6E55D9224499234907D8171D12134A0FF0346534175282B3E191D40 + 834ACBB9BE141D4292244952A53D089C1D1D4283CE875C970AAA7A5931A60EE7 + BFB6D889795997244992240D256D1D9F101D4203DA9E0AAA7A59B13A306F7408 + 0DE865575548922449EAD0F5C0C5D12134A00D80F9A998AA97155B4407D0A07E + 0F3C1E1D42922449526D1C04BC1A1D42030EDAACDC8E862A971533029B4587D0 + 80D231A55F890E21499224A956FE0C5C1B1D4203DAA96AFD40A5C24C614360FA + E8101AD01F813BA24348922449AA9D23A20368404B002B5021552E2BDC02524D + 6928CEFED12124499224D5D22F80FBA34368405B5321552D2BE6043E1A1D4203 + FA077079740849922449B5755C74000D68CB3C8EA112AA5A567C3C0FF950F51C + 1A1D4092244952AD7D1378213A84A632437E2F5E09D354B8D151F5DC049C1D1D + 4292244952ADBD08FC363A84AABD15A48A65C502C0AAD12134A0C3A303489224 + 496A84FDF32983AA96B58005A9802A9615955976A2C93C08FC2C3A84244992A4 + 46B81BB8283A8406F4092AA08A65C527A30368D0A9BDAF468790244992D418DF + 8B0EA0017D8A0AA85A59F10660C5E8109A4A1A7EF38DE810922449921AE57CE0 + B6E8109ACA7B81250956B5B262C3E8001AD06FF3101C499224492AD2F1D10134 + A04D0956B5B2A2127B63349934F4E680E810922449921AE9BBC073D1213495AD + 805104AA5259312FB07274084D250DBDB92B3A84244992A4467A19F85D74084D + 652960590255A9AC583F3A80A692066A1E121D4292244952A37D1398101D42D5 + 3AA9B34A65C5C6D10134951B800BA343489224496AB43464F3EFD1213495CD22 + B78254A5AC9819582B3A84A6F2E3E800922449925AE1A8E8009ACA12915B41AA + 5256A4A2624C74084DE631E0A7D12124499224B5C249C043D12134958D687959 + B15E74000DF86491665648922449523F9C1A1D4053F964D456902A941529C3C7 + A2436832E3806F448790244992D42A8702E3A34368AAAD20EFA0A565C5078079 + A2436832E7038F448790244992D42A0F00174787D0543ED6D6B2E2A3D1013499 + 5773A32949922449FDE6A0CDEAD9B8AD6585F32AAAE57AE06FD12124499224B5 + D2690EDAAC9C77038BB6ADAC580858263883267774740049922449AD76667400 + C56F05892E2BD60CFEFA9ADCD3C08FA343489224496AB5C33C99B072366A5B59 + B16EF0D7D7E47EEBF45D49922449C16E01AE8A0EA1C9AC02CC464BCA8AD19615 + 95320138383A842449922401274607D06446F5FBFDFB34C14796CE1AF8F535B9 + 7F0077448790244992A4BC3DFDC5E8108A3B1C23B2AC582DF06B6B6ACEAA9024 + 49925415A9A8B8203A84A62A2BD20E89C697156B077E6D4DEE61E0A4E8109224 + 49923489A3A203683273001FA2E165C52CFDFC1FA961FD263A80244992244DE1 + 3CE0BEE8109ACC3A34BCAC58250FE850BC74FAC7A1D121244992246900674507 + D0643E42C3CB8AD583BEAEA676896DA5244992A48AFA11F06A7408BD6E596041 + 1A5C56AC15F4753535F78149922449AAAA9B81EBA343A8FFEFE723CA8AF981B7 + 077C5D0D3C58F3D4E810922449923484D3A303A8FF732B22CA8A9503BEA606F6 + FBE80092244992348C238109D121345959314D13CB8A345C53F1D20FFB77A343 + 48922449D2301E012E8B0EA1C98E307D2F0D2C2B560BF89A9ADA95C09DD12124 + 499224A903AE0AAF96D59A5656BC0158AACF5F53033B293A802449922475E8E7 + C0F8E810EADF90CD7E97152BF6F9EB6960AFE41F7649922449AA83A7807F4487 + D0EB560266A04165C50A7DFE7A1AD8C5C073D1212449922469047E1B1D40AF1B + 5DF6E119FD2E2B1CAE590D27470790244992A4113ACEAD20ED995BD1CFB2622E + E09D7DFC7A1AD88BC02FA34348922449D2083D0D5C1A1D42CD2B2B3EDCC7AFA5 + C15D04BC1C1D4292244992BA70467400BD2E1D5F3A3B0D282B9C57510DA74507 + 90244992A42E1D0B4C880EA1C9066DD6BEACF024907869458547964A922449AA + ABC7802BA343E8752BD7BDAC980E58BE4F5F4B83FB479E59214992244975F587 + E8007ADDEAD4BCAC781F30A64F5F4B833B333A8024499224F5E878E0D5E8107A + CDB2C06CD4B8ACF8609FBE8E0697F675790A88244992A4BABB03B8353A84CA9D + 4FD9AFB2C29340E25D0B3C1E1D42922449920A3AE550D5F0E1BA9615A32C2B2A + E192E80092244992549013A203A8DC219BFD282BDE02CCD387AFA3A1790A8824 + 4992A4A6F83BF0707408BDE6FDC0F4D4B0AC48C335152BFD105F1A1D42922449 + 920A2E2C146F4C2E2C6A57567CA00F5F4343FB677400499224492AD8EFA203A8 + BC4335FA51567CA80F5F43433B3F3A802449922415EC34E095E8107ACD87CB58 + AE51A61981E54AFE1A1A5A3A7FF8F7D1212449921A6E9AFC183DC8EF47E5C734 + 1DDC349C30C5631C303EFFEA1B33E97F5E062EF7067965CA8A51F9FD672DCA8A + E57360C5B90578243A845411132F14BB5D6D16F9DF87CB5EE7FF6DC3FDF781FE + B7A57F9E6D927F9E7D90DFCF3AC9E74E05FA74F9F7D3E57F9EF8B5671DE0F376 + FA3566C96F489219261930353AFFB7813E979A6161E0B9E8102ACC6CF96775E2 + F3C3ECF9B921FDFB392679CC0DCC35C963F6FCEFFB75CD9B4A8B7B81AB802B81 + 2B809B8117F2E3A53EE590AA7484A96545BCF47CB824706B9DCA0AC5BA2C3A80 + D447A3F245E3DB812F01EB470792D468374607502BA52274B1FCD86480FF7E6B + 3E05EEC43C64FDD922EF744A157432B05F7408BD3EAFF2D6BACCAC287C22A846 + ECCCE80052C9A6C9C723EF982FCA9ECC93A12D2A24496DB4147000701BF03470 + 3FB03D306F9FE6D549FD7603705F740815FFFEBFEC272C4F02899596099E171D + 422A7105C596C0A3F9F1B37C21264992FEE70DC0D1795B707ABDDC3CBF86BA55 + 5B4DE2E987D5509BB262416091123FBF86771DF0627408A94069EBDA5B814B80 + A7805FE7FD719224697873E5ED21E935F4E2BC0AA3EC6DE1523F9C1B1D40AF59 + 36CFEFAA7C59E1BC8A7869E892D40469D0D9C679DFEDCD651C8D244952CBAC90 + 07B13F03AC57E41B0C29C0EFF3C9398A95FA85F714F9C9CAF2DE123FB73A63C3 + A8BA9B19D83D4F37FF8D17529224957243E0ACFC5ABB9DAFB5AAA967F2AA72C5 + 5BBE0E6585C335E3E7559C1F1D42EAE1C2E90BF948C0EF47879124A905D20C8B + 637269F14960DAE840D208FD233A808AED01A629F1C9CE6D20B1D252F9B1D121 + A4111A9397A23E0FFC303A8C24492D342A1F7DFA64BE9EF70411D585A72056C3 + FB8AFA44653DF92C0ECC59D2E75667AE8E0E208DF0C26809E0DF7929AA13CA25 + 498ADF8AF9AF3C88D3D3B654077F025E8A0E21162BAA0B28ABAC705E45BC3F47 + 07903A94F6C61E96CF834FA7084992A4EAF8703EF6741B6074741869986DF01E + 30500DCB55B9AC286C02A8BAF22AF087E810D230D2EA8977E665A6BB46879124 + 49433A16B8D15516AAB87F4607D06BDE4D85CB0A876BC64A4BE91F8C0E210D33 + 9B623FE07AA78E4B92541B4BE55516ABBB655315E5DC8A6A784F55CB8AF439DD + 0612CB637B54657303B7020745079124495DCF06F851BEF92055C925F9441BC5 + AA6C59F1B67CECA0E25C1A1D401AC4B2C0A379F08E2449AAAFFF036E00668F0E + 224DB11DFEAAE810220DCE9FB58A654521FB53D473DB2D55495A2ABA593EA5C6 + 65A3922435675BC8C3C09BA283489348A7D828DE32552C2B1CAE196B2C707974 + 08698AE799AF00274707912449859B1EB8DBF700AA9073A303E835EFA2826585 + F32A625D9F973F4955908E38FB3170607410499254AA2B80D5A24348C045C04B + D12144E5CA8AF4F96C5563A523A5A4AA1415BF02768E0E224992FAE24260ADE8 + 106ABD091E3850995975952A2BDEE131849598802B454BCF2DC7019B47079124 + 497DF50760E5E8106ABD34274DF1332B4655A9AC70B866BCBF440750EBA527A5 + EF029F8A0E224992C2AE47978F0EA156BB203A8098210FE1AD4C59E1BC8A588F + E60147526451F11960F7E820922429FC448625A343A8D5658573FCE2A59D175D + B3AC68969BA203A8F53E9A076A4A9224DD00CC131D42ADF434705B74085199B2 + 220DD3731B482C07C928D23B81B3A2434892A4CA9816F847FE558A382551F173 + 2B2A5156A4372AD315F8F934727F8D0EA0D69A331F5926499234A925801FF63A + 684FEA422ACA142B750495282B5C55112BEDC9B2AC508469F28A8AE9A3834892 + A44ADA0558273A845A7994AE622DD9CB828622CB8AF714F8B93472F7018F4587 + 502B6D0F7C383A842449AAB4738185A243A8755BE4D3EC0AC5492BAADE5E85B2 + C2E19AB16E8C0EA0D6B6A53F8B0E2149926AE18C1206FC4BC30D7955ACB776FB + 07A72970B8E672057D2E75E7DAE8006A9D31C01FA3434892A4DA482BB1378B0E + A156F1866EBCF0B2C2E19AF12E8E0EA0D6F934B06874084992542B2702F34787 + 506BF81E295EF83610E755C40FD7BC243A845A6541E0E8E8109224A9968EF474 + 10F5890710C4B3AC68B9BB81E7A243A835D2C5C50FA2434892A4DADAD89304D5 + 27F7030F458768B9A5BAED1D2C2B9AE1E6E8006A95B4EDEB13D121244952AD9D + E2B04DF5C94DD1015A6E0CF0966EFE60114F100ED78C77757400B56A55C5B1D1 + 21244952ED2D0EAC1C1D42AD6059116F89A8B26269876B8673708CFA251D51EC + 4A2A499254D4B0CD74E3532AD3DFA3038825A3CA0AF79BC59A00FC2D3A845AB3 + AAE227D121244952632C007C283A841ACFF74AF12C2B5AEA2E606C7408B5425A + 45E5CFBB24492AD28F3D19447D18B2F9487488965B22AAAC58BE80CFA1EE395C + 53FDB27F74004992D4C8C1DD5D1F6D2875E896E8002DB7544459E170CD785746 + 07502BBC01F87874084992D4489F8F0EA0C6BB353A40CB2D0CCCD4EFB2E25DC0 + B43D7E0EF5E6AFD101D40A6B47079024498DB533307B740835DAE5D101443A01 + A8AF6585A702C41A0FFC233A841A2FED233D383A8424496A34E762A94C974507 + 108BF5BBAC705E45ACDB8097A343A8150371E68F0E2149921A6DAFE8006AB4EB + 8197A243B4DC6223FD039615F576537400B5C2EAD101244952E3AD0BCC111D42 + 8DF52A707B7488965BBC9F65C5F4C0323DFC79F5EE5FD101D40ABB4607902449 + ADD0D589015287EE880ED0728BF7B3AC58AEA0A34FD5BD8BA303A8F1E6F3C241 + 9224F5C9C7A203A8D16E8E0ED0728B8FF40FF45236BCB7873FABDEA55915AEAC + 50E5F6964992247569EBE8006AB42BA203B4DC9BF2E0FE8E5956D47B5EC584E8 + 106ABC55A3034892A4D6581898273A841ACBB222D6B4C042FD2A2BDED7C39F55 + EF6E8C0EA056D8203A8024496A5D612195E1DFC033D1215A6ED17E9415B3006F + EBF2CFAA18974607502BDACFF74787902449AD5B2A2E95E5EEE8002DB7683FCA + 8AF774F9E7549C0BA303A815C335254992FA6995E8006A34CB8A5896152DF0A4 + D36CD507734707902449ADE3FB0C95E9B6E8002DF7A67E9415EE258B757D7400 + B5C29CD101244952EB2C1B1D408D76757480965BB41F6585537A635D131D40AD + 30A227134992A402A4D97833468750635D1B1DA0E516E94759E15EF6587F8E0E + A056B0AC90244911668E0EA0C6BA0518171DA2C516E94759316F977F4EBD7BD5 + B242557C329124492AC8F4D101D4E8F752E90853C5981598A3D30FB6ACA89F3B + 8067A343A815DCEE25499222CC101D408D665951931BA2CEACA89FEBA203A835 + DC2F2A4992228C8A0EA046BB273A40CB2D526659E1D09B58FF8C0EA0D6F0AE86 + 24498AD0ED0D55A9D3B9158AB370994F046E018975617400B5C6F8E8009224A9 + 95BC0651996E8E0ED0720B965956B805244E9A5CEBB1A5EA9717A2034892A456 + F2B40695E9A6E8002DB750A71F6859512F4F440750ABBC181D409224B5D22BD1 + 01D468775A8835776585DB40E23C191D40ADF25874004992D44ACF470750E38F + 2FBD3F3A448B2DD4E907BAB2A25E9E8A0EA056F94F74004992D44A96152A9B65 + 451C575634942B2BD44F9E412D4992225676BA445F657B303A408B2D008CEEE4 + 032D2BEAC5B242FD746F74004992D43AD74707502BB8B222D6FC9D7C90DB40EA + C5019BEA27B71D4992A47EBB3A3A805AE1F6E8002D377F5965C57C5DFC1915E3 + E1E8006A15CB0A4992D46FFF8C0EA056B8233A40CBCDDFC907B90DA45EDC5BA5 + 7E7A3C3A8024496A9DBBA203A8155C5911CB6D200D6459A17E4FE2BE273A8424 + 496A9587A203A835B3D9C6478768B1F9CA282BA605E6E82E8F0A6059A17EBB38 + 3A8024496A8D740A886585FAE155BFD79AB7B2C22D20B1FC8152BFFD213A8024 + 496A8DB38009D121D41A0F440768B1793BF920CB8A7A71C0A6FAEDC6E8009224 + A9354E8E0EA056F14670C3CA0AE755C49ECCE0BE2AF59B67504B92A47EB9213A + 805AC52DF671E6EEE4835C59511F4F4607506B4F04B93B3A8424496AC50C01AF + 39D4EF219B8AE1369006AEAC9022FC2A3A8024496ABC3380B1D121D42A961571 + 2C2B1AC695158A726E74004992D4783F8D0EA0D6B9273A408BCD02CC30DC0739 + B3A23E2C2B14E5CEE8009224A9F11CEAAD7E736545C5E7565856D4876585A23C + 065C151D42922435D65DC07DD121D43AFFF1008350730EF7016E03A98F47A203 + A8D58E8C0E2049921AEBE0E8006AED50D7344C5E31E62ABAAC98AFFB2CEA91E7 + 002BD2C5D101244952635D181D40AD6559D1A095156E0389E339C08A9E5BE156 + 24499254B45B3CB254812C2BE2585634C803D10144DB97C97D233A8424496A9C + 7DA303A8D52C2B1A326073EE2ECA0D15C76D208A766674004992D438FF880EA0 + 56B3AC68C8CA0A876BC67A383A805AEF0EE0FEE8109224A9317EEB35AE82F9FD + 1767B622CB0AB780C47901783E3A8404EC171D4092243586A780289A7301E3CC + 3EDC07B8B2A21E1C6CA8AAB8203A8024496A847423EE9AE8106A3DB7DAC7B1AC + 6808CB0A55A97D3E373A842449AABDFF03C6478750EB7988411CCB8A86782A3A + 803489AF4707902449B53F65EC9CE810922B2B9A33B362F1DEB2A807AEAC5095 + 5C058C8D0E2149926AEBC79EC2A08A78243A408BCD5E6459B1646F59D403CB0A + 55C938E00BD1212449526D7D3F3A80943D0BBC1C1DA2A5662DB2AC58AAB72CEA + C1A3D101A4299C9597704A92248DC479C05DD121A4493C1D1DA0A56629AAAC98 + C3A34B4379FEAFAAF83D797474084992543BFB440790A6F04C7480969A091855 + 4459F1E662F2A84B9EFFAB2AFA7674004992542BE9A8D2EBA343485370654545 + B7825856D4836585AAE80EE0E2E8109224A936B68F0E200D32B74215DC0AD269 + 59B1683159D425CB0A5595833625495227EECA278A4955635951F3B262E162B2 + A84BCEAC50555D0BDC1C1D42922455DE27A3034883782E3A40CBE7560CCAB2A2 + FA5EF41C6A55DC36D101244952E5B78E5E1E1D421A8465459C9987FA8F9615D5 + F7EFE800D230FE05DC1D1D42922455D616D101A4213C191DA0C5662CA2AC58A0 + 982CEAC2BDD101A40EB8B45392240DE4065755A8E29E8A0ED062D3175156CC57 + 4C1675E19EE8005287AB2BD2124F4992A4497D2A3A80340C8F2EADF136909987 + 9BD2A952DD1E1D40EAD0C6D101244952A55C9C87714B55665951E3019BF31697 + 455DB82D3A80D4A1EB80BF458790244995B1637400A903CF440768B1197B2D2B + E62A2E8BBA6059A13AD9213A802449AA845F791DAB9A7066459C1986FA8F9615 + D5E73610D5C9ADC0A9D121244952B87DA303481D7265458D076C5A56C4791C18 + 171D421AA1BDA3034892A4500702F74787903AF45C7480169BA1D7B262D6E2B2 + 68841E8D0E207579DCEEB7A2434892A410AF028745879046606C7480169BBED7 + B262B6E2B268841E890E2075E9DBC084E810922429E4A8526700A84E9E8D0ED0 + 626386FA8FAEACA8B6C7A203483D1C01B56974084992D4F72DCCA744879046C8 + B2A2C665C5CCC565D1083D191D40EAC119AE0E9224A955D602C647879046286D + 5D7A393A444B4DDF6B5931E4D9A72A95332B5467E962659DE8109224A92FFE08 + 5C151D42EA9265458CD143FD47CB8A6A7B303A80D4A3AB81F3A3434892A4D2ED + 181D40EAC14BD1015A6ADAA1FEA36545B53D1C1D402AC076D101244952A9F603 + FE1D1D42EA812B2B6A5A568C2A2E8B46E889E80052412B84768E0E2149924A31 + 0EF8617408A947AF440768A969BAFE8FD90CC56551171395A52638D663CC2449 + 6AA48F02CF4787907A645951D3019B8A6359A126BD00AC121D42922415EA76E0 + 82E810520126440768A951BD9615434EE854A99E8E0E2015E85ACF5E9724A951 + 36C8C73E4A75E7CC8A0AEAA4ACF0ACE438CF4407900AF67F5ED44892D408C703 + 374787900AE2F5694DCB0AFFE2E2DA3D9723A9894363D78F0E2149927AB65774 + 00A940AEACA8E9CC0ACF9C8DF1427400A924E700D747879024495DDB1678343A + 8454206FD057900336AB6B6C7400A944EB45079024495D790E38213A8454304F + 03A920575654FBCC6AA9A9FE0D7C2E3A8424491AB1D57C6327A92A6585DB1162 + 5856A8E97EE2125249926AE512E0F2E81092DAA193B2E2F93EE4D0D42C2BD474 + E9A4A115A2434892A48E6D1D1D40527B7452563CDB871C9A9A1369D506B70107 + 4487902449C3FA16704F740849EDD14959F1741F72486AAF835DC1254952A54D + C8AFD79254A4977A2D2B9E2C2E8B240DB88AE883D1212449D2A03E964F0191A4 + BEE9A4AC78AC0F3934354F61519B5C0FFC203A8424499ACAFDC079D12124B54F + 276585D3FA25F5C3978117A3434892A4C9AC93B7814852E5CA8A07FB9043539B + 2E3A80D467A9A8703B882449D5710A70637408498DF562AF65C543B6A9214645 + 0790025C031C151D429224BD66B7E800529F78A3B8823A292B26E4BD6A92D40F + 7B02AF44879024A9E53E9B6F5A4A52654F03493C53B9FFA68D0E20057901F840 + 740849925A6C2C704C7408A98F5C5951419D9615B7979C4353731B88DAEC2AE0 + D8E8109224B5D49A9E4CA796E9F47DB12A36B322716545FFD9EEA9EDBE008C8F + 0E2149520B6F18FC3D3A84D467AE6A8F31A188B2E2D962B268042C2BD476CF01 + 2B44879024A965368D0E2005B0AC8831E49C3ACB8AEAB2AC90E052E037D12124 + 496A89EF037745879002B80DA4C6DB409E29268B4660FAE8005245EC04BC1A1D + 4292A41638303A8014C4F75E353E0DC49515FD37437400A9229ECC83BE244952 + 793E0E3C1D1D420AE2AAF61AAFACB0ACE8BF31FED048AFBB10B8383A8424490D + F530706674082990EFBB62B8B2A2C6668D0E2055C8E6D10124496AA8B53C814B + 2D675911C399153536477400A9421E00B68D0E214952C39C055C171D420A94DE + 137B1A480C5756D4D86CD101A48AF915F048740849921AE433D101A460AE668F + E3CC8A1A73658534B9B4447595E810922435C417F3CA45A9CD66890ED0622F15 + 5156BC325CEBA152CC131D40AAA09B8193A34348925473E9FAFEA8E8105205B8 + B222CEF345941589732BFA6FEEE8005245ED161D4092A4060CD51C1B1D42AA00 + CB8A0694156E05E9BFF9A20348153E62EDB3D1212449AAA99B80BF4687902A62 + E6E8002DF6E250FFD1B2A2DA5C59210DEE18B7A74992D4958D8057A3434815E1 + A10671865CDD6559516D0ED894861EC8B346740849926A26CDA9B82D3A845421 + BEE78AE3CC8A1AB3E59386F677E0DAE8109224D5C87ED101A48AB1AC88F3DC50 + FFD19515D56659210D6FE3E8009224D5C416C093D121A48AB1AC883364C76059 + 516DB34707906AE04EE088E810922455DC53C069D121A40AB2AC883B3EB9B001 + 9B6E03E9BF39A3034835B17F740049922A6E35605C7408A9825CCD5EC1791589 + 2B2BAA6DAEE800524DA425AD9F8C0E21495245FD09B83A3A845451B3440768A9 + 6786FB005756547F49D2E8E810524DFC1678223A84244915B45D7400A9C25C59 + 51C1E19A892B2BAA6FA1E800524D8CCB4B5C2549D2FF7C05B82F3A8454619615 + 3186ED172C2BAA6FE1E800528DA4634C2F880E214952458C077E101D42AAB859 + A303B478E8EF902C2BAACFB2421A1997BA4A92F45F1FE964889DD472AEAC88F1 + F4701FE0CC8AEA5B243A805433F7035F8D0E214952B0BB5D6D2875C4B2A20165 + 852B2B62BC293A805443870113A243489214685DE0D5E810520DCC1E1DA0A59E + 1EEE032C2BAA6F81E800520D3D9F2FD224496AA35F02B74687906A601E4F5F0C + E3CC8A06B0AC90BA3F53FE9EE810922405D8333A805413F3450768B1A787FB00 + CB8AEA9B3F3A805453691B88AB2B24496DB32DF0687408A926BC311CE7C922CB + 8A1781977BCBA32ED8F649DDBB0538213A8424497DF21C70627408A9462C2BE2 + 3C5E645991B8BA2266E08B67FF4ADDDB233A8024497DB29A3717A51159303A40 + 8B3D39DC075856D4C362D101A41A7B04D8393A84244925FB3B70457408A966DE + 101DA0C51E1FEE032C2BEAE1CDD101A49A3B1E181B1D4292A4126DE951A5D288 + B9E5BE412B2B9EE93E8B7AB0647400A9E65E02568F0E21495249BE05DC1B1D42 + AAA1B9A303B4D813C37D802B2BEAC1B242EADDA5C0D5D12124492A585A4D7148 + 7408A9A6E68A0ED0E2A2E2D5E13EC89515F5B0507400A901D213E2C6D1212449 + 2AD8FADE5094BAE6CA8A181D1DAFECCA8A7AB0AC908A7137F083E810922415E4 + 7EE0FCE810528DCD131DA0A51EEBE4832C2BEAC1B2422ACE01D10124492AC83A + C0F8E810524DCD00CC111DA2A51EEDE483DC06529FBD54B34787901AE269B783 + 48921AE054E0C6E810528D2D1A1DA0C51EEDE4835C59511F4B4507901AE4CC4E + 9F242549AAA82F4407906AEE8DD1015AECD14E3EC8B2A23EDE161D406A90711E + 652A49AAB1CF010F4787906AEE4DD1015AECD14E3EC8B2A23E968E0E2035CC0D + 0E259324D5D08BC0D1D121A406B0AC88F348271FE4CC8AFA583C3A80D4C0A34C + B78F0E2149D208AD0ABC141D426A8045A203B4D8439D7C902B2BEAC33D5552F1 + 1E00F68B0E21495287AE062E8B0E2135C402D1015AECE14E3EC8B2A23E9C562B + 95E3071EFB2649AA898DF3CA4049BD9B3F3A408BB9B2A261E6CE47984A2AD60B + C0DAD12124491AC6F781BBA343480DE2CA8AB841F78F77F281CEACA817876C4A + E5B808B8333A8424494338303A80D420A38179A343B4D4439D7EA02B2BEA6599 + E80052434D003E1A1D4292A4416C023C1D1D426A90258151D1215AEAA1B2CA8A + B45CDAC2228E6585549E5B81E3A343489234C0117FA74787901A5856286EC07D + 296545F2AF2EFE8C8AE1F1A552B9F68C0E2049D214D67010B45438CB8A38FFE9 + F4032D2BEAC5B2422AD763C0F6D1212449CACE016E880E2135D012D1015AEC81 + 4E3FD0B2A25E160166880E2135DCAF81E7A343489204ECE451A55229DE101DA0 + C5FE5366597145177F46C5484360968B0E2135DCCBC06AD1212449ADB7E748EE + 404A1A9185A203B4D803659615F7030F76F1E7548CF74407905AE0F2FC902429 + C22BC08FA343480D5FB1AE06AEAC485C5D1167D9E800520BA425B79B46879024 + B5D65AC0D8E8105243CD0ECC1D1DA2C5EE2FBBACB8B2CB3FA7DEBD253A80D412 + F702DF8D0E21496A9D9B81BF4687901AEC6DD1015AEC59E0A9B2CB8AABBBFC73 + EA9D936BA5FE39283A8024A975D677A8A654AAB7470768B17F8FE483BB2D2BAE + EAF2CFA998C9B5F34487905AE21960C3E81092A4D6F81970677408A9E1DE111D + A0C5FEDD8FB222ED3379B8CB3FABDEBD3F3A80D42267FB7C2749EA932F450790 + 5A60B1E8002DF6EF7E9415C9353DFC59F5C6B242EA9FF1C09AD12124498DB705 + F0647408A905168D0ED062F78DE4832D2BEA6999E80052CBDC009C131D4292D4 + 5869E0DC6FA243482DF1A6E8002D76DF483ED8B2A29E968C0E20B54C1A74B663 + 7408495263AD0ABC121D426A81F98039A343B4D83DFD2A2BAEEDE1CFAAF71341 + 7AF9BB9334720F02FB4487902435CE855E574B7DE30AF558F78EE4837B79C37B + 0BF0620F7F5EDD1B032C1F1D426AA11F01E3A24348921A651B8F2A95FAE65DD1 + 015A3E07EEBE7E9515E949F5FA1EFEBC7AB3627400A9855E00D6880E21496A8C + FDF3297B92FAC39515B15B40268CE40FF4BA95C0256B715C5921C5B804B82D3A + 8424A9F6D245FBF7A243482DE3B1A5359957514459715D8F7F5EDD7B7B7400A9 + C517971F8D0E2149AABD7580E7A343482D635911E7EE7E97156E0389B3944336 + A5307700BF880E2149AAF5457B1AAC29A97F6605168C0ED162778DF40FB8B2A2 + BEA6053E101D426AB1BDA30348926A6BDD91EEDD96D4B3E58051D1215AECCE7E + 97154F000FF4F839D4BD95A203482DF638B06D74084952EDFCCAD947520867FE + B56C6545E2569038FEC049B14E049E8B0E2149AA953D3CAA540A5B59A116ADAC + 482C2BE22C1D1D406AB9978155A34348926A6307E0B1E810524B2D111DA0C59E + 009E8C282B6E2CE073A83B6F0166890E21B5DC95C0A5D121244995F75CDE0222 + 29866545EC707A22CA8A1B0AF81CEA4E1A10E35D5D29565ACABB5974084952E5 + AD9A57E449EABF858139A343B4D81DDDFC215756D4DF6AD10124F16FE0D0E810 + 92A4CABA34AFC49314E343D1015AEEB6A8B2626CB74D890AB16C740049AFF9A6 + 03D3244983482BF07C8D90E27C303A40CBDD165556246E0589F38EE800925EF3 + 2CB06174084952E51C9C57E0498AF3F6E8002D777B6459E1892071E605968A0E + 21E935E7000F4687902455C6ABB9AC9014EBADD1015AEED66EFE902B2B9A619D + E800925E331E583D3A8424A932D6CF2BEF24C5991D58243A448B3DD8EDF36051 + 6585433663AD181D40D2EB6E01CE880E21490AF71FE0FCE81092F8703E455135 + 5A55516459912ECEC715F4B934720ED994AAB5E477E7E81092A4706BE6157792 + 62AD1C1DA0E56E892E2BD213F1CD057D2E8DDC62C03CD12124BDEE61608FE810 + 92A430BFEBE5025D52A1DE151DA0E56E8A2E2B92EB0AFC5C1A99B4AC69ADE810 + 9226F313E095E81092A410BB7854A954199E0412EBE62A94150ED98CB5467400 + 499319EBCFA524B5D2E78047A243487ACDDCC0C2D1215AEEE62A94150ED98CF5 + EEE80092A6F2B75E860A49926AE725E098E81092269B57E170CD38CF000F74FB + 875D59D11C4B0333458790349909C047A3434892FA6615E0C5E810925EB75A74 + 8096BBB9972D71459615F700CF17F8F934F2BFCB75A343489ACA9DC0CFA34348 + 924A770D70597408499359263A40CBDDD8CB1F2EB2AC488DC9F5057E3E8D9C65 + 85544DFB44079024956E23876A4A955C7DAE383754A5AC48DC0A12EBBDD10124 + 0DE84960ABE81092A4D21C9E57194BAA8E770073448768B91BAA5456787C69AC + 77023346879034A053F390214952F37C353A80A4A938AF22DEF5552A2BDC0612 + 6B34F091E8109206F432B06A74084952E136B18C962A69A5E8002DF718F0502F + 9FC09515CDB35E74004983BA3A1F672A496ACEC5F819D121240DE85DD1015AEE + FA5E3F41D165C513C07D057F4E8DCCF2D101240D2A0D5EDB3C3A8424A93069C5 + DCB8E81092A63227F096E8102D777DD5CA8A89C73629CEDB81B9A343481AD4FD + C0B7A24348927A766EAFC7F2492ACD5AC0A8E8102D776D15CB8A9E43A927A3F2 + D15992AAEB608FB793A4DADBC1E772A9B2D6880E202A595638B722DEBAD10124 + 0DE939E0A3D12124495DDB1B78303A84A441BD3B3A40CB4DA8EA36104F0489F7 + FEE8009286F547E03FD121244923F60AF0A3E8109206351DB04C748896BB299F + 8457B9B2E236E0A5123EAF3AB710F0CEE810928634DE258A9254DBBDF063A343 + 481AF267744C748896BBA6884F324D494B3EDC0A126FD3E8009286752BF0BBE8 + 1092A4113D6F5F1C1D42D2903E121D4054B6AC48AE2AE9F36A64476949AAB634 + 986D97E81092A411BD094A37E62455D7F2D101C4D5457C12CB8A66CFAD98363A + 84A4613D02EC161D429234AC9F037747879034A4F4FEE75DD121C455552E2B0A + 59F6A19E07CB6C101D4252477E5AC410224952A9F6F1A852A9F2D6F1866DB83B + 81A7AA5C56A433555D22176FE3E800923AF222B07A740849D2A0B6049E8C0E21 + 6958EB4707105714F589CA2A2BD269203794F4B9D5B90F470790D4B17FE4639E + 2449D5F234705A7408491D6F8557AC2BAB5E5624FF2AF173AB338BB8674BAA8D + B41A6DBDE81092A4A9AC02BC121D42D2B06605DE191D42D4A2ACB8BCC4CFADCE + 6D151D4052C7D2E0B6A3A24348925EF797BCBD5952F56D50F2FB5B35A8AC286C + AF8A7AE23E78A95EF68D0E20499A6C56854335A57A70856ABC5BF2D6B9CA9715 + D7B964AE129601E68B0E21A963697AF2E6D12124491C003C101D4252C73E181D + 405C5AE4272BB3AC1857E41210F5F477FCE9E8109246E4B745B6D292A4AEE608 + 7D373A84A48E2D05BC313A84B8ACC84F364D1FA6DB2B9E4BA2A47A49ABD2568E + 0E21492DB62EF07C7408491DDB243A808A1F05517659F1CF923FBF3A5F123563 + 74084923DE4AF7D7E81092D442F700174687903422CEE9ABC6CDB66BEA545614 + BA0C445D9B16D8223A84A4114903DDFCB995A4FE5B1B181F1D4252C7C638AFA2 + 32AB2AD22888DA9415F7E587E26D1C1D40D288A5C16E07458790A416F935707B + 74084923DEF23E437408F1F7A23FE134750CADAEACE4B9C3522D1DEAB17992D4 + 37BBF99C2BD5CEA6D10154CE08887EBC79BDB80F5F43C39BD9D515522DA5016F + EB448790A416D801783C3A84A411FB707400157F6C69BFCA8ABFF5E16BA833EE + 7F97EA290D7A734B9D2495E705E057D121248DD83B8045A343887BF2F6E5DA95 + 1537004FF6E1EB6878AB02A3A243481AB134E86D8DE81092D4F0EDB22F478790 + 34625B47075079A31FFA5156A47D7F6E05A986D9810DA24348EA4A1AF8765A74 + 08496AA0747ADDD5D1212475C5234BABA1B6654572519FBE8E86F7A9E80092BA + 2E7E3F1B1D42921A3A9C6F42740849233637B05C7408BDE61FD4B8ACF8739FBE + 8E3A6B1FDD0A22D5D3A3C0E7A3434852C34E5C722690544F5B79DA61253C0D5C + 5FC627EED75F6E9A5BF1709FBE96863607B0617408495D3B1A78293A84243564 + C5DA37A24348EADAFAD101F49A4BCA5A9D364D1F5F0CFED4A7AFA5E1398846AA + AF178155A243485203A4395ECF458790D495E93CB2B432FE5AD627EEE7B219CB + 8A6A6D0571C994545FFF2A6BB99D24B5C483C0B9D12124756D0B60FAE8102A6F + B8267D7EC3FAC73E7E2D0D6D56E013D12124752D2DB573E9A324756FB57C2CB4 + A4FA0EC655BCB435F9F22694150F782C54A5782A88546FF70247468790A41AFA + 3D706B7408495D1BED96D8CAB8181857D627EFF7568073FAFCF534F41D8569A3 + 4348EAC97ED10124A9863E93E7A949AAA78D8199A243A8FC533FFB5D569CD7E7 + AFA7C1CD086C1B1D4252CF47456D161D42926AE40BC023D12124F564CBE8002A + 7FB86644597129F0449FBFA6861E4C23A9FECB997D5E95A4CEF656FF3C3A84A4 + 9EB780A4C302146F6C1EFADE98B2220D853BB3CF5F53835B0198333A84A49EBC + E2BE4D49EAC8AAF9F86749F5955694CE1C1D42AFF94BD9838A238EAFB4ACA856 + 33B94B7408493DBBA1EC3D83925473D70297458790D433B7805447E9D79E1165 + C5F9F94EA0AAE1E3D10124F52C0D8AF3841F491ADC067985AFA4FA1A935748A9 + 1A1A5956A4BD2D0EDAAC8EE580C5A34348EAD983C001D12124A9827E948F7B96 + 546FDBE6430214EF71E09A269615C919415F57037F0FEC1A1D425221BEE39D43 + 499A8AC73C4BCDB0797400BDEE827E5C7346951567077D5D0DEC63D1012415E2 + 05609DE8109254219B00CF448790D4B3398015A343E8757FA20FA2CA8A74BEF5 + DF82BEB6A6B628B05A74084985ED1F74B9B324C1630E76971AE333796685AAE1 + C2269715C96F03BFB6A6E6A9205233A423A4D6880E2149159006F139D45D6ACE + 2A2955C3EDC03D4D2F2B6CBAAB65ED7C94A9A4FABB1338293A8424054AC3DC6F + 8C0E21A9104B01EF8E0EA1D7F5EDB08CC8B2E2AE7E4C1055C76605B68B0E21A9 + B0A34C3F171D4292026D979F0B25D5DF6EC0A8E8107ADD1F69415991FC26F8EB + 6B72DB440790549827F2FE4E496A9B2F030F4587905498F5A303E875E3F27CB4 + 5694156E05A9960FE4619B929AE138606C740849EAF385F40FA343482ACC4780 + 85A243E87517F5F3DA32BAACB801B835388326FF7ED8233A84A4C2BC04AC121D + 4292FA280D18B6A4959AC34300AAE5DC7E7EB1E8B222ED253C35388326B76174 + 004985BAC2F940925AE236E06FD1212415666660CDE8108A19AE5985B222F97D + 74004DE68DC0BAD12124156602B041740849EA8375F2F1CD929A617760FAE810 + 9AECC8D2540AB7AAACB8261FB3A7EAF01401A959FE0D1C1E1D42924A740C704F + 74084985DA3C3A80267346BF4F59AA4259E15690EA49CBAD668F0E21A9505F89 + 0E204925DAD3A34AA546F920F0B6E8108A9B575195B222712B48B54C9B5FF425 + 35C7B3C026D12124A9045B034F45879054F8169051D121F4BAE7804B68695991 + 06C0DD1D1D4293D92C3A80A45296EF3D161D42920AF4347072740849859A0158 + 2F3A842673763E1ABA9565455AB6775274084D660960F5E810920A955E643CCA + 545293AC0CBC121D4252A1BE08CC181D429339930055292B92DF4607D054768B + 0E20A97037017F8C0E214905B818B82E3A84A4C26D151D40539D2C770E2D2F2B + AECEC7A1A83AD602E6880E21A9F0956C5E04486A824F3A54536A9CD580A5A243 + 68327F029EA1E565457AB171CF61B54C077C293A84A4C23DE2E920926AEE40E0 + C1E810920AB74774004DE57704A9525991B815A49A772D2435CFF781F1D12124 + A9CB25C98746879054B8F981B5A34368C0E19A21AA5656A47D87374487D06416 + 0536880E21A970638135A343485217D6055E880E21A9705F03C64487D0642E03 + FE4390AA9515692BC8AFA343682A5F880E20A9B4E1741E1B2DA94EEE012E8C0E + 21A994F7A5AEE8AE9E5323BF78D5CA8AE494E8001AF058B03746879054B8B40D + C4D51592EA36FCDB2D6C52F3EC02CC151D4253F93D81A6A96863FEF7E8109ACC + 68E0ABD1212495E22E57B449AA893488FD8EE810924A2B2B542D5744AFC0AD62 + 5991FC2A3A80A6B2692E2D24354BDA7EE7562F4975F0598F2A951A693DE01DD1 + 2154BD1D0F552D2B7EE38B51E5CCEE1B1AA9B19E04768C0E21494348CF514F44 + 8790548ABDA203A87A5B40AA5C563C0E9C1B1D4253D93E3A80A4D2FCD2E9FA92 + 2AEA85FC1C25A979960656880EA1A95C05DC49B0AA9615C909D1013495B703AB + 478790548A978155A24348D20056CACF51929A67FF8ABF276DAB93A8802A7F63 + 9CE10B53E58C02F6890E21A93457E6265D92AAE2EAFC90D43C0B001F8B0EA141 + C732849BA6E24BFE4E8B0EA1A9AC062C121D42522926001B448790A4496C9C9F + 9B2435CFC1C0B4D12134957FE4133AC355B9AC484E8C0EA0A9A41341BE1E1D42 + 5269EE07BE1F1D429280B3AB72C12CA970B3029B4587D0802A73A47DD5CB8A3F + 3AF9B9B2C7984E171D4252A9FB4725A90A2780783A9CD44C0701334687D054D2 + 73EEA95444D5CB8A71C0F1D121349559802F458790549AE7800DA343486AB51F + 030F458790548AB4F5639BE8101AD079F964CE4AA87A5991782A4835798CA9D4 + 6CE7008F448790D45A5F890E20A9D49FEFD9A3436840953A26BA0E65459A4C7F + 5374084DE58DC0D6D1212495BAB2CDA34C2545F832F064740849A59D2EB85374 + 080D686C3E91B332A6A9C9BE995F4487D080768F0E20A954B700E7478790D42A + E9BAEF88E810924AF3857C64A9AA79B8C58B54481DCA8AE4A4E8001AD0BB80D5 + A343482AF54D832BA824F5D3A780E7A343482ACDE7A3036850BFA262EA52563C + E0DDBDCA2EE3DA2F3A84A4523D9A97644B523F9620FF263A84A4D26C052C1E1D + 42034AC7445F42C5D4A5AC48DC0A524D2B016F8B0E21A9543FCC332C24A94C6B + 022F478790549ABDA3036850470313A8983A951569D8C7B3D1213495D1C037A3 + 43482AFD6EA75BBE2495E97EE0D2E810924AB309F0CEE810AACF1690BA9515A9 + 693F2E3A8406B41EB060740849A5FA3B70477408498DB506303E3A84A4D2781C + 7175FD01F8371554A7B2A272E7BEEA75D3020747879054AAF42662ADE810921A + E96FC06DD121249566833C985FD5740C1555B7B2E24AE086E8101AD0A6C0ACD1 + 2124953E7CC9D25852D136CFA70F496AA6AF4607D0A09EC9E3162AA96E65457A + 21FB5974080D6826E0A0E810924A7F0EDE353A84A446391EF84F740849A5F928 + F0EEE8101A72B06665071BD7ADAC484E704F63656D034C171D4252A99E02B68D + 0E21A931F6705585D4680702A3A24368C8B2A2B2EA58563C019C121D42039A1D + F87A740849A53B11783E3A84A4DADB275FD7496AEEAC8AE5A24368507F056EA6 + C2EA585624BF880EA041ED988F3395D45C69B9E08AD12124D5DA04E088E81092 + 4A956E62BAAAA2BA8EA2E2EA5A565C9407BDA97AE606F68D0E21A974D702FF8A + 0E21A9D6775CC7468790549A8D3D01A4D29E047E4FC54D53E336FEA7D12134A8 + FFB345951A2F3D0F6F141D42522DA5AD1FE747879054AAFDA30368483FA9F260 + CDBA9715C9710E64AAAC05803DA343482ADD03C077A34348AA9DD58071D12124 + 95660B60E9E8101A522D6EFCD7B9AC7808F85D74080D6A37575748AD7080C5B1 + A411B81AB83E3A84A452B9AAA2DA4E07EEA506EA5C56243F8F0EA041BD01F862 + 740849A57B3EEF3D97A44E6C94B791496AA69D8125A3436848475213752F2BFE + 549756A8A576777585D40AE7010F4787905479BF06FE1D1D4252A91CB45F6D37 + 037FA626EA5E568C077E1C1D4243AEAED82B3A84A4D2A5BDE72B47879054795F + 70DB98D4686966DD1BA343684887D769755BDDCB8AE4785FF82A6D57575748AD + 701B704E740849959E65958ECA93D44CA3BD495979CFE6F7CEB5D184B2222D3D + 3E253A84865C5DF1E5E810924A974AE36DA24348AAECEAAB5A4C9E97D4B58380 + F9A24368D8551563A99126941513CF8955B5EFA634E57B4DD2E01EF3AE8AA401 + AC05BC181D42526966023E1B1D42C3DE54AADDF884A6BC81BC04B8293A840635 + 2FF0F5E81092FAE247C02BD1212455C6FDC0C5D1212495EA3060B6E8101AD209 + C003D44C53CA8A09F90259D595DAD669A343482A5DBA7BBA7A74084995B17A1E + 882EA999D2D68FADA343A8A32D20B5D394B262625BF45274080D6A4EE0E0E810 + 92FAE2EF79E0A6A476BB00B83D3A84A4521D09CC101D42C35E975D410D35A9AC + 7806F87974080D69A7BCA74D52B34DC87BD425B5DB569ED82635DA3B810DA343 + 6858DFABEB737193CA8AC449D3D5362BF0C3E81092FAE2DFC0B1D12124859E0C + 904E6C93D45C470063A243684877016751534D2B2B6E002E8A0EA1217DCA638D + A45678359F0424A99D3FFF8744879054AA758095A3436858DFCEC747D752D3CA + 8A890D9FAA2BED697318AAD40E697B9E43B7A4F6590F78213A84A4527D071815 + 1D42437A0A389E1A6B625971563E264BD5B511B0447408497D7132F06C740849 + 7D93B67EFC313A84A452ED92E755A8FA47CABE488D35B1AC48CB5C7E101D4243 + 4A7BDB5C0123B5C32BC08AD12124F5CD2A755E722CA9A3EBF803A2436858E979 + F8C7D45C13CB8AE4987C81ACEA5AD33730526B5C0FFC333A84A4D2FD01B8353A + 84A4527DD7F973B57034F01835374D83F7E7A4BF2055FB7B2F2D4D92D48EA34C + 3F1E1D4252E9B6AEEBF178923A322FB053740875A411EFB39A5A5624474607D0 + B0DE0D6C191D42525F3C9427524B6AA6AF018F44879054AA9F02334687D0B07E + 03DC460334B9ACB8312F475475A509C2DF880E21A96FBEEE5D57A9B1ABA7D2D2 + 7049CDF57EE063D121D491C6DC1C6A7259911C1E1D40C37A13B06F7408497DF1 + 423ED25052B3AC0B8C8D0E21A9546958E3E8E8101AD685C0E53444D3CB8AB4B2 + E2E6E8101AD65EC00CD12124F5453AD2F081E810920AF340BE3896D45C3BE7ED + DBAABE436890A69715E35D96580B7334E1681D491D1FA5B56A740849851E559A + AEB72435F7A8D203A343A8235736AD3C6E7A59919C984F0751B5A5419B8B4587 + 90D417B70367448790D4B3B3813BA243482AD5111E555A1BDF6ADA6CB0369415 + 2F02DF8B0EA1614D97270C4B6ABEF442BA6D7408493DDBA66917C692A69A2DE7 + EB753DDC0A9C49C3B4A1AC20BF09768962F5AD06AC151D42525F3C09EC111D42 + 52D7D270ECC7A343482AD52F80E9A343A823DFCC5B6D1BA52D65C5A3C0D1D121 + D4D1F7E30FA34348EA9B34ABE6E5E81092462CDD003A2C3A84A4526D9A67D2A8 + FAEE034EA681DA5256243F880EA08EBC15D8273A84A4BE78C9619B522DAD9EB7 + D94A6AA6F41EF1FBC0A8E820EAC837805768A0369515B700A747875047BE0CCC + 1C1D42525F5CEA11D352ADA4819A7F8B0E21A95469DEDFC2D121D4914780E369 + A8369515C977A203A823B3033F890E21A92F26006B478790D4B1359D032635DA + 1B81CF448750C7BE9957AA3652DBCA8A7F027F8F0EA18E6C062C131D42525FDC + 0FFC3C3A84A4611D07DC1B1D4252A9D25DFA19A243A8234F377D2E63DBCA8A74 + BCD6A1D121D491697DF322B5EAB9F98BD121240D6B578F2A951AED53C0CAD121 + 34A255152FD0606D2B2B9273819BA243A823EF73199AD41ACF025B46879034A8 + F4F3F94C740849A519037CD7A19AB5F14C3E55ADD1DA58568CCF2D94EAE120CF + 77965AE3B4BCA45152B53C9D7F3E2535D751C0FCD121D4B16F01CFD3706D2C2B + C82FB8E93C5A55DF3CC0CFA24348EA8B74ECD64AD121244D6585A61E8B27E935 + EF023E1D1D42235A8D7A242DD0D6B2E295DC46A91E3677D8A6D41AD73B0859AA + 94BF003746879054FA50CD342F4EF57030F01C2DD0D6B262E20FE553D121D491 + F4E4796C7408497D9186F76D1C1D42D2EB3EE1504DA9D1F6CB2B2B540FCF013F + A225DA5C568C757645ADBC1BD8233A84A4BE78D8D56F5225EC0F3C1A1D425269 + E603BE1C1D42235E55F12C2DD1E6B222F9691B069334ECA269B6E81092FA365C + D7BBB952EC40F26F47879054AA138099A343684427801C418BB4BDAC48ADD4A1 + D121D4B15454FC323A84A4BE781158273A84D4626BE69F4349CDB415B07A7408 + 8DC8816D5A5591B4BDAC20EFF979293A843AB6BE6F60A4D6B810B83F3A84D442 + 770017478790549A1981C38051D141D4B127F3F1B2AD6259F1DFBFF8EF4587D0 + 88BE677FE2F7AED49A65E8AB4487905A688DFCF327A9997E05CC1D1D42237200 + F0022DE31BBEFFFA01302E3A843AB62870787408497D7117F0FBE81052CB4E4B + FB77740849A5F908B06174088DC8A3C0CF6921CB8AFF7D03A4A550AA8F1D8165 + A243482A5D1AB2B95D7408A9453EEF705BA9B146033FCBBFAA5E870C8CA5852C + 2BFE276D057175457D4CE7B04DA9359E02768D0E21B5C0166D1BDE26B5CCD1C0 + 42D1213422FF017E414B5956FCCFC3793B88EAE35DC0D7A24348EA8B34ABC661 + C852B9AB4C4F8B0E21A934AB029F8A0EA111DBAFCDD73F961553AFAE70A054BD + 7C0958243A84A4D2BDECB04DA9542BB8C2546AACB4EDE338604C74108DC8ADC0 + 89B49865C5E41E027E181D42233E7AE994E81092FAE25FC08DD121A4063A0BB8 + 3D3A84A4D2A439156F8C0EA1AE5655BC428B59564CEDDBDE59A89D0F025F8C0E + 21A974138075A243480DB4B54335A5466FFF483FE3AA972B81D36939CB8A8167 + 57A4ED20AA97AF03F345879054BAFB819F4687901AE4B37988ADA4E6199307D2 + BBFDA37EF6753C8165C560BE9BF747AB3E66064E8D0E21A92FF68C0E2035C40B + F9740049CD94E6542C1C1D4223F617E082E81055605931B0C78043A34368C456 + 02BE101D4252E99E033E191D426A8015BD392335D67ABE56D6FA008157A34354 + 8165C5E0D231A62F4687D0888C02BE09CC1F1D4452E97E0B3C191D42AAB1CB80 + 6BA243482AC50CC031F91410D5CB69F9F9599615437A0238283A84466C96FC26 + 4652B38DCB472D4AEACE067968ADA4E639C9596EB53E01449965C5D08E009E89 + 0EA111FB30B077740849A5BB19F86B7408A9A643A9D3407149CDB30DF0B1E810 + EACA911E233D39CB8AA13D0B7C2D3A84BAB23FB048740849A54AFB3937890E21 + D54C9A2E7F48740849A59807F8A1EFF16A29CD0F3A303A44D5F88D3CBC9F018F + 4487D088CD04FC3E3A84A4BE0C44F6C55DEADCEACEE4921A2B5DFBCE161D425D + 49E3077CCF3905CB8AE18D75EF506DBD0738383A84A4D27DCBBDF752476E052E + 890E21A9145F7596536D3D9E0F77D0142C2B3AF34BE0CEE810EACAEEC0BBA343 + 482AD54BC03AD121A41A58D3624F6AA47700FB468750D7F6C9C7B26B0A96159D + EF214AE7DDAA7EA6074EF57B5D6ABC3F03FF8E0E2155D84F81FBA343482ADC34 + 79FB473AAE54F57353BE31AE01F806AE73E949E0CAE810EACAE2F9AC6949CD1E + 1AB86A7408A9C2F6C843692535CBB1C012D121D4B52F02AF4487A82ACB8A915D + 08A7253AAAA7AD800DA343482AD5DDC06FA2434815945EFF5E880E21A9709F00 + B68C0EA1AE5D00FC213A449559568C7C9971FAA652FD8CCEAB2B9C902C3557BA + 6BBC437408A9621E04CE8E0E21A97073E5ED5DE91A57F5B4A72BDE8666593132 + E99BC9D515F57E523F233A84A4523D0D7C363A8454212BE6D5A1929A25959073 + 448750D77E0E5C171DA2EA2C2B46EE6AE0F8E810EADA2A4E4B961AEF68E0C5E8 + 105205A46D517745879054B8EF001F8C0EA19E4E31FB4A74883AB0ACE8FE1C63 + EF52D4FBEF6FE9E810924A3DC129DD4D96DA6E7B97184B8DB33AB06B7408F524 + 15158F4487A803CB8AEEDC071C121D425D9B216F07718F9FD45C5701D7478790 + 02ED083C131D4252A166064E04A68D0EA2AEA563D67F141DA22E2C2B7A5B7EF5 + 6C740875EDCDC0C9D12124956602B07674082948BA3E71CBAAD43C6702F34587 + 504F7673AB6AE72C2B7A1BE2E6B0CD7AFB38B073740849A59E82F0E3E8105280 + 158057A243482AD441C06AD121D493BF38EC7F642C2B7A938EC2BC3D3A847AFA + FEFF5E5E6521A999F68A0E20F5D9456E81921A39207EEFE810EAD9EE79E5A73A + 6459D1FB10B7F44DA77AEFFD3BCF9F05A9B15E00368D0E21F551FA7E77A8A6D4 + 1CB302A702D34507514FD24ACF6BA243D48D6FD07A97DEE8FE293A847AB214F0 + ABE810924A733AF0787408A90FBEECF7BAD438E702F34687504F9ECBA7116A84 + 2C2B7A9796F2EC191D423DFB24B053740849A51897F7F04B4D9666547C3F3A84 + A4421DE6EB5723A4F78A4F4487A823CB8A625C0BFC243A847AFE59482F084B46 + 0791548A5BF35E7EA9A956CEDB532535C3C6C0E7A243A8676986D02FA243D495 + 654571D2D29EB1D121D49399F2B69ED1D14124152EEDE1DF243A8454E2C5F065 + D121241566A1FC06774C7410F52C154E9ECED425CB8AE23C96F78AAADE16037E + 171D425229D212CCAF4787904AB0B613E6A546BD3FBB00982D3A887AF66BE0E2 + E81075665951ACB415E48EE810EAD9FA164F52631D0C8C8F0E2115E870E0C1E8 + 10920A7332F0B6E810EAD94B1E9FDE3BCB8AE2BF29778D0EA19E8D02F607568A + 0E22A994E7E9B5A24348056E6FFA5274084985D9C72D8B8D91FE2E1F8A0E5177 + 9615C54B330FCE8E0EA19E4D0FFC0698233A88A4C2FD15B8373A8454D04A40E7 + 6549CDB00A7060BE69A67ABB09382A3A441358569473976337F78E36C2BC79CF + A0A466199F2F0AA53AFB0F707E740849859807F82D305D74101562174F672A86 + 654539EE040E8A0EA142BC17F855740849854B2B2B4E890E21F56045E7AF488D + 905652FC19982B3A880A719C43358B6359519EEFB84FA931B6C8AB6524356B15 + DC0ED121A42EA5A2ED9EE810920AFB795E3A3A840AF13CB077748826B1AC28F7 + 9B359DABAB66FC9C1C027C283A88A4423D07EC1C1D42EAC28EB97093546F69A0 + BB03359B6377E0D1E8104D625951AEDF3BF3A05103374F07E68C0E22A950C73A + A05035B31DF06C7408493DDB00D8CF819A8DF1CF7C4DA1025956942B0DD9FCAC + 773F1A3570F32FBEA8488DF24ADEFB2FD5412A299CA324D5DF62F96779DAE820 + 2ACC4EC0B8E8104D635951BEDBF331446A8665F291A6929AE36AE0DAE8105207 + 56F06258AABD19F240CD59A383A830DF026E880ED1449615FDF16DE0FEE8102A + CC469EF622356E15DCDAD121A4615C025C1F1D4252CF2E04168D0EA1C2DC9FCB + 0A95C0B2A23F5EC8E7EDAA19D236907D1C882435CAC3C011D121A4217CDC6DA5 + 52EDA5AD1F0E6C6FDEF68F74B0824A6059D13FE700BF8B0EA1C24C9BCF517E5B + 741049854925A454455F051E8B0E21A9E79FE32DA343A8502703E747876832CB + 8AFE497743BE00BC1C1D44859939EF399C2D3A88A4428CCD77AFA52A199FB793 + 4AAAAF4D7259E190F6E648AB297675C55BB92C2BFAEB3FC09ED12154A80580BF + F9B32435C699DEC156C5ACE68D0EA9F6C3D9D36A5C4FFE689674E2E323D1219A + CE3758FDF753E09AE8102AD4D2C019D121241576173B9DB82055C19DB9109754 + 4F730117E4D5B86AD690D45F47876803CB8AFE4B7747768C0EA1C2AD07FC203A + 84A442DC962F44A468ABE6D36A24D54F5A49F10F60BEE8202AFCA6C64EF95795 + CCB222C615C077A343A8709F07BE181D4252CFD2FED34DA343A8F5D2A9011E7B + 2ED5575A51B1547408156E6FE0AEE8106D615911E7EBC003D12154F8CFD3B7F2 + 2A0B49F5F624F095E8106AB574E4B983DBA47A3A0158393A840A7715F0A3E810 + 6D625911E73960FBE8102ADC74F918A3344C4952BD7DC725F80AB2759E342FA9 + 7E0E05368F0EA1C2A5F2781B071EF7976545AC3F389CA59166CEFBDDE78F0E22 + A927E982E4A3D121D43A4F0327458790D4952FE693FF3CA2B479D2D1B3D74787 + 681BCB8AF8866E77E0D9E8202ADC3C79A8D20CD14124F5BCE7D8A34CD54FE934 + 9A71D121248DD826C0C1BEBF6AA45452386F30803F4CF11ECB1365D53C8B0117 + FB7326D59A4799AA9FFE0EDC181D42D2882D0F1C9F4F0051F37C1A78293A441B + F926AA1A4E05CE8A0EA1D25EBCCE890E21A9E7A34C2F8D0EA156D8D0A19A522D + 6F4EFD1198293A884A712070757488B6B2ACA88634C0ED33C08BD141548A7580 + 63A34348EA5A7AF3B841740835DE216E39926A67DEBC226A8EE8202AC52DF9B9 + 59412C2BAA231D63FAD9E8102A75F9D8B7A34348EADA23C069D121D4E842EC80 + E81092463C503DADBA5B203A884AB32530363A449B595654CBF179989B9A6754 + 9E10FDA5E82092BAB643740035D647DC0F2DD5CAE83C483D6D015133ED0F5C15 + 1DA2ED2C2BAA37C86D7B2F581AFDF376906F78A4DA7A06F841740835CE7FBC51 + 21D5EE06D45F8165A283A834D70287468790654515DD07FC5F740895660CF023 + E0E3D141247565BFE8006A9C95F2CD0A49F5702EF0E1E8102A755B5EDAFEE1CD + E30AB0ACA8EE76903F44875069A6077E05AC1C1D44D288BDE0762E15289D2070 + 77740849233AC12F0D4E5773EDE311D2D56159514DE3F356014F0769AE74BCD5 + D9C07BA283481A31B782A8289B7954A9541B47039B468750A9D2C0D41F4687D0 + FF585654D7FDC04ED12154AA59803F014B45079134222FE5137EA45E1C0C3C15 + 1D4252C725F576D12154AA57F2F68F97A383E87F2C2BAAED04E0F4E8102AD51C + F97CEE45A283481A91939C33A01EA4D5145F8F0E21A92387005FC88335D55C69 + 66E05DD1213439CB8A6A9B00EC9C27D0ABB9E6062E03E68B0E2269447760D68F + 0EA1DADAC4E16D522D1C00EC6551D1786702C74687D0D42C2BAAEF11609BE810 + 2ADD82C095B9B890549FE18869E0A63412E906C419D121240D2B0D53FE8AEF97 + 5AF19CBCA3AB25ABC91FBE7A485B418E8B0EA1D22D9C0B8BB4354452F5A50B9B + D5A343A87656F1A258AABC3D808380D1D14154BAADF2CD61559065457DF6B6EE + 063C181D44A55B14B80A98353A88A48EFCCB8B1C8DC0EDC0B5D121240D295D73 + 1F0A8C890EA2D2FD0C382B3A84066759511F4F039F8C0EA1BE78732E2C668E0E + 22A9A3D942AB4687506DAC91BF672455531AA4F91D8B8A5648C334BFE8F1D1D5 + 6659512F17E7A3CED47C6F01AEB6B0906AE1967CC75C1A6EC6C97DD121240DEA + 73C0F72C2A5AE1D53CE8F8B9E8201A9A6545FD1C085C131D427DB144FEBB9E25 + 3A88A421A53BE56B468750E56DEE1D3CA9D245C5F72D2A5A63AF7C5350156759 + 513F2F029B01E3A283A8AF2B2C9C612155DBBFF3FC0A692047014F44879034A0 + 5D81C38069A383A82F2E040E8F0EA1CE5856D4D36DC02ED121D4D7C222ADB098 + 2D3A88A441A53BE61F8B0EA1CA4AFBA22555CF9EC0775D51D11A69DBC7D6C02B + D141D419CB8AFAFA05705A7408F5CD627982FC9CD141240D2A9D0AF2DBE810AA + E4C90263A343489ACA9781432C2A5AE553C003D121D439CB8A7AEF91FE8C47E6 + B5CA9B7261316F74104983AEAED8363A842A653CF0E3E81092A672007010303A + 3A88FAE687C019D12134329615F596F6BF6E1A1D427DB5482E2C168A0E226940 + CF02DF8C0EA1CAD8D0E5C652E57C1BF8AA4545AB5C9B57D2A8662C2B9A719CE9 + FED121D4570BE6A19B8B47079134A074B74E7A06382F3A84A4C91C99E754F81E + A83D5E0636763B5E3DF983DA0C87E4D242ED91B6825C0E2C1B1D44D2545E02B6 + 8C0EA1702BE76D2092AA33EF2D0DA81F151D447D95B667DE191D42DDB1AC684E + 63B8795E7EACF648C3362FC917C492AAE554EFE2B4DA2DC075D121244DF69C9C + DEB45A54B4CB31C049D121D43DCB8AE648936DB7880EA1BE9B053817D8203A88 + A4C98C0356890EA1306BE641D892E2FDC1196FAD745B3E8D290DBF564D595634 + CBD9F9AC68B5CB4CC029C0A7A383489ACC15F96249ED7B2DFE4F7408494C0BFC + 13582B3A88426E18A41B79CF4507516F2C2B9A274D37BE2C3A84FA6E7AE0E779 + 6894A46A4877D6578D0EA1BE4BF34ABC9327C59A19B80AF840741085D8266FC7 + 53CD595634CF8B79A9DBF3D141147207E1907C2497A4EA6CD13B393A84FAE61B + F914104971E6076E00DE191D44217E069C181D42C5B0AC68A6FB80CDA24328C4 + E8BCBA224DBC96540DDB450750DF56D2786CAD14EB6DC0F5C09BA2832844FABB + DFDDD56DCD6159D15CE700DF8A0EA110A3F2C4EB339D7A2D55423A1564EBE810 + 2ADDBAF9742E493156CD5BA1D3F1EE6AE7B1E11B012F440751712C2B9AEDEBC0 + 5FA24328CCFA79B0549A672129565A92FA54740895BADDE74FD121A416DB229F + 8E366B741085F9247067740815CBB2A2D95ECEDB419E880EA230EF076EF42E83 + 146E3CF0BEE8102ACD873DAA540AB30F701C30437410853918383D3A848A6759 + D17C8F001F8B0EA1508BE7C2E21DD141A496BB03F87D740815EE2CE0DEE81052 + 4B1D91B73DA721E36AA73F0307448750392C2BDAE1EFC01ED121142AADACB814 + F8487410A9C5D2C0AF4F458750E13677989BD477A3F29DF4CFF97EA6D51ECDCF + C1CE0B6A287FB8DBE3708FCF6BBD59F25DDD2F4407915A2C0DFEDA383A840AB3 + 8D47854B7D3743BE01B341741055623E5B5A45AE86B2AC68D77EE99D805BA383 + 28D474C061B9BC921423DD0DBC2D3A847AF630F0EBE81052CB2C02DCEC0C2001 + BBE4D35FD4609615EDF22CB01EF062741085FFDC7FDEA34DA5306910E38AD121 + 54C800E3742340527FA4E7CDEB8037450751B89F033F8B0EA1F25956B473C0DB + 27A243A8324BE7AE02668B0E22B5505AB6FAC5E810EADA910ED594FA6A7BE08F + C01CD14114EE7260374F606A07CB8AF64E2E776AAE9265F3D6A0774607915AE8 + 87C003D12134626975E2EED121A416F936F0538F2615F014B0619EFFA416B0AC + 68AF6F02BF8B0EA14A58200FAA4AD39425F54FDA42F0DEE8101AB1E58157A243 + 482D799F92B6ACEE058C8E0EA34A48DBD92DF95BC4B2A2BDC601DB3AE44DD9CC + C02F816F4407915AE64160CFE810EAD8B1C08DD121A416980BB8266F599592CF + 027F8F0EA1FEB2AC68B767807581B1D141540963807DF3F1A63E3748FD934EE8 + B92B3A8486958E28DD1978353A88D470EF016E01968E0EA2CA380AF8497408F5 + 9F6F48942E903DA75A138DCA7B01AF07E68B0E23B5441A12E6317CF57803E5F6 + 0FA95C3B029700F3460751655C0CECE140CD76B2AC507281C3C23485B7E7BB1A + AB4607915AE27160E3E8101AD497F2306249E5DE3D4F8F19A383A832D27C8A4D + F26063B5906585263A3C9F592C4D3427705E1E6C25A97C690BD6B9D12134959B + 80EF4487901A2C9DF2F157E0330ED2D414F3F5D6061E8D0EA23896159A282DAD + DA352FBD93269A1E381438D5E70BA9746916C2461EC956B9D7C60FBAFC582ACD + 5BF3B0F795A283A87236056E880EA158BEF9D0A4C6E665C81E09A429E7584C7C + C158303A8CD4702F3B54AE52DE9D87514B2ADE76C095C022D141543969E0FBE9 + D12114CFB242534A4BADD6CC17CCD2A4DE06DC0C7C2C3A88D482C1C79B478710 + 9F07AE8D0E213554DA7AFC3360A6E820AA9CE3806F47875035585668B0FDB9BE + 21D54066077E0B7C373A88D470A700BF8C0ED1622703474687901A6836E03260 + 07E7536800FF003E0B8C8F0EA26AB0ACD060FE909F2CA4298D01BE988761CD12 + 1D466AF0FC8AB444FABEE8202D7427F0A9FC7720A9382B03777854B306F11F60 + 43E736695296151A4A3A3EEA07D12154592BE58BFA15A283480D353ECFAF4813 + D1D51FCF02EFF2AE9E54B8FD813F02F346075125A5A349D7F0E40F4DC9B24243 + 79359F2D7F56741055D67CC085F9224452F19ECED3F255BE74E2C712C0F3D141 + A4869D2A763E7000305D741855D6FAC02DD121543D96151ACE4BC096C075D141 + 5459D3E58B90545ACC1C1D466AA0B48269ADE8102D28E75329F4707410A94196 + CBDB3ED68E0EA24ADB09F8537408559365853A5D16BB8E17711AC66AF91483F4 + ABA4625D00EC1C1DA2C196016E8F0E2135ECE8C97F020B470751A51D041C1D1D + 42D56559A14E3D08ACE291A6EA605B485AEEE99153523947FDA50B3B157FF7F7 + 86E8105243CC9087B47F236F019106730270A0C38C3514CB0A8D44DA4BF691E8 + 10AABC6981BDF21D15076949C57935CF8749A5858AF9FFF39DC035D141A48658 + 21AFB04CDBD646458751A5FD256FFF7080B4866459A1914A73093E1D1D42B5F0 + 81BC5775ABE82052C3DE60A7ED2027470769C03CA625811BA383480D7170BE46 + 5C303A882AEF6E60138F2855272C2BD48D5FE65342A4E1CC061C079C048C8E0E + 2335A8B048838F4F8B0E52530F018BE43255526FD20ACA7FE4EB424FFB502727 + 5CAD0E3C1E1D44F56059A16E7D07F8617408D5E679E693F94483E5A3C3480D3A + 66F393B90C54E72E0216071E8D0E2235C0167930ED07A383A8165ECEF3EFD2CA + 0AA9239615EAE542796FE037D141541B8B027F030E8D0E2235E879783B07DA76 + ECC07C47CFA5C7526FD24AC913815F01B34787516D7CD419411A29CB0AF5DA90 + 6E9387E4489D982E975C57016F8A0E2335644B485A7EBD4F74908AFF7FF4913C + 9CD4A9F3526F3E9887686EEEFB088D407ABFF0A7E810AA1F9F64D4ABFF6FEF3E + A0352DABBB8D5F88884893DECBD07B6F82343F7A4004114589522480820A169A + 829048FB680A221A94A2109022559022D2A4F7DE7B672883B41906B2EE957D92 + E330339CF2BEEF7ECAF55BEB5EE7307199BD12E62DFFE7DE7BBF096CE6DA370D + 6155E03D115C481A9E0FE27645690BD13FBB0B9803B828BB10A9018E00AE04E6 + CE2E44B55236C49D945D84EAC9B0429DF01AB02EF0747621AA954F454B48690D + 9935BB18A9014E8F2D3C63B30BA9885D80A581E7B20B916A6E3EE00E60B7584F + 2E0DD491117249436258A14E4E575F33A6FC4A83B15A0CE8FA5E76215203DC00 + CCD9F24D17B7C65AD25FDAF6210DDBDE717B76A9EC42543B27C50DDA325F491A + 12C30A75D2A31158BC935D886A67AA7ED74B67CE2E466A4078BC483CD16ADB1C + A52D80152200953474B303D7013F03A6C82E46B5733EB013F05E7621AA37C30A + 755AB926B88E29AA866012608D5871BA7B763152CD8D8DBF47EBC797F8A62BC3 + 336704CEF23685346CA5DDE3C1682B9306EBFA586BEBC34B0D9B6185BAE1DA58 + 4F240DF596C5E1C0DF1DE2250DDB25C04CB162B0898E8D019A652DE91BD9C548 + 35376BDC702C371DA7CC2E46B5F4407C07F84776216A06C30A75CBC5B1D64A1A + CE7AB4FBE389A9A4A11B057C3D06219781C84D50BE4C8D00BE0D3C9B5D8CD400 + DF8F5937E586A33414CF006B03AF6417A2E630AC50379D06EC905D846AADF4C9 + FE14B81D5826BB18A9E62E8B9930BBD4B4556254D43E737CB17A3CBB20A901E6 + 8E9B8C87799B42C3301258DDED4BEA34C30A75DBF16E79500794F5833702BF01 + 26CD2E46AAB131B12563A60802EBE04F310B69FAA8FDA5EC82A486D83F6E3096 + 9B8CD25095968FCF028F6517A2E631AC502FFC02D827BB08D5DE647153E709E0 + 0BD9C5480D780AB67F0CA52CC3F4DEA65AAE8A56C2D243BF3970790C0D95347C + CB017701FBBAE943C3343A6E5494D04BEA38C30AF542B96E7C30706076216A84 + 3962E2FF85C00CD9C5480D082D8E02A60536022E4AAAA3041167009B02B3C41A + ECD24AF842523D52134D1A3714CBB68625B28B51ED8D8D1915A55557EA0AC30A + F5CAFB91E097A16852275EBB368A5B16E5DF2B49C36F0FB928FE5ECD0E6C019C + DBC5D916E543EE5F809DE229EF27812D81F38017BBF4BF536AB3CFC79C971DE2 + A6A2341CE5BD61C398772275CDC7BBF75F2D8DF7C3E91EC02762489A345C53C6 + 55F6AF003B025767172435C073717BE9AC0811168F536E3BAC1CBF0F7630E62D + C075C04DB1DAEE41DB3AA49E2837104F8A2F963EA454A76C065C9A5D849ACFB0 + 42BDF65EF4474F165F2EA54E5814B8023807D81E783DBB20A921DE89A0A19C93 + E3CF268B019DE54BD054D1F35E42E8BE1B1AE575FE8D0829CA304CFF3E4A39F6 + 02F68EBFA752A77C256EDE495D6758A10CE583ECAEF1E176DBEC62D4A85EDC2F + 02EBC70AB672E34252E79540E2D93892AA6795984DB16476216A9C6D80D3B38B + 507B781D4C991F764BAFF289D985A871A68A958C0F45FFBD24496D30757C91BC + C6A0425DB043B414493D6358A1EC7547A515C4C042DDB000703E70093022BB18 + 4992BAE847C05331A8B6DC34943AE95BC0F1D945A87D0C2B5495C0C2A456DD7A + 8D5B37F67FFF3686054A92D41465F0EDDDC021B18258EA4650F1ABEC22D44E86 + 15AA4A60F16F0616EAA2321F65BBD872F0C3EC6224491AA699E2F6E0E543D8D0 + 230DD4B70D2A94C9B042550B2C7E975D881AEDD3C0A1B136B10CE39424A96E9F + DD8F009E0036B6E5435D0E2A8ECD2E42ED6658A1AA051665E8E6AFB30B51E32D + 089C015C07AC9C5D8C2449035056733F1D2BE0CBCA60A95B7631A850151856A8 + 8A5B42CA0BE42FB30B51E34D12EBDDAE8DABB47365172449D2787C16B825061C + CE965D8C1A6F573F87AB2A0C2B5445EF01DF038ECA2E44AD30695CA57D18F8BD + 03CA2449155142F43F035702CB6517A356D8193826BB08A98F6185AA1C58FC00 + 3830BB10B56A08E7D6C0B3C0D1C0E4D90549925AE953718BE22160433FAFAB87 + 6D46C7651721F5E78B9FAA6C2CF013E0C7D985A8751F124B2BD2F3C07F38BC4C + 92D4C3CFE507C5FB4FF9E26868AE5EF95787DCAB8A0C2B5475EFC7ED8ADDB30B + 512B3787EC13EB4E7F12332E2449EA86EFC6CDBE3D81A9B38B51AB6C09FC21BB + 08697C0C2B54071F0047023B6617A2D6EEB23F20428B3D0C2D24491DF4D558A7 + 5DE674CD925D8C5AF7F97AB3D88E2655926185EAE437C056D945A8B5CA87C883 + 636DDC8F0C2D2449C350063BDF019C12EBB4A55EB75A6F009C935D8834318615 + AA9BD3808DE24556CA303B70485CD72D6D22BE8E4A92066A2DE006E03C60A9EC + 62D44AA38135814BB20B913E8A1FB2554717C59BFDBBD985A8D5668D019CA53D + 643F07714A9226E233C0DF80CB8195BC9DA7246F02AB02D76617220D846185EA + EA1A6015605476216ABD99819F022F0287015364172449AA8C9522A0B8269E66 + FBD95B595E8D7F1F6FC92E441A285F305567B703CBC5757C29DBF4C0F7819762 + BECA0CD9054992D2AC1C21C575C0E7FCCCAD64E516E88AC0BDD9854883E10BA7 + EAEE1160795F7C552153023B00CFC48C1507A749527B7C36DA3DFE6E48A18A78 + 0058213E334BB5E20BA89AE0F9F87070757621523F93035F06EE032E05D6C82E + 4892D435EBC51C80AB6CF75085DC10332ABC85AC5AF285544DEAC3DB10382BBB + 10691C65F0E63AF1A4ADF4897E2DBB204952C76C01DC0C5C1C5F0A1D9CA92A0D + A45F177825BB1069A80C2BD4B409C75F058ECE2E441A8F4962C6CA1F80278003 + 804F661725491A921D81FB8133A21DD5904255720AF045E08DEC42A4E130AC50 + 1377477F0FD82BBB106922E6067E02BC0CFC1E983FBB2049D2806ECAED033C05 + 1C072C9C5D90341E3F07B605DECE2E441A2EC30A35D1FBC0C1F1422D557D18E7 + D631FCEAAFC026D90549923EE4D3C02F62DBD37F00736617244D407958B73B30 + 26BB10A9130C2BD46427C6C0AB77B30B9106F0B46E6DE03CE051607FE053D945 + 4952CB2D1C5B9DCA20EF5D81E9B20B9226629B7858571EDA498D6058A1A6BB34 + D63595A721521D8C00F60546462F74D98B2E49EA9D0D80CB817B62AB53D9EE24 + 55D598F877F6A4EC42A44E33AC501BDC0D2C131F3AA4BAF8644C992F6BC7EE88 + 6B9D93651725490DBEE1B65BAC9B2E5B143E177F2655D9286015E02FD98548DD + 6058A1B628FBA55703FE9C5D88344865C2FC52C0E1B17EEC5460D9ECA224A921 + 66038E8D1B9847008B6417240DD0A3F130EED6EC42A46E31AC509BBC0E6C0E1C + 935D88344453015B01B7C48793D243ED933F491ABCF5E269F493C0CECEA350CD + 5C03AC043C965D88D44D86156A9B326CF3BBB1DE54AAF36D8B65633AFD2BB1FE + D4DB169234719F886D090F445051028B8F6717250DD229C0FA31DB4A6A34C30A + B5D1FBB1837A63573BA901A689F5A7B7C46C8B1FC5BC0B49D2FF583EB67A9470 + F74060A1EC82A4213A28B67EBC955D88D40B86156AB30B6353C80BD985481D9C + 6D71487C203F3BD6A14A521B951B13DF8996B99B62ABC794D94549C3B013B00F + F05E762152AF1856A8EDEE8C2F78D765172275D014C066C05F8187809F01D367 + 1725493DBA45714A84B63F8F16B912E64A756E612E2D4BBF063EC82E46EA25C3 + 0A095E04D6014ECC2E44EA820580BDE306D125C0967E7097D4C0E1C37BC70388 + 728BE2ABC0D4D945491DF034B034706976215206C30AE97F94DEBF6F027B6417 + 2275F14AF4BAC0E9B1A2EFA4688392A4BAFA17E07CE0E5B841B6A461AC1AE4DA + B8195406C24AAD645821FD9FB1C0A1F1E1E79DEC62A42E9A01F83A7023700FF0 + EFF1679254758B02C7C513E70B6258F6E4D945491D76523C6028419CD45A8615 + D287FD39AEDCB9BB5A4D579E402E06FC38DA44AE00BEE17B83A40A6E3D2A2B47 + 6F8B807547608EECA2A42E29FFAE6F0FBC9D5D8894CD0FA4D2F83D082C17C185 + D40693026BC5EC96578133628FBB2465B5AE6D1F838247C6CAD1656CF350838D + 013E0F1C1CB77DA5D633AC9026ECB5D8A850FA60A5B63DC5DC02B81878163801 + 5831BB2849AD50BEAC9D13EFC1C7C70AE6125C486D18A45966B0480A8615D2C4 + 8D8E2BF25F8CC45B6A9BD9806D62BE4559837A546C1891A44E593F86FF96FEFC + 73814D8129B38B927AE48AB835745F762152D518564803737624DE8F67172225 + 2A21C577A34DAAF48EFF049839BB2849B5546E4CFC1E783E6E7195B5CA0EFA55 + DB1C036C14AD4E92C66158210DDC7DB142EABCEC42A46493C453A00380E780EB + 813D8119B30B9354691B02A746405166516C0DCC925D9494E08398C9F21D37D0 + 49136658210DCE6BD112B27776215285DE4756060E8A8D227F077E647021295E + 1F368F81BD236368F55606146AB997E27DF377115A489A00C30A69F0DE8B2F66 + 65FFF51BD9C548157B4FF90C704804173744ABC8ECD98549EA99A962B5E845C0 + 28E0AC18D83B7D766152055C032C09DC945D8854078615D2D05D062CE61B8E34 + C1F79795A255E429E0D608F916CE2E4C52C72D08EC1737ABCA0DC4E3800D1C92 + 29FD93A3E3415709F3250D80ABA0A4E1AF9A5A33BE8495C18392C61F5C2C1B67 + 8FD82A52FAD54F8A791792EAF7777A83188AB91A307FCCB291F4616381ED62A0 + AC6D1FD220185648C3F736B01B702DF007E013D905491556BED02C1467A718D0 + 7935F047E09CF85027A97A9688768EB5E2D6D414D9054935F024B03170577621 + 521D1956489DF1410C10BB2DBE702D9E5D905413B3C5D3D92D23F82BD7C82F04 + 4E8B2043528E79804D81FF072C0FCC915D905433E5F3E0B6D11A2569080C2BA4 + CE7A38263C1F09EC905D8C543353C417A3720E07EE895B17A7035766172735DC + 0860A3B83951C289796DED90866C2FE0B018CA2E69880C2BA4CE7B3326A15F01 + 9C685B88342493C4B5F37276065E05AE032E06CE069EC92E50AAB91580F56283 + 4F9927E3CD0969F85E8F75BD652E93A46132AC90BAD716F25FB129E44C60E9EC + 82A49A9B2E9EFA96F373E0816819393756248EC92E50AAB01980B5E32C032C15 + 2B462575762D696969B48551EA10C30AA9FB6D21AB0207BA2D44EAE8AD8B45E2 + 6C1741C52D115E9C13AD23525B4D1E1B3AD688DB138BC7FC095B3AA4EE295BE1 + F607DECD2E446A12C30AA9FBDE02BE1757024FF16996D4719301ABC4D91D7803 + B839C28BF3801BB30B94BAE493D1C6B15ACC9958145830568B4AEABE37E23645 + 695194D461861552EF942F4D0BC77AD372155752774CDDEFCAFB3ED1435C6E5E + DC005C16372F6C1B511D5B39568D506EA9B859349FC18494A6BC976CE50C25A9 + 7B0C2BA4DE7A16583F9EFE1E9C5D8CD412D3029F8BB3574C67BF0FB83B7A8CAF + 8ADFA5AA5832364BAD182177B92D317B765192FED74FA3F56374762152931956 + 48BD579EE81E12DB42CE00E6CE2E486AE17BDF9271CA5331A2CFF811E051E0FE + 681DB92DE6CE48DD324704122BC66C89F923982873272455CFCBC016AED3967A + C3B042CA73637C593A3286044ACA53BE1C2E1667E371C2C5A780A7E3E7C31166 + 9460E321E0B5C49A551FD3C4B0CB15A385638138D36717266950EDBCE5F3DAC8 + EC42A4B630AC90728D02BE095C089C0C4C995D90A40F0DEF9C2FCE8486AB3D1F + ABEAFA7E3E1637341E8BF3668F6B56EEC0CBE562D8E5B2715362FEB84121A9BE + EBE8CB46B76381B1D9C5486D62582155E34DF06CE07AE00460BDEC82240D6A98 + E7D471757F42CAED8B178117E29440E3F108341E8C1B1A0EFCAC97498165E2B6 + C472FD6E4ACCE58A50A9511E8C6D1F77641722B591618554ADE19B1B013B0047 + FBF7536A8C4FC7596822FF99E7E335A0EFDC03DC09DCE595E3748B4528B142FC + FFB0DC9418118185A4E63A3A86327B3B4E4AE29721A95ACAF5C2E3804BA22D64 + B5EC8224F5C4AC71CA53FA7195B0E289386556C6EDF194EF5EE0FD845A9B623A + 606660A63833F7FB394FDC9428C184C32EA57629EBAEBF162DBA9212195648D5 + 54AE87AF0D7C073814F858764192D2CC1067B9F1849B4F444BC9E3710BA32FC4 + 28ED266D3049BFB061DCC061C6B8D1326D0CB89C267EEFFB676F46481AD705C0 + F6D1BA2729996185545DA587FD70E062E00FD11F2D497D269DC8F0CF7FC40693 + 729E8930E391D866F248053F884F369EC0A17FE830ED444207491AAEF7805D80 + E31DA22955876185547DA577FD33C01EC04FB38B91540B53018BC4199FB78197 + C773FA0F027D31FEAC0C087D65182D27D344E030479C3981B9E3CC15FF5C4209 + 49CA50069C6F1D41AEA40A31AC90EAE11D60FFE89F3CF523360F48D247992282 + 827206EADD7E67746C322ABFF73779BF9F93C73A66DB2D245551790DDB1B3822 + 5ED324558C6185542F37473BC8BE71D342927AA52F8090A4BABB0FD8CA95A452 + B539B44FAA9FB7803D815562FFB724499206E6206079830AA9FA0C2BA4FABA21 + 6E591C985D88244952C53D140F7AF68EB93D922ACEB042AAB7F266BB0FB0625C + 69942449D23F3B241EF094073D926AC2B0426ACE2C8BE58003B20B912449AA88 + 8763A3DA9ED1462BA9460C2BA4666D0CD92F428BB2EE549224A9AD4A9BECD2B1 + 9A54520D195648CD731BB0420417652D972449525BDC1903344B9BACB729A41A + 33AC909A7BCBA2B4842C05DC945D8C24495297BD1FED1E2B01B766172369F80C + 2BA466BB1BF82CB03B3036BB184992A42EB80E583C0669BE9B5D8CA4CE30AC90 + 9A6F347024B010704576319224491DBC49BA33B006707F7631923ACBB0426A8F + 478175811DE2CD5D9224A9AECE04E6078E03DECB2E4652E7195648ED525A418E + 8F37F7F3B28B9124491AA4E7814D802D8167B38B91D43D8615523B9537F7CD80 + AF00A3B28B9124491A80C38105810BDC7826359F6185D4EEA9D9A703F3012764 + 1723499234013702CB013F00FE915D8CA4DE30AC903412D80E58077822BB1849 + 92A4F066CCDA5A0DB82DBB1849BD655821A9CFE5C062C0CFB20B912449ADF73B + 60DE98B5E5004DA9850C2B24F5F716F0636029E0FAEC62244952EBDC13AB48B7 + 075ECE2E46521EC30A49E37317B03AF06F11604892247553F9BCB14BCCA6B83A + BB1849F90C2B244D48B972F99FC008E094EC6224495263FD67B47CFC12189D5D + 8CA46A30AC90F4515E04B606D6051ECE2E469224356ACBC74A7193F3A5EC6224 + 558B6185A481BA0C5812D8D34157922469185E01B6892D1F37651723A99A0C2B + 240DC63BC021C0FCC039D9C54892A45A190BFC7BB47C9CE4C30F491363582169 + 289E04360736061ECF2E46922455DE99C082C0BEC01BD9C548AA3EC30A4943F5 + 017021B028B0073026BB2049925439B7036B025F021ECB2E46527D185648EA44 + 6BC8A1B135E4B4EC6224495225BC147329CA00CDABB28B91543F8615923AE519 + 602B606DE0CEEC622449528A77817DFACDA5F0E6A5A42131AC90D4697F039607 + B68F69DF9224A91D8E05E6060E04DECA2E4652BD195648EA8632DDFB77D11A72 + 30F07E76419224A96BCE8F1956DF065ECC2E465233185648EAA651C05EC002C0 + 19D9C54892A48EFA3BB006B029707F7631929AC5B042522F94E9DF5B02ABC607 + 1B4992545FF7019F075607AE8E0D6192D4518615927AE9BAF860B339F0487631 + 922469509E03BE012C1DAD1FB6794AEA1AC30A49BD563ED8FC09581CD8D9219C + 922455DE6BC07780F98093DDF021A9170C2B2465AE363B2EA686EF0DBC935D90 + 2449FA276FC6ECA93981A37DAF96D44B861592AAF041E820600EE050606C7641 + 9224B5DC68E080786F3E38DEAB25A9A70C2B2455456907D9236E5A1C631FAC24 + 4929ABC70F8D90623FE0F5EC8224B5976185A4AA7916D8151801FCDA09E39224 + F524A4382C428AF2E0E0E5EC8224C9B04252553D09EC04CC0FFC36BB1849921A + 1A521C1E33297E08BC985D9024F531AC9054758F01DF8C09E4BFB23D4492A461 + 1B1B21C55CC00F8017B20B92A471195648AA5368F1AD986971643C0D92244983 + DBC47570B47B9490E2F9EC822469420C2B24D5CD33C0EEF141EB40D7A84992F4 + 91DE8A8199B3C52A526F5248AA3CC30A497555FA6AF701668D616023B30B9224 + A9625E8F7062B65845FA6A76419234508615929AF041AC6FCDDA76C0FDD90549 + 9294ACB4777C37DE1B4BDBC7A8EC822469B00C2B2435A90FF70460096023E092 + EC822449EAB187806D8179805F006F6617244943655821A98913CE2F02D60716 + 077E098CC92E4A92A42EBA11D81C58143811189D5D90240D976185A426BB17D8 + 059819F83EF0447641922475D005C05AC02AC09F22B097A44630AC90D406AF01 + 4700F3031B02E766172449D2109540E237717B7013E04AE083ECA224A9D30C2B + 24B5ED03DEC5C01780B9638D9BEBDB2449751928DDB77E74C7B83D28498D6558 + 21A9AD9E8A356E73019BC6555A4992AAE6C10827FAD68FBE945D9024F5826185 + A4B62BC337CF8BABB473027B034F661725496ABDBF44EBE262D1F6F176764192 + D44B861592F47F9E010E02E68B6D227FB40F5892D4E300FD57B1867B83685D74 + 68A6A45632AC90A40F2B1F0C2F01BE0CCC02EC1ED7702549EA566BE20F637BD5 + B7807BB20B92A46C8615923471A537F8C8D85DBF0670423CF9922469B82E8DB9 + 49E546DF61B1BD4A926458214903F63E7035B01D3003F04DE0C6ECA22449B553 + 664F1C1521F87A3137E9BDECA224A96A0C2B2469F0DE007E0BAC0C2C051C1E2B + E524499A903B63ABC74CC06EC0FDD905495295195648D2F0DC05FC20FA8CBF14 + D3DB2549226E4C94F6C155816562ABC79BD94549521D18564852678C06CE8CE9 + EDF3003F7605AA24B556B935B12B3063B40F5EE77629491A1CC30A49EABC1252 + FC0C1801AC154FD5DECD2E4A92D4F55B1427036B028B03C7D822284943675821 + 49DD1DCA7965BFA19CDB02D764172549EAA8BBE316459945F10DE0AA78FD9724 + 0D83618524F546E9513E11581D580838007826BB2849D290BC05FCAADFA0E572 + 8BC2B5A392D441861592D47B0F01FBC56C8BB2B6EE14D7D649522D5C0E6C1DB3 + 28BE152BAC9D4521495DF0F16EFC974A9206642C70699C9D812D80AFC79C0B49 + 52353C021C0F9CEAE064497577E105E75017861592540D6FC420CE13E2C6C556 + C036C0C2D98549524BDB3C4E8D8199D73A8342927ACF361049AA9E2780838145 + 819580A38057B28B92A4862BED1C17005F8EA1C83B00571B5448520EC30A49AA + F607E79B80DD8059804D803F3ADF42923AAACC9DF8363073BFD7D977B28B92A4 + B6B30D4492EAE1BD78E257CED4C06631E46DDDECC224A9A6838E7F0F9C0E3C98 + 5D8C24E9C30C2B24A99EF32D4E8E332BB06504172B6617264915F674CCA13803 + B8C52D1E92546D861592546FCF03BF88B3606C14F92AB04476619254012381D3 + E20685833225A9460C2B24A959D79A0F8AB37804175F8B104392DAE295B83D71 + 267045AC899624D58C61852435D33D710E0096013607BE022C905D98247529A0 + 288331CF32A090A46630AC90A4662B3DD9B7C5D937828BCD22B8F0C685A43A7B + 0EF8137036F037030A496A16C30A496A6770B11FB024F005E04BCEB8905413F7 + C7ED89F363B5B3332824A9A10C2B24A9BDC1C59D714AABC842C0A6115CB85544 + 5295D63697B68E0B818B8107B20B9224F586618524A97810F8FF71E604368E76 + 9175808F651727A9551E8F70E222E0AFC0DBD90549927ACFB0429234AEA781E3 + E24C036C14ED22FF024C955D9CA4C67919B81CB82C664F3C9C5D9024299F6185 + 2469624601A7C529EF196B4468F179378B481AA291C055C095114EDC19AD6992 + 24FD2FC30A49D2607AC7FF1AE7FBC02271EB629308316C1791343E4F02D74438 + 712D70AFE18424E9A318564892863395BF9C23802963BEC5061160CC9D5D9CA4 + 1463634B470925AE8F535ACB24491A14C30A495227BC099C1B671260F1082FD6 + 073E077C22BB40495D1BCE7B7D04143703B702A3B38B9224D59F618524A9D3CA + F5EEBBE31C054C166D227DE1C5B2D9054A1A92472290B8254289F2F3B5ECA224 + 49CD64582149EAB63131E9BF9CBD801980D58135E3D6C552D9054AFA50E0786F + 0412B701B7C74F83094952CF185648923236019C13A7980E5839CE67E29495A9 + 92BAEFB5D8C671478412E5F7BB8077B30B9324B59B61852429DBABC0C5718899 + 170B01CBC459215A47CA8D0C4943F37EDC96B8230289BE56ADA7DCCC2149AA22 + C30A4952D5942F4E0FC439BDDF9FCF1E833BFB4E599DBA20304B62AD52153D1B + B723EE8840E2CE082A4A4B962449B560582149AAD317B0722E1DE7CFA78DD0A2 + EF945B190B030B009F4EAA55EA85D72394E83BF74438F14A766192240D976185 + 24A9095FD86E8E33AE1256CC03CC1B3FCB1911679E98972155DD980821EEEAD7 + BE51CED3B67048929ACAB04292D4F4E181AFC575F8F129833CE702E68E9F7DBF + F73FBE57AA979E8CB68DBE534289FB62E6842449ADE1073049529B8D8AABF3E5 + 8C4F19F6395B8416F3F4FB396FBF9F53F5B86635C39BE384127DAD1CAE079524 + C9B04292A489FAA0DFAC8CEB27F09F993E428BBEF692F980F96366C688083CD4 + 6ECFC45AD0DBE267B9E9F3882D1C92244D9861852449C3F34A9C5B27F03EBB40 + 9C32FC735160B1F859420E354F09216E89736BDC9A7831BB284992EAC6B04292 + A4EE790FB83FCEB8668EE06249600960A9F87DCA843A35F0B6A197FB9D91C04B + 71F3E6D6B839611B8724491D60582149528E17E3FC6D9C3F1F1121C6E2710363 + 91B8993163529D6D081E46F60B1EFA7EEFFF3FEBFB393ABB684992DAC2B04292 + A46A792CCE85E3FCF9B4310F63DE38730273C40693BEDF27A59D061B3CBC1CEB + 402549524519564892540FAF479B4139E3530679CE0ACCD2EFCC1C7F366BCCC8 + 2867867EBF57DDD311DC3C183F271442183C4892D430861592243543D92CF15C + 9C819824028BE9E2D6C6D471FA7E9F26D6B24E3181F3B1F8D9F779A2EF3345DF + 9F8D89991DC53BF1F36DE01F71DEEAF7CFAFC590D2123CBC003C1F41C5D80EFE + DF479224D5C8241F7CE0D62C4992244992541DE5A98824499224495265185648 + 92244992A44A31AC902449922449956258214992244992A892FF0687FFD3AD2F + 08CE640000000049454E44AE426082 } PopupMenu = pmDropTarget Proportional = True From 02c267abed21e15db097d571d333a3f6a723b107 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Fri, 6 Feb 2026 22:24:19 +0800 Subject: [PATCH 22/35] Fixed: Forgotten anchor and image edge blend --- mangadownloader/forms/frmDropTarget.lfm | 3721 ++++++++++++++--------- mangadownloader/forms/frmMain.lfm | 11 +- 2 files changed, 2366 insertions(+), 1366 deletions(-) diff --git a/mangadownloader/forms/frmDropTarget.lfm b/mangadownloader/forms/frmDropTarget.lfm index fcced0fda..2be5ef3fe 100644 --- a/mangadownloader/forms/frmDropTarget.lfm +++ b/mangadownloader/forms/frmDropTarget.lfm @@ -39,7 +39,7 @@ object FormDropTarget: TFormDropTarget BorderSpacing.Around = 4 Center = True Picture.Data = { - 1754506F727461626C654E6574776F726B4772617068696373B4000089504E47 + 1754506F727461626C654E6574776F726B477261706869631C31010089504E47 0D0A1A0A0000000D494844520000042B0000042B0806000000A5CB265100000A 3A69434350735247422049454336313936362D322E31000048899D5377585377 173EF7DEECC14A88808CB0976C81002223EC215396A8C4244018218604DC0311 @@ -123,1367 +123,2364 @@ object FormDropTarget: TFormDropTarget 98DFD8E547731E8D3C963C9E7C52F0B3EACF554FCD9E7EF78BE72FDDE371E323 CFA4CF3EFEBAF1B9E6F3FD2FA6BFE898089FB8F732F3E5E4ABC2D79AAF0FBCE1 BCE97A1BFB767432F71DF15DD97BF3F7ED1F823FDCF998F9F1E36FF784F3FBC5 - A88942000000097048597300002E2300002E230178A53F760000A9DF49444154 - 789CECDD09DCA563FDC7F1CF98B1EF3B214568232AADF65D11424264977F8B25 - 4B511115DA14490BA1B2B7D82949D142F67DDF22FBBE8D6566FC5F97AED12CCF - 729E73EEFBFCEEE5F37EBDCE6B06CF3CCFB7E679CEB9CFF7BEAEDF35EAD5575F - 459224499224A92AA6890E2049922449923429CB0A4992244992542996159224 - 499224A9522C2B244992244952A558564892244992A44AB1AC90244992244995 - 62592149922449922A65CC701FF0D1F536EC4F124992146D76605E60EE491EF3 - E47F9FCC30C9C7CE38C4E7190FBC3CC93FBF04BC9A7F3F36FFFEA5FCFBE4C5FC - FB17F3E3E5FCEB73F9DF3F9F7F9F7E9524490D71CED9A7775F564892A45A9A6B - 92B261D25F27FE7ECA7F9EBB26D70563737131B1C878363F9ECABF3E937F3FF1 - F164FEF509E0B1FC7825FA7F8424491A5A1D2E4A24496AB35153AC749874E5C3 - 50054453B77ACE981FE9FF876E3D334971F1F814BF7F6892C7C3F9D77105E697 - 24491DB0AC9024A97F460FB2D261CA7F9E722B868A355B7E2CD6E1C73F9A4B8B - 077381F100701FF01FE0DFC0FDC02325679624A9552C2B2449EACEB453940C73 - 0DB2D261D27262CEE8D0EACABCF9B1F4101FF3522E30EE9FA4C0B81BB827FF7A - AF2B342449EA9C65852449C34BDB0EDE03BC373F9607968C0EA54A991E784B7E - 0CE4D55C66DC95CB8BBB7291917EBD3DAFDE902449996585244953AF9878777E - 2C9F1FEF8C0EA546CC1E79637EAC32C07F7F1AB8231717B702B7E5C7AD7970A8 - 2449AD625921496AFBEBE032B99898B86262D9060FA75475CD9E57EFA4C794D2 - AC8C1BF3E3A6FCB8390F049524A9912C2B24496D2C26266EE948C584AF85AABA - 05F3638D29FEFD43B9B89858625C0F5C9B8F759524A9D6BC4093243591C584DA - 6081FC586D8A7F9FE6605C938B8B6B738971779E9B2149522D78D126496AC271 - A0936EE5B09850DB2D961F1F9FE4DF3D035C075C39C9236D25B1C09024559217 - 7292A43A99261F1F3971C5C4C41913D34507932A6E366085FC98E8855C5A5C91 - 7FBD0AB8C50243925405961592A42A9F9EF0B6BC52626231917EB598908A3113 - B0627E4CF43C7019F04FE0F2FC782030A324A9A52C2B244955F1C649B671BC1F - 781F304B7428A96566CE3330269D83F16FE06FB9C0B82CAFC0181F985192D402 - 961592A408734D514CA4C7FCD1A1240D5A246E911FC94BC03F808B272931D28A - 0C49920A63592149EAC700CC65F34A890F021F02168F0E25A96BD303ABE60779 - C6C5959394177F071E09CE2849AA39CB0A4952D1D20A890F4C524CBC2FBFB991 - D4DCF93213574AED91FF5D1AD479217011F057E0B1E08C92A49AB1AC9024F5FA - 26E5EDB99C48A70C7C1858223A94A4706FCD8FCFE67F4EC7A6FE09F84B2E2FD2 - 51AA92240DCAB2429234D22D1DEFC9A5C44AF91481B9A34349AABC65F263E2CA - 8B74CAC805B9C0B80418179C4F925431961592A4E1CA89B48D63E5BC3F3D9513 - 33468792547BCBE7C7BEC08BB9B4F843FEF5D63C074392D462961592A4494D93 - 574EAC928F2E4CAB27668A0E25A9D16600D6CB8F8947A59E9F575EA402E3D9E0 - 7C92A400961592A4B7E455136BE6C71CD18124D1F6A35277CA8F57F390CEB372 - 81E1AA0B496A09CB0A496A9F997229B136B00EF0E6E8409234C410DFB4CA2B3D - 0E03EE02CE04CECBC33A5F8E0E28492A87658524B5E362FF9DB9A0F848DEE291 - 66514852DD2C06EC961F2FE6D2E274E05C8F4795A466B1AC90A4669A36971269 - 0FF8867959B524356DD6C546F9413E55E4F779CBC81DC1D924493DB2AC90A4E6 - 981D581FF818F05107634A6A9915F3E3FBC075C06FF29691F47BE75C4852CD58 - 564852BDCD97CB894D80B5F2960F496ABB65F2E340E076E0E4BCEAE21A8B0B49 - AA07CB0A49AA9F05818D814DF3D1A292A4C12D017C353FD2F6905380DF01575B - 5C485275595648523DCC9B0B8ACD2D2824A9A7A39AF7CB8F3B737191B68BB8E2 - 42922A669AE80092A441CD066C0D9C0F3C021C6551214985591CD817B80AB801 - F852FE7792A40AB0AC90A46A992E9FDE711AF004703CB0767428496AB8B70307 - E76D2297029F05E68F0E25496D66592149D5782E4E2B267E023C9687C0A58199 - A3A38349520BBD1FF811F010F047602B4F5792A4FEB3AC90A4D83B790701F700 - 7F057606668D0E25497ADD9AC02FF34AB76381D52C9225A93F1CB02949FD3547 - 3EC563FB7CF74E92547DD303DBE4C77F805F002702B7440793A4A67265852495 - 2FDD855B0738396FF3F899458524D5D642F918D49BF37C8B1DF340644952812C - 2B24A93C4B01DFCC77E1CE033673F9B02435CAFB7301FD58DE2EB28AD7D79254 - 0C9F4C25A95833E6616C97E4E5C1E9583C27CA4B52B34D9B9FFB2F026E07F6F6 - B95F927A63592149BD1B052C0B1C0E3C9AEFAEAD101D4A92146231E050E041E0 - 37F9F86957D549D20859564852F76600B6062E03AE063E0FCC1C1D4A92549922 - 7B63E0FCBCDA620F60EEE85092541796159234726F03BE9757511C0F2C1F1D48 - 9254696FCEAF1B0FE7D5771FCE6586246910961592D4F97EE44DF37EE49BF21D - B259A24349926A65749E6DF137E05A60275F4B24696096159234B40581AF010F - 00A7E649EF9224F56A69E0A7C023C0F78125A203495295585648D2D446E525BA - 27E66347BF0ECC131D4A92D4D853A476076E03CE01D67220A724595648D2A4A6 - 073E0D5C9997E86EEE9E6249521F7D04F843DE6EB88B439B25B599658524FD77 - ABC781C043C071C072D1812449ADB624F0E3BC45E43BC0A2D18124A9DF2C2B24 - B5D97BF2691E69ABC7578139A2034992348999803D817B8093800FB8E24F525B - 5856486A9BB40F783DE02FC015C0D65EF849926AE093C03F814B800D9C6B21A9 - E92C2B24B5C50CC00EC0CDC059C0CAD1812449EA421A007D7A7E3DDB21BFBE49 - 52E35856486ABAB980FDF2D1A33FF768384952432C915FD7D256C6BD81D9A303 - 4952912C2B2435551A4676581E9AF90D60CEE84092249554CA1F9A5FEF0EC943 - A325A9F62C2B2435CDD2C02FF330B2DD8069A3034992D407693BC83EC0FDF924 - 91C5A20349522F2C2B2435411A90F921E00CE03A60ABE8409224055EDFEF02DC - 09FC1A7847742049EA866585A4BA97146B007F06FE0E7C2C3A90244915B22570 - 03701AF0EEE830923412961592EAFADCB55E3EC2ED026095E840922455D826C0 - 95F934ACF7458791A44E585648AADB73D6FAC0BFF205D7FBA30349925423A9E8 - BF0C38C7D7504955675921A90E46031BE4BB426702EF890E2449528D7D04B834 - 9716EF8D0E234903B1AC9054F5926223E02AE07460D9E840922435ACB4B81CF8 - 1DF0AEE830923429CB0A49557D6E4A2B29AECE1750CB44079224A9C1D28D816B - 809381B7458791A4C4B24252D59E93D6C93329D24A8AA5A3034992D4229B0137 - 01BF0496880E23A9DD2C2B2455E508D2D5804B80F39C49214952A8AD80DB80A3 - 8085A2C3486A27CB0A49D13E045C981FE9F79224A91A3E03DC0B1C0ACC191D46 - 52BB5856488AF2CEBCD5E3EFC0AAD1612449D2A0C3AEF7061E00F601668A0E24 - A91D2C2B24F5DB1B815F00D7E7219A9224A9FA66000E01EE01B607A68D0E24A9 - D92C2B24F5CB3CC07781BB816DA3C34892A4AECC0B1C0DDC00ACE7FB094965F1 - C94552D9D272D12F03F7035FF4794792A4465812380BB8C0C1D892CAE09B0649 - 6519036C93978B7E0B983E3A9024492A5C3ACDEB0AE07860E1E830929AC3B242 - 5219C790AE0D5C0D1C9B978B4A92A466DB3ADFA03808982D3A8CA4FAB3AC9054 - A477017F00CECFA77D4892A4769D1CF2953C9F6A3B87704AEA856585A422CC0F - FC14B80658333A8C24490A3517700C7019B072741849F5645921A91733E6B3D7 - EF05768A0E2349922A6539E02FC0C9C0A2D16124D58B6585A46E9F3B36026E06 - 0E7578A624491AC266C09DC0D78099A3C348AA07CB0A4923B52C7011F03BEF92 - 4892A411CCB3F87A2E2D3EE1FB1049C3F14942D248F69F1E994FF958293A8C24 - 49AAED9CAB53800B1DC62D692896159286932679EF9CE752FC5F74184992D408 - AB00D703DFF3A8534903B1AC90349415812B819F00B344879124498DB3077017 - B079DE2A2249AFB1AC90349005805F0317034B47879124498D36377022F02760 - A9E83092AAC1B242D2945B3E3E07DC0D6C191D469224B56E6B483A69EC0060A6 - E83092625956489AE883C0E5C011C00CD1612449522B8D02F6076E02D6CEFF2C - A9852C2B24CD956752FC03785774184992A47C3CFAF9795B6A3A414452CB5856 - 48ED9586586D0DDC934FFB902449AA9A2DF2F6D49D8031D16124F58F6585D44E - 4B001700C703B346879124491AC28CC04F818B1CC029B5876585D42E6916C5BE - C02DC0AAD1612449924660853CCBE2CBC0F4D1612495CBB2426A8F15816B806F - FAB32F49926A2A5DC37C0BB80A787F741849E5F10D8BD47CB303470117BB7452 - 922435C4DB814B81EF03B3448791543CCB0AA9B9D2515F1B0077009F890E2349 - 925482DD819B81D5A283482A966585D44CF3022700A703F344879124492AD1C2 - C085C0910E0E979AC3B2426ADECF743AE2EB4E60F3E8309224497DF47FAEB290 - 9AC3B2426A8E370067E41515DE559024496DB4D024AB2C668B0E23A97B961552 - 337E8EB7CEB329D68B0E23499254915516E9A87657594835655921D5DB827935 - C5F1C08CD1612449922A769D9456591C06CC1C1D46D2C8585648F5FDD9FD94AB - 2924499286B51B702DB07C7410499DB3AC90EA677EE077C0AF8099A2C3489224 - D5C0E2C0BF80FD81E9A3C3481A9E6585541FA3808D81DB810DA2C3489224D5D0 - 01C03F81B74507913434CB0AA91EE6008E057EE3491F9224493D590EB801F81C - 303A3A8CA481595648D5B75A3E33FCD3D1412449921AF43EE808E0ACBCC55652 - C58C890E206950691EC541C01ED1412435DA78E099291ECF4EF2FBC781C70678 - 3C0A3C3DC5E79A748ECE8C79FBDAE8BC3F7CA6497E9FA6F2CF907F9D293F26FE - 7E1660F6FCFB19F23F4FFCF733E7C7ACF9E1BE7349BD5A17B80DD812383B3A8C - A4FFB1AC90AA6969E03460A9E820926A5B384C5A3A3C3E48D9F0D80085432F5E - 18E4F7654985C8DCC03CF9CEE87C933CD23FCF99FFFBDC93FCDE6B1F49539A2D - AFB03812D807783E3A90245FB0A52AFE4CFE5F3E0FDC6D5A52BB8C9B6245C370 - 85C3C4B2A1E8C2A14EC602F7E747A752B1F1066061E08DC09B80852629382696 - 1DEE6397DAE7B3C05AC0A6F9A85349812C2BA4EA58200FD15C273A88A452BD0A - DC9B4FF6B92D1FA5971EB744076B898905CF75C37CDC22C09BF363A95C6CA492 - 63C15C6E38EC586AA62580AB805D81A3F2CA3549012C2BA46A581FF8755E8628 - A9399ECCA5447A5C035C065C0EBC181D4CC3BA2F3F2E1EE4BFA7D5176FCD8FB7 - E75263D1FC48273849AAFFF0CD3580EDF3CA36497D665921C54A43E3BE9D971D - 4AAAF7168E3B722971F324AB25D29B5D35D323F9315099316F9E3DF4CEFC5834 - 6F3759CC6B2FA95636003E086C025C121D466A1B5F30A538E96EDC6FF31D3949 - F5F1E024AB25AECCAB25D2AA8909D1C15419699EC89FF363CABBB5A9C4780FF0 - EEBCDC7CB1BC2AC319195235CD974BC9AF0187022F470792DAC2B242EABF74B1 - FA69E067FE0C4A95F6522E246E05AECFA5445A2DF1447430D5D6843CB42F3D7E - 31C9BF4F45C5BB80F703CBE7323BCDC9982B30ABA4C91D08AC0E6C9E4B6B4925 - F38D92D45F6926C58FF359DE92AAE3A129065E5E9A0B8A340C532ADBF83CD0EF - AA3CD06FA2B47DE4437919FADB7281914E31191598556AB395819B808D075839 - 25A960961552FFA465BFBFCB13E525C5BD29BC339FBC3171B5C4A579D9BE5435 - F7E6C749531CBD9ADE30AD022C93B712A67F27A93FD200DD0BF3B690438057A2 - 03494D655921952F2DEFDD0538DCBB61525FBD924B895BF21DEB4BF2AA092F2C - 55678FE57947E931D1E2B9BC581178472E31A60BCC28B5655BC84AC01616DE52 - 392C2BA4F2DBF7349B62D3E820520B564CDC9A4FE2B83C0F434BAB261C7AA936 - B8333F8E996436522A2ED606DE97E761B8FA422ADE1A795BC846C0DFA2C3484D - 635921956759E0ACBCBF5852B1EE076ECCA771FC39AF9A7042BBF45FA9A4FB6B - 7E4C94665EAC95EF042F9B4F2071B59FD4BB79F26BD05EC061B93C975400CB0A - A978E98ED6F6C04FF2EF25F5661C70433E412115131738895D1AB19BF3E387F9 - 9FDF007C24DF197E4FDE4A62792175EF3BF9449F740DF84C7418A9092C2BA462 - CD021C096C1D1D44AAB1E7F38C89B48DE30FF9EEB07326A4623D001C9D1F13CB - 8BF5F3EA8BF73A0C5AEACA26C072C07A795E92A41E585648C54977A5CECC93D9 - 2575EEB9BC9DE39FC039C0DF3D32540A292F7E9A1FC992F978C655F3DDE274F4 - B6A4CEAE07AFCBC7D49F161D46AA33CB0AA918E96ED4A9C00CD141A49A6CEBB8 - 369713BF072EB29C902AE736E0E0FC209F36F209E043C0D26E739486346DBE2E - 4C5B43BE0ABC141D48AA23CB0AA937E968B8AFE417224983BB2FAF98383DAF40 - 1A1B1D48D288FC253F923973719196BA7F38FFB3A4A9ED954FE449A7C279BCA9 - 34429615526FD39F4FC8FB7B254D2E4D43BF22BFB939312F8995D40C4F4EB165 - 24ADBAD83C9F34B294833AA5C9AC9C5F03D705AE890E23D5896585D49D7466FD - F9C002D141A40A199BCF994F5B3B7E956751486AD7AA8B7424EAA78075F21D65 - AF35A5FF5E2F5E9107B09FE4D647A933EE37944626DD2DDA220F03B4A890FE7B - 3CDBE9F9AEEA6C79A5D1511615526BDD0D1C34C9F690CFE4537D5E880E26051B - 9D57E41E92B7114B1A866585D4B9F4C272687EA1492F38525BBD90E74EA43DEB - 73001B0127E7C1999234D17379ABC83AB9CC4CA5E619B9E494DA6AEFFC1A3A57 - 7410A9EA2C2BA4CECC0D9C9D0725496D9D41914EEDD82117141BE423D95CCA2A - A9D3E790546A6E3849C999B68C3D1B1D4C0AB0769E5FF1D6E8205295595648C3 - 7B477E4159333A8814E0E6BCA43B6D7B5A0D380678253A94A45A7B356F1FFB78 - 2E2E3E996F08B855446DB248BEBE4C8337250DC0B2421A5ABA7B7C35B0707410 - A98F5EC8AB265600DE0E7C0D782C3A94A4469A009C02AC0FCC0E7C3ACFB87829 - 3A98D407D303E702BBF9BE4C9A9A3F14D2C0D24C8A2FE53B3FD3468791FA74A7 - F3FABCD569CE3C8FE2EFD1A124B54A9A7BF3CB3CE32215175F00FE990B0DA9C9 - 0E037E02CC181D44AA12CB0A696A3303C70207470791FA74DCE86F800F01CB00 - DF055E8E0E25A9F5D2CA8A23F273D32279C0F52DCEC95183ED985715CD131D44 - AA0ACB0A69720BE6B3E2B78A0E2295ECF6BCBD234D23DF14B8343A90240DE281 - BCDAF16DC0FB80E38047A24349255811B8D6C19BD27F595648FFB31C701DF0DE - E82052894BACCFCF4BAC97CC83335F8C0E2549237005B02D303FB01970A1C726 - AB61DE90E7A5AD111D448A665921FD573A42ED7297DEA9A11E050E0716CA53C7 - D3325349AABB53F31BBAF4E6EE10E08EE840524166002E00760646458791A258 - 56A8EDD220CDBD81DFE5DF4B4DF16ABE33B353BE03B9ABCBA62535B890FD32B0 - 04B02AF0FB3C8F47AABB3474F3DB0E7B575B5956A8EDADF54FF2D02EA9295E01 - CEC843E9DE0DFCDC8174925A24CD9DFA789EC7930A8C9BA203493DDA13380998 - 253A88D46F96156AAB7434E3D9C00ED141A4823C91B77AA421B11B3A305352CB - BD98B786BC0358291F45EE4947AAAB8D818B80F9A28348FD6459A1367A237019 - B07A7410A900E928BFDD8179F3568FC7A3034952C55C926753CD9B0B8C7BA303 - 495D4803E0AF04DE121D44EA17CB0AB5CDB2C035795FAB545713808B818FE6A3 - FC7E90FF9D246970CFE4AD216FCA4736FFCDE74ED5CCC2F93AF683D141A47EB0 - AC509BA4E31AFF95B78048759D47F1BB5CBAAD0C9C1B1D48926AEA37C08A799B - C809C00BD181A40ECD9C8BB6349B456A34CB0AB5C1A83C9BE23CA729ABC67703 - 7F9A8FE74BFB56AF8F0E24490DDA4AF7A97C74F93780FBA303491DBE87FB2DF0 - 398F3655935956A8E9C6005FCF27224875F3207060BE88FE0CF0587420496AA8 - 74D4E957814580ADF3D1CF9EA4A4AA3B0238385FEF4A8D6359A1A61F4DFAF37C - F121D5C9EDC0E7818580FDF3F60F49527FFC2A1FFD9C0671FF19181F1D481AC2 - 3EC031F9BA576A14CB0A35D5AC796FFF36D141A40EA53B7857019B034B023FF2 - AE9E2485BA2817164BE719171E7DAAAA4AAB817E0FCC161D442A9265859A68DE - 7C2764DDE82052075221F14FE023C07B8093A30349922673733E3D24CD0DFA49 - 9E2324557190FC9FF375B0D40896156A9A370297E5B3A8A52A4BC7E5FD155805 - F810707E742049D2901E077601E603BE9DFF59AA9274D3E3D23C7B45AA3DCB0A - 35C93BF340AC374707918629292E00DE978B8A8BA303499246E4A53C2760FE3C - 57E8A1E840D22416CBDB4ADF1A1D44EA9565859A6205E07260AEE820D220C6E7 - D5136968DB5AC095D18124493D3FAF1F98B7877C11B8373A9094A553C4AE70A5 - B1EACEB2424D90F6FAFFC529C8AAF0C5ECB9C072798ECAB5D181244985CF1EFA - 3EF0266067E0CEE840123033F08FBC8A53AA25CB0AD5DD16C039C0E8E820D220 - 2B2996013E0A5C1F1D489254BA9F016F017604EE880EA3D69B16B810F8587410 - A91B9615AAAB51C0E78013A2834803CCA4F813B07C5E49715374204952DF1D0D - 2C01EC04DC1D1D46B4FDFDDE19C056D141A491B2AC505DBF6FF7038E880E224D - 5152A4ED481F04D6CCC35E2549EDF6F33CF0F0F3C0FDD161D46ABFCCDF87E986 - 9F540B9615AA9B31F9B8B083A2834893EC554EC7E5AE9A1FFF8A0E2449AA9C1F - E5E324D329228F4487516B1D0EECEB7B40D585DFA8AADBBEBBC3F3C46DA90A6E - 0036043EE011A492A40E7C3B9F1EF22DE0A9E8306AA56F0007F83E5075E037A9 - EA62FABC947297E820127017F0696069E0CCE83092A4DA0D604EDB5917007E0C - 8C8D0EA4D6F92A70685EB12C55966585EA60C6BCCF2EBD3994223D0AEC052C9E - BF272549EAD64BC067F3F690938157A203A955F6047E90572E4B956459A13A9C - 117D2AF089E8206AB5E781EF010B02DF8D0E23496A94C781CD81770017E481CD - 523FA4B2EC2860BAE820D2402C2B5465B3E5A396D68B0EA2D67A25AFA05830DF - 81484B7725492AC3EDC05AC01A9E28A53EDA1E380E98213A883425CB0A55B9A8 - 3807583D3A885A6942BEBBB554DE7EF46C742049526B5C04BC1BD8C1E34ED527 - 9BE79B331616AA14CB0A55D1ECC0F9C00AD141D44AD7E5BB5AE9EED6DDD16124 - 49AD750CF046E060E0B9E8306ABC4D8113F2AC38A9122C2B543573007F043E18 - 1D44ADF320B023F0AE7C574B92A468AF02FB020B03BF713BA24AF671E0440B0B - 55856585AA644EE04FC0FBA283A855C6E6E199E942F0E8E83092240DE0E97CE7 - FBC3CEB350C936044E02668A0E225956A82AE602FE0CBC273A885A637C1EE0FA - A63C3CD3E9EB92A4AABB2CCFB3D8251FA72D9561837C9CAE8585425956A82A2B - 2A5251B16C7410B5C635C02AF9EEC123D16124491AA19F000BE55F5F8A0EA346 - 5A1F38D5C242912C2B548519157FCA7302A4B23D01EC0A2C07FC2D3A8C24493D - 1EAF9D5658BC0DF86B9E6F2115E9A3CEB05024CB0A556198665ACE28957D4177 - 5CBE0B7578741849920A74775E2DF8A93C2C5A2A7A4BC8AF3DD65411C6847C55 - E97FC7932E1F1D448D77693EABFEC6E82052438C021604E603E6CECFE76999F0 - ACC0F4791ECC8BC033F9F174DE5BFF10F06C7478A9C1D21DF0538023816D81E9 - A203A951A7841C0F6CEDB623F593658522CC069C03BC3F3A881AEDB17CDCDBCF - A3834835F766E0EDC00AC0CAC07B8169BBFC5C0FE4E5EA9700D70137E7ED5992 - 8A91CAC2CFE45584C77AC29A0AF409601CB09D8585FAC5B242FD360B70563E7A - 4B2AC3B87C7769275F4CA5AE4C9757BDAD076C032C50E0E77E03B0797E4C742D - 701A701170555E9521A93737E59B429F070ECA2BA0A45E6D91AFB376045E8E0E - A3E6B3AC503FA565C2BF01568A0EA2C6BA3A6FF9486F78248DCC7BF385E8E7FB - 7C7DF0AE49862CBF9AA7CF9F90575F3CD5C71C52131D9197EFFF329FEEE0BC3A - F56AEB5C2A7F36171752697CC252BFCC9087F3AC1D1D448DF41CB04F1ED66A51 - 21756EC6BCB4F71EE07260F7E01B19691EC666C099C09379C5C5EA3D6C3B91F4 - DFD9311BE64189FF890EA34648AB57BF0D8C8E0EA266B3AC50BF96141F0D6C14 - 1D448D3301380F5834BF684AEAFC34A63DF39B9853F2CF50156D928FB74E39BF - 0A2C161D48AAB1B3F3CFFA31F9942CA917A9DC3EC0F7932A93DF5C2ADB983C95 - 7ACBE8206A9C743CDBA6C0471CD0278D683BDEDEF967E63B35DA0E9A56E71D08 - DC99575D38A059EA7E0067DA2EB922705B7418D5DE57802FE5557152E12C2B54 - A6B434EC7BF945512ACAB83CE17C11E077D161A49A1895875AA6AD1587D6FCC2 - 72FD7C24F115F9741249237719B01470988312D5A36F02BB468750335956A82C - E942F8EBC017A283A8516ECF6F4EB6CB7787240D6FB97C07F5C4BC2DAF29DE03 - FC05F817F081E830524DED9187EBDE101D44B5964A2F6F4EAA7096152ACB1781 - FDA243A831D211A4DF079604FE111D46AA89E9F3568F3474F62D34573A66F59F - C0E9C09BA3C34835743DB0749EFDE42A0B75EBE779CE905418CB0A9561FB7C81 - 2C15E15A60D95C8049EACCFB8007F210CDB648271DDC05EC55A3591C5295EC93 - 5759DC141D44B5958E9E5E233A849AC3B24245DB389FFC2115B19AE21BB9A8B8 - 253A8C54A32D787BE5FDE87345870992EE0EDF97575C481AF92A8B77003FF0C4 - 1075F91A745E2ECCA59E5956A848AB03A7458750235C9397A4A6A30A257566F6 - BC4DCA637C61813CCBE26B79D8B3A4911F4BB90A706F7410D5CE983C4FE8EDD1 - 41547F96152A4A5A36787ECD27CC2BDE8B7935C5727998A6A4CE2C9DB77D3868 - 727269D0F38DF9F420492393CACFC5815F3BD45A2334237031F0A6E820AA37CB - 0A15210D3DBCC83DC22A60E969DAF2E16A0A6964D603AE03668A0E52514BE5BB - C36B4607916A2895145BE56DBE8F468751ADCC0D5C02CC171D44F56559A15EBD - 2137A7B34407516DA5C9E3DF0596016E8D0E23D5485AC9B61B705674909AFC7F - F5C7BCB4DD1580D2C89D91EF929F0BBC1A1D46B5B130F087BC4D511A31CB0AF5 - 62CEBCA262FEE820AAAD3B810FE58180923A372ACFA64867DBAB73DFCF43A0BD - FE9146EE05E0A3B9244DBF973AB16C3E25C4D57F1A315FACD5AD998133F31610 - A99B65A5C7E5EF9F2BA3C348357CED3EB665C79216693BB72E4A3D393CCFC9B9 - 213A886A632DE0E7C0B4D141542F9615EAC674C0F1C00AD141544B69CFEB46C0 - B6C084E830520D5FB74F013E1D1DA4E65602AECAAF679246EEAE5C58FC141817 - 1D46B5B005F01DDF7F6A24FC665137DF33DFCE8396A49178359F18F366F7D84B - 5D6FFDF815B049749086486FB4AEF04E9FD493CF001B028F4507512DEC0AEC13 - 1D42F56159A191DA3D3FD14823F142DEE3BA2EF07C7418A9A645C5E1F9CE948A - 2D2CD2B4FAD1D141A41A3B27DF88F86B7410D5C2B780ADA343A81E2C2B34129B - E5531BA491B829BF21486FB424755F147F2E3A4443BD1FF8BDA784483D790E58 - 05381878253A8C2A2F6D275F2D3A84AACFB2429D5A1138293A846A3744334DDD - 7F67DEDB2AA9FBC164DF8B0ED170EB03FB5B58483DDB373F673D121D44957736 - F0D6E810AA36CB0A7562C97C46B21771EAD413795FFD8E9EC72EF56491FCFCAB - F2A5B2629DE8105203FC05583CFF2A0D66C6FC3DB26074105597658586331F70 - 617E42913AF14FE02DC0E9D141A49A4B831F6F8C0ED132E7E6D73D49BD6F0B59 - 35CF27705B8806333FF04760F6E820AA26CB0A0D65E6BC446BE1E820AA8557F2 - 52F50F014F4687916A6E543EA274D6E8202D74B50337A5C2EC97572C795A8806 - 93B60B9F0ACC101D44D56359A1A1EEE8A57903CB4707512D3C0A7C14D8333A88 - D410E98EE446D1215AEA0DC061D121A406F933B004F0AFE820AAAC34E7E48716 - C59A92658506BBA37700F0C9E820AA85BFE5BDA9174407911A22DD5DFA537488 - 96FBBC83DFA4423D954FDEF9491EC02D4D69276F7A694A96151AC8A7F3346769 - 28E3801FE493629E8D0E2335A82C3EC181C69570B977F9A4C2ED02EC00BC101D - 449574481ED02EBDC6B242535A1938363A842AEFE9FC62B27B7410A961DE047C - 3C3A845E330BB06B7408A9818E03DE0DDC131D449574B2DBD035916585269596 - F29F171D4295776D3ECEF68CE82052035F932F890EA1C9A4A1C1334587901AE8 - 566029B7BC6900A3F3D6E245A383289E6585269A231F1DE411A51ACC84BC3C7D - 39E091E8305203A53B8D0B4587D0548E890E2035D4CBC09A79A0AD732C34A974 - 94A9479ACAB242AF990E3809582C3A882AEB456037E053C0ABD161A486BE1E5F - 181D4203FA642EF42595630F606BE0F9E820AA94B48AF7D7F97D8A5ACAB24269 - 88DBC1F90C6C69200F021F068E880E2235FC9CF9D9A2436850E9286F49E53911 - 781FF040741055CA7AC0371D3ADD5E9615DA2E37DAD240FE91CF46BF2A3A88D4 - 60E922ECDCE8101AD2C6CEAE904A7753BE9B7E697410554A3ACE74DBE8108A61 - 59D16EE96EB9778B34D87C8AA3F3F788CB32A572CDEDAC8A5AF8527400A905D2 - 35C707F3F27FB79D6AD2D9412B468750FF5956B4D71BBD93A721E6537C01D831 - 3A88D4124746075047BE0A4C1B1D426A89AD80FDF2104E89FCBE251DEFAD16B1 - AC68A7998133DD1FAD013C0AACEA9B27A96FD29BDF4F448750C7DE1A1D406A91 - 34536D53E0B9E820AA845980F37CFFD22E9615ED3CBBF8C7C0BBA283A8726EC8 - 17E2EE1595FA3B5853F5E1D649A9BFD2CDB5F73A785359BA4EFD0530263A88FA - C3B2A27DBE908F87922675562EB09E880E22B54CBAE8527DA4D30A3C464FEAAF - 5BF39BD46BA283A832038FF78D0EA1FEB0AC6897D581EF478750A58C03BE037C - 2C0FD594D43FE94DEFB2D121D4D5CC2749FDF52CF06EE09CE820AA84AF031B45 - 8750F92C2BDA230DA4393D3A842A652CB003B0777410A9A57CD35BDF8B6449FD - 974E07590FF8A93758049C02BC3D3A84CA6559D1AE819A69308D44DEEE910669 - 1E1F1D446AB103A203A82B9B7BFD2485FA0CF015E095E8200A1F507D3E305774 - 1095C717DB76FC1D1F012C1D1D44957107F00EE0B2E82052CB9F9BB7880EA1AE - 8C02A68F0E21B55C3A29E4D3C00BD141146A11E004670935976545F3ED086C1B - 1D4295F1B75C543C141D446AB9E9F39B5ED5D39BA30348E22460358783B7DE3A - C057A343A81C9615CDB63C7054740855669F677A515F1178393A8C24168B0EA0 - 9E6C171D40D26B2ECBA799DD1F1D44A1D2B620076E3690654573CD0B9CED9D3B - 01E381EFBAE45CAA945DA203A8275B450790F4BAFBF3AAD19BA38328D4C9C092 - D121542CCB8A669A2EDF459F2F3A88C2BD04ECEA891F52E5581ED65B7A7D1D13 - 1D42D2EB9EC92B2CFE111D44A1EF7FD2D1B6B3450751712C2B9A29EDDB5A3D3A - 84C23D076C021C191D44D25413CCE78C0EA142FE1E2555473A1D6405E0ACE820 - 0AF316E01796C9CD6159D13CEBE67D5B6AB7C7810FE7AD4092AAC537B9CD3043 - 74004903CEE8FA18706CFEBDDA67E3BCAA580D6059D1BCE37B4E8B0EA170F7E5 - A590D745079134A0D9A303A8101F880E2069C821B8DF012644075188EFE6A1F2 - AA39CB8A66DDE14945C5CCD14114EAC63C64EA3FD141240D6ACDE8002A443A32 - 515275ED03EC078C8B0EA210A703F34787506F2C2B9AE320E0FDD12114EAEFC0 - B2C0B3D141240DC9B2A219D2563B49D57608B05B9E67A176990B3805983E3A88 - BA6759D10C696FDE9ED12114EA9C3C54CABB0752F5AD141D4085786F7400491D - 4983C6B7CF27A4A95D5606F68F0EA1EE5956D4DFC2F99852B5531A1E7522B05E - 7410491DBFEEBE313A840A1B943A3A3A84A48EFC0AF804F0427410F5DD9781F5 - A343A83B9615F53F4FF86460A6E8200A2B2A8E02B68C0E22A963BEB96D16FF3E - A5FA3813F8483EDA5DED92DE2F79A3A0862C2BEA2D0D0D72CF6C3B8D070E063E - 1B1D44D288F8E6B659BC8E92EAE5AFC0AAC033D141D45733E583083C72BA667C - 91ADF714F2AF458750883497E22BB9AC92542FBEEE368BE593543F57E4632D9F - 8A0EA2BE7A1FF08DE8101A192F9AEA69DEDC0EAA7DD234EB2FE6E9D692EAC737 - B7CDE27594544FD7011F029E880EA2BEFA623E984035E18B6CFD8C018ECFC7F1 - A85D5E06FE0F383C3A88A4AECD171D40859A393A80A4AEDD0CBC1F782C3A88FA - 2A1D4CE0FC8A9AB0ACA89F34A360DDE810EABB17816D80A3A38348EAC9E2D101 - 54F8895C92EAEB8E7C0CF123D141D4D7F915A702D34707D1F02C2BEA6569E0B0 - E8100A292AD2891F1E512BD5DFA2D10154A837440790D4B37B81F7000F470751 - DFA41535FB4787D0F02C2BEAB5D4F437C0A8E820EAABB1C066C0EFA283482A84 - 6545B32C141D405221EE0796071E8D0EA2BEF932B05674080DCDB2A23ED240C5 - 25A343A8EF45C526F95C7049CDB060740015CAB2426A8EFB7261E10C8BF63805 - 983F3A84066759510FEB019F8B0EA1BE7A01D81038373A88A4423960B359E68E - 0E20A9F02D211F001E8F0EA2BE9803382E1F60A00AB2ACA8BED4F69D101D427D - 35B1A8F863741049A51C3DADE6982D3A80A4C2DD990B0B8F356D877580CF4787 - D0C02C2BAA6D34708C1743AD2B2A36022E880E22A914B3470750A17C7D969A7B - 4AC8878027A383A82FBE07BC3B3A84A66659516DDB011F8D0EA1BECEA8D8D815 - 1552E3979CAA392C2BA4E6BA15580978263A884A970E30380D98253A88266759 - 515D8B03474687505F8F27DD1C383F3A88A452CD191D40859A353A80A452DD90 - 4F8C783E3A884AB718F05D4F5EAC16CB8A6A9A0EF835306D7410F5C54BC0A781 - 33A283482ADDF4D10154A819A203482ADD657996585A01AB66DB19F8587408FD - 8F654535ED9107FBA8F95EC94F8CA7460791543AEFD6348F2B2BA476F813B045 - BEC1A466FB15B0407408FD976545F52C0B1C1C1D427D310ED80D383E3A88A4BE - B0AC90A4FA3A1DD81178393A884A2FA18FF538D36AB0ACA896198193A243A82F - C6035F027E1C1D449224491DDF75DF2DDF705273A5E34C77890E21CB8AAAD90F - 786B7408956E0270503E26499254EF195392DAE52860FF7C3DA7E63A0C785B74 - 88B6B3ACA88EE57359A1667B15381CF87A74104952CF1CB029B5D3B780EFE7EB - 3A35D368E0440763C7B2ACA8CEF68F13A243A82FD27C8ADDA34348920AE19D55 - A9BDF6027E111D42A5CF12FC72748836B3ACA886AF014B448750E97E0F6C1B1D - 425218076C36CF73D1012485DAC1A3E71B2F6DF9797F7488B6B2AC88F7813C68 - 51CDF667E0E3D12124499254A80D81BF458750A9D201083347876823CB8A5833 - E5A9C26AB66B8035A343489224A914AB003746875069DE0C1C1C1DA28D2C2B62 - ED0BBC253A844A7517F041F7354B52233D1D1D4052658EA4FF10F09FE8202ACD - E78135A243B48D65459CE53CFDA3F11ECE45C58BD14124499254AA6780152D31 - 1B2DAD889F2D3A449B5856C44847E01C171D42A54A2F542B038F44079154191E - 712749CD7637B03E30363A884AB100F0DDE8106D625911231D5DB94C74089566 - 6C7EA1BA353A8824A954AE9C9334A54B809D8057A283A8143B02EB4487680BCB - 8AFE5B0AF866740895E695FC02955EA82449CDF67274004995F46BE000679635 - D6F1C01CD121DAC0B2A2BFC600BFF0FFF7C69A905F98D20B9424A9F99E8D0E20 - A9B2BE05FC2C3A844A311FF03D60547490A6F34D737FED902705AB998EC92F4C - 92A4767099B7A4A1EC029C171D42A5D8CEED20E5B3ACE89F0581C3A243A8347F - CCDB3F2449EDF14274004995B71E704374089522AD98F77490125956F4475A22 - 74383043741095E24660DDE81092A490A30A2569B86DC21FCE47DAAB79A783B8 - AABA449615FD6B5437890EA1523C9CB7F638404992DA675C740049B529365705 - 9E8F0EA2C27D1658393A44535956946F5687EB34567AC159C53B6B92D45ABEF1 - 90D4A99B812D9C75D3D8D341668A0ED1449615E53B202F1152B3A4179ACD815B - A2834892C258564B1A893381FD8157A383A8508BE6F77C2A986545B9DE03EC11 - 1D42857B353F219D151D449214CA6D209246EA60E0C4E8102ADC5EC0F2D1219A - C6B2A23C63809F448750294E70988EA42E7827AD793C0D4452373E05FC2B3A84 - 0A7734305D748826B1AC28CFB6C07BA343A870FF04B68A0E2149AA04B78148EA - D66AC003D12154A86580CF45876812CB8A72CC031C161D4285BB1F58233A8424 - A9325E8E0E20A9D6037AD774506FE31C02BC313A4453585694E3DBC0CCD12154 - A8F442B2BA4B7E254993F03541522F6E027670FE4DA34C0B1CE5FBEC62F87F62 - F156CC5B40D41CE3F20BC96DD141244995F25C740049B57732F0BDE8102AD447 - 808DA24334816545B1D24015876A36CF61F9854492A449B9B2425211BE049C1F - 1D4285FA912BED7B675951AC9D81B7478750A1CE03F68E0E21A9113C0DA4795E - 8A0E20A931D607EE8C0EA1C22C007C393A44DD595614675EE0D0E8102AD41DF9 - 854392A481B80D445291DB8ED37CB467A383A830FB024B4487A833CB8AE27C0B - 98313A840AF36C3EF9637C7410499224B5C2BD0EDC6C9451C011BEE7EE9EFFC7 - 15E37DF98945CD1AA8995E3024491A8C5B7B2415EDD43CEF40CDB036F0B1E810 - 756559D1BB31C091D12154A823F30B8524494371B9B6A432EC0E5C1C1D4285F9 - 21304374883AB2ACE8DDA780F746875061FE0AEC161D42922449B4FDF8CB87A3 - 43A8106F043E1F1DA28E2C2B7A335B3ED652CDF020B06E7408499224B5DEF3C0 - C73D75A831BE01CC1F1DA26E2C2B7A938EA399233A840A915E083604C6460791 - 24D5C633D1012435DA3F80AF3B1FA711A6030E8A0E51379615DD5B0CD83B3A84 - 0A915E00F607FE151D449224499AC4C1C0D9D12154881D81774587A813CB8AEE - 8FA1F98EFFFF35467A0138343A842449923480B41DE4EEE8102AC4A1F9BDA43A - E09BEDEEAC9A9F34547FE989DFBF4B49922455D5B83C70D3EDCACD38CA748DE8 - 107561593172D33A54B331D213FE7AF90540922449AAAA5BF2BC3CE757D4DFB7 - 8131D121EAC0B262E4B60696890EA19EA527FA7D819BA283489224491DF82170 - 667408F56C59E013D121EAC0B2626466C94D98EAEF2CE007D121244992A411D8 - 14B82F3A840A995D31437488AAB3AC1899DD81B9A243A867FF0636890E214992 - 248DD02BC086C04BD141D49385811DA243549D6545E71600BE1A1D423D7B293F - C1A7277A499224A96EAE020E8C0EA19E1D9857EE6B1096159DFB7A1EAEA97AFB - 2670757408499224A907DF022E880EA19ECC097C363A4495595674E61DC04ED1 - 21D4B38B8083A2434892244905F838F0687408F5E46BB9B4D0002C2B8637CAA1 - 9A8DF018B0417408499224A920CF01DB02E3A283A86B33015F8C0E51559615C3 - 5B15F8487408F5643CB01DF06C7410499224A940E700BF880EA19EEC0DCC171D - A28A2C2B86361A38243A847A765C3EAA549224496A9ACF0037478750D7D25CC4 - BDA243549165C5D03E062C1F1D423DB91DD8313A84244992549257818D80B1D1 - 41D4B5DD8105A343548D65C5D00D97AB2AEA7F4CE9C7F313B8244992D454B702 - FB4787504F2BFAD376104DC2B262705B024B4687504F52D974437408499224A9 - 0FBE03FC253A84BAF67957574CCEB262603302074787504FFE091C101D429224 - 49EAA38D81A7A343A8EBD515CEAE988465C5C0760116880EA1AE3D9BF7ED4992 - 24496DF2449E7FE036E8FAAEAE983F3A445558564C6D36E0EBD121D4B5F4C4FC - 65E0E1E82092244952806381B3A343A82B6380DDA243548565C5D4760566890E - A1AEFD0938323A84244992146833E0D1E810EACA1EC0DCD121AAC0B2627273E6 - BBF2AAA727814DA24348922449C1D231A63B02E3A38368C4A6CBDB415ACFB262 - EA162B0DD754FD4CC8AB629E890E2249922455C019C069D121D495BD81D96939 - CB8AFF99C7B36D6BED3CE057D121244992A40AF934F05074088DD88CC0676839 - CB8AFFD93B2FB9513DA71EA77D7992244992FEE7656027B783D4D297DABEEADF - B2E2BF16CC5B4054CFD33FD2C4DCE7A38348922449157416F0DBE8101AB13980 - 6D6831CB8AFFDA07181D1D425D39DFED1F922449D290B6061E8E0EA111DBAFCD - ABFF2D2BFEBBAAE273D121D4F5E91F6EFF9024499286F612B04B1E4AAFFA5808 - F8042D6559017BBAAAA2B6DB3FF6029E8D0E22499224D5C0EF81D3A343A8ABD5 - 15A369A1B69715F3E7E32E553F1701C74487902449926A642BE0F1E8101A91B7 - 02EBD2426D2F2BBED8D696AAE6D230CD2DA2434892244935F3425E599E5629AB - 5E331647D1326D2E2BE603768F0EA1AE1CE48020499224A92BC701174687D088 - AC007C8096697359918E2A1D131D4223760570687408499224A9C6B6CCAB9555 - 1F7BD2326D2D2BE6CA6585EAE565E053D121244992A49A7B04F85674088DC8C7 - F3FC8AD6686B59918E2A9D363A8446ECA7C0ADD121244992A4064865C535D121 - 3422BBD1226D2C2B6605F68E0EA111BBB76D3F9C92244952C9B6015E890EA18E - 6D0FCC434BB4B1ACF80C307374088DC8046097FCAB244992A4625C0B1C1B1D42 - 1D1B93DFCFB642DBCA8A19812F4587D0889D099C171D429224496AA0CF020F44 - 8750C7F6C8EF6B1BAF6D65C5B679B8A6EAE319E0D3D121244992A4861A97B75B - BF1A1D441D9913D88216685359311DB06F74087535F827151692244992CA711A - F0E7E810EAD8DEC0681AAE4D65C5278085A2436844AE030E8D0E21499224B540 - 5ACDFC627408756449606D1AAE2D6545FADFB94F74088D7839DA0ED121244992 - A496F80F704474088D687645A3B5A5AC580B786774088DC829C0E5D121244992 - A416493778EF8D0EA18EAC0EBC8B066B435931CA13406AE72960A7E810922449 - 52CBA4219BBB3A6CB3363E4783B5A1AC581E58393A84463C54F385E810922449 - 520B9D01FC293A843A3EED721E1AAA0D65C59ED10134223701DF890E21499224 - B5D8F6C04BD12134ACD14D9EF3D7F4B2627160D3E810EAD804E00BD121244992 - A496BB0FF8597408753C68733A1AA8E96545A3F7F034D0F9C085D12124499224 - B13BF07074080D6BDEA6DEA06F7259311BB04B740875ECC5BCDC4C92244952BC - F1C07ED121D4912FE683251AA5C965457AE33B7D740875ECC7C043D121244992 - 24BDEE18E08AE8101AD672C04A344C53CB8A6981BDA343A8630F007B45879024 - 49923495CFE65516AAB6DD6898A696151F0716880EA18EA4339CF7C9C3352549 - 922455CBBFF271A6AAB60D81B7D0204D2C2BD25E1D8F2BAD8FCB805F47879024 - 499234A89D81B1D12134ACCFD0204D2C2B5600DE1B1D421D1907EC141D429224 - 49D2901E037E121D42C3FA3F60161AA2896585C795D6C7EF80EBA34348922449 - 1A569A09E851A6D53623F0691AA26965C522C027A243A8232F78B4AC24499254 - AB55D1DF8C0EA161ED018CA601A669E05E2AD5C351C013D1212449922475EC08 - E096E8101AD262C0DA344093CA8AE9F3B13AAABE87F3092092244992EA65AF7C - A29FAABDBAA2F69A54566C06CC111D421D39D0B39A254992A45A3A1BF87B7408 - 0D6975E01DD4DC340D3AAEF40BD121D491B46CECC7D12124499224756D376F3E - 56DEE7A8B9A69415EF07DE131D42C34ACBC5BE1C1D42922449524FAE04CE8D0E - A1216D5FF79D074D292B3C55A21E2E054E8F0E21499224A967695EE02BD12134 - A869811DA9B126941573035B4687D0B0D232B1DDA343489224492AC47DC029D1 - 2134A4342A610C35D584B2E2D34D3947B6E1FE005C161D4292244952A16F86C7 - 4687D0A0160636A4A6EA5E568C6EC2E0901648CBC33E1F1D4292244952A19E04 - 8E890EA16187A1A603296A679A061CC9F2E6E8101AD6EF81BBA243489224492A - DC5EC033D12134A80F03EFA586EA5E56EC1C1D40C37AC955159224495263BD08 - 1C151D42C36ED7A99D3A97150B021F8F0EA1619D003C121D429224495269BE02 - 3C1E1D4283DA02989F9AA97359B14D74000DEB3960D7E810922449924A350E38 - 3C3A84867CDFBF0B35334D8D076B7E263A8486F5B35C58489224496AB66F000F - 4787D0A0D24DE4E9A991696A3C58F38DD12134A4A7817DA34348922449EA8B09 - C00FA243685073E4ED20B551D7B26287E8001AD64FF2704D49922449ED7028F0 - 6074080D6AF73A7500B5093A8979814DA24368484FE4213B92244992DAE355E0 - 87D12134A8A58155A9893A96159F02464587D0908ECC437624499224B5CBB75D - 5D51699FA726EA5656A49262C7E8101AD2A3C001D1212449922485707545B56D - 002C4E0DD4ADACF800F0B6E8101AD28FF2701D49922449ED5D5DF14874080DAA - 16C798D6ADACD82A3A80865D55918E2C92244992D4EED515474587D0A03E03CC - 44C5D5A9AC4867C26E1D1D4243FAB1AB2A244992240107E5C1FBAA9E99EBB010 - A04E65C586F9FF5455D363F9094992244992C603474787D0A076AB7A1F50E970 - 53D8363A808674547E4292244992A4E46BC033D12134A0B702AB516175292B16 - 02D68E0EA141A5E55D5F8F0E21499224A9525E028E8B0EA141ED4C85D5A5ACD8 - 323A8086949677B9AA42922449D294F6035E880EA1016D0C2C4045D5A1AC1805 - 6C171D42837A362FEF92244992A4293D079C1A1D42F57BAF5D87B2E2BDC052D1 - 2134A85FE6E55D9224499234907D8171D12134A0FF0346534175282B3E191D40 - 834ACBB9BE141D4292244952A53D089C1D1D4283CE875C970AAA7A5931A60EE7 - BFB6D889795997244992240D256D1D9F101D4203DA9E0AAA7A59B13A306F7408 - 0DE865575548922449EAD0F5C0C5D12134A00D80F9A998AA97155B4407D0A07E - 0F3C1E1D42922449526D1C04BC1A1D42030EDAACDC8E862A971533029B4587D0 - 80D231A55F890E21499224A956FE0C5C1B1D4203DAA96AFD40A5C24C614360FA - E8101AD01F813BA24348922449AA9D23A20368404B002B5021552E2BDC02524D - 6928CEFED12124499224D5D22F80FBA34368405B5321552D2BE6043E1A1D4203 - FA077079740849922449B5755C74000D68CB3C8EA112AA5A567C3C0FF950F51C - 1A1D4092244952AD7D1378213A84A632437E2F5E09D354B8D151F5DC049C1D1D - 4292244952ADBD08FC363A84AABD15A48A65C502C0AAD12134A0C3A303489224 - 496A84FDF32983AA96B58005A9802A9615955976A2C93C08FC2C3A84244992A4 - 46B81BB8283A8406F4092AA08A65C527A30368D0A9BDAF468790244992D418DF - 8B0EA0017D8A0AA85A59F10660C5E8109A4A1A7EF38DE810922449921AE57CE0 - B6E8109ACA7B81250956B5B262C3E8001AD06FF3101C499224492AD2F1D10134 - A04D0956B5B2A2127B63349934F4E680E810922449921AE9BBC073D1213495AD - 805104AA5259312FB07274084D250DBDB92B3A84244992A4467A19F85D74084D - 652960590255A9AC583F3A80A692066A1E121D4292244952A37D1398101D42D5 - 3AA9B34A65C5C6D10134951B800BA343489224496AB43464F3EFD1213495CD22 - B78254A5AC9819582B3A84A6F2E3E800922449925AE1A8E8009ACA12915B41AA - 5256A4A2624C74084DE631E0A7D12124499224B5C249C043D12134958D687959 - B15E74000DF86491665648922449523F9C1A1D4053F964D456902A941529C3C7 - A2436832E3806F448790244992D42A8702E3A34368AAAD20EFA0A565C5078079 - A2436832E7038F448790244992D42A0F00174787D0543ED6D6B2E2A3D1013499 - 5773A32949922449FDE6A0CDEAD9B8AD6585F32AAAE57AE06FD12124499224B5 - D2690EDAAC9C77038BB6ADAC580858263883267774740049922449AD76667400 - C56F05892E2BD60CFEFA9ADCD3C08FA343489224496AB5C33C99B072366A5B59 - B16EF0D7D7E47EEBF45D49922449C16E01AE8A0EA1C9AC02CC464BCA8AD19615 - 95320138383A842449922401274607D06446F5FBFDFB34C14796CE1AF8F535B9 - 7F0077448790244992A4BC3DFDC5E8108A3B1C23B2AC582DF06B6B6ACEAA9024 - 49925415A9A8B8203A84A62A2BD20E89C697156B077E6D4DEE61E0A4E8109224 - 49923489A3A203683273001FA2E165C52CFDFC1FA961FD263A80244992244DE1 - 3CE0BEE8109ACC3A34BCAC58250FE850BC74FAC7A1D121244992246900674507 - D0643E42C3CB8AD583BEAEA676896DA5244992A48AFA11F06A7408BD6E596041 - 1A5C56AC15F4753535F78149922449AAAA9B81EBA343A8FFEFE723CA8AF981B7 - 077C5D0D3C58F3D4E810922449923484D3A303A8FF732B22CA8A9503BEA606F6 - FBE80092244992348C238109D121345959314D13CB8A345C53F1D20FFB77A343 - 48922449D2301E012E8B0EA1C98E307D2F0D2C2B560BF89A9ADA95C09DD12124 - 499224A903AE0AAF96D59A5656BC0158AACF5F53033B293A802449922475E8E7 - C0F8E810EADF90CD7E97152BF6F9EB6960AFE41F7649922449AA83A7807F4487 - D0EB560266A04165C50A7DFE7A1AD8C5C073D1212449922469047E1B1D40AF1B - 5DF6E119FD2E2B1CAE590D27470790244992A4113ACEAD20ED995BD1CFB2622E - E09D7DFC7A1AD88BC02FA34348922449D2083D0D5C1A1D42CD2B2B3EDCC7AFA5 - C15D04BC1C1D4292244992BA70467400BD2E1D5F3A3B0D282B9C57510DA74507 - 90244992A42E1D0B4C880EA1C9066DD6BEACF024907869458547964A922449AA - ABC7802BA343E8752BD7BDAC980E58BE4F5F4B83FB479E59214992244975F587 - E8007ADDEAD4BCAC781F30A64F5F4B833B333A8024499224F5E878E0D5E8107A - CDB2C06CD4B8ACF8609FBE8E0697F675790A88244992A4BABB03B8353A84CA9D - 4FD9AFB2C29340E25D0B3C1E1D42922449920A3AE550D5F0E1BA9615A32C2B2A - E192E80092244992549013A203A8DC219BFD282BDE02CCD387AFA3A1790A8824 - 4992A4A6F83BF0707408BDE6FDC0F4D4B0AC48C335152BFD105F1A1D42922449 - 920A2E2C146F4C2E2C6A57567CA00F5F4343FB677400499224492AD8EFA203A8 - BC4335FA51567CA80F5F43433B3F3A802449922415EC34E095E8107ACD87CB58 - AE51A61981E54AFE1A1A5A3A7FF8F7D1212449921A6E9AFC183DC8EF47E5C734 - 1DDC349C30C5631C303EFFEA1B33E97F5E062EF7067965CA8A51F9FD672DCA8A - E57360C5B90578243A845411132F14BB5D6D16F9DF87CB5EE7FF6DC3FDF781FE - B7A57F9E6D927F9E7D90DFCF3AC9E74E05FA74F9F7D3E57F9EF8B5671DE0F376 - FA3566C96F489219261930353AFFB7813E979A6161E0B9E8102ACC6CF96775E2 - F3C3ECF9B921FDFB392679CC0DCC35C963F6FCEFFB75CD9B4A8B7B81AB802B81 - 2B809B8117F2E3A53EE590AA7484A96545BCF47CB824706B9DCA0AC5BA2C3A80 - D447A3F245E3DB812F01EB470792D468374607502BA52274B1FCD86480FF7E6B - 3E05EEC43C64FDD922EF744A157432B05F7408BD3EAFF2D6BACCAC287C22A846 - ECCCE80052C9A6C9C723EF982FCA9ECC93A12D2A24496DB4147000701BF03470 - 3FB03D306F9FE6D549FD7603705F740815FFFEBFEC272C4F02899596099E171D - 422A7105C596C0A3F9F1B37C21264992FEE70DC0D1795B707ABDDC3CBF86BA55 - 5B4DE2E987D5509BB262416091123FBF86771DF0627408A94069EBDA5B814B80 - A7805FE7FD719224697873E5ED21E935F4E2BC0AA3EC6DE1523F9C1B1D40AF59 - 36CFEFAA7C59E1BC8A7869E892D40469D0D9C679DFEDCD651C8D244952CBAC90 - 07B13F03AC57E41B0C29C0EFF3C9398A95FA85F714F9C9CAF2DE123FB73A63C3 - A8BA9B19D83D4F37FF8D17529224957243E0ACFC5ABB9DAFB5AAA967F2AA72C5 - 5BBE0E6585C335E3E7559C1F1D42EAE1C2E90BF948C0EF47879124A905D20C8B - 637269F14960DAE840D208FD233A808AED01A629F1C9CE6D20B1D252F9B1D121 - A4111A9397A23E0FFC303A8C24492D342A1F7DFA64BE9EF70411D585A72056C3 - FB8AFA44653DF92C0ECC59D2E75667AE8E0E208DF0C26809E0DF7929AA13CA25 - 498ADF8AF9AF3C88D3D3B654077F025E8A0E21162BAA0B28ABAC705E45BC3F47 - 07903A94F6C61E96CF834FA7084992A4EAF8703EF6741B6074741869986DF01E - 30500DCB55B9AC286C02A8BAF22AF087E810D230D2EA8977E665A6BB46879124 - 49433A16B8D15516AAB87F4607D06BDE4D85CB0A876BC64A4BE91F8C0E210D33 - 9B623FE07AA78E4B92541B4BE55516ABBB655315E5DC8A6A784F55CB8AF439DD - 0612CB637B54657303B7020745079124495DCF06F851BEF92055C925F9441BC5 - AA6C59F1B67CECA0E25C1A1D401AC4B2C0A379F08E2449AAAFFF036E00668F0E - 224DB11DFEAAE810220DCE9FB58A654521FB53D473DB2D55495A2ABA593EA5C6 - 65A3922435675BC8C3C09BA283489348A7D828DE32552C2B1CAE196B2C707974 - 08698AE799AF00274707912449859B1EB8DBF700AA9073A303E835EFA2826585 - F32A625D9F973F4955908E38FB3170607410499254AA2B80D5A24348C045C04B - D12144E5CA8AF4F96C5563A523A5A4AA1415BF02768E0E224992FAE24260ADE8 - 106ABD091E3850995975952A2BDEE131849598802B454BCF2DC7019B47079124 - 497DF50760E5E8106ABD34274DF1332B4655A9AC70B866BCBF440750EBA527A5 - EF029F8A0E224992C2AE47978F0EA156BB203A8098210FE1AD4C59E1BC8A588F - E60147526451F11960F7E820922429FC448625A343A8D5658573FCE2A59D175D - B3AC68969BA203A8F53E9A076A4A9224DD00CC131D42ADF434705B74085199B2 - 220DD3731B482C07C928D23B81B3A2434892A4CA9816F847FE558A382551F173 - 2B2A5156A4372AD315F8F934727F8D0EA0D69A331F5926499234A925801FF63A - 684FEA422ACA142B750495282B5C55112BEDC9B2AC508469F28A8AE9A3834892 - A44ADA0558273A845A7994AE622DD9CB828622CB8AF714F8B93472F7018F4587 - 502B6D0F7C383A842449AAB4738185A243A8755BE4D3EC0AC5492BAADE5E85B2 - C2E19AB16E8C0EA0D6B6A53F8B0E2149926AE18C1206FC4BC30D7955ACB776FB - 07A72970B8E672057D2E75E7DAE8006A9D31C01FA3434892A4DA482BB1378B0E - A156F1866EBCF0B2C2E19AF12E8E0EA0D6F934B06874084992542B2702F34787 - 506BF81E295EF83610E755C40FD7BC243A845A6541E0E8E8109224A9968EF474 - 10F5890710C4B3AC68B9BB81E7A243A835D2C5C50FA2434892A4DADAD89304D5 - 27F7030F458768B9A5BAED1D2C2B9AE1E6E8006A95B4EDEB13D121244952AD9D - E2B04DF5C94DD1015A6E0CF0966EFE60114F100ED78C77757400B56A55C5B1D1 - 21244952ED2D0EAC1C1D42AD6059116F89A8B26269876B8673708CFA251D51EC - 4A2A499254D4B0CD74E3532AD3DFA3038825A3CA0AF79BC59A00FC2D3A845AB3 - AAE227D121244952632C007C283A841ACFF74AF12C2B5AEA2E606C7408B5425A - 45E5CFBB24492AD28F3D19447D18B2F9487488965B22AAAC58BE80CFA1EE395C - 53FDB27F74004992D4C8C1DD5D1F6D2875E896E8002DB7544459E170CD785746 - 07502BBC01F87874084992D4489F8F0EA0C6BB353A40CB2D0CCCD4EFB2E25DC0 - B43D7E0EF5E6AFD101D40A6B47079024498DB533307B740835DAE5D101443A01 - A8AF6585A702C41A0FFC233A841A2FED233D383A8424496A34E762A94C974507 - 108BF5BBAC705E45ACDB8097A343A8150371E68F0E2149921A6DAFE8006AB4EB - 8197A243B4DC6223FD039615F576537400B5C2EAD101244952E3AD0BCC111D42 - 8DF52A707B7488965BBC9F65C5F4C0323DFC79F5EE5FD101D40ABB4607902449 - ADD0D589015287EE880ED0728BF7B3AC58AEA0A34FD5BD8BA303A8F1E6F3C241 - 9224F5C9C7A203A8D16E8E0ED0728B8FF40FF45236BCB7873FABDEA55915AEAC - 50E5F6964992247569EBE8006AB42BA203B4DC9BF2E0FE8E5956D47B5EC584E8 - 106ABC55A3034892A4D6581898273A841ACBB222D6B4C042FD2A2BDED7C39F55 - EF6E8C0EA056D8203A8024496A5D612195E1DFC033D1215A6ED17E9415B3006F - EBF2CFAA18974607502BDACFF74787902449AD5B2A2E95E5EEE8002DB7683FCA - 8AF774F9E7549C0BA303A815C335254992FA6995E8006A34CB8A5896152DF0A4 - D36CD507734707902449ADE3FB0C95E9B6E8002DF7A67E9415EE258B757D7400 - B5C29CD101244952EB2C1B1D408D76757480965BB41F6585537A635D131D40AD - 30A227134992A402A4D97833468750635D1B1DA0E516E94759E15EF6587F8E0E - A056B0AC90244911668E0EA0C6BA0518171DA2C516E94759316F977F4EBD7BD5 - B242557C329124492AC8F4D101D4E8F752E90853C5981598A3D30FB6ACA89F3B - 8067A343A815DCEE25499222CC101D408D665951931BA2CEACA89FEBA203A835 - DC2F2A4992228C8A0EA046BB273A40CB2D526659E1D09B58FF8C0EA0D6F0AE86 - 24498AD0ED0D55A9D3B9158AB370994F046E018975617400B5C6F8E8009224A9 - 95BC0651996E8E0ED0720B965956B805244E9A5CEBB1A5EA9717A2034892A456 - F2B40695E9A6E8002DB750A71F6859512F4F440750ABBC181D409224B5D22BD1 - 01D468775A8835776585DB40E23C191D40ADF25874004992D44ACF470750E38F - 2FBD3F3A448B2DD4E907BAB2A25E9E8A0EA056F94F74004992D44A96152A9B65 - 451C575634942B2BD44F9E412D4992225676BA445F657B303A408B2D008CEEE4 - 032D2BEAC5B242FD746F74004992D43AD74707502BB8B222D6FC9D7C90DB40EA - C5019BEA27B71D4992A47EBB3A3A805AE1F6E8002D377F5965C57C5DFC1915E3 - E1E8006A15CB0A4992D46FFF8C0EA056B8233A40CBCDDFC907B90DA45EDC5BA5 - 7E7A3C3A8024496A9DBBA203A8155C5911CB6D200D6459A17E4FE2BE273A8424 - 496A9587A203A835B3D9C6478768B1F9CA282BA605E6E82E8F0A6059A17EBB38 - 3A8024496A8D740A886585FAE155BFD79AB7B2C22D20B1FC8152BFFD213A8024 - 496A8DB38009D121D41A0F440768B1793BF920CB8A7A71C0A6FAEDC6E8009224 - A9354E8E0EA056F14670C3CA0AE755C49ECCE0BE2AF59B67504B92A47EB9213A - 805AC52DF671E6EEE4835C59511F4F4607506B4F04B93B3A8424496AC50C01AF - 39D4EF219B8AE1369006AEAC9022FC2A3A8024496ABC3380B1D121D42A961571 - 2C2B1AC695158A726E74004992D4783F8D0EA0D6B9273A408BCD02CC30DC0739 - B3A23E2C2B14E5CEE8009224A9F11CEAAD7E736545C5E7565856D4876585A23C - 065C151D42922435D65DC07DD121D43AFFF1008350730EF7016E03A98F47A203 - A8D58E8C0E2049921AEBE0E8006AED50D7344C5E31E62ABAAC98AFFB2CEA91E7 - 002BD2C5D101244952635D181D40AD6559D1A095156E0389E339C08A9E5BE156 - 24499254B45B3CB254812C2BE2585634C803D10144DB97C97D233A8424496A9C - 7DA303A8D52C2B1A326073EE2ECA0D15C76D208A766674004992D438FF880EA0 - 56B3AC68C8CA0A876BC67A383A805AEF0EE0FEE8109224A9317EEB35AE82F9FD - 1767B622CB0AB780C47901783E3A8404EC171D4092243586A780289A7301E3CC - 3EDC07B8B2A21E1C6CA8AAB8203A8024496A847423EE9AE8106A3DB7DAC7B1AC - 6808CB0A55A97D3E373A842449AABDFF03C6478750EB7988411CCB8A86782A3A - 803489AF4707902449B53F65EC9CE810922B2B9A33B362F1DEB2A807AEAC5095 - 5C058C8D0E2149926AEBC79EC2A08A78243A408BCD5E6459B1646F59D403CB0A - 55C938E00BD1212449526D7D3F3A80943D0BBC1C1DA2A5662DB2AC58AAB72CEA - C1A3D101A4299C9597704A92248DC479C05DD121A4493C1D1DA0A56629AAAC98 - C3A34B4379FEAFAAF83D797474084992543BFB440790A6F04C7480969A091855 - 4459F1E662F2A84B9EFFAB2AFA7674004992542BE9A8D2EBA343485370654545 - B7825856D4836585AAE80EE0E2E8109224A936B68F0E200D32B74215DC0AD269 - 59B1683159D425CB0A5595833625495227EECA278A4955635951F3B262E162B2 - A84BCEAC50555D0BDC1C1D42922455DE27A3034883782E3A40CBE7560CCAB2A2 - FA5EF41C6A55DC36D101244952E5B78E5E1E1D421A8465459C9987FA8F9615D5 - F7EFE800D230FE05DC1D1D42922455D616D101A4213C191DA0C5662CA2AC58A0 - 982CEAC2BDD101A40EB8B45392240DE4065755A8E29E8A0ED062D3175156CC57 - 4C1675E19EE8005287AB2BD2124F4992A4497D2A3A80340C8F2EADF136909987 - 9BD2A952DD1E1D40EAD0C6D101244952A55C9C87714B55665951E3019BF31697 - 455DB82D3A80D4A1EB80BF458790244995B1637400A903CF440768B1197B2D2B - E62A2E8BBA6059A13AD9213A802449AA845F791DAB9A7066459C1986FA8F9615 - D5E73610D5C9ADC0A9D121244952B87DA303481D7265458D076C5A56C4791C18 - 171D421AA1BDA3034892A4500702F74787903AF45C7480169BA1D7B262D6E2B2 - 68841E8D0E207579DCEEB7A2434892A410AF028745879046606C7480169BBED7 - B262B6E2B268841E890E2075E9DBC084E810922429E4A8526700A84E9E8D0ED0 - 626386FA8FAEACA8B6C7A203483D1C01B56974084992D4F72DCCA744879046C8 - B2A2C665C5CCC565D1083D191D40EAC119AE0E9224A955D602C647879046286D - 5D7A393A444B4DDF6B5931E4D9A72A95332B5467E962659DE8109224A92FFE08 - 5C151D42EA9265458CD143FD47CB8A6A7B303A80D4A3AB81F3A3434892A4D2ED - 181D40EAC14BD1015A6ADAA1FEA36545B53D1C1D402AC076D101244952A9F603 - FE1D1D42EA812B2B6A5A568C2A2E8B46E889E80052412B84768E0E2149924A31 - 0EF8617408A947AF440768A969BAFE8FD90CC56551171395A52638D663CC2449 - 6AA48F02CF4787907A645951D3019B8A6359A126BD00AC121D42922415EA76E0 - 82E810520126440768A951BD9615434EE854A99E8E0E2015E85ACF5E9724A951 - 36C8C73E4A75E7CC8A0AEAA4ACF0ACE438CF4407900AF67F5ED44892D408C703 - 374787900AE2F5694DCB0AFFE2E2DA3D9723A9894363D78F0E2149927AB65774 - 00A940AEACA8E9CC0ACF9C8DF1427400A924E700D747879024495DDB1678343A - 8454206FD057900336AB6B6C7400A944EB45079024495D790E38213A8454304F - 03A920575654FBCC6AA9A9FE0D7C2E3A8424491AB1D57C6327A92A6585DB1162 - 5856A8E97EE2125249926AE512E0F2E81092DAA193B2E2F93EE4D0D42C2BD474 - E9A4A115A2434892A48E6D1D1D40527B7452563CDB871C9A9A1369D506B70107 - 4487902449C3FA16704F740849EDD14959F1741F72486AAF835DC1254952A54D - C8AFD79254A4977A2D2B9E2C2E8B240DB88AE883D1212449D2A03E964F0191A4 - BEE9A4AC78AC0F3934354F61519B5C0FFC203A8424499ACAFDC079D12124B54F - 276585D3FA25F5C3978117A3434892A4C9AC93B7814852E5CA8A07FB9043539B - 2E3A80D467A9A8703B882449D5710A70637408498DF562AF65C543B6A9214645 - 0790025C031C151D429224BD66B7E800529F78A3B8823A292B26E4BD6A92D40F - 7B02AF44879024A9E53E9B6F5A4A52654F03493C53B9FFA68D0E20057901F840 - 740849925A6C2C704C7408A98F5C5951419D9615B7979C4353731B88DAEC2AE0 - D8E8109224B5D49A9E4CA796E9F47DB12A36B322716545FFD9EEA9EDBE008C8F - 0E2149520B6F18FC3D3A84D467AE6A8F31A188B2E2D962B268042C2BD476CF01 - 2B44879024A965368D0E2005B0AC8831E49C3ACB8AEAB2AC90E052E037D12124 - 496A89EF037745879002B80DA4C6DB409E29268B4660FAE8005245EC04BC1A1D - 4292A41638303A8014C4F75E353E0DC49515FD37437400A9229ECC83BE244952 - 793E0E3C1D1D420AE2AAF61AAFACB0ACE8BF31FED048AFBB10B8383A8424490D - F530706674082990EFBB62B8B2A2C6668D0E2055C8E6D10124496AA8B53C814B - 2D675911C399153536477400A9421E00B68D0E214952C39C055C171D420A94DE - 137B1A480C5756D4D86CD101A48AF915F048740849921AE433D101A460AE668F - E3CC8A1A73658534B9B4447595E810922435C417F3CA45A9CD66890ED0622F15 - 5156BC325CEBA152CC131D40AAA09B8193A34348925473E9FAFEA8E8105205B8 - B222CEF345941589732BFA6FEEE8005245ED161D4092A4060CD51C1B1D42AA00 - CB8A0694156E05E9BFF9A20348153E62EDB3D1212449AAA99B80BF4687902A62 - E6E8002DF6E250FFD1B2A2DA5C59210DEE18B7A74992D4958D8057A3434815E1 - A10671865CDD6559516D0ED894861EC8B346740849926A26CDA9B82D3A845421 - BEE78AE3CC8A1AB3E59386F677E0DAE8109224D5C87ED101A48AB1AC88F3DC50 - FFD19515D56659210D6FE3E8009224D5C416C093D121A48AB1AC883364C76059 - 516DB34707906AE04EE088E810922455DC53C069D121A40AB2AC883B3EB9B001 - 9B6E03E9BF39A3034835B17F740049922A6E35605C7408A9825CCD5EC1791589 - 2B2BAA6DAEE800524DA425AD9F8C0E21495245FD09B83A3A845451B3440768A9 - 6786FB005756547F49D2E8E810524DFC1678223A84244915B45D7400A9C25C59 - 51C1E19A892B2BAA6FA1E800524D8CCB4B5C2549D2FF7C05B82F3A8454619615 - 3186ED172C2BAA6FE1E800528DA4634C2F880E214952458C077E101D42AAB859 - A303B478E8EF902C2BAACFB2421A1997BA4A92F45F1FE964889DD472AEAC88F1 - F4701FE0CC8AEA5B243A805433F7035F8D0E214952B0BB5D6D2875C4B2A20165 - 852B2B62BC293A805443870113A243489214685DE0D5E810520DCC1E1DA0A59E - 1EEE032C2BAA6F81E800520D3D9F2FD224496AA35F02B74687906A601E4F5F0C - E3CC8A06B0AC90BA3F53FE9EE810922405D8333A805413F3450768B1A787FB00 - CB8AEA9B3F3A805453691B88AB2B24496DB32DF0687408A926BC311CE7C922CB - 8A1781977BCBA32ED8F649DDBB0538213A8424497DF21C70627408A9462C2BE2 - 3C5E645991B8BA2266E08B67FF4ADDDB233A8024497DB29A3717A51159303A40 - 8B3D39DC075856D4C362D101A41A7B04D8393A84244925FB3B70457408A966DE - 101DA0C51E1FEE032C2BEAE1CDD101A49A3B1E181B1D4292A4126DE951A5D288 - B9E5BE412B2B9EE93E8B7AB0647400A9E65E02568F0E21495249BE05DC1B1D42 - AAA1B9A303B4D813C37D802B2BEAC1B242EADDA5C0D5D12124492A585A4D7148 - 7408A9A6E68A0ED0E2A2E2D5E13EC89515F5B0507400A901D213E2C6D1212449 - 2AD8FADE5094BAE6CA8A181D1DAFECCA8A7AB0AC908A7137F083E810922415E4 - 7EE0FCE810528DCD131DA0A51EEBE4832C2BEAC1B2422ACE01D10124492AC83A - C0F8E810524DCD00CC111DA2A51EEDE483DC06529FBD54B34787901AE269B783 - 48921AE054E0C6E810528D2D1A1DA0C51EEDE4835C59511F4B4507901AE4CC4E - 9F242549AAA82F4407906AEE8DD1015AECD14E3EC8B2A23EDE161D406A90711E - 652A49AAB1CF010F4787906AEE4DD1015AECD14E3EC8B2A23E968E0E2035CC0D - 0E259324D5D08BC0D1D121A406B0AC88F348271FE4CC8AFA583C3A80D4C0A34C - B78F0E2149D208AD0ABC141D426A8045A203B4D8439D7C902B2BEAC33D5552F1 - 1E00F68B0E21495287AE062E8B0E2135C402D1015AECE14E3EC8B2A23E9C562B - 95E3071EFB2649AA898DF3CA4049BD9B3F3A408BB9B2A261E6CE47984A2AD60B - C0DAD12124491AC6F781BBA343480DE2CA8AB841F78F77F281CEACA817876C4A - E5B808B8333A8424494338303A80D420A38179A343B4D4439D7EA02B2BEA6599 - E80052434D003E1A1D4292A4416C023C1D1D426A90258151D1215AEAA1B2CA8A - B45CDAC2228E6585549E5B81E3A343489234C0117FA74787901A5856286EC07D - 296545F2AF2EFE8C8AE1F1A552B9F68C0E2049D214D67010B45438CB8A38FFE9 - F4032D2BEAC5B2422AD763C0F6D1212449CACE016E880E2135D012D1015AEC81 - 4E3FD0B2A25E160166880E2135DCAF81E7A343489204ECE451A55229DE101DA0 - C5FE5366597145177F46C5484360968B0E2135DCCBC06AD1212449ADB7E748EE - 404A1A9185A203B4D803659615F7030F76F1E7548CF74407905AE0F2FC902429 - C22BC08FA343480D5FB1AE06AEAC485C5D1167D9E800520BA425B79B46879024 - B5D65AC0D8E8105243CD0ECC1D1DA2C5EE2FBBACB8B2CB3FA7DEBD253A80D412 - F702DF8D0E21496A9D9B81BF4687901AEC6DD1015AEC59E0A9B2CB8AABBBFC73 - EA9D936BA5FE39283A8024A975D677A8A654AAB7470768B17F8FE483BB2D2BAE - EAF2CFA998C9B5F34487905AE21960C3E81092A4D6F81970677408A9E1DE111D - A0C5FEDD8FB222ED3379B8CB3FABDEBD3F3A80D42267FB7C2749EA932F450790 - 5A60B1E8002DF6EF7E9415C9353DFC59F5C6B242EA9FF1C09AD12124498DB705 - F0647408A905168D0ED062F78DE4832D2BEA6999E80052CBDC009C131D4292D4 - 5869E0DC6FA243482DF1A6E8002D76DF483ED8B2A29E968C0E20B54C1A74B663 - 7408495263AD0ABC121D426A81F98039A343B4D83DFD2A2BAEEDE1CFAAF71341 - 7AF9BB9334720F02FB4487902435CE855E574B7DE30AF558F78EE4837B79C37B - 0BF0620F7F5EDD1B032C1F1D426AA11F01E3A24348921A651B8F2A95FAE65DD1 - 015A3E07EEBE7E9515E949F5FA1EFEBC7AB3627400A9855E00D6880E21496A8C - FDF3297B92FAC39515B15B40268CE40FF4BA95C0256B715C5921C5B804B82D3A - 8424A9F6D245FBF7A243482DE3B1A5359957514459715D8F7F5EDD7B7B7400A9 - C517971F8D0E2149AABD7580E7A343482D635911E7EE7E97156E0389B3944336 - A5307700BF880E2149AAF5457B1AAC29A97F6605168C0ED162778DF40FB8B2A2 - BEA6053E101D426AB1BDA30348926A6BDD91EEDD96D4B3E58051D1215AECCE7E - 97154F000FF4F839D4BD95A203482DF638B06D74084952EDFCCAD947520867FE - B56C6545E2569038FEC049B14E049E8B0E2149AA953D3CAA540A5B59A116ADAC - 482C2BE22C1D1D406AB9978155A34348926A6307E0B1E810524B2D111DA0C59E - 009E8C282B6E2CE073A83B6F0166890E21B5DC95C0A5D121244995F75CDE0222 - 29866545EC707A22CA8A1B0AF81CEA4E1A10E35D5D29565ACABB5974084952E5 - AD9A57E449EABF858139A343B4D81DDDFC215756D4DF6AD10124F16FE0D0E810 - 92A4CABA34AFC49314E343D1015AEEB6A8B2626CB74D890AB16C740049AFF9A6 - 03D3244983482BF07C8D90E27C303A40CBDD165556246E0589F38EE800925EF3 - 2CB06174084952E51C9C57E0498AF3F6E8002D777B6459E1892071E605968A0E - 21E935E7000F4687902455C6ABB9AC9014EBADD1015AEED66EFE902B2B9A619D - E800925E331E583D3A8424A932D6CF2BEF24C5991D58243A448B3DD8EDF36051 - 6585433663AD181D40D2EB6E01CE880E21490AF71FE0FCE81092F8703E455135 - 5A55516459912ECEC715F4B934720ED994AAB5E477E7E81092A4706BE6157792 - 62AD1C1DA0E56E892E2BD213F1CD057D2E8DDC62C03CD12124BDEE61608FE810 - 92A430BFEBE5025D52A1DE151DA0E56E8A2E2B92EB0AFC5C1A99B4AC69ADE810 - 9226F313E095E81092A410BB7854A954199E0412EBE62A94150ED98CB5467400 - 499319EBCFA524B5D2E78047A243487ACDDCC0C2D1215AEEE62A94150ED98CF5 - EEE80092A6F2B75E860A49926AE725E098E81092269B57E170CD38CF000F74FB - 875D59D11C4B0333458790349909C047A3434892FA6615E0C5E810925EB75A74 - 8096BBB9972D71459615F700CF17F8F934F2BFCB75A343489ACA9DC0CFA34348 - 924A770D70597408499359263A40CBDDD8CB1F2EB2AC488DC9F5057E3E8D9C65 - 85544DFB44079024956E23876A4A955C7DAE383754A5AC48DC0A12EBBDD10124 - 0DE84960ABE81092A4D21C9E57194BAA8E770073448768B91BAA5456787C69AC - 77023346879034A053F390214952F37C353A80A4A938AF22DEF5552A2BDC0612 - 6B34F091E8109206F432B06A74084952E136B18C962A69A5E8002DF718F0502F - 9FC09515CDB35E74004983BA3A1F672A496ACEC5F819D121240DE85DD1015AEE - FA5E3F41D165C513C07D057F4E8DCCF2D101240D2A0D5EDB3C3A8424A93069C5 - DCB8E81092A63227F096E8102D777DD5CA8A89C73629CEDB81B9A343481AD4FD - C0B7A24348927A766EAFC7F2492ACD5AC0A8E8102D776D15CB8A9E43A927A3F2 - D15992AAEB608FB793A4DADBC1E772A9B2D6880E202A595638B722DEBAD10124 - 0DE939E0A3D12124495DDB1B78303A84A441BD3B3A40CB4DA8EA36104F0489F7 - FEE8009286F547E03FD121244923F60AF0A3E8109206351DB04C748896BB299F - 8457B9B2E236E0A5123EAF3AB710F0CEE810928634DE258A9254DBBDF063A343 - 481AF267744C748896BBA6884F324D494B3EDC0A126FD3E8009286752BF0BBE8 - 1092A4113D6F5F1C1D42D2903E121D4054B6AC48AE2AE9F36A64476949AAB634 - 986D97E81092A411BD094A37E62455D7F2D101C4D5457C12CB8A66CFAD98363A - 84A4613D02EC161D429234AC9F037747879034A4F4FEE75DD121C455552E2B0A - 59F6A19E07CB6C101D4252477E5AC410224952A9F6F1A852A9F2D6F1866DB83B - 81A7AA5C56A433555D22176FE3E800923AF222B07A740849D2A0B6049E8C0E21 - 6958EB4707105714F589CA2A2BD269203794F4B9D5B90F470790D4B17FE4639E - 2449D5F234705A7408491D6F8557AC2BAB5E5624FF2AF173AB338BB8674BAA8D - B41A6DBDE81092A4A9AC02BC121D42D2B06605DE191D42D4A2ACB8BCC4CFADCE - 6D151D4052C7D2E0B6A3A24348925EF797BCBD5952F56D50F2FB5B35A8AC286C - AF8A7AE23E78A95EF68D0E20499A6C56854335A57A70856ABC5BF2D6B9CA9715 - D7B964AE129601E68B0E21A963697AF2E6D12124491C003C101D4252C73E181D - 405C5AE4272BB3AC1857E41210F5F477FCE9E8109246E4B745B6D292A4AEE608 - 7D373A84A48E2D05BC313A84B8ACC84F364D1FA6DB2B9E4BA2A47A49ABD2568E - 0E21492DB62EF07C7408491DDB243A808A1F05517659F1CF923FBF3A5F123563 - 74084923DE4AF7D7E81092D442F700174687903422CEE9ABC6CDB66BEA545614 - BA0C445D9B16D8223A84A4114903DDFCB995A4FE5B1B181F1D4252C7C638AFA2 - 32AB2AD22888DA9415F7E587E26D1C1D40D288A5C16E07458790A416F935707B - 74084923DEF23E437408F1F7A23FE134750CADAEACE4B9C3522D1DEAB17992D4 - 37BBF99C2BD5CEA6D10154CE08887EBC79BDB80F5F43C39BD9D515522DA5016F - EB448790A416D801783C3A84A411FB707400157F6C69BFCA8ABFF5E16BA833EE - 7F97EA290D7A734B9D2495E705E057D121248DD83B8045A343887BF2F6E5DA95 - 1537004FF6E1EB6878AB02A3A243481AB134E86D8DE81092D4F0EDB22F478790 - 34625B47075079A31FFA5156A47D7F6E05A986D9810DA24348EA4A1AF8765A74 - 08496AA0747ADDD5D1212475C5234BABA1B6654572519FBE8E86F7A9E80092BA - 2E7E3F1B1D42921A3A9C6F42740849233637B05C7408BDE61FD4B8ACF8739FBE - 8E3A6B1FDD0A22D5D3A3C0E7A3434852C34E5C722690544F5B79DA61253C0D5C - 5FC627EED75F6E9A5BF1709FBE96863607B0617408495D3B1A78293A84243564 - C5DA37A24348EADAFAD101F49A4BCA5A9D364D1F5F0CFED4A7AFA5E1398846AA - AF178155A243485203A4395ECF458790D495E93CB2B432FE5AD627EEE7B219CB - 8A6A6D0571C994545FFF2A6BB99D24B5C483C0B9D12124756D0B60FAE8102A6F - B8267D7EC3FAC73E7E2D0D6D56E013D12124752D2DB573E9A324756FB57C2CB4 - A4FA0EC655BCB435F9F22694150F782C54A5782A88546FF70247468790A41AFA - 3D706B7408495D1BED96D8CAB8181857D627EFF7568073FAFCF534F41D8569A3 - 4348EAC97ED10124A9863E93E7A949AAA78D8199A243A8FC533FFB5D569CD7E7 - AFA7C1CD086C1B1D4252CF47456D161D42926AE40BC023D12124F564CBE8002A - 7FB86644597129F0449FBFA6861E4C23A9FECB997D5E95A4CEF656FF3C3A84A4 - 9EB780A4C302146F6C1EFADE98B2220D853BB3CF5F53835B0198333A84A49EBC - E2BE4D49EAC8AAF9F86749F5955694CE1C1D42AFF94BD9838A238EAFB4ACA856 - 33B94B7408493DBBA1EC3D83925473D70297458790D433B7805447E9D79E1165 - C5F9F94EA0AAE1E3D10124F52C0D8AF3841F491ADC067985AFA4FA1A935748A9 - 1A1A5956A4BD2D0EDAAC8EE580C5A34348EAD983C001D12124A9827E948F7B96 - 546FDBE6430214EF71E09A269615C919415F57037F0FEC1A1D425221BEE39D43 - 499A8AC73C4BCDB0797400BDEE827E5C7346951567077D5D0DEC63D1012415E2 - 05609DE8109254219B00CF448790D4B3398015A343E8757FA20FA2CA8A74BEF5 - DF82BEB6A6B628B05A74084985ED1F74B9B324C1630E76971AE333796685AAE1 - C2269715C96F03BFB6A6E6A9205233A423A4D6880E2149159006F139D45D6ACE - 2A2955C3EDC03D4D2F2B6CBAAB65ED7C94A9A4FABB1338293A8424054AC3DC6F - 8C0E21A9104B01EF8E0EA1D7F5EDB08CC8B2E2AE7E4C1055C76605B68B0E21A9 - B0A34C3F171D4292026D979F0B25D5DF6EC0A8E8107ADD1F69415991FC26F8EB - 6B72DB440790549827F2FE4E496A9B2F030F4587905498F5A303E875E3F27CB4 - 5694156E05A9960FE4619B929AE138606C740849EAF385F40FA343482ACC4780 - 85A243E87517F5F3DA32BAACB801B835388326FF7ED8233A84A4C2BC04AC121D - 4292FA280D18B6A4959AC34300AAE5DC7E7EB1E8B222ED253C35388326B76174 - 004985BAC2F940925AE236E06FD1212415666660CDE8108A19AE5985B222F97D - 74004DE68DC0BAD12124156602B041740849EA8375F2F1CD929A617760FAE810 - 9AECC8D2540AB7AAACB8261FB3A7EAF01401A959FE0D1C1E1D42924A740C704F - 74084985DA3C3A80267346BF4F59AA4259E15690EA49CBAD668F0E21A9505F89 - 0E204925DAD3A34AA546F920F0B6E8108A9B575195B222712B48B54C9B5FF425 - 35C7B3C026D12124A9045B034F45879054F8169051D121F4BAE7804B68695991 - 06C0DD1D1D4293D92C3A80A45296EF3D161D42920AF4347072740849859A0158 - 2F3A842673763E1ABA9565455AB6775274084D660960F5E810920A955E643CCA - 545293AC0CBC121D4252A1BE08CC181D429339930055292B92DF4607D054768B - 0E20A97037017F8C0E214905B818B82E3A84A4C26D151D40539D2C770E2D2F2B - AECEC7A1A83AD602E6880E21A9F0956C5E04486A824F3A54536A9CD580A5A243 - 68327F029EA1E565457AB171CF61B54C077C293A84A4C23DE2E920926AEE40E0 - C1E810920AB74774004DE57704A9525991B815A49A772D2435CFF781F1D12124 - A9CB25C98746879054B8F981B5A34368C0E19A21AA5656A47D87374487D06416 - 0536880E21A970638135A343485217D6055E880E21A9705F03C64487D0642E03 - FE4390AA9515692BC8AFA343682A5F880E20A9B4E1741E1B2DA94EEE012E8C0E - 21A994F7A5AEE8AE9E5323BF78D5CA8AE494E8001AF058B03746879054B8B40D - C4D51592EA36FCDB2D6C52F3EC02CC151D4253F93D81A6A96863FEF7E8109ACC - 68E0ABD1212495E22E57B449AA893488FD8EE810924A2B2B542D5744AFC0AD62 - 5991FC2A3A80A6B2692E2D24354BDA7EE7562F4975F0598F2A951A693DE01DD1 - 2154BD1D0F552D2B7EE38B51E5CCEE1B1AA9B19E04768C0E21494348CF514F44 - 8790548ABDA203A87A5B40AA5C563C0E9C1B1D4253D93E3A80A4D2FCD2E9FA92 - 2AEA85FC1C25A979960656880EA1A95C05DC49B0AA9615C909D1013495B703AB - 478790548A978155A24348D20056CACF51929A67FF8ABF276DAB93A8802A7F63 - 9CE10B53E58C02F6890E21A93457E6265D92AAE2EAFC90D43C0B001F8B0EA141 - C732849BA6E24BFE4E8B0EA1A9AC062C121D42522926001B448790A4496C9C9F - 9B2435CFC1C0B4D12134957FE4133AC355B9AC484E8C0EA0A9A41341BE1E1D42 - 5269EE07BE1F1D429280B3AB72C12CA970B3029B4587D0802A73A47DD5CB8A3F - 3AF9B9B2C7984E171D4252A9FB4725A90A2780783A9CD44C0701334687D054D2 - 73EEA95444D5CB8A71C0F1D121349559802F458790549AE7800DA343486AB51F - 030F458790548AB4F5639BE8101AD079F964CE4AA87A5991782A4835798CA9D4 - 6CE7008F448790D45A5F890E20A9D49FEFD9A3436840953A26BA0E65459A4C7F - 5374084DE58DC0D6D1212495BAB2CDA34C2545F832F064740849A59D2EB85374 - 080D686C3E91B332A6A9C9BE995F4487D080768F0E20A954B700E7478790D42A - E9BAEF88E810924AF3857C64A9AA79B8C58B54481DCA8AE4A4E8001AD0BB80D5 - A343482AF54D832BA824F5D3A780E7A343482ACDE7A3036850BFA262EA52563C - E0DDBDCA2EE3DA2F3A84A4523D9A97644B523F9620FF263A84A4D26C052C1E1D - 42034AC7445F42C5D4A5AC48DC0A524D2B016F8B0E21A9543FCC332C24A94C6B - 022F478790549ABDA3036850470313A8983A951569D8C7B3D1213495D1C037A3 - 43482AFD6EA75BBE2495E97EE0D2E810924AB309F0CEE810AACF1690BA9515A9 - 693F2E3A8406B41EB060740849A5FA3B70477408498DB506303E3A84A4D2781C - 7175FD01F8371554A7B2A272E7BEEA75D3020747879054AAF42662ADE810921A - E96FC06DD121249566833C985FD5740C1555B7B2E24AE086E8101AD0A6C0ACD1 - 2124953E7CC9D25852D136CFA70F496AA6AF4607D0A09EC9E3162AA96E65457A - 21FB5974080D6826E0A0E810924A7F0EDE353A84A446391EF84F740849A5F928 - F0EEE8101A72B06665071BD7ADAC484E704F63656D034C171D4252A99E02B68D - 0E21A931F6705585D4680702A3A24368C8B2A2B2EA58563C019C121D42039A1D - F87A740849A53B11783E3A84A4DADB275FD7496AEEAC8AE5A24368507F056EA6 - C2EA585624BF880EA041ED988F3395D45C69B9E08AD12124D5DA04E088E81092 - 4A956E62BAAAA2BA8EA2E2EA5A565C9407BDA97AE606F68D0E21A974D702FF8A - 0E21A9D6775CC7468790549A8D3D01A4D29E047E4FC54D53E336FEA7D12134A8 - FFB345951A2F3D0F6F141D42522DA5AD1FE747879054AAFDA30368483FA9F260 - CDBA9715C9710E64AAAC05803DA343482ADD03C077A34348AA9DD58071D12124 - 95660B60E9E8101A522D6EFCD7B9AC7808F85D74080D6A37575748AD7080C5B1 - A411B81AB83E3A84A452B9AAA2DA4E07EEA506EA5C56243F8F0EA041BD01F862 - 740849A57B3EEF3D97A44E6C94B791496AA69D8125A3436848475213752F2BFE - 549756A8A576777585D40AE7010F4787905479BF06FE1D1D4252A91CB45F6D37 - 037FA626EA5E568C077E1C1D4243AEAED82B3A84A4D2A5BDE72B47879054795F - 70DB98D4686966DD1BA343684887D769755BDDCB8AE4785FF82A6D57575748AD - 701B704E740849959E65958ECA93D44CA3BD495979CFE6F7CEB5D184B2222D3D - 3E253A84865C5DF1E5E810924A974AE36DA24348AAECEAAB5A4C9E97D4B58380 - F9A24368D8551563A99126941513CF8955B5EFA634E57B4DD2E01EF3AE8AA401 - AC05BC181D42526966023E1B1D42C3DE54AADDF884A6BC81BC04B8293A840635 - 2FF0F5E81092FAE247C02BD1212455C6FDC0C5D1212495EA3060B6E8101AD209 - C003D44C53CA8A09F90259D595DAD669A343482A5DBA7BBA7A74084995B17A1E - 882EA999D2D68FADA343A8A32D20B5D394B262625BF45274080D6A4EE0E0E810 - 92FAE2EF79E0A6A476BB00B83D3A84A4521D09CC101D42C35E975D410D35A9AC - 7806F87974080D69A7BCA74D52B34DC87BD425B5DB569ED82635DA3B810DA343 - 6858DFABEB737193CA8AC449D3D5362BF0C3E81092FAE2DFC0B1D12124859E0C - 904E6C93D45C470063A243684877016751534D2B2B6E002E8A0EA1217DCA638D - A45678359F0424A99D3FFF8744879054AA758095A3436858DFCEC747D752D3CA - 8A890D9FAA2BED697318AAD40E697B9E43B7A4F6590F78213A84A4527D071815 - 1D42437A0A389E1A6B625971563E264BD5B511B0447408497D7132F06C740849 - 7D93B67EFC313A84A452ED92E755A8FA47CABE488D35B1AC48CB5C7E101D4243 - 4A7BDB5C0123B5C32BC08AD12124F5CD2A755E722CA9A3EBF803A2436858E979 - F8C7D45C13CB8AE4987C81ACEA5AD33730526B5C0FFC333A84A4D2FD01B8353A - 84A4527DD7F973B57034F01835374D83F7E7A4BF2055FB7B2F2D4D92D48EA34C - 3F1E1D4252E9B6AEEBF178923A322FB053740875A411EFB39A5A5624474607D0 - B0DE0D6C191D42525F3C9427524B6AA6AF018F44879054AA9F02334687D0B07E - 03DC460334B9ACB8312F475475A509C2DF880E21A96FBEEE5D57A9B1ABA7D2D2 - 7049CDF57EE063D121D491C6DC1C6A7259911C1E1D40C37A13B06F7408497DF1 - 423ED25052B3AC0B8C8D0E21A9546958E3E8E8101AD685C0E53444D3CB8AB4B2 - E2E6E8101AD65EC00CD12124F5453AD2F081E810920AF340BE3896D45C3BE7ED - DBAABE436890A69715E35D96580B7334E1681D491D1FA5B56A740849851E559A - AEB72435F7A8D203A343A8235736AD3C6E7A59919C984F0751B5A5419B8B4587 - 90D417B70367448790D4B3B3813BA243482AD5111E555A1BDF6ADA6CB0369415 - 2F02DF8B0EA1614D97270C4B6ABEF442BA6D7408493DDBA66917C692A69A2DE7 - EB753DDC0A9C49C3B4A1AC20BF09768962F5AD06AC151D42525F3C09EC111D42 - 52D7D270ECC7A343482AD52F80E9A343A823DFCC5B6D1BA52D65C5A3C0D1D121 - D4D1F7E30FA34348EA9B34ABE6E5E81092462CDD003A2C3A84A4526D9A67D2A8 - FAEE034EA681DA5256243F880EA08EBC15D8273A84A4BE78C9619B522DAD9EB7 - D94A6AA6F41EF1FBC0A8E820EAC837805768A0369515B700A747875047BE0CCC - 1C1D42525F5CEA11D352ADA4819A7F8B0E21A95469DEDFC2D121D4914780E369 - A8369515C977A203A823B3033F890E21A92F26006B478790D4B1359D032635DA - 1B81CF448750C7BE9957AA3652DBCA8A7F027F8F0EA18E6C062C131D42525FDC - 0FFC3C3A84A4611D07DC1B1D4252A9D25DFA19A243A8234F377D2E63DBCA8A74 - BCD6A1D121D491697DF322B5EAB9F98BD121240D6B578F2A951AED53C0CAD121 - 34A255152FD0606D2B2B9273819BA243A823EF73199AD41ACF025B46879034A8 - F4F3F94C740849A519037CD7A19AB5F14C3E55ADD1DA58568CCF2D94EAE120CF - 77965AE3B4BCA45152B53C9D7F3E2535D751C0FCD121D4B16F01CFD3706D2C2B - C82FB8E93C5A55DF3CC0CFA24348EA8B74ECD64AD121244D6585A61E8B27E935 - EF023E1D1D42235A8D7A242DD0D6B2E295DC46A91E3677D8A6D41AD73B0859AA - 94BF003746879054FA50CD342F4EF57030F01C2DD0D6B262E20FE553D121D491 - F4E4796C7408497D9186F76D1C1D42D2EB3EE1504DA9D1F6CB2B2B540FCF013F - A225DA5C568C757645ADBC1BD8233A84A4BE78D8D56F5225EC0F3C1A1D425269 - E603BE1C1D42235E55F12C2DD1E6B222F9691B069334ECA269B6E81092FA365C - D7BBB952EC40F26F47879054AA138099A343684427801C418BB4BDAC48ADD4A1 - D121D4B15454FC323A84A4BE781158273A84D4626BE69F4349CDB415B07A7408 - 8DC8816D5A5591B4BDAC20EFF979293A843AB6BE6F60A4D6B810B83F3A84D442 - 770017478790549A1981C38051D141D4B127F3F1B2AD6259F1DFBFF8EF4587D0 - 88BE677FE2F7AED49A65E8AB4487905A688DFCF327A9997E05CC1D1D42237200 - F0022DE31BBEFFFA01302E3A843AB62870787408497D7117F0FBE81052CB4E4B - FB77740849A5F908B06174088DC8A3C0CF6921CB8AFF7D03A4A550AA8F1D8165 - A243482A5D1AB2B95D7408A9453EEF705BA9B146033FCBBFAA5E870C8CA5852C - 2BFE276D057175457D4CE7B04DA9359E02768D0E21B5C0166D1BDE26B5CCD1C0 - 42D1213422FF017E414B5956FCCFC3793B88EAE35DC0D7A24348EA8B34ABC661 - C852B9AB4C4F8B0E21A934AB029F8A0EA111DBAFCDD73F961553AFAE70A054BD - 7C0958243A84A4D2BDECB04DA9542BB8C2546AACB4EDE338604C74108DC8ADC0 - 89B49865C5E41E027E181D42233E7AE994E81092FAE25FC08DD121A4063A0BB8 - 3D3A84A4D2A439156F8C0EA1AE5655BC428B59564CEDDBDE59A89D0F025F8C0E - 21A974138075A243480DB4B54335A5466FFF483FE3AA972B81D36939CB8A8167 - 57A4ED20AA97AF03F345879054BAFB819F4687901AE4B37988ADA4E6199307D2 - BBFDA37EF6753C8165C560BE9BF747AB3E66064E8D0E21A92FF68C0E2035C40B - F9740049CD94E6542C1C1D4223F617E082E81055605931B0C78043A34368C456 - 02BE101D4252E99E033E191D426A8015BD392335D67ABE56D6FA008157A34354 - 8165C5E0D231A62F4687D0888C02BE09CC1F1D4452E97E0B3C191D42AAB1CB80 - 6BA243482AC50CC031F91410D5CB69F9F9599615437A0238283A84466C96FC26 - 4652B38DCB472D4AEACE067968ADA4E639C9596EB53E01449965C5D08E009E89 - 0EA111FB30B077740849A5BB19F86B7408A9A643A9D3407149CDB30DF0B1E810 - EACA911E233D39CB8AA13D0B7C2D3A84BAB23FB048740849A54AFB3937890E21 - D54C9A2E7F48740849A59807F8A1EFF16A29CD0F3A303A44D5F88D3CBC9F018F - 4487D088CD04FC3E3A84A4BE0C44F6C55DEADCEACEE4921A2B5DFBCE161D425D - 49E3077CCF3905CB8AE18D75EF506DBD0738383A84A4D27DCBBDF752476E052E - 890E21A9145F7596536D3D9E0F77D0142C2B3AF34BE0CEE810EACAEEC0BBA343 - 482AD54BC03AD121A41A58D3624F6AA47700FB468750D7F6C9C7B26B0A96159D - EF214AE7DDAA7EA6074EF57B5D6ABC3F03FF8E0E2155D84F81FBA343482ADC34 - 79FB473AAE54F57353BE31AE01F806AE73E949E0CAE810EACAE2F9AC6949CD1E - 1AB86A7408A9C2F6C843692535CBB1C012D121D4B52F02AF4487A82ACB8A915D - 08A7253AAAA7AD800DA343482AD5DDC06FA2434815945EFF5E880E21A9709F00 - B68C0EA1AE5D00FC213A449559568C7C9971FAA652FD8CCEAB2B9C902C3557BA - 6BBC437408A9621E04CE8E0E21A97073E5ED5DE91A57F5B4A72BDE8666593132 - E99BC9D515F57E523F233A84A4523D0D7C363A8454212BE6D5A1929A25959073 - 448750D77E0E5C171DA2EA2C2B46EE6AE0F8E810EADA2A4E4B961AEF68E0C5E8 - 105205A46D517745879054B8EF001F8C0EA19E4E31FB4A74883AB0ACE8FE1C63 - EF52D4FBEF6FE9E810924A3DC129DD4D96DA6E7B97184B8DB33AB06B7408F524 - 15158F4487A803CB8AEEDC071C121D425D9B216F07718F9FD45C5701D7478790 - 02ED083C131D4252A166064E04A68D0EA2AEA563D67F141DA22E2C2B7A5B7EF5 - 6C740875EDCDC0C9D12124956602B07674082948BA3E71CBAAD43C6702F34587 - 504F7673AB6AE72C2B7A1BE2E6B0CD7AFB38B073740849A59E82F0E3E8105280 - 158057A243482AD441C06AD121D493BF38EC7F642C2B7A938EC2BC3D3A847AFA - FEFF5E5E6521A999F68A0E20F5D9456E81921A39207EEFE810EAD9EE79E5A73A - 6459D1FB10B7F44DA77AEFFD3BCF9F05A9B15E00368D0E21F551FA7E77A8A6D4 - 1CB302A702D34507514FD24ACF6BA243D48D6FD07A97DEE8FE293A847AB214F0 - ABE810924A733AF0787408A90FBEECF7BAD438E702F34687504F9ECBA7116A84 - 2C2B7A9796F2EC191D423DFB24B053740849A51897F7F04B4D9666547C3F3A84 - A4421DE6EB5723A4F78A4F4487A823CB8A625C0BFC243A847AFE59482F084B46 - 0791548A5BF35E7EA9A956CEDB532535C3C6C0E7A243A8676986D02FA243D495 - 654571D2D29EB1D121D49399F2B69ED1D14124152EEDE1DF243A8454E2C5F065 - D121241566A1FC06774C7410F52C154E9ECED425CB8AE23C96F78AAADE16037E - 171D425229D212CCAF4787904AB0B613E6A546BD3FBB00982D3A887AF66BE0E2 - E81075665951ACB415E48EE810EAD9FA164F52631D0C8C8F0E2115E870E0C1E8 - 10920A7332F0B6E810EAD94B1E9FDE3BCB8AE2BF29778D0EA19E8D02F607568A - 0E22A994E7E9B5A24348056E6FFA5274084985D9C72D8B8D91FE2E1F8A0E5177 - 9615C54B330FCE8E0EA19E4D0FFC0698233A88A4C2FD15B8373A8454D04A40E7 - 6549CDB00A7060BE69A67ABB09382A3A441358569473976337F78E36C2BC79CF - A0A466199F2F0AA53AFB0F707E740849859807F82D305D74101562174F672A86 - 654539EE040E8A0EA142BC17F855740849854B2B2B4E890E21F56045E7AF488D - 905652FC19982B3A880A719C43358B6359519EEFB84FA931B6C8AB6524356B15 - DC0ED121A42EA5A2ED9EE810920AFB795E3A3A840AF13CB077748826B1AC28F7 - 9B359DABAB66FC9C1C027C283A88A4423D07EC1C1D42EAC28EB97093546F69A0 - BB03359B6377E0D1E8104D625951AEDF3BF3A05103374F07E68C0E22A950C73A - A05035B31DF06C7408493DDB00D8CF819A8DF1CF7C4DA1025956942B0DD9FCAC - 773F1A3570F32FBEA8488DF24ADEFB2FD5412A299CA324D5DF62F96779DAE820 - 2ACC4EC0B8E8104D635951BEDBF331446A8665F291A6929AE36AE0DAE8105207 - 56F06258AABD19F240CD59A383A830DF026E880ED1449615FDF16DE0FEE8102A - CC469EF622356E15DCDAD121A4615C025C1F1D4252CF2E04168D0EA1C2DC9FCB - 0A95C0B2A23F5EC8E7EDAA19D236907D1C882435CAC3C011D121A4217CDC6DA5 - 52EDA5AD1F0E6C6FDEF68F74B0824A6059D13FE700BF8B0EA1C24C9BCF517E5B - 741049854925A454455F051E8B0E21A9E79FE32DA343A8502703E747876832CB - 8AFE497743BE00BC1C1D44859939EF399C2D3A88A4428CCD77AFA52A199FB793 - 4AAAAF4D7259E190F6E648AB297675C55BB92C2BFAEB3FC09ED12154A80580BF - F9B32435C699DEC156C5ACE68D0EA9F6C3D9D36A5C4FFE689674E2E323D1219A - CE3758FDF753E09AE8102AD4D2C019D121241576173B9DB82055C19DB9109754 - 4F730117E4D5B86AD690D45F47876803CB8AFE4B7747768C0EA1C2AD07FC203A - 84A442DC962F44A468ABE6D36A24D54F5A49F10F60BEE8202AFCA6C64EF95795 - CCB222C615C077A343A8709F07BE181D4252CFD2FED34DA343A8F5D2A9011E7B - 2ED5575A51B1547408156E6FE0AEE8106D615911E7EBC003D12154F8CFD3B7F2 - 2A0B49F5F624F095E8106AB574E4B983DBA47A3A0158393A840A7715F0A3E810 - 6D625911E73960FBE8102ADC74F918A3344C4952BD7DC725F80AB2759E342FA9 - 7E0E05368F0EA1C2A5F2781B071EF7976545AC3F389CA59166CEFBDDE78F0E22 - A927E982E4A3D121D43A4F0327458790D4952FE693FF3CA2B479D2D1B3D74787 - 681BCB8AF8866E77E0D9E8202ADC3C79A8D20CD14124F5BCE7D8A34CD54FE934 - 9A71D121248DD826C0C1BEBF6AA45452386F30803F4CF11ECB1365D53C8B0117 - FB7326D59A4799AA9FFE0EDC181D42D2882D0F1C9F4F0051F37C1A78293A441B - F926AA1A4E05CE8A0EA1D25EBCCE890E21A9E7A34C2F8D0EA156D8D0A19A522D - 6F4EFD1198293A884A712070757488B6B2ACA88634C0ED33C08BD141548A7580 - 63A34348EA5A7AF3B841740835DE216E39926A67DEBC226A8EE8202AC52DF9B9 - 59412C2BAA231D63FAD9E8102A75F9D8B7A34348EADA23C069D121D4E842EC80 - E81092463C503DADBA5B203A884AB32530363A449B595654CBF179989B9A6754 - 9E10FDA5E82092BAB643740035D647DC0F2DD5CAE83C483D6D015133ED0F5C15 - 1DA2ED2C2BAA37C86D7B2F581AFDF376906F78A4DA7A06F841740835CE7FBC51 - 21D5EE06D45F8165A283A834D70287468790654515DD07FC5F740895660CF023 - E0E3D141247565BFE8006A9C95F2CD0A49F5702EF0E1E8102A755B5EDAFEE1CD - E30AB0ACA8EE76903F44875069A6077E05AC1C1D44D288BDE0762E15289D2070 - 77740849233AC12F0D4E5773EDE311D2D56159514DE3F356014F0769AE74BCD5 - D9C07BA283481A31B782A8289B7954A9541B47039B468750A9D2C0D41F4687D0 - FF585654D7FDC04ED12154AA59803F014B45079134222FE5137EA45E1C0C3C15 - 1D4252C725F576D12154AA57F2F68F97A383E87F2C2BAAED04E0F4E8102AD51C - F97CEE45A283481A91939C33A01EA4D5145F8F0E21A92387005FC88335D55C69 - 66E05DD1213439CB8A6A9B00EC9C27D0ABB9E6062E03E68B0E2269447760D68F - 0EA1DADAC4E16D522D1C00EC6551D1786702C74687D0D42C2BAAEF11609BE810 - 2ADD82C095B9B890549FE18869E0A63412E906C419D121240D2B0D53FE8AEF97 - 5AF19CBCA3AB25ABC91FBE7A485B418E8B0EA1D22D9C0B8BB4354452F5A50B9B - D5A343A87656F1A258AABC3D808380D1D14154BAADF2CD61559065457DF6B6EE - 063C181D44A55B14B80A98353A88A48EFCCB8B1C8DC0EDC0B5D121240D295D73 - 1F0A8C890EA2D2FD0C382B3A84066759511F4F039F8C0EA1BE78732E2C668E0E - 22A9A3D942AB4687506DAC91BF672455531AA4F91D8B8A5648C334BFE8F1D1D5 - 6659512F17E7A3CED47C6F01AEB6B0906AE1967CC75C1A6EC6C97DD121240DEA - 73C0F72C2A5AE1D53CE8F8B9E8201A9A6545FD1C085C131D427DB144FEBB9E25 - 3A88A421A53BE56B468750E56DEE1D3CA9D245C5F72D2A5A63AF7C5350156759 - 513F2F029B01E3A283A8AF2B2C9C612155DBBFF3FC0A692047014F44879034A0 - 5D81C38069A383A82F2E040E8F0EA1CE5856D4D36DC02ED121D4D7C222ADB098 - 2D3A88A441A53BE61F8B0EA1CA4AFBA22555CF9EC0775D51D11A69DBC7D6C02B - D141D419CB8AFAFA05705A7408F5CD627982FC9CD141240D2A9D0AF2DBE810AA - E4C90263A343489ACA9781432C2A5AE553C003D121D439CB8A7AEF91FE8C47E6 - B5CA9B7261316F74104983AEAED8363A842A653CF0E3E81092A672007010303A - 3A88FAE687C019D12134329615F596F6BF6E1A1D427DB5482E2C168A0E226940 - CF02DF8C0EA1CAD8D0E5C652E57C1BF8AA4545AB5C9B57D2A8662C2B9A719CE9 - FED121D4570BE6A19B8B47079134A074B74E7A06382F3A84A4C91C99E754F81E - A83D5E0636763B5E3DF983DA0C87E4D242ED91B6825C0E2C1B1D44D2545E02B6 - 8C0EA1702BE76D2092AA33EF2D0DA81F151D447D95B667DE191D42DDB1AC684E - 63B8795E7EACF648C3362FC917C492AAE554EFE2B4DA2DC075D121244DF69C9C - DEB45A54B4CB31C049D121D43DCB8AE648936DB7880EA1BE9B053817D8203A88 - A4C98C0356890EA1306BE641D892E2FDC1196FAD745B3E8D290DBF564D595634 - CBD9F9AC68B5CB4CC029C0A7A383489ACC15F96249ED7B2DFE4F7408494C0BFC - 13582B3A88426E18A41B79CF4507516F2C2B9A274D37BE2C3A84FA6E7AE0E779 - 6894A46A4877D6578D0EA1BE4BF34ABC9327C59A19B80AF840741085D8266FC7 - 53CD595634CF8B79A9DBF3D141147207E1907C2497A4EA6CD13B393A84FAE61B - F914104971E6076E00DE191D44217E069C181D42C5B0AC68A6FB80CDA24328C4 - E8BCBA224DBC96540DDB450750DF56D2786CAD14EB6DC0F5C09BA2832844FABB - DFDDD56DCD6159D15CE700DF8A0EA110A3F2C4EB339D7A2D55423A1564EBE810 - 2ADDBAF9742E493156CD5BA1D3F1EE6AE7B1E11B012F440751712C2B9AEDEBC0 - 5FA24328CCFA79B0549A672129565A92FA54740895BADDE74FD121A416DB229F - 8E366B741085F9247067740815CBB2A2D95ECEDB419E880EA230EF076EF42E83 - 146E3CF0BEE8102ACD873DAA540AB30F701C30437410853918383D3A848A6759 - D17C8F001F8B0EA1508BE7C2E21DD141A496BB03F87D740815EE2CE0DEE81052 - 4B1D91B73DA721E36AA73F0307448750392C2BDAE1EFC01ED121142AADACB814 - F8487410A9C5D2C0AF4F458750E13677989BD477A3F29DF4CFF97EA6D51ECDCF - C1CE0B6A287FB8DBE3708FCF6BBD59F25DDD2F4407915A2C0DFEDA383A840AB3 - 8D47854B7D3743BE01B341741055623E5B5A45AE86B2AC68D77EE99D805BA383 - 28D474C061B9BC921423DD0DBC2D3A847AF630F0EBE81052CB2C02DCEC0C2001 - BBE4D35FD4609615EDF22CB01EF062741085FFDC7FDEA34DA5306910E38AD121 - 54C800E3742340527FA4E7CDEB8037450751B89F033F8B0EA1F25956B473C0DB - 27A243A8324BE7AE02668B0E22B5505AB6FAC5E810EADA910ED594FA6A7BE08F - C01CD14114EE7260374F606A07CB8AF64E2E776AAE9265F3D6A0774607915AE8 - 87C003D12134626975E2EED121A416F936F0538F2615F014B0619EFFA416B0AC - 68AF6F02BF8B0EA14A58200FAA4AD39425F54FDA42F0DEE8101AB1E58157A243 - 482D799F92B6ACEE058C8E0EA34A48DBD92DF95BC4B2A2BDC601DB3AE44DD9CC - C02F816F4407915AE64160CFE810EAD8B1C08DD121A416980BB8266F599592CF - 027F8F0EA1FEB2AC68B767807581B1D141540963807DF3F1A63E3748FD934EE8 - B92B3A8486958E28DD1978353A88D470EF016E01968E0EA2CA380AF8497408F5 - 9F6F48942E903DA75A138DCA7B01AF07E68B0E23B5441A12E6317CF57803E5F6 - 0FA95C3B029700F3460751655C0CECE140CD76B2AC507281C3C23485B7E7BB1A - AB4607915AE27160E3E8101AD497F2306249E5DE3D4F8F19A383A832D27C8A4D - F26063B5906585263A3C9F592C4D3427705E1E6C25A97C690BD6B9D12134959B - 80EF4487901A2C9DF2F157E0330ED2D414F3F5D6061E8D0EA23896159A282DAD - DA352FBD93269A1E381438D5E70BA9746916C2461EC956B9D7C60FBAFC582ACD - 5BF3B0F795A283A87236056E880EA158BEF9D0A4C6E665C81E09A429E7584C7C - C158303A8CD4702F3B54AE52DE9D87514B2ADE76C095C022D141543969E0FBE9 - D12114CFB242534A4BADD6CC17CCD2A4DE06DC0C7C2C3A88D482C1C79B478710 - 9F07AE8D0E213554DA7AFC3360A6E820AA9CE3806F47875035585668B0FDB9BE - 21D54066077E0B7C373A88D470A700BF8C0ED1622703474687901A6836E03260 - 07E7536800FF003E0B8C8F0EA26AB0ACD060FE909F2CA4298D01BE988761CD12 - 1D466AF0FC8AB444FABEE8202D7427F0A9FC7720A9382B03777854B306F11F60 - 43E736695296151A4A3A3EEA07D12154592BE58BFA15A283480D353ECFAF4813 - D1D51FCF02EFF2AE9E54B8FD813F02F346075125A5A349D7F0E40F4DC9B24243 - 79359F2D7F56741055D67CC085F9224452F19ECED3F255BE74E2C712C0F3D141 - A4869D2A763E7000305D741855D6FAC02DD121543D96151ACE4BC096C075D141 - 5459D3E58B90545ACC1C1D466AA0B48269ADE8102D28E75329F4707410A94196 - CBDB3ED68E0EA24ADB09F8537408559365853A5D16BB8E17711AC66AF91483F4 - ABA4625D00EC1C1DA2C196016E8F0E2135ECE8C97F020B470751A51D041C1D1D - 42D56559A14E3D08ACE291A6EA605B485AEEE99153523947FDA50B3B157FF7F7 - 86E8105243CC9087B47F236F019106730270A0C38C3514CB0A8D44DA4BF691E8 - 10AABC6981BDF21D15076949C57935CF8749A5858AF9FFF39DC035D141A48658 - 21AFB04CDBD646458751A5FD256FFF7080B4866459A1914A73093E1D1D42B5F0 - 81BC5775ABE82052C3DE60A7ED2027470769C03CA625811BA383480D7170BE46 - 5C303A882AEF6E60138F2855272C2BD48D5FE65342A4E1CC061C079C048C8E0E - 2335A8B048838F4F8B0E52530F018BE43255526FD20ACA7FE4EB424FFB502727 - 5CAD0E3C1E1D44F56059A16E7D07F8617408D5E679E693F94483E5A3C3480D3A - 66F393B90C54E72E0216071E8D0E2235C0167930ED07A383A8165ECEF3EFD2CA - 0AA9239615EAE542796FE037D141541B8B027F030E8D0E2235E879783B07DA76 - ECC07C47CFA5C7526FD24AC913815F01B34787516D7CD419411A29CB0AF5DA90 - 6E9387E4489D982E975C57016F8A0E2335644B485A7EBD4F74908AFF7FF4913C - 9CD4A9F3526F3E9887686EEEFB088D407ABFF0A7E810AA1F9F64D4ABFF6FEF3E - A0352DABBB8D5F88884893DECBD07B6F82343F7A4004114589522480820A169A - 829048FB680A221A94A2109022559022D2A4F7DE7B672883B41906B2EE957D92 - E330339CF2BEEF7ECAF55BEB5EE7307199BD12E62DFFE7DE7BBF096CE6DA370D - 6155E03D115C481A9E0FE27645690BD13FBB0B9803B828BB10A9018E00AE04E6 - CE2E44B55236C49D945D84EAC9B0429DF01AB02EF0747621AA954F454B48690D - 9935BB18A9014E8F2D3C63B30BA9885D80A581E7B20B916A6E3EE00E60B7584F - 2E0DD491117249436258A14E4E575F33A6FC4A83B15A0CE8FA5E76215203DC00 - CCD9F24D17B7C65AD25FDAF6210DDBDE717B76A9EC42543B27C50DDA325F491A - 12C30A75D2A31158BC935D886A67AA7ED74B67CE2E466A4078BC483CD16ADB1C - A52D80152200953474B303D7013F03A6C82E46B5733EB013F05E7621AA37C30A - 755AB926B88E29AA866012608D5871BA7B763152CD8D8DBF47EBC797F8A62BC3 - 336704CEF23685346CA5DDE3C1682B9306EBFA586BEBC34B0D9B6185BAE1DA58 - 4F240DF596C5E1C0DF1DE2250DDB25C04CB162B0898E8D019A652DE91BD9C548 - 35376BDC702C371DA7CC2E46B5F4407C07F84776216A06C30A75CBC5B1D64A1A - CE7AB4FBE389A9A4A11B057C3D06219781C84D50BE4C8D00BE0D3C9B5D8CD400 - DF8F5937E586A33414CF006B03AF6417A2E630AC50379D06EC905D846AADF4C9 - FE14B81D5826BB18A9E62E8B9930BBD4B4556254D43E737CB17A3CBB20A901E6 - 8E9B8C87799B42C3301258DDED4BEA34C30A75DBF16E79500794F5833702BF01 - 26CD2E46AAB131B12563A60802EBE04F310B69FAA8FDA5EC82A486D83F6E3096 - 9B8CD25095968FCF028F6517A2E631AC502FFC02D827BB08D5DE647153E709E0 - 0BD9C5480D780AB67F0CA52CC3F4DEA65AAE8A56C2D243BF3970790C0D95347C - CB017701FBBAE943C3343A6E5494D04BEA38C30AF542B96E7C30706076216A84 - 3962E2FF85C00CD9C5480D082D8E02A60536022E4AAAA3041167009B02B3C41A - ECD24AF842523D52134D1A3714CBB68625B28B51ED8D8D1915A55557EA0AC30A - F5CAFB91E097A16852275EBB368A5B16E5DF2B49C36F0FB928FE5ECD0E6C019C - DBC5D916E543EE5F809DE229EF27812D81F38017BBF4BF536AB3CFC79C971DE2 - A6A2341CE5BD61C398772275CDC7BBF75F2D8DF7C3E91EC02762489A345C53C6 - 55F6AF003B025767172435C073717BE9AC0811168F536E3BAC1CBF0F7630E62D - C075C04DB1DAEE41DB3AA49E2837104F8A2F963EA454A76C065C9A5D849ACFB0 - 42BDF65EF4474F165F2EA54E5814B8023807D81E783DBB20A921DE89A0A19C93 - E3CF268B019DE54BD054D1F35E42E8BE1B1AE575FE8D0829CA304CFF3E4A39F6 - 02F68EBFA752A77C256EDE495D6758A10CE583ECAEF1E176DBEC62D4A85EDC2F - 02EBC70AB672E34252E79540E2D93892AA6795984DB16476216A9C6D80D3B38B - 507B781D4C991F764BAFF289D985A871A68A958C0F45FFBD24496D30757C91BC - C6A0425DB043B414493D6358A1EC7547A515C4C042DDB000703E70093022BB18 - 4992BAE847C05331A8B6DC34943AE95BC0F1D945A87D0C2B5495C0C2A456DD7A - 8D5B37F67FFF3686054A92D41465F0EDDDC021B18258EA4650F1ABEC22D44E86 - 15AA4A60F16F0616EAA2321F65BBD872F0C3EC6224491AA699E2F6E0E543D8D0 - 230DD4B70D2A94C9B042550B2C7E975D881AEDD3C0A1B136B10CE39424A96E9F - DD8F009E0036B6E5435D0E2A8ECD2E42ED6658A1AA051665E8E6AFB30B51E32D - 089C015C07AC9C5D8C2449035056733F1D2BE0CBCA60A95B7631A850151856A8 - 8A5B42CA0BE42FB30B51E34D12EBDDAE8DABB47365172449D2787C16B825061C - CE965D8C1A6F573F87AB2A0C2B5445EF01DF038ECA2E44AD30695CA57D18F8BD - 03CA2449155142F43F035702CB6517A356D8193826BB08A98F6185AA1C58FC00 - 3830BB10B56A08E7D6C0B3C0D1C0E4D90549925AE953718BE22160433FAFAB87 - 6D46C7651721F5E78B9FAA6C2CF013E0C7D985A8751F124B2BD2F3C07F38BC4C - 92D4C3CFE507C5FB4FF9E26868AE5EF95787DCAB8A0C2B5475EFC7ED8ADDB30B - 512B3787EC13EB4E7F12332E2449EA86EFC6CDBE3D81A9B38B51AB6C09FC21BB - 08697C0C2B54071F0047023B6617A2D6EEB23F20428B3D0C2D24491DF4D558A7 - 5DE674CD925D8C5AF7F97AB3D88E2655926185EAE437C056D945A8B5CA87C883 - 636DDC8F0C2D2449C350063BDF019C12EBB4A55EB75A6F009C935D8834318615 - AA9BD3808DE24556CA303B70485CD72D6D22BE8E4A92066A2DE006E03C60A9EC - 62D44AA38135814BB20B913E8A1FB2554717C59BFDBBD985A8D5668D019CA53D - 643F07714A9226E233C0DF80CB8195BC9DA7246F02AB02D76617220D846185EA - EA1A6015605476216ABD99819F022F0287015364172449AA8C9522A0B8269E66 - FBD95B595E8D7F1F6FC92E441A285F305567B703CBC5757C29DBF4C0F7819762 - BECA0CD9054992D2AC1C21C575C0E7FCCCAD64E516E88AC0BDD9854883E10BA7 - EAEE1160795F7C552153023B00CFC48C1507A749527B7C36DA3DFE6E48A18A78 - 0058213E334BB5E20BA89AE0F9F87070757621523F93035F06EE032E05D6C82E - 4892D435EBC51C80AB6CF75085DC10332ABC85AC5AF285544DEAC3DB10382BBB - 10691C65F0E63AF1A4ADF4897E2DBB204952C76C01DC0C5C1C5F0A1D9CA92A0D - A45F177825BB1069A80C2BD4B409C75F058ECE2E441A8F4962C6CA1F80278003 - 804F661725491A921D81FB8133A21DD5904255720AF045E08DEC42A4E130AC50 - 1377477F0FD82BBB106922E6067E02BC0CFC1E983FBB2049D2806ECAED033C05 - 1C072C9C5D90341E3F07B605DECE2E441A2EC30A35D1FBC0C1F1422D557D18E7 - D631FCEAAFC026D90549923EE4D3C02F62DBD37F00736617244D407958B73B30 - 26BB10A9130C2BD46427C6C0AB77B30B9106F0B46E6DE03CE051607FE053D945 - 4952CB2D1C5B9DCA20EF5D81E9B20B9226629B7858571EDA498D6058A1A6BB34 - D63595A721521D8C00F60546462F74D98B2E49EA9D0D80CB817B62AB53D9EE24 - 55D598F877F6A4EC42A44E33AC501BDC0D2C131F3AA4BAF8644C992F6BC7EE88 - 6B9D93651725490DBEE1B65BAC9B2E5B143E177F2655D9286015E02FD98548DD - 6058A1B628FBA55703FE9C5D88344865C2FC52C0E1B17EEC5460D9ECA224A921 - 66038E8D1B9847008B6417240DD0A3F130EED6EC42A46E31AC509BBC0E6C0E1C - 935D88344453015B01B7C48793D243ED933F491ABCF5E269F493C0CECEA350CD - 5C03AC043C965D88D44D86156A9B326CF3BBB1DE54AAF36D8B65633AFD2BB1FE - D4DB169234719F886D090F445051028B8F6717250DD229C0FA31DB4A6A34C30A - B5D1FBB1837A63573BA901A689F5A7B7C46C8B1FC5BC0B49D2FF583EB67A9470 - F74060A1EC82A4213A28B67EBC955D88D40B86156AB30B6353C80BD985481D9C - 6D71487C203F3BD6A14A521B951B13DF8996B99B62ABC794D94549C3B013B00F - F05E762152AF1856A8EDEE8C2F78D765172275D014C066C05F8187809F01D367 - 1725493DBA45714A84B63F8F16B912E64A756E612E2D4BBF063EC82E46EA25C3 - 0A095E04D6014ECC2E44EA820580BDE306D125C0967E7097D4C0E1C37BC70388 - 728BE2ABC0D4D945491DF034B034706976215206C30AE97F94DEBF6F027B6417 - 2275F14AF4BAC0E9B1A2EFA4688392A4BAFA17E07CE0E5B841B6A461AC1AE4DA - B8195406C24AAD645821FD9FB1C0A1F1E1E79DEC62A42E9A01F83A7023700FF0 - EFF1679254758B02C7C513E70B6258F6E4D945491D76523C6028419CD45A8615 - D287FD39AEDCB9BB5A4D579E402E06FC38DA44AE00BEE17B83A40A6E3D2A2B47 - 6F8B807547608EECA2A42E29FFAE6F0FBC9D5D8894CD0FA4D2F83D082C17C185 - D40693026BC5EC96578133628FBB2465B5AE6D1F838247C6CAD1656CF350838D - 013E0F1C1CB77DA5D633AC9026ECB5D8A850FA60A5B63DC5DC02B81878163801 - 5831BB2849AD50BEAC9D13EFC1C7C70AE6125C486D18A45966B0480A8615D2C4 - 8D8E2BF25F8CC45B6A9BD9806D62BE4559837A546C1891A44E593F86FF96FEFC - 73814D8129B38B927AE48AB835745F762152D518564803737624DE8F67172225 - 2A21C577A34DAAF48EFF049839BB2849B5546E4CFC1E783E6E7195B5CA0EFA55 - DB1C036C14AD4E92C66158210DDC7DB142EABCEC42A46493C453A00380E780EB - 813D8119B30B9354691B02A746405166516C0DCC925D9494E08398C9F21D37D0 - 49136658210DCE6BD112B27776215285DE4756060E8A8D227F077E647021295E - 1F368F81BD236368F55606146AB997E27DF377115A489A00C30A69F0DE8B2F66 - 65FFF51BD9C548157B4FF90C704804173744ABC8ECD98549EA99A962B5E845C0 - 28E0AC18D83B7D766152055C032C09DC945D8854078615D2D05D062CE61B8E34 - C1F79795A255E429E0D608F916CE2E4C52C72D08EC1737ABCA0DC4E3800D1C92 - 29FD93A3E3415709F3250D80ABA0A4E1AF9A5A33BE8495C18392C61F5C2C1B67 - 8FD82A52FAD54F8A791792EAF7777A83188AB91A307FCCB291F4616381ED62A0 - AC6D1FD220185648C3F736B01B702DF007E013D905491556BED02C1467A718D0 - 7935F047E09CF85027A97A9688768EB5E2D6D414D9054935F024B03170577621 - 521D1956489DF1410C10BB2DBE702D9E5D905413B3C5D3D92D23F82BD7C82F04 - 4E8B2043528E79804D81FF072C0FCC915D905433E5F3E0B6D11A2569080C2BA4 - CE7A38263C1F09EC905D8C543353C417A3720E07EE895B17A7035766172735DC - 0860A3B83951C289796DED90866C2FE0B018CA2E69880C2BA4CE7B3326A15F01 - 9C685B88342493C4B5F37276065E05AE032E06CE069EC92E50AAB91580F56283 - 4F9927E3CD0969F85E8F75BD652E93A46132AC90BAD716F25FB129E44C60E9EC - 82A49A9B2E9EFA96F373E0816819393756248EC92E50AAB01980B5E32C032C15 - 2B462575762D696969B48551EA10C30AA9FB6D21AB0207BA2D44EAE8AD8B45E2 - 6C1741C52D115E9C13AD23525B4D1E1B3AD688DB138BC7FC095B3AA4EE295BE1 - F607DECD2E446A12C30AA9FBDE02BE1757024FF16996D4719301ABC4D91D7803 - B839C28BF3801BB30B94BAE493D1C6B15ACC9958145830568B4AEABE37E23645 - 695194D461861552EF942F4D0BC77AD372155752774CDDEFCAFB3ED1435C6E5E - DC005C16372F6C1B511D5B39568D506EA9B859349FC18494A6BC976CE50C25A9 - 7B0C2BA4DE7A16583F9EFE1E9C5D8CD412D3029F8BB3574C67BF0FB83B7A8CAF - 8ADFA5AA5832364BAD182177B92D317B765192FED74FA3F56374762152931956 - 48BD579EE81E12DB42CE00E6CE2E486AE17BDF9271CA5331A2CFF811E051E0FE - 681DB92DE6CE48DD324704122BC66C89F923982873272455CFCBC016AED3967A - C3B042CA73637C593A3286044ACA53BE1C2E1667E371C2C5A780A7E3E7C31166 - 9460E321E0B5C49A551FD3C4B0CB15A385638138D36717266950EDBCE5F3DAC8 - EC42A4B630AC90728D02BE095C089C0C4C995D90A40F0DEF9C2FCE8486AB3D1F - ABEAFA7E3E1637341E8BF3668F6B56EEC0CBE562D8E5B2715362FEB84121A9BE - EBE8CB46B76381B1D9C5486D62582155E34DF06CE07AE00460BDEC82240D6A98 - E7D471757F42CAED8B178117E29440E3F108341E8C1B1A0EFCAC97498165E2B6 - C472FD6E4ACCE58A50A9511E8C6D1F77641722B591618554ADE19B1B013B0047 - FBF7536A8C4FC7596822FF99E7E335A0EFDC03DC09DCE595E3748B4528B142FC - FFB0DC9418118185A4E63A3A86327B3B4E4AE29721A95ACAF5C2E3804BA22D64 - B5EC8224F5C4AC71CA53FA7195B0E289386556C6EDF194EF5EE0FD845A9B623A - 606660A63833F7FB394FDC9428C184C32EA57629EBAEBF162DBA9212195648D5 - 54AE87AF0D7C073814F858764192D2CC1067B9F1849B4F444BC9E3710BA32FC4 - 28ED266D3049BFB061DCC061C6B8D1326D0CB89C267EEFFB676F46481AD705C0 - F6D1BA2729996185545DA587FD70E062E00FD11F2D497D269DC8F0CF7FC40693 - 729E8930E391D866F248053F884F369EC0A17FE830ED444207491AAEF7805D80 - E31DA22955876185547DA577FD33C01EC04FB38B91540B53018BC4199FB78197 - C773FA0F027D31FEAC0C087D65182D27D344E030479C3981B9E3CC15FF5C4209 - 49CA50069C6F1D41AEA40A31AC90EAE11D60FFE89F3CF523360F48D247992282 - 827206EADD7E67746C322ABFF73779BF9F93C73A66DB2D245551790DDB1B3822 - 5ED324558C6185542F37473BC8BE71D342927AA52F8090A4BABB0FD8CA95A452 - B539B44FAA9FB7803D815562FFB724499206E6206079830AA9FA0C2BA4FABA21 - 6E591C985D88244952C53D140F7AF68EB93D922ACEB042AAB7F266BB0FB0625C - 69942449D23F3B241EF094073D926AC2B0426ACE2C8BE58003B20B912449AA88 - 8763A3DA9ED1462BA9460C2BA4666D0CD92F428BB2EE549224A9AD4A9BECD2B1 - 9A54520D195648CD731BB0420417652D972449525BDC1903344B9BACB729A41A - 33AC909A7BCBA2B4842C05DC945D8C24495297BD1FED1E2B01B766172369F80C - 2BA466BB1BF82CB03B3036BB184992A42EB80E583C0669BE9B5D8CA4CE30AC90 - 9A6F347024B010704576319224491DBC49BA33B006707F7631923ACBB0426A8F - 478175811DE2CD5D9224A9AECE04E6078E03DECB2E4652E7195648ED525A418E - 8F37F7F3B28B9124491AA4E7814D802D8167B38B91D43D8615523B9537F7CD80 - AF00A3B28B9124491A80C38105810BDC7826359F6185D4EEA9D9A703F3012764 - 1723499234013702CB013F00FE915D8CA4DE30AC903412D80E58077822BB1849 - 92A4F066CCDA5A0DB82DBB1849BD655821A9CFE5C062C0CFB20B912449ADF73B - 60DE98B5E5004DA9850C2B24F5F716F0636029E0FAEC62244952EBDC13AB48B7 - 075ECE2E46521EC30A49E37317B03AF06F11604892247553F9BCB14BCCA6B83A - BB1849F90C2B244D48B972F99FC008E094EC6224495263FD67B47CFC12189D5D - 8CA46A30AC90F4515E04B606D6051ECE2E469224356ACBC74A7193F3A5EC6224 - 558B6185A481BA0C5812D8D34157922469185E01B6892D1F37651723A99A0C2B - 240DC63BC021C0FCC039D9C54892A45A190BFC7BB47C9CE4C30F491363582169 - 289E04360736061ECF2E46922455DE99C082C0BEC01BD9C548AA3EC30A4943F5 - 017021B028B0073026BB2049925439B7036B025F021ECB2E46527D185648EA44 - 6BC8A1B135E4B4EC6224495225BC147329CA00CDABB28B91543F8615923AE519 - 602B606DE0CEEC622449528A77817DFACDA5F0E6A5A42131AC90D4697F039607 - B68F69DF9224A91D8E05E6060E04DECA2E4652BD195648EA8632DDFB77D11A72 - 30F07E76419224A96BCE8F1956DF065ECC2E465233185648EAA651C05EC002C0 - 19D9C54892A48EFA3BB006B029707F7631929AC5B042522F94E9DF5B02ABC607 - 1B4992545FF7019F075607AE8E0D6192D4518615927AE9BAF860B339F0487631 - 922469509E03BE012C1DAD1FB6794AEA1AC30A49BD563ED8FC09581CD8D9219C - 922455DE6BC07780F98093DDF021A9170C2B2465AE363B2EA686EF0DBC935D90 - 2449FA276FC6ECA93981A37DAF96D44B861592AAF041E820600EE050606C7641 - 9224B5DC68E080786F3E38DEAB25A9A70C2B2455456907D9236E5A1C631FAC24 - 4929ABC70F8D90623FE0F5EC8224B5976185A4AA7916D8151801FCDA09E39224 - F524A4382C428AF2E0E0E5EC8224C9B04252553D09EC04CC0FFC36BB1849921A - 1A521C1E33297E08BC985D9024F531AC9054758F01DF8C09E4BFB23D4492A461 - 1B1B21C55CC00F8017B20B92A471195648AA5368F1AD986971643C0D92244983 - DBC47570B47B9490E2F9EC822469420C2B24D5CD33C0EEF141EB40D7A84992F4 - 91DE8A8199B3C52A526F5248AA3CC30A497555FA6AF701668D616023B30B9224 - A9625E8F7062B65845FA6A76419234508615929AF041AC6FCDDA76C0FDD90549 - 9294ACB4777C37DE1B4BDBC7A8EC822469B00C2B2435A90FF70460096023E092 - EC822449EAB187806D8179805F006F6617244943655821A98913CE2F02D60716 - 077E098CC92E4A92A42EBA11D81C58143811189D5D90240D976185A426BB17D8 - 059819F83EF0447641922475D005C05AC02AC09F22B097A44630AC90D406AF01 - 4700F3031B02E766172449D2109540E237717B7013E04AE083ECA224A9D30C2B - 24B5ED03DEC5C01780B9638D9BEBDB2449751928DDB77E74C7B83D28498D6558 - 21A9AD9E8A356E73019BC6555A4992AAE6C10827FAD68FBE945D9024F5826185 - A4B62BC337CF8BABB473027B034F661725496ABDBF44EBE262D1F6F176764192 - D44B861592F47F9E010E02E68B6D227FB40F5892D4E300FD57B1867B83685D74 - 68A6A45632AC90A40F2B1F0C2F01BE0CCC02EC1ED7702549EA566BE20F637BD5 - B7807BB20B92A46C8615923471A537F8C8D85DBF0670423CF9922469B82E8DB9 - 49E546DF61B1BD4A926458214903F63E7035B01D3003F04DE0C6ECA22449B553 - 664F1C1521F87A3137E9BDECA224A96A0C2B2469F0DE007E0BAC0C2C051C1E2B - E524499A903B63ABC74CC06EC0FDD905495295195648D2F0DC05FC20FA8CBF14 - D3DB2549226E4C94F6C155816562ABC79BD94549521D18564852678C06CE8CE9 - EDF3003F7605AA24B556B935B12B3063B40F5EE77629491A1CC30A49EABC1252 - FC0C1801AC154FD5DECD2E4A92D4F55B1427036B028B03C7D822284943675821 - 49DD1DCA7965BFA19CDB02D764172549EAA8BBE316459945F10DE0AA78FD9724 - 0D83618524F546E9513E11581D580838007826BB2849D290BC05FCAADFA0E572 - 8BC2B5A392D441861592D47B0F01FBC56C8BB2B6EE14D7D649522D5C0E6C1DB3 - 28BE152BAC9D4521495DF0F16EFC974A9206642C70699C9D812D80AFC79C0B49 - 52353C021C0F9CEAE064497577E105E75017861592540D6FC420CE13E2C6C556 - C036C0C2D98549524BDB3C4E8D8199D73A8342927ACF361049AA9E2780838145 - 819580A38057B28B92A4862BED1C17005F8EA1C83B00571B5448520EC30A49AA - F607E79B80DD8059804D803F3ADF42923AAACC9DF8363073BFD7D977B28B92A4 - B6B30D4492EAE1BD78E257CED4C06631E46DDDECC224A9A6838E7F0F9C0E3C98 - 5D8C24E9C30C2B24A99EF32D4E8E332BB06504172B6617264915F674CCA13803 - B8C52D1E92546D861592546FCF03BF88B3606C14F92AB04476619254012381D3 - E20685833225A9460C2B24A959D79A0F8AB37804175F8B104392DAE295B83D71 - 267045AC899624D58C61852435D33D710E0096013607BE022C905D98247529A0 - 288331CF32A090A46630AC90A4662B3DD9B7C5D937828BCD22B8F0C685A43A7B - 0EF8137036F037030A496A16C30A496A6770B11FB024F005E04BCEB8905413F7 - C7ED89F363B5B3332824A9A10C2B24A9BDC1C59D714AABC842C0A6115CB85544 - 5295D63697B68E0B818B8107B20B9224F586618524A97810F8FF71E604368E76 - 9175808F651727A9551E8F70E222E0AFC0DBD90549927ACFB0429234AEA781E3 - E24C036C14ED22FF024C955D9CA4C67919B81CB82C664F3C9C5D9024299F6185 - 2469624601A7C529EF196B4468F179378B481AA291C055C095114EDC19AD6992 - 24FD2FC30A49D2607AC7FF1AE7FBC02271EB629308316C1791343E4F02D74438 - 712D70AFE18424E9A318564892863395BF9C23802963BEC5061160CC9D5D9CA4 - 1463634B470925AE8F535ACB24491A14C30A495227BC099C1B671260F1082FD6 - 073E077C22BB40495D1BCE7B7D04143703B702A3B38B9224D59F618524A9D3CA - F5EEBBE31C054C166D227DE1C5B2D9054A1A92472290B8254289F2F3B5ECA224 - 49CD64582149EAB63131E9BF9CBD801980D58135E3D6C552D9054AFA50E0786F - 0412B701B7C74F83094952CF185648923236019C13A7980E5839CE67E29495A9 - 92BAEFB5D8C671478412E5F7BB8077B30B9324B59B61852429DBABC0C5718899 - 170B01CBC459215A47CA8D0C4943F37EDC96B8230289BE56ADA7DCCC2149AA22 - C30A4952D5942F4E0FC439BDDF9FCF1E833BFB4E599DBA20304B62AD52153D1B - B723EE8840E2CE082A4A4B962449B560582149AAD317B0722E1DE7CFA78DD0A2 - EF945B190B030B009F4EAA55EA85D72394E83BF74438F14A766192240D976185 - 24A9095FD86E8E33AE1256CC03CC1B3FCB1911679E98972155DD980821EEEAD7 - BE51CED3B67048929ACAB04292D4F4E181AFC575F8F129833CE702E68E9F7DBF - F73FBE57AA979E8CB68DBE534289FB62E6842449ADE1073049529B8D8AABF3E5 - 8C4F19F6395B8416F3F4FB396FBF9F53F5B86635C39BE384127DAD1CAE079524 - C9B04292A489FAA0DFAC8CEB27F09F993E428BBEF692F980F96366C688083CD4 - 6ECFC45AD0DBE267B9E9F3882D1C92244D9861852449C3F34A9C5B27F03EBB40 - 9C32FC735160B1F859420E354F09216E89736BDC9A7831BB284992EAC6B04292 - A4EE790FB83FCEB8668EE06249600960A9F87DCA843A35F0B6A197FB9D91C04B - 71F3E6D6B839611B8724491D60582149528E17E3FC6D9C3F1F1121C6E2710363 - 91B8993163529D6D081E46F60B1EFA7EEFFF3FEBFB393ABB684992DAC2B04292 - A46A792CCE85E3FCF9B4310F63DE38730273C40693BEDF27A59D061B3CBC1CEB - 402549524519564892540FAF479B4139E3530679CE0ACCD2EFCC1C7F366BCCC8 - 2867867EBF57DDD311DC3C183F271442183C4892D430861592243543D92CF15C - 9C819824028BE9E2D6C6D471FA7E9F26D6B24E3181F3B1F8D9F779A2EF3345DF - 9F8D89991DC53BF1F36DE01F71DEEAF7CFAFC590D2123CBC003C1F41C5D80EFE - DF479224D5C8241F7CE0D62C4992244992541DE5A98824499224495265185648 - 92244992A44A31AC902449922449956258214992244992A892FF0687FFD3AD2F - 08CE640000000049454E44AE426082 + A88942000000097048597300002E2300002E230178A53F760001268849444154 + 789CECFD07B82E5775E7F9AF9B73560E57594222092421720663AA80C206271A + D34EED76688FBBC77FF7FC677A7AC63DDD63B76D7230989CA36103BB40480421 + 32882009E59CAFC2CD39CFB3606DBC29BDE7DC13DEAA5DE1FB799EF3DCAB8054 + E8DE53EFAE5FAD30E7F0E1C3020000000000D01673535F000000000000408CB0 + 020000000000B40A610500000000006815C20A0000000000D02A841500000000 + 00A055082B000000000040AB105600000000008056999FFA020000403B6479B1 + 504496445F4B456499FD7C8E9D1BF447B560927FD461113910FDF101FB736A7F + F4D7AB3F3F605F07EDC77DD15FDB5F7A17FF330100408FCD397C389C1D000040 + 5F6479B1A8123A84E061B988AC88BE56D9D76A0B20E6DBD73CFB9A6B5F732A5F + 41FC737578C4CF47FD38EAEBD0889F1FAA7CED15915D22B25B44F6443FDF693F + EEB63F17FE7CF8FB7EF1F3D23BFDE70000801623AC0000A0E5B2BC586CA1C362 + 0B1C9659F8B0220A1F5646C1C32A0B1EE645C1431C40CC9BE4CFCDAD8414D5A0 + 625440314AF58031516011FF7CB2AF439384180747FCFC60F475A852B1A1C1C6 + 6611D9167D6D17911D959FFF2CF420DC0000A079841500003424CB0B7DC85F3C + A2E26179F415573B84AF6AB030D1CF8F143C544388EA1F876062A24A8A6A4831 + 516831D1E1E2F0117E3E9D4063547831AA12A3FA7570C4D781CACF0F545A5334 + D8D828229B44648BFDF166FBF9CFC28DD23BADDA0000006342580100C00C6479 + 31B7123C2C89AA1EE26A87B8E261E524950E93FDF164A1C3A8C061A2E061A29F + 8FFA0A266BF998AEC333A8C4A8FEF164D51832414BC9E159546554038C38C888 + BF34AC7840441EB22F0D361EB65063AB051A546800003045841500001C419617 + 1A1C1C2B22278AC8A9227296889C2C220BA3390F53091DAAC1C39142877951B0 + 3059D03095E061AA3F8E2B98988D231D4E0E4FE3E79355698C9A91315975C644 + 1519938518FBEC6BAF8519F747A1C62FAA35A8CC0000E09711560000F0C88A89 + 632AC1C499950A8A451654846194D369B7984EB543F863A92978481948A40A37 + AA7F5C0D31E23F3795CA8CA90619138518E14B5B4AEE1191FB2CD078308419A5 + 77FAF70300302884150080A107134789C80922728A05136745032C1747E144F8 + 5A50A9A698681025C143374C67BEC69186824ED66632598811D6B4562B31C297 + 5662DC292277C74146E99D6E390100A097082B0000430D26CE1091B36DBE44A8 + 98586C81C462AB9C085F5359E9A9081EFA6DD4A1693AED26F18F13CDC7D85F09 + 324288B1B7F2B5C7428CBBEC4B438C0DDA5E42250600A00F082B0000430D2642 + 28112A26422851AD9C98289C986C10658CE06158A6D272325155C6446D257105 + C6A859187180B1DB2A306EB310E35EADC428BDD3AD2500007406610500A00FEB + 40433071EA1482898523DA398E543571A4159EC0544DB6E5E44821465C8D316A + A86735C0D8130518BA95E4D628C4B8AFF44E877B0200D04A84150080AE0513EB + A28A8933ED6B65346362F1348289EAC68DE9564D00E336D9AC8C516D2513AD59 + 9D2CC0D86D5F3AD4F3260B317ED64A42800100680BC20A00406B6579B1D68289 + F5164A9C63C1443C63220E2646CD982098C090428C89DA48E200636F1460C4D5 + 17FAA561C50D2272B30DF5D4006367A2FFCF00800123AC0000B44296172B44E4 + 780B26CEB260626D656528C10430F510A3BA9D64D41C8C6A80510D2F76DA4AD5 + EBA20A0C9D81C1011200502BC20A0040E3B2BC5864C1C4C93663E2512272ACB5 + 724CD4CEB1C07E2498008E6CA22D25935560C46B54F74D125E6C15919F5A05C6 + ED3AC4B3F44EFF7700008C0D610500A089391347578289532C9488AB26164DB0 + 9963A2AD1C0413C0F44CB699A41A601C88028CFD13CCBDD8655FDB2DB808D517 + F794DEE95F070060C6082B00006395E585060F278AC869B695E33C9B33B16CC4 + 9C89B8A563FE8870826002481360841692B08164547851ADBC08E1C50E0B2DAE + 11911BB575A4F44EFF1E0000A68CB00200302B595EE8768E936CCEC4B916522C + 1DD1D211071393554D8C6AE708082680342D24D5F0A23AB8B35A7911828B9D16 + 5E686871B50DEEBCBBF44EFF7E00002644580100986E4BC7B1D6C6A103301F5B + 993531AAA56341F475A4760E19F12380F6565F84AFC9DA46E279173BAD6DE45A + ABBCB8C9665EE83F0300805F20AC00001C299C384E444EB7768EC789C81A6BE9 + 18154E545B3AE68D188239AA9D836002E896A90CEE8C378EC4AB527757AA2E74 + 5DEA8F6C68E72DA5779B13FF7F0300B400610500A01A4E1C63E1C4A32D9C586B + E1C4B20956882E98C6AC89807002186E78519D7711CFBAD0AF3B2DBCB85E446E + 2BBDD3FF0D006060082B0060E0B2BC58657326349C78A28515CB2BAD1DF140CC + C9C209AA26001C29BC08AB520F1CA1EA42DB45B65970F1636D19A1EA02008683 + B002000626CB0B0D194EB5B68E275850B13C0A28AAAD1D713831BFD2D211020A + 45380160A6E145DC3212CFBA88DB4534B8B85D44BE6F5517BA6584591700D053 + 841500309C8D1DBAADE3F11650ACB670229E3D516DED982C9C20980030CEF0A2 + 3AAC33AEBA18D52EA255171B2DB8F8896E19613D2A00F40B610500F45096171A + 2A9C6CAD1D4FB6ED1D2B2A014558291A0FC58C5B3B0827003425841632855917 + 5A71B127AAB808ED22DA2A72A588DC507AB735F1FF1F00C02C115600404F6479 + B1D0AA27CE17912789C8D19580624925A038D2DC09453801A02D551761D645DC + 2E12AA2EC25AD46DF6A56D22DF1591EB4AEF1E4EFCFF07003003841500D06159 + 5E6800718E885C6801C5EA28A0080332174F301873A26D1D041400DA249E7371 + 7882769178CE4535B8B85944BE2522D796DE3D98FAFF0C00606A082B00A063B2 + BC586AC3319F64DB3B749BC7CA111514714041F50480BE565D8CDA2E126F16D9 + 51092EBE2D22D7105C0040BB11560040772A28CEB5F913178C08289646DB3BC2 + FC8938A018B5521400FADA2E3251C5451C5CDC6215175797DE3D94F8FF0B00A0 + 82B00200DA3D83425B3C2EB69062957D5587644E544141F5048021B78B4C5671 + 1107175B6DC6C53744E4A70CE704807620AC008016B12D1E67588BC7334464AD + 5550AC1C1150C41B3C68EF0080E90717BBA2E062AB7DFDC42A2E7438A7FE7500 + 4002841500905896171A2A9C68ED1DCF1291E32B6D1E1A50681B080105008C3F + B8D85B092EB65B68B14544BE2722DFB175A8FAF703001A42580100896479B1D6 + D68C3E5B444E139135230665868062A2160FC20900184F70B12F0A2EE28D221A + 5CE84C8BCB45E4FB227277E91D076800A8196105003428CB8B45B6C9E3991654 + 848022AC1B0D9B3C168E58334A400100E3336A1DEAC1A84DA43A9833545BDC2E + 225F13911F97DE6D4EFD7F0200FA8AB002009A69F33855449E6221C5BA116D1E + F1A0CC7893072D1E00D07C70112A2E46CDB7086D229B6DBEC51522726DE99DFE + 7D00803121AC00809A6479A155134F1491E78BC8FA29B679C4732814010500A4 + 0F2E429BC83EABB6D855D926F290555B7C5744EEA14D0400668FB00200C628CB + 0BAD8A78940DCABCD0028A55519BC7520B281645833243058586148A800200D2 + 0B87E4A9B489C4D516378BC897B5EA826D220030738415003006595E1C6DEB46 + 5F60DB3C565B4851DDE6C11C0A00E89E70603E140DE63C605FF13691506DA1B3 + 2D365A8BC83745E44EAA2D00607A082B006086B2BC9867C3329F67C332D746B3 + 2896455514B47900C030DA44AAD5165BACDAE22611B9D4AA2D34D800001C0161 + 0500CC6CE5A85651FC8A889C10B57A845914A38665D2E60100FD6F1399A8DA22 + 6C12D1D9165F11916F95DEDD97F8FA01A0D5082B00600AB2BCD0A0E16C11798E + 05156BADD563E58895A36116056D1E0030BC3691C9AA2D428BC82611F9A9885C + A63F96DEE91C0C004084B002002691E585B6725C2422BF2A22A75406662E3BC2 + 2C0A45480100C3727844B5C5FECA26917820E70611F9826E1229BDD320030040 + 580100A3657971A2883C43449E2B2247456B47574CB0D1832A0A00C054AB2D42 + 8BC8CE28B4D864C338BFCA404E0020AC00805103335F28228F179175D1C0CCB8 + D5832A0A00C06CAB2DF645D516F116110D2DAE17914B44E4AAD23BFD7B016070 + 082B000C9EB57A5CAC3F159193A279142B460CCC9C170DCCA48A020030DB4D22 + FBA3819C618BC8560B2DEEB716916F97DEE99F0780C120AC003058595E1C2B22 + CF14911758ABC7DA4AAB473C30335E3BAA08290000E3DA2432AA456447D422F2 + B0887C5944BE5E7AA7010600F41E61058041C9F2424386D3ADD5E3626BF588E7 + 5184819921A408010555140080260772EE1D31D762A388FC4044BE2422B730D7 + 02409F11560018D23C8AC78A482E22E75A4811568F8EDAEAC1C04C0040CA819C + 07ECABBAFA3484163AD7C28BC835A5775A990100BD425801A0D7B2BCD000E249 + 22F25211595F199A19CFA3085B3D3498A0D50300D0A6169178F569986BB1C542 + 8B3B45C489C895A577FAF700402F105600E8A52C2FB4A5E3E922F2121139B632 + 3473A2791454510000DAE4F011E65A6CB316110D2D7496C5E744E45BA577FAD7 + 00A0D3082B00F44A96173A28F33922F22BD1D0CC559590225E3D4AAB0700A04B + 5B44E2D022CCB5089516BA41E44111296D18A7061900D0498415007A21CB8B13 + 6CABC7B3476CF658520929D8EA0100E8C3EAD3308C33DE2012428B8744E45211 + F94AE99D565E0040A7105600E8B42C2F4E11915F1591A754428AE55649118666 + B27A1400D0D7619C072B951661ED69082DBE22229795DE69D505007402610580 + 2EAF1FD5CD1E175A48B1C6DA3D96479B3DC2D04CE6510000FA3E8CF360348C73 + A2D0E2EB227249E9DD86C4D70D0047445801A06B21C519B6D9E389232A2996D8 + D0CCB892829002003004D5F6900323420B6D0779380A2D74282700B412610580 + AE8414675A48F10411393AAAA45856A9A420A400000C59758348A8B4D86D8338 + AB95165F28BD7B20F545034015610580B68714674521C5649514611E05210500 + 00938716F1204E9D63F155ABB4D00003005A81B002409B2B290A11397F0AED1E + AC1F05006066951671687199887CA9F44EFF18009222AC00D0B690E2540B292E + B0768FB595760F420A0000C6175AC42B4F375A6871896D0FD13F070049105600 + 68852C2FD65BBBC7C59590A2BADD83900200807A428BED95D0E273BAF6B4F46E + 67EA8B06303C84150092CAF2E2040B299E1A8514AB09290000683CB4D853092D + 747388AE39FD1711B9A2F44E430D00680461058024B2BC58A73F88C87345E498 + 4A48B194760F0000928416FBA24A8B6D22B2D9428B7B44E4E322F2BDD23B5D8B + 0A00B522AC00D0A82C2F5688C80B2CA8385644D655420AADA460BB070000E942 + 8B0351A5C5CE28B4D06D21B78AC8C744E4EAD23BFD7B01A0168415001A91E5C5 + 6211799688FCBA8514BAE163CD8890422B2908290000684768B12F0A2DB6469B + 437E6AA1C56DA5773C5000183BC20A00B5CAF242E74D3C59447E53444EB4B914 + 1A52ACB00D1F84140000B437B43858092DC2E6100D2D1E10916F8A882BBDD39F + 03C0D8105600A84596171A3C3C46447E4744CE88428A555649B1D8E652105200 + 00D05EA1CAE290B5866868B1BBB23944838A2F88C8174BEF34CC00805923AC00 + 3076595E9C2622AF14912744C333575925450829B4E28290020080F60B0F0CF1 + E6907DD1E69030CFE27E11F984565B94DEE95F07801923AC003036595E68F544 + 2122CF888667AE8AD690869022DEF0010000BAD51A72B8B239241EC2A9F32C6E + 13910F8BC8350CE1043053841500662DCB8BA5B6E1E3655148B166C41AD278C3 + 070000E8A651EB4EE3219C1B2DB4B8522B2D4AEFEE4E7DC100BA87B002C06C87 + 673EC9E6529C54199E396AC38722A80000A0BF9B43749EC50EABB2D0D0628388 + 7C49447CE99DB68C00C09410560098B62C2F347038CB428AF346CCA50821C5FC + A8DD8390020080616C0ED91BCDB3D0AD210F8BC87D22F25111F956E99DFE3D00 + 3029C20A0033994BF10A11795AD4F2B1DA428A3097820D1F00000CCBA8219CF1 + 3C8B8D3684F32611F9A088DC507AC78308800911560098922C2FB45AE28522F2 + 720B298E8A5A3E189E090000269B67B1239A67A1AD21DF14914F96DEE91F03C0 + 23105600985496175A2171BE88BC5A444EB5B9146B2DA4885B3E189E09000026 + 9A67B1D7E659686BC816ABB2D0D0E29322F255569D02A822AC0030A12C2F7468 + E66F8BC805369722AC22D5906271A5E543115400008058082C0E45AD21BBA2D6 + 10DD1A728B88BC5F44AEA735044040580160A255A4B988BC58448EB3968FD556 + 4DB1386AF9602E05000098EE3C8B78D5E9161BC0F980885C61AB4E7593088081 + 23AC00506DF9B8C05A3ED65B3585CEA55819AD22652E05000018E7AAD3B035E4 + 21DB1AF2119D69C1D61060D8082B00FC4C961727D82AD20BA32D1F71CBC782CA + 960F000080D9AE3A8D5B43C2004EADB2F8A9887CA0F4EEF6D4170B200DC20A60 + E06CCBC78B44A4B0968FA3A3960F5691020080265B43746BC8E66800E71744E4 + F3A5771A66001810C20A60A0B2BCD0D0E13122F26F45E4746BF9D02D1FB47C00 + 0080D45B43B6596B885659DC2522EF1591AB4AEFF4EF0330008415C0006579A1 + 9513BF2522CFA80CD0A4E5030000B4616B487500A756597C53443ECA004E6018 + 082B8001C9F2420388A7DA00CD13ACE563ADB57C2CB590822D1F0000206595C5 + E1490670DEABB32C44E43BA577DA3E02A0A7082B8081C8F2E22411F95D1139DF + 06681E652D1FA19A82960F0000D0B6019CA13564A70DE00C6B4E7F680338EF4F + 7DB100EA415801F45C96170B6D80E6CB45E478ABA6D075A4CB470CD054041500 + 00A04DAD2107A32A8B3080F34111D1A0E21322F295D23B6D1D01D0238415408F + 6579719688FCBE889C63D5146B6D1D693C4093960F0000D0A5019C3B6D00E746 + 9B6571AD88BCBBF44E077102E809C20AA087B2BCD08A899789C88BA36A8AD556 + 4DC1004D0000D0E52A8B3080737BB4E654AB2CFE45442EA1CA02E807C20AA07F + EB48CF13913FB075A4C756D6916ACB07D5140000A00F5516FB4654595C2722EF + A4CA02E83EC20AA027B2BCD04199AF1091175835C551369BA2BA8E9490020000 + F465CDE93EABB2D8115559DC6755165F2ABDD3BF0EA083082B807E54533C4644 + FE48444E15916344645DB48E34AEA65004150000A08F5516BB6C6348A8B2B85E + 44FE992A0BA09B082B80FE54539C60D5146136850ED0A49A0200000C65CD69B5 + CA226C0CF9B8885C567AA7A106808E20AC00BA5B4DF1E8A89AE258ABA65819AD + 23A59A02C04C4D763818D7C161BAF725EE6300665265F1B05559FC4444DE557A + A73F07D001841540C76479B1D4AA295E38C1A60F0D29A8A600309DC0E1F0117E + 7EA41F4799338DBF36679A3F9FCA1F4FE53A00F4CB4455169BACCAE25E11F9A0 + 887CA3F44EFF1E002D46580174489617E788C81F8BC819513505B32980FEAA3B + 70A8FE7CB2AF4313FCF9F89F39EABE33670A3FC6E1EAA89F4FE7EF9DCABFF348 + D70AA07F1B43B6DAF04DADACF8AE88BCAFF44E430C002D455801744096173A7F + E22522F2529B4D71B46DFA603605D05D530D17EA0A1CAA3F0F7F1CFF187F1D1C + F1E7E27F7F6CA24022FE79BC4279D49F9B3B85BF36D99F1BF5CF9FE86BD43556 + FFBF4CF4C700BAB13164B7886CB72A8B0744E41E6D0B11912B4BEF7820025A88 + B00268B92C2FD65B35C5B922729C0DD1D4D914545300DD3051E83095AA853A03 + 8723FD3CFE317C1D887E3E2AB098AC6A6254F03077C4CFE74EE1CF87AF79237E + 5EFD71AA5F470A4BE2FF3FA3FEBF567F0EA07D55167BAD2D646BB4E2F4CB22F2 + B1D23B9D7101A045082B8096CAF2424388E78BC86F8AC889B692744D349B826A + 0AA07D26AA7CA8060A713070F008950B75050EE1C7FD5622BDC37EDC157DEDB6 + 3F1FBE7EE9AF95DEE9DBCAEA7D2B083F9F63F7AA05F6F3F9F6F3F916B82EB0AF + 45F6C78B6C5070F8E3C5D19F5B6C3F6A58BBCCFE7C98D333CF7E1EFE38FEF3F3 + A6F8E742C8510D3AE64D12B04C54A511FF58FD398066857B699865A1F7B66DD1 + 8AD35B44E46DA577B7A6BE5000FF8AB00268A12C2F8EB24D1F4FB4219AFAC7AB + EC801E0EE7545300EDA99688C389512143352C38602141F80A7F1C0284C90287 + B8BA61A681C34EFBF38F081CBAC4C29110602CB33077B9CDF259653F5F695F2B + 2CF00D1569212409C1C9445FD51064D4D76481C6646146F5E700EA1387C6FB6D + F8E64E6B0B79C8866F7E52442E61C529D00E8415408B6479A187DB0B45E40F45 + E4241BA2B9D60ED97A18A79A026877B5C4A850220E26F6D9D7DEE8C73D957EEA + 1038EC1C42E0D0B42C2F164721C66A1B54BCC67EBEC6BED646156C0B2A152021 + DCA8FE580D38AA61C6642D2784184073265B717ABF88FC4844DE597AA7010680 + 84082B8076AD24FD2D1179416525695CEA1C1F6E01D45F2D31513011AA1DE296 + 8A51A14408244228B1C702867B6DB89BFE78A7F64D3395BE5DB2BC586ED5196B + AD0DEF28FBF951767F5E19B5AAC45F71B8510D3546B5A28C0A32A6D25602603C + 2B4E43954518BEB9C1EECFEF64F82690166105D002595E9C29227F2222675A50 + B1D60EC24BECD01B971703A8B75A226EE3885B30E260226EE1A886127BA35042 + FBA1EFB650E22EFBF986D23BFDE7A0C3B2BC5862551947DBF0E3632DD438DEAA + 3316455F1385199355654C166228020C6076C2FD3FDCD7F75AC5DA9668F8E625 + 22F289D23BBDA7036818610590BEDFFA4522F24A5B497AAC1D72974525C85453 + 00F5041387A6502DB17F8AD5123B2D8CA8564B68CB068619641C6DF7F43020F9 + 386BEF5B1A0D0D5D3C4965C644D518476A25517C5E00531787D3FBAD2D240CDF + D4B690EB6CF8A6DEDF013488B0024824CB8BB53644F3A2114334E395A41C3A81 + A99B68AEC474065E1EA985E301AB90B8CF42093DC03E44A9308E24CB8B39568D + A1E1F4C9F6E3099510237C55AB32460D041D558571A4819E00A6367C7387B585 + 3C68F7F9F78BC8374AEFF4EF01D000C20A20CD61F571D6F6B19E219AC0D88209 + 99A05AE248032FE361977B2D9008FDCBA175E36EFBB9564BE8DF038CFB73E168 + 0B2D4EB52063BD85D84BA2B5AD716B490832A61B60047CBE00471EBE596D0BB9 + 5C443E507AA7D517006A4658013428CB0B3D581622F2522B0D3E3A6AFB084334 + F590A9384802536BE5A8564C1C690BC744D5123F0B2344E4767D8B567AA793E1 + 8164B2BC5861C1451C609C609F19A3428C6A3B49BC7A75D40C0C45F50530F1F0 + CDB0A929B485E8F0CD9B44E4CDA5775A5907A04684154043B2BC38D6AA291E57 + 69FB608826F048475A135AAD98A8CE9698289408B32542C544982DA17F0DE8CA + EAD5F53690F934FB3AC6DA48E200230E31E2391871054675FE8522BC007EF933 + E740A52DE4019B4DF43EDA42807A115600CD94F75E68F329AA6D1F0CD10426DF + CA3159C5C4A86A89D0C2B1CB0E96B75B3071877DE9260E0E96E8952C2F5659F5 + C599D18FAB4654608400E348D517F1F04EC56713862A1EBE19B6856CB539165A + 89F71511F9108137500FC20AA046595EE8A1F0D7F5A7D144F8D595B60FAA2930 + 44938513A3065F4E36F0B21A4CDC663FD760820F390C3524D7CF9C7344E40C11 + 39CBB6912C8DBE46B59054675F8C9A7BA1F8CCC250DB42466D0BB9DEDA42B4DA + 02C01811560035C9F242E751FC79A5ED63A51D12C381906A0A0CC554C3896A2B + C79EA862220413FA75AF8512FA758BCD98A06202987C0395565C9C6D3F9E6215 + 7E7178B164C4FC8B89DA46082F30F4B6101DC2BCD9E658E8B6907789C87709C9 + 81F121AC00EA79A375BECDA738D9DE66D1F681A10714614BC7C1E8B017871313 + 554CECB403E1CD164CDCA85513A577FAE701CC509617CB2CB438D7028CD3EC73 + 6A591460545B4726AABC20B8C0D0B7853C68217A29229F2CBDD3BF066096082B + 8031CAF2420F722FB38D1FA1EDA3BAED83B60F0CAD7AA25A39115A3AAAC1C4AE + 6880D90D16506838713755134023E18586168FB6F611ADBC586E5FA3C28BEACA + D45155177CD66128DB42748EC5C336C7E24722F2B6D23BFD2C03300B8415C078 + 079CFD7B11B9C8828AB0ED6369B4ED83C31BFA66A255A2A3C2896A3BC74E0B27 + 365ACFAF061337D0F70BA497E58506EDE7D9D7636CD5761C5E54DB464278A19F + 75545DA0EFE2CFBCFD515B48586FAA039DDF547AA7C13B801922AC00C620CB0B + 2DA5FD5F44E4746BFB5867E5B47A90A3ED0343082842F5C4A89913BB2AE1C456 + 0B27F410F7D3D23B1D8A09A0C5B2BCD0B6C6C75BDBC8A32C8C5F1EB58D2C99A4 + 6584E00243680BD96B9F719B6DBDA9CEB1F8B06E0C29BDD3CF4700D3445801CC + 4296177AF87A9688BC46444E8AD6922EB3431B6D1FE87B4011664FC4E144B572 + 42DF36DDA9C184885CA5ED1DA577FABF01D0DD4D57E75978F1380BE957545A46 + 8E5475417081BE089F8BE1B37057B4DE542B052F1791F7B1DE14983EC20A6086 + B2BCD030E25522F282CA5AD2B8ED83A0025D77789280221E8A19CF9C0813D2AF + B580E227A577DACB0BA0BF55174FB4769133ADEA220CEB5C36A2EAA25A71117F + 56F299892E8A3F27C31C0B5D6FFAB0AD37BD4644DE587AF750EA0B05BA84B002 + 98F95AD2FFC50E6627446B4943DB07F329D065A3D68BC6F327C2EC89104EEC88 + 0E653F11911FEAC1ACF44EFF7E000392E5C54ADB88A555178FB521D32B2A2D23 + A3DA45A8B8401F84C19BF17AD34DD11C8B3797DE69900F600A082B8069CAF242 + 27A5FF079B947E7C652D69FCA608E8F29AD178BD68D8DC110714DBADCC758385 + 1357EA804CB67600A86CC8D250FF020B3034E85F190517A16532ACF526B8401F + C495887BAC2532CCB1B8DBE6587C99CF4BE0C8082B80E9CDA778BEB57E9C6CF3 + 29584B8ABEB6798CAAA0D816F5E1FE4044BEC7A473005391E5C51C1BCC7991B5 + 8C1C67C1453CEB6249A5E262D48C0B3E63D1C5F5A63B2B732C2E15910F95DEE9 + E72C8009105600539F4FF16A0B2BC27C8A551654B096145D34519B473C83220E + 28365A05C577ACC583374200662CCB8BB344E4C9567571DC883917A1E2229E71 + 113E6B43F5229FB9E8D21C8B3DF679FAB0051657DB1C0B6D1301300261057004 + 595EE81AD2BFB0FEDB309F62557488622D29BA22DCF00F8DA8A2086D1E3BA380 + 628B885C6701C5774AEFF4EF01803A2A2E9E242217462F0326AAB818B50E55F1 + 198C2ECDB1D86883376F1391D795DEE98F002A082B8023BFF9F98F22729ABDF9 + 5957994F11DEF2006D36D9B0CCD0E6B1DD428ACD3687E2DB227245E99DBEFD01 + 80A6DA2DCF8B2A2E8E9A24B808F32DE2164C5E1CA0ADC26770D8A4B523FABCBD + 4B44DE2122DF2FBDE3C10C8810560013BFE9799A88FC8188ACB7F9143A4893F9 + 14E8EAC0CC831650EC8FAA28C2A0CC2DF69647AB28BE6E0726DA3C002493E5C5 + 3C9B6DF1641BCEB9B6D22A126F1559306215AAE2331A6D7C71102A1A7755066F + 7E4A447CE99DFE75008415C0236579A1079E97DBD7491654ACB683911E8A984F + 812E0DCC8CAB28C254F21DD6E6110E49DF1291AF95DE69492A00B44A96171A4E + 3CC55A451E65C3ADE3E19C4BA2D6CC3098336E13E1F31A6D1CBCB9DF028B78F0 + E6D744E43DB45D023F4758013CF240F44722F2741BA479B4BDC9591A1D8038F8 + A02BAD1EF1468F308B628B8514BAC5E3726DF728BDD3431300B45E9617C75AE5 + E3C5B6427C75145C8C9A6FC13611B451F8ACDE6F9FD1DB6CF0E67D3678F3F50C + DE04082B805FC8F2E2189B4FF1E86890E6CA68FF7B5C5A0AB4B1D5E340656066 + D8E81186653E64C332B58AE2F6C4D70E00B392E58556593CD3D6A1AE8B828B78 + A348A8B6A80EE524B4406AF1677768CDDC6881C52D22F2DAD2BB3B535F249012 + 6105F0F303CFD9D120CDE3AD37361EA4C97C0AB479AB477560E6CE6816855651 + DC69A5A59797DEE95F0780DEC8F242AB299E6A5FE7589B4875BEC5A86A0B665B + A06D8337F5F35B2B2AEEB7C19B6F2DBDFB51EA8B045221ACC0A0D920CDA758EB + C77ADBF8B1C67A60C37C0A820AB4711E455883561D98195A3D1EB652D2AF94DE + FD24F585034013B2BC3859449E659FED61E6D42AFB5C5F5619CA39AFD2DEC967 + 3DDA3078736734534A038B0F89C897197C8D2122ACC0D0278DBF44445E292227 + 47879A65F6F685F91468E33C8A83235A3DC2DAD14D36A44B07665EC6C04C0003 + FF8CD74D22CF1091C7D88B88D595A19C93CDB600520EDEDC692D9C1A58DC2322 + 9F17914F94DEE95F030683B0028394E5851E505E2322CFB78D1F3AAF82419AE8 + C23C8ABDD1568FD0EAB1C95A3DBE6AF32898220E0026CB0BFD9C7F8EB5891C5B + D926B274924D228A7300520EDE8C37855C2122FF4C3B278684B0028393E5851E + 4EFE830DE40A1B3F56DA5B160669A26DF328C25B96BD235A3D7410D7B55A1E2A + 223F28BDE3860E0013C8F262A1555AE850CEB327A9B6A04504291D9E60538806 + 163FB14D217A06007A8FB0028392E58506137F2D22E7461B3FC220CD10547020 + 41EA7914D5D5A361ABC736EB63D5AD1EDF17912F95DEDD96FAC201A06BB2BC38 + C7AA2B2FB44D22A1DA6279A5DA822D2248213E0BECB14ACAB029E42611F9FBD2 + 3BFD39D06B8415188C2C2F4E1791BF1291D32DA858170DD264E307DA34343384 + 143B2DA4085B3DB477F51B227249E99DBE650100CC4296176B2DB478A66D038B + AB2D426811CE09CCB54093E259557B2DB0D0B6CFFBACF553579BDE98FA22813A + 11566010B2BC385F44FEC2367E84D5A4CBA20308070FB421A408F328765915C5 + 567B93A2C3B5BE624333994701006396E5C57C6B11799E889C69E784D5566DB1 + 2C6A11995F79C1C1D901758ACF097BED05C6E668B5E9DB4AEF7E90FA2281BA10 + 566008AB499F2D22BF6741C5B15150C1C60FB469B3C76EABA488E751DCA20185 + 0ED5626519003423CB0BDD1EF22211799CB58B565B44E2B9160CE3449381C5A8 + D5A61FB0D5A63CD4A177082BD0F7B5658588FCFA88D5A46CFC401B428ABD9590 + 420F1FDADE719DB57A5C99FAA20160A8B2BC586FA1C5C5B6356C8D6D0E5B6195 + 1661DE553CD74271AE401DC2E0ED7D5681B9250A2C3E2D229F29BDD3F305D01B + 8415E8A52C2FF4F0F06A3B649C6441C52A3B5C6845051B3F902AA4D81F1D34C2 + 1EF53034F3C722F2C5D2BBEB535F3400E097E65ABCC8E65A1C17B5884C368C53 + 115A60DC0E4767895DD16AD3BBF52587887CA8F44ECF18402F1056A077B2BCD0 + 40E28FADF7F4247B1B12828A30208B0304528414F1FAD1AD36284B430AADA0F0 + A577B7A7BE6800C068595E6828F1421179AE556CAE8B86712EAB545A841611C5 + 9903E314CFBADA6DE789876CBE950EE17E7BE99DFE79A0F3082BD02B595EE881 + E12F6D15D9892272B4F599B29A146D0829B657428AEF89C8E74BEFF4800100E8 + 4E9BE9732DB838355A7D1A8716A1D282D00275AF36DD6DADA47AAEB8D75E80BC + BEF44E5F8C009D465881DEC8F2420F0BFF5944CEB3A0E2283B38E8A181D5A448 + 1552ECAA545268B9E6B745E473A577DA6B0A00E8EE10EF67588BC89995D0425B + 44082DD05460B1C75E883C6C81C53522F20FA5777AEE003A8BB002BD90E5C549 + 1654E861E1040B2AC24121DE8B0E341D52E8002C3D2C6830F12DABA4D0B71F00 + 809EC8F2428770BE5844CE19B14184D0027589CF1F21B0D06D62F789C88D22F2 + B7BC1841971156A0F3B2BC384344FE7F2272BA05156BED7010F6A1B3F1034D0F + CE0C21851E18F490F04D0B29F48D0700A0A7B2BC788288BCC4AA3C4368B12A6A + 0F096713067162DCE791B0656C471458DC2A227F577AA71B4380CE21AC40A765 + 79F16811F94F22724A14542CB3C300AB4951E7A1E0F0142A2934A4F86CE99D1E + 1A00000391E5C5F9165A3C7A4468113693C5A1056715CC467C2E0981C5260B2C + 6EB796909B535F24305D8415E8AC2C2F2E12913FB3A022AC125B660700820A34 + 1152542B29C24C8A6F5948A13F07000C3BB47899889C6B43BFD75A7BC8A8419C + 9C5B301BF119655F1458DC2F227788C81B4AEF749605D0198415E8F240AB3F8C + 828A35515011975602B3156E92A1DDE3401452EC8CDA3D3498F88E88B8D2BB0D + 89AF1900D022595E5C68A145986931516811AA2C082D308EC062A705167A2EB9 + 5344DE5A7AF783D417094C156105BA1854E8AAB0578BC8FA28A8584A50811A84 + 991461DAF65E1B6015B67B8490423FF83FCD0A5200C064B2BC78AA88BCD40682 + C78338E3D0221E0C4E68819908679710586CB6C0422B2CDEA56DAAA5773C04A2 + F5082BD019595EE807772622BF6D41C5B15150B1202AA104C6F96622BC9DD86D + 21C5360B2974A3C74F2CA4B825F50503003AF5E2E53922928BC8A951A5C58A68 + EE5638D7105A60A6E20A8B5D5160A11516EF1191CB092CD0768415E8842C2FF4 + 03BB1091574441C56A820AD4B8E1E380CDA5D81385149B2CA4B8CE420A7A3F01 + 00B339DBFCAA7D9D14555AACB0F34D35B4509C75301DF19CAD38B0D0ED201F10 + 914B092CD0668415E8CA87F96F5858A141C5311654E8346D820AD4B586748F95 + 4E6E8F420A5D01F699D2BBEFA6BE6000403F6479B1D8E6593C5F448EB7D06275 + 145A2CB4F30E9B43308EC0624B14587C4444BE507AA7E71FA075082BD06A595E + E8B0A95759FBC7A8A0820F6D8C737866BC86749BBD8178D83ED0BD885CC61B08 + 00401DB2BC586D15A4CFB00AD27576E6596EE79EB0969DCD21986D60B1350A2C + 3E611BCC082CD03A841568AD2C2FF44DC2BFB5819A275B50A13BCA092A30EEE1 + 99F11AD2EDF6D6E161DB4FFE2511F95CE99DFE3D0000D42ACB0B7D39F34A11B9 + C0CE3EEBECFCA3A1054338318EC062B79D751EB0C0E23322F2A9D23BFDEB406B + 1056A0CD4185AE267D5E25A8D00F69820A8C732E45189E19428A8DF6E1FD0D7D + DB507AA715160000342ACB8BC75BA5C5A3EC1C545D77CA3C0B4C5738FFC41516 + 21B07076EE21B0406B1056A0AD41C51FDBA4EC1054ACB48A8A780739309BB914 + FBA2B9145B6C2E85AE21FDA17D58EB07370000496579F13C9B69718A881C1DAD + 3B8DE759D01A82990416BB2B81C5E744E4A30416680BC20AB44A96178B2A41C5 + D1514505410566EAF088B9143B2B6B486F14914F96DEE93A520000DAF622E715 + 95219C6BA279160B2BE724CE4A986960F1791DBC4960813620AC40DB828A3F15 + 9167562A2A082A30DB6A8A83D6F2118667860D1F3A97E26E1D2CC5F04C0040DB + 6579A141C56F8BC845D13C8BD5516B483CCF42716EC274028B072B81859E9D80 + 64082BD00A1654FC5914546845054105C63D9762476578E6D76CA094FE350000 + 3A21CB8B278AC86F8AC89923E659E8998A55A7986D60A15BD03E4C608194082B + D096A0E2CF6D55174105C6B98A749F5553ECB00FE0303CF34A11F958E9DDBD89 + AF17008019C9F262AEAD76D7AF932AF32C680DC14C028B3D95969052443E4460 + 8154082BD096D68F678D082AF4AD001FAE9869CBC71E6BF9D8160DCFBCD58667 + FE20F5C50200300E595EE8B9E97744E469D13C8BB0EA34AC7B8F579D02D3092C + 74E826332C900461055207157F6241C5FA28A8085B3F082A30DB55A49BADE543 + 2B28BEA8B329F8B00500F45196178FB6D0E251D13C8BB83544CF566C0DC17403 + 8B3BD9128254082B9072AAF5BF9F643D291FA498C9968F3D51CBC7C3F621FB1D + 7B23A02D2000C620CB0B5D99B8D4EED961A85F28393F1C5537ED8DAA9C7695DE + E9F729809A6479A167A79744AD21C7586BC88AA835649E7D29CE5A982CB0D812 + 55587CC6AA53092CD018C20AA40A2AFE48449E671515041518D7968FB08A545B + 3E6EB6B700AC2205665F62AE65E5A78BC8B9227296BDA95D10BDA90D83FCAA07 + DE50F1B4DFAA9EF4D07B9D7D7FDEAFDFAFA577FAFD0B608CB2BCD0AA8A5789C8 + 5344E458FB1E8EB786308013D30D2CB4C2E2D336989CC0028D20AC40A3B2BCD0 + 0FC73F109117444185F655125460BA0334AB5B3EB4E5E3A1A8E5C3F1610ACC78 + 68DF7122729E6D683AD11E704225C5A249828A3923DAB3C2F76BF89EDD63DFB7 + FAB553446E1491EFDB4C9907F8BE05C627CB8B8B6CD5E91995AD21FAFDCC004E + 4C674BC806ABB0F8A48616A577FAD7815A1156A031595EE807E26B44E4572DA8 + 38D6820A866962BAD51421EDDF5969F9D0C1991F2CBDD3CA0A00D390E585DE93 + 9F20222FB6079A1536A06FA9DDA717D9C34D082AE2B7B27346841552092C0E56 + AA2CE216919D510BD737ED7BF9AED23BFDFB00CCBEA255D79C3EDF067086AD21 + CBA33318033871A4C022AEB0F8A8CEB128BDE34112B522AC4023B2BC9867439F + 5E5A092A4245051F9098CE00CD5D3640336CF9B85D443E5E7AF7EDD4170B7430 + 44D6B68E5788C8995626BE32EA6F0F3DEE0BA2079A30A0AF7ADFAEDEC3E3C022 + 0E1BE34A8BFD165AECB5C3F02E0B2DB6D9C1F81B165EDCCD5B3C6076B2BCD0EA + 8A7F6B55537A0E5B6767B1A5D1004EAA2C70A4C0422B2CEE10910F88C897082C + 5027C20A345552FC0AFB3A85A0026318A0B9C55A3EB4E7FD6B369B42FF1A80A9 + BF69BDC0CAC34369F8AA4A254528118FAB28463DC81CE9FE3D2AB488BFB7C3F7 + 77A8B8082D227168A16FF33E2B223F2EBDD33F0760E603385F2622B90DE00C55 + 1621A0A4CA02930516BB2A81C5BBF51C466081BA1056A0A90FC5DF129153A3A0 + 420FC30415986A354518A0B9D5AA29F4C1E57A4DF54BEFB4DF1DC0D42B299E64 + 83F7E237AB2BA2B7AB21A4881F5846B57ACCD4A8F0A21A5C843691105A8455C4 + FAFD7F85885C567AA761258019C8F242DB417E5F44CE8F0670AEAAAC39A5CA02 + 1305169B2DB0D0CAD67F2EBDD32A3860EC082B507750A1F3295E6D1515C75989 + 7148EE092A30956A8ADDD1834A18A0E96D80263730608AB2BC78B46D623AD11E + 4CD6449B9842254568F388EFCF75DFA747CDB788B78884D042E75A6CB37B81CE + A9F9B10D79BBBBE6EB037A2BCB8B1789C8CBA3A1E754596022E11E1DDA71F55E + 7CBF5558BCB5F4EE7BA92F10FD435881DA6479F15CDBFC71AA0515FA01485081 + A9565384C17BF1004D5D43FADED2BBFB525F2CD015595E1C636F501F670F23EB + 2CA48887EB55DFA2A6BA3F4F3498338416A1156C5B14605EA9D3E9A9B4006626 + CB0B0D2F7F4F442EB2F31A551698483CE87C9755BBDD6F15166F605D3CC68DB0 + 02B5C8F242F77AFFA90515C75B50A125C6041538523545586D180FD0D455599F + 29BDFB52EA0B053A36D8F879B605206C00586D2145189C19CFA39096DD9BE355 + C587A3A19C71A5C596A835EC2B369D9E9916C00C6479F1029B2FB63E9A6513DF + 2FC270DD36DD279036B0D869F7E0FB2CB0F8FBD2BB1B525F20FA83B0026397E5 + 85F63FFE471139AD1254E8071D41058E349B223C803C6CFD90BAC2F03DA577FA + 6108600AB2BCD0B7A37F619B3E8E8BAA299645DB3DE281996D579D6D11871671 + 9B98DE33DE2F22DF657B0830E32A8B3FB001BCC74F5265211DB977A0DEC0625F + 25B0B85544FE47E99DB68600B3465881B1CAF2E21C11F9CF16549C6841C5B2A8 + EF910F361C693645784BAAD5149F28BDD36D1F00A628CB8BA75ADBC78936386F + 4DF47634EE41970EDE9347851671CBD8260B2C74F0EEDB4AEFF4E7006636CBE2 + D745E4E4E83EB2226A1DA3CA02D5C062A3CD15BB4544FE86D63C8C036105C626 + CB0B1DA2F95F44E4743B24EB9B3C820ACCA49AE27B564DA17F0EC0D4D791EA00 + CDA78BC80951DBC7D21EF69D1F9EA07D6C8705166118EF07757B08C37881E9CB + F2E204BBA73CAE32CB2254CBB2D50D21B00867B987EDDE7B8305161A60003346 + 5881B1C8F24253F7FF5B44CEB4BDDDA1CF31EE710426ABA6D0D91477524D01CC + B874FB7FB37B7028DD0E9B3E420B5E1F1F2AE2D022AC3CDD190DE6D5377B3FB2 + 49F51A640098FE6637ADB0C8EC7C173686C4037AFB12826266E2D07887DD7B75 + 4BD3D5D612C21C21CC186105662DCB0BFDD0FAAF22729E7D90ADB30F317D9347 + 5001156E34A16C3B7EA078289A4DF1AED23BED3D073045595E9C21227F6D43F1 + 8EB7B038946BF7A99A622641E846BBBF685BD93FD0470DCC4C96173AFFE60F45 + E451D616520D4459713A6C87A20A8BED76B6D3C0E28722F277A5777A4F06A68D + B002B392E585B679FC1F2272BEF5351E6587E4F8830BC316DE7CC60F113B2AD5 + 14FF527A7769EA0B05BA26CB8B8B45E48FA3A0624D252C1ED2C3C3A8F5C77AAF + D91CCDC1F9E7D23B6D3303304D595E68F8F96ADB3274A2B59A85D964A1D54CEF + 3B32A0FB0E1E79D60B1BDD1EB4C0E2EB22F2E6D23B7D51054C0B6105662CCB0B + FD60FA5F45E42976503EDA828AF8908C618B1F1CF64543F04279F655F6F0A00F + 1200A621CB8B178AC8BFB1FBEF71D1E6A5B8AA6D880F0C872B6FF9F4BEB3C52A + 2CEED17054441C732C8099C9F2E22211798D0D533F2EAAE68A87F80EF5FE3364 + 21B00861F1B6E8A5D41744E47DA577FAD7802923ACC06CD2F57F27222F8CF671 + AFB4B2633EA450ED238FDF703E680F0C9F1791CFF0C000CCA887FCE5D6471E82 + 8AB05A900785D1155D21B008F79FAF58DB19EB4D8119C8F262959D039F14CDC9 + 8907FA0EADB20B8F0C2C76DB0BAA072CB0F894887C92FB2EA683B002D396E585 + 7EF8FCB61D964FB1DEC555517FF4D00FC943579DD0BFDBD2F58D564D71833D24 + E86A2B00D30F2A7E4B445E5A092AF40181CD4B8F74280A4DC3C1390416DF1691 + 37707006662ECB8B97884861F7A37855F29066E660E2AADA70DFD5F39FCE0CFA + 80885CC28B2A4C1565FA98C94159776FBFC486691E6D1515432F3BC6E8D914DB + A2214B378BC8E744E4FF24A80066EC1516549C6241457893495031F139679ECD + 515A6A0F52C7D983D5D344E42F2D80073003A5775A25F9FFDAD69D3BECA17493 + 5553EEB53341381F6018F47368AE85554BEC39E158BBEFBECAEEBDC094505981 + 69C9F242E753FC99F5291E1F1D94D9B53D6CA3828AB09254FBC46F1791F797DE + E9C60F003390E5C58B6D46C5A9232A2AB8FF4EEF4D5FE8A5D6A19B5F1591B7F1 + A60F98B92C2FF43EF40722F26C1139C15E66ADB6F6340D0B39270E4FDC0EBCCB + CE841A66DD2622AF2DBDBB26F505A2FD082B3065595E9C2B22FFD9828A13A361 + 6E1C94876DD430BBB092543F94AE1491B797DEE99F0330F3AD1F1A149F5E098A + B9FF4E5D7553C8560B53B597FAF3A5771F4C7D8140D76579F13C6B550B6DC23A + 7C93B690E10AF7DDB0B25E038B7B2DB0F87F4AEFF4FE0B4C88B0025392E585B6 + 7CFC571139D3828AB5515ACE417998C2CDE3E0883581615DD5674BEF5CE2EB04 + 3A2DCB8B53EDFE7B7A141487619ADC7F675761B1C54255ADFE7A67E9DDE5A92F + 10E8BA2C2F7495FD9F8AC87916AEAEB356806ACB1AF7AE610895B721B0D86873 + 837486D9FF557AA70106301261058E28CB0B3D18FF8D883CCAE654ACB3945C83 + 0A7AA48769A2F9146188E68DB69254E7540098A12C2F741DE0DF5B507CB2DD7F + 098AC7175884D2E4FB44E4567BD3A76FFC00CCBE2DE4F745E439D616724CB4B5 + 886D21C30E2CB6DB0A7B7DA9F56311F91FA5771A62008F405881496579A18371 + FEFF2272A11D948FB6A0221EA8896119D5F6B1C5DA3EF4C0FF0D7B43A97F0DC0 + 0CD9E0471D5CF7582BA9D6D5801A5E10148FBF3439BCE9D380F53F95DE69000B + 60BC6D213A6B678DDDC7F41C4975D8B0C467C7ED766ED4B9415788C81B4BEFF4 + 7E0CFC1226606342595ECCB71DDA8FB7549C377AC356ADA608B329C2903AADA6 + 7877E9DD5B082A80B1F82DABA838AED2FA415031BE69F50BAC347DB5F5D76B28 + FFD7B6F90AC02C95DE7D452B96EC0DFA1D362766B39D21F6D999421F62797B3A + 9CED4C8BECC5E73A7BBED0E1FDAFCEF242FF1AF04B082B30D91B3D5D91F70CEB + 910EAD1F71E91E8617541C88DE446EB643C71DB6B2ECBF97DE5D9AFA42813EC8 + F242DF42FE4AD4EF4DEBDDF8CDB1FF9E0B2C080A6B4D1F6D2BBA018C41E9DD5D + 3677E7CB361FE63EAB66DA6EF3AEF46CC17AD36108F7DD45566173943D67E8E7 + 5D4E508C2A1E383111ED317C99CDA808A5C7B47E0C53DCDFBD37EA350CD39C2F + 1191FFB3F44E430B00B3646F97FECADE38C5F75FAD76E3FE5BCFC179A105426B + 2D207A459617FA730063A01597A5776F12910F5ABBD53D7696088185566C5261 + D17F732A81C54A6B31D7E78DDF1091A7A6BE40B40B61051E21CB8BC789C86BEC + C671B4DD4874E514D39B87A73A393FAC24D5A1483789C87B4BEFDE567AA7870C + 00E3F11BF6A6E9681B481756FE71FF6DEE4D9F0645B4830063567AF77911799D + 885C6B2DA40FD8D942CF18FBAD2D84C062186D78F3EDF36D950D60D536BC3FCA + F24207FA033F43588151EBA6FEC26E18C7DA0D644965373686354433B47D6CB1 + 4385EEC4BE5A44FEAEF44EAB2A008C4996177ACF7D811DDC56DBFD972174CD1D + 9C97446FFA7465ECC5A92F0EE89BD2BBABAD2DE4BBD64A7ABFB596EEB43387BE + 20A1CA62387383F4BEBB2A9A1BF41FB3BCD0963C80B0028F38246BE9F17AEBDB + 5D1DEDC4E6A03CCC419ADAF6B1235AEDA7BDA65F1391FFC25A5260BCEC2DFE7F + B0FBEFDACA9C0A3477700EF32BF4E0FC1A1B360D608C4AEF36DBE0CDB232C762 + 879D3D42850581C5B0061D1F6741F15FD9EA6E0C1C61057E26CB8B45565171A6 + F5EBEA418DA062D86D1FDA43BACD7A4AB5B7F45611F944E9DD6B59EB07D4421F + 8ECFB1819A2B2B732AB807373FBF629DFD9AFC5AEA0B03FAA8F4EE50E9DDBB44 + E47DCCB118ACF8BEBB2C9A1BA4AD20FF21CB0BFDF31830C20A84CD1FAF129127 + DA0D426F14AC281D6E50B13F9A4F11D6925E2F226F2ABDFB44EA8B047A5C55F1 + 1751FB8786C5DC83D3F651877690E75BA00FA006D652FA8FD11C8B07A33916B4 + 840CE7DE1B07163A37E84211F96D7B4EC140F18B0FF5425B1974A20D168B4B8F + F93D32BCF914BBA2B5A43A9FE28722F237A5773F487DA1408F1D65BDBA5AD5C6 + 9AD2F6BCE55B6D01D2CB535F18D067A5771A54FC8D885C69678F0D362B2BCCB1 + 386867150C63D0F13A7B2EF9559BE38481E24174E0B2BC385F447E67C48A5256 + E40DC391E6535C2A22FF77E99D0ED604509F3FB67BF0CA68A826ED1F69CCB1CF + C07068D6B77CCF61760550AFD23B9D59F1DF44E4B209066F86C0822A8BFE9953 + B9F7C62B4D5F95E5C5E3535F20D220AC18B02C2F34B1FC737B9BA76F8E589137 + ECF914DB2BF3293E527AF756D69202F5CAF242C38933EC2D3E2D78ED1BFAB6CA + 82A4A7A7BE30A0EFF4CC517AF71611F9B888DC2622F7DAE04D3DA33078733881 + 4575A5A9CEAFD0E00203435831503661F73FB1A274B0E2A062B70DD2D41ED1BB + 45E4069B4FE1525F2430102FB5B7F7A1AA82FB70BB4A92975B7BCEAFD33B0D34 + A3F4EE5322F27611B971C4E04DE6580C679574D810A29B0AFFD72C2FF4731203 + C287EE005929AB961C9F3D62F3073DD2FD17DA3EF6DB7C0A1D62F5800DB5FAB1 + 966096DE69CF28809AD9C3EFB32A4335B90FB7ABBA420FCC2B2D50D22F000D28 + BDFBA688FC3D8337071B1687EAB63516589C25227FC686906121AC18E6C4791D + 14F6649BB4CBE68F610ED2DC6F3DA09BAD27547B43AFB0F914FAC7009A719405 + 155AED465545BBCCB503F362ABAED05FA7DF487D51C09094DEDDA267131BF67D + 97BD5C098105AB4D87B521445FB05E2422AFA4CA6D38F8851E9E8B45A4B009BB + EBEC00A665AE6CFE18F620CDCFEADAB0D23B2DAF04D09CDFAACCAAA0AAA25DE2 + EA0A0D941ECB21196856E9DD661BBC7979B42964B3558786C19B0416FD0D8C17 + DAFDF7287BD19A8BC833525F1C9AC164EB01C9F2E21411F9773659F7682B6BD5 + 37461C8E8711541CB0A02254546CB08A8A8F95DEE9D60F000DB287DE73ED10B6 + D81E8A79106EDF9BBD30BB62997D6EAEB4958A001A62C3BE5F97E585BE687991 + 9D690E565AE842551A67DAFE6E67D25F77FDBDF07B595EDC5F7A7753EA0B44BD + 38140D840DA4F9CB09367F5072DCFFD68FFDD1C68F87A2419AAF27A800925969 + F7E2A5D1CA68EEC7EDEE9DD65FB317A4BE2860A84AEFDEA7DBCA6C538856876E + B26A513685F47F43C892CA8690BFCCF242ABC4D1638415C31AA879960DA88907 + 6A7230EEAF38A8D85D19A4799588FC3FA577D7A4BE4860C09E6F6F8AB81F77A3 + 152454573CCDE63F0148A0F4EE7322F20E11B9D93685C4AB4DF5CD3B8145FF37 + 84E826C35345E42FB2BCD07B337A8AB0A2E7EC40F5529B55C1E68FE106155BAC + ED437B3DBFC3204DA015F7E6A7DBC3AF1EB4680169F75BBDD0371D6657E81F03 + 48BB29E4752272BD558B3E6C6BD8C36A53028B7E57B985819B8F179157314BA8 + BFF885EDBF2788C8AFD9409AEA404D828A7E0A1B3FF655E6536850719988FC6D + E99D0EA50290CEBC6803483C5893FB72BBD7982EB680494B910124547A779D88 + FC0F11B9DAAA461F8A020B3685F44F1C1C2FB3E71A0D2C5E2822CF4E7D71A807 + 61458F6579A12D1F7F120DD40C43DC082AFABF9A34041561E387F6767EAAF4EE + 6DA577FAF700482B6C0089076B725FEE4658A16FF52E4C7D51007E16586895E8 + DF88C89516583C18AD36D50A0B028B7E0FDC3CDA361CFE6E961767A7BE388C1F + 61454F6579A16FEBFE4244D6470335F5CF31C06D18AB49B75B0FA70615B78AC8 + FB4AEF3E9EFA2201FCC2C595B08210B93B2BF4F4B3F429A92F08C0CF95DEEDB0 + 0A8B6F5960F18005165A454A85457F076E2EB6A1C761E0A6CEAFD07677F40861 + 450F59DFD6AB45E4D1368086819AC35A4DBAC3820A1D3A75A388BCA5F44EDB3F + 00B4C75346B480A0FD732BC21BBD6318B209B447E99D5694FE83887CD9DA5E37 + D8BCAE1058844D21E8EFC0CDD345E4CFB2BCD0CF55F40461453F69DFD673AD8F + 6B9DBDBD8BF74FA37FAD1F07AC47735BB49A547B39FFBEF44E4B2301B42B505E + 170DD6645E45B70EC70BA3D94F005A42DB5C4BEFDE2A229FAB0416DA164B60D1 + EF819BFA6256DBDF9F2822AF244CEE0FC28A9EC9F2E274ABAAD0FEADA318A839 + B8A0E2412B81BCDA56936A0B0880F67DF62EB6875E5AF3BA793826AC005AAAF4 + EE0322A2ADAFB78BC8FD36685C030BADBE20B0E88F78E0E6727B09A00B053211 + 7972EA8BC3781056F4489617CB6D4EC549D6BFB5B2325093C3703F838ADDD69B + F9A05554FC5044FE5BE99D565800689F4523AA2AD08DCA8A10562CB69702005A + A8F4EED33AAFCB068C87C062571458306CBC9F03378FB27BF31F6679A1CF43E8 + 38C28A9EC8F2420F50BF2F226758DF160335FB1F54EC8F828A07ACE4F11B22F2 + DF6DD81480763ABD3258937B74372B2BCE4C7D41002666F3BADE2122B7D8C0F1 + 8D5661B1370A2CA8B2E8CFC0CD25F6FC130FDCD41611741861457F3C5F449E6E + 732AD6DA9C0ADEDAF54FD8F811828A2D5150A143A55E5B7AA77F0D407B3D2A6A + 03E11EDDBD219B21AC382BF54501985CE99D6E0879DB88C0226E0921B0E8E7C0 + CD7344E435F642171D4558D103595EE8DB9DDFB63E2DEDD7D276100EC1FD0E2A + 765949E3060B2A3E5F7AF7361D2E95FA22014C29ACD07B34C335BB3D6493CA0A + A0036CD0F81B44E46611B9D7020BAD4025B0E8E7FC8A65F6E2F6785B3AF09CD4 + 17879923ACE8C79C8A3FB73915475BBF160335871354E8F0A84F95DEBD3FF505 + 0238329B507E5C1428D302D22D616EC5CFDEE031711EE886D2BB9FDA6AD31B6C + B5FBC322B23D6A0921B0E84F60A1CF41CB6D7E85BEC8FD37F662171D4458D1FD + F577AFB13915DA9FC59C8A7E0715FBAC7471B30D8BD2A0E2A3A5779F487D8100 + A66C4E5451415545B7CCA90416BC14003AA4F44E5B41FEA705167185058145FF + 028BC5B668E0187BA1FBE7595EE80B5D740C6145B73D4B449E696FE99853D14F + 87A2A062571454E874EBF796DE7D3EF5050298D1412A04CADCABBB25FC9A8596 + 107EFD800E29BDD3AD69FF4344AEA3C26210F32BC2C04D7DB1FB7BCCAFE81EC2 + 8A8ECAF262BD88FC6E34A742830AE654F42FA8381455546CB2E150FA66E09F4B + EFBE92FA0201CCF820C5836EB71156001D557AA783C9FF5F11B9B61258EC21B0 + E8857818723CBFE2E9B690001D4258D141595E2CB139152746732AB4DC89A0A2 + 7F41C5DE4A5071AB88BCDDA65B03E81E2A2BBA8DCA0AA0074AEF1EB20A8B6B2C + B078280A2C0E1058F46AE0E6727BB1AB2F787F3BCB0B363975086145C7D8302F + DDFC71B6ADE5614E45BF1C8E5A3F4250B1D1820A9D62FDE6D2BBEFA7BE480033 + A63BDF19ACD99FEA187D7307A0834AEF365985C5D5235A42082CFA35707385BD + E0657E45C7105674CF4556C2A4E54C6BA2F60F0EBEDD7778C430CD1054DCA46B + B74AEF7E92FA2201CCCA1A0B97A9AEE87E58A1BF861C78810E2BBDDB62151657 + 31C36230F32B4E677E4577105674489617BA82E70FA339155AD6C49C8A7E0615 + 3B2A41C5EB4BEF741814806E5B3D22AC40F75A40C2FA52C20AA0E34AEFB65B85 + 4535B06086453FE757E86282A789C873525F1C8E8CB0A223B2BCD043D11F8BC8 + C956C6B4D2E654E89FE7CD5CFF828A4D5150F1DAD2BB1B535F2480B1581B6D6D + 22ACE8760BC87CFB2C06D071A5777AF6FADB4A4B086B4DFB37BF625934BFE255 + 595E9C9AFAE23039C28AEE7891883CC1E654ACB6BE673DF072D8ED675071AF05 + 15FF687BC101F4AFB2827B77F7C49515F3ECD71340BF2A2CAEB173182D21FD11 + EEDB8B2D648EE757E833155A8AB0A203B2BCD0DDC0AFB439156B2D1524A8E887 + 89820AADA4F8FBD2BBDB525F2080B1D29E59DA40BA2DAEACD0764C00FD0A2CFE + 36DA124260D1EFF915BA19E4B7B2BCE099B8A5F88569394BFBFED4D6941E65FD + B18BA2F60F74D7A149820AADA8B823F5050218BB5523820AEEE5DD11AF2D9D67 + 875E003D527AB7D5028B9FDAB94C6788D112D27DE1DE1DE657ACB1F9152F1091 + 27A5BE388C4658D1FE35A5BF2122675AFAA7875CE654F427A838146DFD886754 + 105400FDA56FE2D904D29FB9157AE005D0CF2D211A585C5B092CF6458105BA3D + BF627934BFE20FB2BCD0672DB40C6145BB9D6F699FA67ECCA9184650A1C33409 + 2A80FE5A1E3DE8721FEF96B81226FC1A525901F454E9DD6611F93B11B9DE028B + 4D95C042CF72E896F09260FE88F9157F9CE5853E67A145082B5A2ACB0BADA2F8 + 23D694F6CEE109828A9B6D3D29332A807E5B51A9AAE07EDEEDC082B002E8B1D2 + 3B9D59F1F7D6A27B9F9DDB76DA392EBC7C4277DB4196DA0BE163ED25F18B535F + 1C7E1961450BD99097DF1591F596F6E9E196F68F7E0DD30C41C5FD22A2DB3EDE + 547AA78105807ED3D099AA8AFECCADD01952007AACF44ECF6AAFB5174B21B0D8 + 150516B484743FB0586B95ECBF96E5850EDD444B1056B4D35345E4E9AC29ED65 + 50B1DF3EE0B4B47083886825C55B4AEFB4C410C0B0DECC733FEFA6B82A86CA0A + 60004AEFEE14913788C8ADF6A2290E2C9861D14DA11D6491BD183ECA161AFC09 + EB4CDB83B0A265B2BCD04A8A7F5B5953CA9BB8FE06156F2FBDD3F55800863134 + 9990A21FF8B50406A6F44E678BBDD9028B0D769EDB65E73B028BEECFAF08EB4C + CFB075A6DCDF5B80B0A245B2BCD06F963F8CD694AEB4B48F3915DD9F51714044 + 768BC816FB80BB5D44DE597A7765EA0B0400CC0861053030A577BACEF4EDF6C2 + 69839DEB76D9398F9690EEA9B6838475A6CF17910B535F1C082BDAE65922F284 + 684DA99697D2FED1FDA022545484A0424B09DF577AF79DD417080098B1F0460E + C08094DEFD5044DE2322BABDED0111D91A55581058747B9DE9B2CA3A53AD7247 + 4284152D91E585A678BF5369FF20A8E84750B1DB3EC81EB0A0E223A57797A7BE + 4000C0AC2B2A5873070C50E9DD3745E44376AE0B81859EF7A8B0E8CF3AD39345 + E4F7B2BCD02003891056B4A7FDE30FA2F60F1DF242FB473F5A3FF688C8361179 + 5044EE16917F29BDFB62EA0B0400CCEA1E1F1E4478200106AAF4EE5211F9949D + EF1EB4F31E8145F7DB419644EB4C2F169167A4BEB82123AC688767DB6EDFD0FE + 11D6945255D1DD43ECA8A0E273A5779F4E7D810092E3BEDE0F87ED3E0F60A04A + EF3E23223E0A2CB6DB7D210CDC24B0E85E6011DA41D65AC5FBEF6679A13F2201 + C28AC4EC37BFB67F1C67435D5853DA8FA062AF7D603D2422F788C865A5771F4E + 7D81000000189FD2BB0F8AC8D7ECBCF7909DFFF41C4860D1DDF915F13A539D5F + F18756098F86F11FBD1DED1FFA4D40FB47B7850FA38323820AED6B7C67EA0B04 + 008CFD9ECF430800F54FF6367EBE9DE3C34B47CEF5DDACAE986FED20619DE9E3 + 45E457349B4A7D8143436545FAED1F8FB7212EB47F745B1C54EC10918D2272AF + 88E86AD23796DE71A005807E88E755E80600000367E7BC378AC85522729F886C + 12919D22B28FF915BD6807D10AF8576679714AEA8B1B1AC28A44B2BCD0948EF6 + 8F7E0DD4DC671F4C1BED83EA1A11796DE99D86180080FEA0B202C02F29BDD373 + E03F88C8F522727F25B0082D21E8DE3AD3E5513BC81F6579A17F0E0D21AC48C0 + 56E0FCAE0D6DD15DBEB47F74BFA2629FBD61DB641F50FA41F50FA5773A151A00 + 621C58BB8FB002C02394DEE960F5D78BC82D22B24144B6D8F95057D95361D1CD + 75A6A11D442BE1CF139117A7BEB82121AC48E329227251B4FD43BF0968FFE86E + 45C57EFB20DA6C1F4CFA01F5BAD23BFD6300407FDB4034A806805F28BDD37965 + 6F1391DBED5CB8D5569A125874779DE952AB84D78AF8976779715AEA8B1B0AC2 + 8A866579B1C6AA2A42FB87F642D1FED1EDA062B77D103D601F4C6FB30F2A0040 + 7F838AB0FD09007E49E9DD4F45E4BD2272979D0FB7DA4A53BD67105874773BC8 + 3AAB8CD77610FD73A819614583B2BCD0FFDEAFAA6CFFD0BE27DA3FBA19541CB0 + 0F9E1054DCA91F4CF6010500E87750A15FB4FA0118A9F44EB7C17D325A69BACD + CE8DAC34ED5E3BC83C5B84B0D22AE31FA58F76A92F6E08082B9AF50411796AA5 + FD83AA8AEEAE28DD631F3C6145E9A7EC830900309CD01A00462ABDFB9C885C62 + E7C4876DB5BD6E8E63E066F7DB415E96E5C5E9A92FAEEF082B1A92E585B67BBC + C64A877405CE32ABAA20A8E8EE8AD2EDF6C1A31F409796DE7D36F5C501006A17 + 5756E86701004CE67D22F25D5B69BFD156DC135874B71D6479D40EF2FB6C07A9 + 176145730A11D1DDBC6CFFE84750B1C33E70EEB50FA0F7A4BE380040A341C521 + ABB003800995DEE9FDE28D22F2D368A569D8104260D1DD7610DD0E72AE88FC4A + EA8BEB33C28A06647971A6FD46D6F68FD5B47F743AA8D85F5951AA1F3C6FB40F + 2200C030306013C09495DEE9E6A07F14919B6D43886E8C63A5693FDA417E2DCB + 8B93535F5C5F1156D42CCB0BFD0DFD7B13B47FA0DB2B4AF503E71FED03080030 + 0C7165056D2000A6A4F44E5F74BDC936C73DC84AD34E0AD5150BA3769013AC1D + 647EEA8BEB231E98EBF73C9B187B94950C2D8EDA3FA8AAE8F68AD237D9070F00 + 6058680301306DA577B788C8FB6DA5A906166C08E996F0FC36BFD20EF2581179 + 6EEA8BEB23C28A1A657971AC88BC326AFFD09221DA3FBA59E61B367FE807CBDD + FA41631F38008061565584F640009832DB1CF7399B7BA683DA19B8D9FD76107D + E6FBCD2C2FB42D0463445851932C2FF4BFED6F5BFBC73A2B15D29221866A7647 + 082AE2CD1FFAC1E258510A60BA986DD32B21B0A00D10C0B495DE7D4244BE2122 + F7451B42F47E4260D1DDED20DA0EF26FEC191063426F4D7D1E2F22175B69D04A + 1BAAA9FFBD69FFE886F0C64C3F3876DA404DFD40F97AE9DDA7525F1C002019B6 + 810018877FB2E78485F6963E6E13E7E56637AA2BE6DB33DE2AFBB5BC48449E64 + 9B023106243F35C8F2427B985E6325416B6CA826ED1FDDDFFC719588BC3DF5C5 + 01005AB3BE946D200066A4F44ECF996F8836846CB1F9687A5F61E066B7DA4196 + 45ED20BF9BE5C58AD417D7178415F578B1889C6243355758891009693784B765 + 07EC03638B0DD4D40F92D797DE71300580E13A3C62F83200CC48E9DD467B1176 + 476543889E3719B8D97EF1769015F6EC779288BC22CB0B9EFBC680B062CCB2BC + D0DFA02FB5A19AABA2F60FAA2ADA2F7E5316367F3C681F206F2FBDD395A50080 + 618BDB4098590160564AEFAE13918F8AC83D361F6DBBCD4B0B8105BA515DB1D8 + 9EFD8EB1CD2067A7BEB83E20AC18231BA8F22A11D149B06BAD24280CD5443707 + 6AEA07C7C7EC830400305C715545F8A2B202C0AC95DE7D59442EB341EE0CDCEC + 9EB9F6CCB7CC9E018FB37610E643CE1261C5785D20224FB012A09596B0C5C372 + D08D819A3BEC83423F302E2DBDD30F0F0018070E9DFD102A2B585D0A605CDE27 + 223FB2F9159B6D6E9A06A20416ED169EF3E65BEB7F68073947449E95FAE2BA8E + B0624CB2BCD0768F5747433575EF2E4335BB395073B37D50FCC83E380000A856 + 55E8176D2000C6A2F44E03D0378AC84D362F8D819BDD0B2C16D833E06A6B07F9 + CD2C2FF4E79821C28AF1799188ACB73DBBBA6F97A19ADD1EA8A91F146F2CBDE3 + 83010050C5E03B0063577AB73D1AB8F990886CB315C9A1BA82FB4EFBE7578476 + 107D263C81619BB343583106595E1C67433575BF2E4335BB23DCF40FDA07C136 + FB60080335F503030080517870003076A5773788C827AD1DF9616B4FD6796AB4 + 837423AC986FCF822BEDD9505B41CE4C7D715D4558319EA19ABF65ED1F0CD5EC + 961054ECB50F8287ED83E153F6410100C06421050336018C5DE9DD2522F23511 + B95F443689C84E6B3BA31DA43BDB4196DA68007D467C5596173C1BCE0061C5EC + 3D46449E64C9990E5461A86637C46BE776DA404DFD40F85AE9DD17535F1C00A0 + F578600050A7778BC8B536472DCCAFD08094C0A2DDC2B0CDC5361A40876D9E27 + 2217A7BEB02E22AC98852C2F1646433575780A4335BB1554ECB71BFF669B53F1 + 53117957EA8B0300B45E3C641300C6AEF44ECFA96FB1F6E4074564ABB52DEB9C + 35EE3FDDD80EB2D44604E8B0CDDFC9F242FF18D34058313BCF1491D36D808A56 + 553054B3FDC2CDFD80DDF0B7DA07C0EDFA81507AA77F1E008051AA0F08B48100 + A84DE9DD7D22F24111B9DBDA95759E1AF32BDA6F8E3D132EB4EA0A1D15709288 + BC30F585750D61C50C6579A129D96F54866A5255D1AD3915DBEDC67F8F887CA0 + F44EDB4000003812DE6A026844E9DD3745E45211D1E082F915DD1CB6B9CA9E19 + 5F92E585FE882922AC98B99788C8F196942DB7E48CFF9EDD9A53B1C96EFC9796 + DE7D3BF5C501000000237C48447E62F32BB47D7917F32B3A535D511DB6F9B2D4 + 17D6253C5CCF409617EB45E405363065A50D5061556977E654ECB241451BECC6 + AF1F0000000040EB94DE1DB2F915B75BFBF236E657746ED8E60A7B767C669617 + A7A6BEB0AE20AC98D9AAD2DFB0646C8DAD2AA5FDA35B732AB645732ADE6A1F00 + 000000402B95DE6945F0FB44E45EE657747695E96A1BB6F9EBF64C8923E03FD2 + F43D56442EB0642C0CD5D4C48CA0A27B732ADE577AA72B4B01000080562BBDFB + BE887C494474CE1AF32BBA555DB1C89E1DD7D9B3E4B9A92FAC0B082BA621CB0B + 4DC55E6589D8AA6855695851836ECDA9D01B3E000000D0151F1691AB45E4016B + 6BDECDFC8A560BCF890B6CD8A65657E890CDDFCCF242675A60128415D3F3545B + 551A0FD564556937E654ECB61BFA037683674E050000003AC5DA97DF26227788 + C843CCAFE8D4B0CD45F60CA9D515E788C813535F58DB11564C5196175A45F19B + AC2AEDF49C8A87ECC6FE36E654000000A08B4AEF1EB0176F5A2DAC2DCD3BAC8A + 98F915ED9F5DB1385A65FA1B56B98F0910564CDD0B45E4041BAAC9AAD2EECCA9 + D86737F08D7643FF48E99D0ED7040000003AA9F4EE9B22F2159B5FB1D9DA9D69 + 0769B7B9565DB1CC2AF54F139127A5BEA836E3617B0AB2BCD0529D97D8504D4D + C25855DAAD35A59BED46FEB5D2BB2B525F1C0000003006EF17911B6CCBDD566B + 7BD6AA62028BF656578455A62BEDD952AB2B34C0C008841553F3D268556918AA + C9AC8AF6B77FECB61BF78376237F6FEA8B03000000C6A1F44E5FCCFDB388DCC5 + 3AD34E05160BADBA429F2D4F1291A7A7BEB0B622AC38822C2FD68BC8B32DF95A + 1955551054B453082AF65AFB475853FA4EBBA103000000BD507A77AB887C9675 + A69D31AABAE2D7B3BCD07988A820AC984496171A48FC9AAD2A5D1D5555D0FED1 + FEF68FB0A6546FDC9F2DBDBB25F5C501000000E3567AF73911B99275A69DDA0C + 1257571C2F22CF4C7D616D445831B9B344E4225B2FB3C206A25055D18D35A55B + ED86FDA3D23B97FAE2000000801AFD73659D29ED20DD5865BAD29E355F6EDB27 + 1121AC98409617FADFE695B6566675B4AA547F731156B477FBC7DE684DE99D76 + E3060000007AABF44E07CA7F306A07D17668028BF657572CB5EA0A9D8FF8ACD4 + 17D6368415137B8C883CD6D6CA2CB7E48BA19AED5F531AB77F7CACF44E675600 + 000000BD567AF71D11B95C4436D00ED299C062B155F0EBEC8A97515DF1CB082B + 46C8F2425B3D7EB35255C1AAD276B77F1CB035A55BEC06FDCDD23BBD59030000 + 00435A677A8B6DC30BED2007A28D79685758A195FB4BED9953AB2B985D1121AC + 18ED429B57B1D6069F2CB4DF4C68EF9AD23D7643D61BB34E457E4FEA8B030000 + 009A547AA767E2F789C87DB6156F87551F6B1532DA1758CC8FAA2B747605D515 + 11C28A8A2C2F164655152BA359155455B45368FFD861ED1F7A63FE50E99D5659 + 0000000083527A77B5885C66C3E67596C52E6B07617E45BBCCB167CC6A75C5D3 + 525F585B10563CD29345E4641B7412AA2AF8EFD4EEED1F71FBC7E5A577BABA09 + 00000018AA8F88C80D5675AC5BF2F644610581453B3783C4D5158B535F581BF0 + 101EC9F2427F93BCC2069C84AA0A665574A3FD43B77FDC2C221F487D71000000 + 404AA5777A4E7EB788DC2B221BD90ED289CD20CBACBAE2787B813E788415BF4C + 4B6E4E8CAA2A68FF68AFEAF60F6DFF785FE99DFE3900000060D04AEFF445DE17 + ADFA386E07613B48FBAB2B7ECDC6130C1A6185B1529B5F8FAA2A16475515686F + FBC766EBC7FB72E9DD4F535F1C000000D0229F1491EBAD0A59AB916907E94675 + C5092272910C1C0FE2FFEA99F69B229E55A1BF69A8AA6867FBC7DEA8FDE326EB + CB03000000604AEFF425DF7B45E41EDA413A535DB1D2AA2B5E9EE585BE3C1F2C + C28A9F5755E8F4D55FB3DF142BEC3709414537B67FDCAFFBA44BEFB4D2020000 + 0040A4F4EE1611F9D288ED20B483B46F33C8C26833C87A1179BC0C1861C5CF3D + DBD6C4E86F0AAA2ADADDFEA15515BB6DFB87DE70BF4AFB0700000070C47610DD + 0E423B48BB9FCDE7DB388215F622BDC8F262B0CFEC83FD3F1E6479A1E1C44B2B + B32A082ABAB1FD4353E20FA5BE38000000A0CD4AEF0E5A3BC87D569DBCC3AA95 + F5CFA37DD515CBEC45FA9922729E0CD4E0C30A1179465455B1D436801056B44F + 18AAB9336AFFF800ED1F000000C09195DEE99CB7CBAC3A798BB583E8CB40DA41 + DA595DB1D25EA8BF24CB8B413E9B0E3AACB0591545655685FEE618E46F860E6C + FF08ED1F0F8AC815A57757A5BE38000000A0433E66C3E91F1691EDB483B452B5 + BAE2D12272BA0CD0A0C30A11797AA5AA62A1FD3721AC688FC37603DD6B3754BD + B1DE4EFB07000000303DA57707EC1C1DDA41765A3B88BE1C447B5A41E657AA2B + 5E240334D8B022CB8B25BA0E860D209DA8AAD867656A7A43DDA08970E99DFE31 + 000000806928BDBB5A44BE6ED5CA5BAC7A99ED20EDADAE5823224FCAF2E20419 + 98C1861595AA0A3680B47FA8E6561BAAF9BDD2BB6FA7BE38000000A0C33E6CD5 + CA1BAD7A796FD40E82F654572C89AA2B9E2B0333C8B022CB8B452366551054B4 + B3FD639F4D2BD61BE9DD22F2FED417060000007459E99D56537CC2AA96375B15 + 33D515ED31C79E4FE3EA8AE76679A13F0EC620C30A1179B2881C5799554158D1 + CEA19ABBEC06AA538B3F5B7AA73F07000000300BA577DF14911F583B885631EF + B6AA66866DB6A7BA6241A5BAE2993220830B2BB2BC58509955A1834B082ADAE3 + 705455A1ED1FDB6CA8E64F45E48BA92F0E000000E8910F88C8BD95619BB483B4 + ABBA6291882CB7EA8A5FCDF2429F5F0761706185885C24222745B32A34BC6003 + 48BB84F68F9D76E3D469C51F28BDE3A6090000008C49E99DCE84F356C5BC256A + 07A1BAA25DD5154B456495881CADC336535F58530615566479313F9A55B1D252 + AAF943FBEFD081F68F035686B6D5CAD2BE527A775BEA8B030000007AE8F32272 + BD0DB30FC336433B08DA555DB156445E62CFB5BD37B487F4F345E4D4CAAC0AAA + 2ADA23B47FECB51BE5C336A5F8E3A92F0C000000E8A3D23B7D59F82111B9DF66 + C5697533C336DB15562CB0E7577D8E5D2F228F9101184C5891E585FE7F7D5965 + 56055515ED1DAAB9C5CAD13E517AA72D21000000006A507A7783887C63C4B04D + 028B760416F3EDF97585555764595EF4FE85FB901ED4CF139133A359155455B4 + 7BA8A696A15D597AF7EDD417070000000CC04745E46E9B19B7C3AA9D092BDA37 + BB62B53DDB9E263D3788B0C252A71747B32AA8AAE8C6504D2D470300000050B3 + D23B0D283E130DDBD4EA0A866DB6B7BAE2F9D273437958D739158FB3752FF1AC + 0AB473A8A656557CA9F46E43EA8B0300000086A2F4EE3211B9D666C76DB7AA67 + 866DB6A7BA62A17509E873ED53B2BCD0ED20BD359407F6174555154BA2AA0A5A + 40DA355453D3DC8D22A29B3F3E9DFAC20000008001FAB0886CB06AE7B0CA9476 + 90768415F3ED7976853DDF3E5D7AACF761459617C789C8932D7D8A675520BD50 + 52B6DFAA2AC250CD4F96DE69820B000000A041A577378BC815565DA1B3E418B6 + D9AECD200B6D8DA93EDFFE4A9617DA1AD24B4378687FEE04B32AA8AA48EFB0DD + F8F6DA8D506F883F2EBDFB4EEA0B0300000006ECE3366C73A3CD94DB676105DA + 3168738988AC12116D03B9507AAAD761459617FA0BF83C4B9D347D5A64691441 + 45BB5695EEB49DCEBADBF963A92F0C00000018B2D23B9D57F1799B25175699D2 + 0ED29EEA8A45F67CAB8336F32C2F7AF95CDFCBFF5391A75A55C52A4B9F3485A2 + AAA27D4335C3AAD2AF97DEDD99FAE200000000C81745E426ABAED86ED5153A6B + 8EB0A25DD515A78AC8B9D243BD0D2BB2BCD05E9ECCD226AA2ADA1956ECB5AA8A + 8D5666A6E56600000000122BBD3B6C55CF619529C336DB61EE8835A6BA50A277 + 7A1B5688C8134544876B5255D1FEA19A5A55F1B9D23BBD01020000006881D2BB + AB44E4FBD1B04D5D654A75457A736DD0E65211592D22E767797192F44C2FC30A + EBD979095515AD5F55BADDAA2A6E10914B535F180000008047F898CD96D31973 + BBA2619B041669CCB1AF6A75C573A4677A195688C8392272BA55552C8DD69512 + 56B4A3FD639FDDE8B6D80EE78F599919000000801629BDD3F3FA57A3619B5A5D + C12AD376CCAE582822CB6CA1C4B36DC1446FF435AC7891A54B2B2C6D9AD7E3FF + AF5DAEAAD072B2EF95DEFD34F5850100000098D0BF88C83D22B28955A6AD1CB4 + B9D2164B3C597AA4770FF0595E9C28224FB0DE9D659636695881F65455C4AB4A + 3F9AFAC2000000004CACF46EF78855A65457B46B8DE91A7D1CCEF242038C5EE8 + 5D582122CFB45469A55555CC8FFA7A907E55E99E6855E9974BEFB4BA02000000 + 40BBE98CB99BADBA6287554B336CB35D6B4C8F1791C74B4FF42AACC8F24213A5 + E755AA2A9855D10EA1AA6287DDE0EE1291CFA4BE280000000047567AA7E7F94F + 8BC8835175C5FE68DB1FDA515DF1E22C2F7AF1FCDBABB042442E8EAA2A5857DA + BEAA8ADD5155C5E74BEFB4CA02000000400794DEFD4044AEB28D7EDBED6524D5 + 15EDA8AE586A2FED75D9C469D203BD092BB2BCD044E9572D4D5A1ECDAA20A868 + CF50CD1D7663BB45442E4B7D6100000000A6ED1322F2806DF6DB65D515CCAE48 + 67CE8835A6CF971EE84D582122E789C8C95455B44A2809DB6F55155BADAAE293 + AC2A05000000BAA7F4EE5611F96E545DA1D5D25457B4638DE952ABAE784A9617 + DA71D0697D0A2B5E6055152BAC67270CD644FAAA8A7D7623D31BDA55A5773F4C + 7D610000000066EC53B6D94F37FC515DD18EB0627E658DE9D3A4E37A11566479 + A1534FCFB709A89A263158B33DB32AF6DB0D6CAB958BE98D0D000000404795DE + E9B9FEEB95EA0A9D5147589176D0E6425B34A12FF15F94E585BEC4EFAC5E8415 + 22F274EBCD5961BD3ACCAA684F55C51EBB81E98AD2EF97DEE9BA2300000000DD + A69BFDEEB3EA8A9DF69292769076AC315D2922C788C805D2619D0F2BB2BC583C + 625D296145BBAA2A74F8CE06AA2A000000807E28BDDB6E43F3F5A524B32BDAB7 + C674AD2EA0C8F2A2B3CFFC9DBDF088B67F1C6555154BAC57871690F655557CA3 + F44EFBDA00000000F4C3E745E4DEA8BA8255A6ED5963BA4A44CE1091B3A5A33A + 1D566479A1BF202F645D692BAB2AF64555151A527C3AF58501000000189FD2BB + BD22F2057B39B92D9A5DA1CF0368DE5C7B79BFA80F6B4C3B1D5688C8299614B1 + AEB45D6185DEA0F64655155F2DBDD3019B00000000FAE51211B9B332BB82CD20 + E9CCADAC31BD28CB8BE3A483E6F660B0665857AAB32B5857DA8EF68FFD76A3DA + 6C43773E9BFAC2000000008C5FE99D9EFFCBA8BA6277545D4160D18E35A6CF94 + 0EEA6C5891E5852645CFB6B4487F4E5545BB66556CB31BD6A5A5777AC3020000 + 00D04F5F1591DB2BB32B680569C71AD3D5DA0A62CFCF9DD2D9B042449E585957 + CA60CD760415FBA2AA8ABB45C4A7BE3000000000F529BD3B64C33647CDAEA0BA + 22ED1AD355B690E249D231733B3C58F305D1BA521D20C260CD76CCAA88AB2ACA + D23B6D0901000000D06FDF10915BA9AE68ED1AD33CCB0BFD739D31B7C38335CF + 64B066AB6755E8909D2FA7BE3000000000F52BBD3B6CD5151BA9AE686575C5C9 + 22F268E990AE86154FB3AA8AE5D60232AFC3FF5FFAB2AA546F44BBA3AA8A2FD8 + B01D0000000003507AF72D11B989EA8AD60416F32BD5152FB22E854EE8DC037E + 96179A0C3D6BC4604DA473C8AA2A76D98DE9761BB2030000006058E2CD205457 + A4AFAE5868CFCD5A5DF158ABB0E8842E3EE43FCE52A15055C160CD7655556CB4 + AA0A125400000060604AEFBE2D2237535DD1AAEA8AC5D11AD3E748477431AC78 + 6E3458535322066BA675C86E40A1AA4287EA5C9EFAA200000000B4AEBA0269AA + 2B165975853E473F33CB0BADB268BD4E8515595E1C2F22E73258B3755515D50D + 20947801000000C3AEAEB84D44B654AA2B784E481356CCB7E7E7505DF164E980 + 4E851522729188ACB1169045F61F9DA0227D5545D800729BAD2C02000000306C + 5FB416F1ED22B2D75E721256A45D63BACC9EA77F35CB0B7D966EB5CE8415B613 + 565B405659098BB6805055914E5C55B13DDA00C20D08000000C01536783F5457 + E8407EDD16C8F342FA35A627D82CC856EB4C582122678BC8710CD66C550B48BC + 01E436BB210100000018387B897969545DA12F39092BD256572C8ED698FE4ADB + D7987629AC789A0D04092D200CD64CE770655685DE80BE48550500000080C857 + 45E42EABAED0979CCCAE485F5DB1D4AA2BCE1391F5D2629D082BB2BCD0DE9AA7 + 54066B6A5881E61DB64474BF95736DB1F2AEAFA7BE3000000000ED517A77D0AA + 2B3631BBA2356B4C1745D5154F9716EB445821228F9FA0AA82CA8A7461459855 + A155159752550100000060842F8BC8BD22B2D5AA2BF4A527D515E9AA2B16DAA0 + 4D7DBE7E5696175A69D14A5D092B9E6DFF3197D97F5C5A40D20615FBEC46A355 + 15775B791700000000FC92D2BBFDF6BCA0D5153BA8AE68C51AD3C522B242448E + 12910BA4A55A1F56647971AC883CCAFE632EB61610066BA60D2BF64655159759 + 7917000000008CF2251179D0AA2B765B58417545DA35A6CBAD20E0856D1DB4D9 + FAB042449E1055553058B33D1B40B6583997F6A001000000C048A5773B6D73E0 + E6A8BA82CD20E9D798AE1491D3EDAB755A1D56647931D75A40F43FA2F6D2D002 + 927E0348A8AAD032AEAF585917000000004CE68B22F2906D13D4F9775457A431 + B7525DB1C6366FB64EABC30A5BA57272D402A2FD35B480A4AFAAD0F2ADFB45E4 + 92D41706000000A0FD4AEF1E1691EF55AA2B082BD2985B5963FAF4360EDA6C7B + 5871112D20AD1BACB9C3AA2ABE5E7AA78928000000004CC51744E461ABD40ED5 + 15FAAC41609176D0E63ADBC0D92AAD0D2BB2BCD0FF78CFB2169025D1604DA4AF + AAD0E13854550000000098B2D2BBBB44E42AABAED8652F43F55903E9066D2EB3 + 0281E7B56DD0669B1FFECFB6552ADA47430B483BAA2A76DA8DE5DBA5773A6013 + 00000000A6E332ABD4DE1EAD3125B048575DB1C40A04CE119113A545DA1C565C + 6CFD330CD64C5F5571C0560C6DB3A1385ABE0500000000D3527AA79515B7D876 + C15D56C1CDEC8AE6CDB1B0225457ACB1310CADD1CAB022CB0BFD0FF6145A405A + E150A5AAE207A5771B525F1400000080CEFA8A3D5B84EA0AD698A6ABAE586805 + 02FAECFD5C1BC7D00A6D0D001E65C9CE326B010955155456A4A9AAD86355151B + 9955010000006096AE1091FBEC1983EA8AF60CDA3CC6DA415AA1AD6145A8AAD0 + B08216907654556899D635A577B7A6BE2800000000DD557AA795145FB7EA8A9D + F6CC417545FA419BAB44E4A9D212AD0B2B6CBFEB8596ECC48335D1AC5055B1D7 + CAB37408CE97525F14000000805EB8D4E6E16DB3F97861D0268145B3E6DAD885 + 3068F3627B264FAE8D21C079B63A6599253C1A56D002927E5DE92DA5773F4E7D + 6100000000BAAFF44E438AEF468336C31A53C28AE6CCA90CDA5C6ECFE28F9116 + 98DBD22D202BA32D20AC2B4DB7AE34AEAAD0213800000000302E5F8ED698EEB1 + EA0AC28AB483365789C8D3A4055A15566479A1D5144FB4169025510B086145BA + AA8A6D36FC467BCA00000000602C4AEF6E1791EBAC925B5B4118B4992EAC5810 + 0DDA7C5C96175A619154ABC20A1139D7929C305833B480A0F9AA8A785DE9D76D + 080E000000008C5318B4B98335A6AD18B4B9DC5A411E9BFAA2DA16565C642D20 + 5A55410B48DA75A5BBADAAE24111B92CF58501000000E8A56F5B2537D515ED68 + 055962CFE4CF487D51AD092BB2BCD0FF28175892136F0121AC683EAC88AB2ABE + 577AA7370E0000000018ABD2BB43565DA1833659639A36AC981FB5829C93E5C5 + D1292FAA356185889C1DB580C45B40D08CC3F615AA2A74C8CD465B2904000000 + 0075F9AA3D7B54076D1258A4690509833693B682B429ACB8201AACA9C33DA8AA + 685EA8AAD865C9E635A57777A6BE2800000000FD557AA715DD575A2BC82E6B05 + 61665E9AB062818515DA0AF254197A5891E5C57C9B57516D0141734255C55E1B + 6EB3D956090100000040DDBE666B4C19B4992EAC9813B582E8B3F959595E1C93 + EA82DA12089C26226B46B4805059D1EC0690D002A289E61DA5773F4A7D610000 + 0000FAAFF44E5798DE6143FE19B499B6BA6261D40AF2E8A187158FA305A41561 + 455C557179EA8B020000003028573068B335AD204BEC19FD69830D2BB2BCD0FF + 204F8A5A4042588174EB4A1FB2322C000000006832AC7898419BC94CD40AB22E + C5C5B42114385E444E885A4034C9A10524DDBA524D32BF557AA7C10500000000 + 34A2F44E9F4718B4D99E5690653668F3BCA18615E7DA7F8025F61F2484156876 + B0E69E685D29833501000000A47079D40AC2A0CDE6CDB19C6061D40AA29D1083 + 0C2B2E18B10584B0A2D9AA8AFDD1604D5D577A6FEA0B03000000303CA5773754 + 066DEA8B55066D361F56CCB7CE077D567F7496171A5A0C27ACC8F242CB4A1E65 + 9346D902D23C066B02000000689BEF44AD200CDA6CC756107D6E1F5465C51956 + 56A2FF016801495B55A1C9E53DD6230600000000A97C434436D90B555A41DAD1 + 0AA21D11830A2B1E33620B086145B35515F160CD6F94DE711300000000904CE9 + 9D0615D744AD20FA82955690668556107D56D78E88276679B1B0E90B48B9B2F4 + 42FB3F1ECFAB40FD0E4F30589375A500000000DAE05BD60AA22F56690569D69C + 095A41B433A2317313AF2C3D66440B089515CD386809E52EBB095C597AA7D515 + 00000000909AB6A73F602F56F7D88BD6F0D215695A411E2B03092BCEB4169025 + D602C2BC8AB48335A9AA00000000D00AA577FABCF27D6B05D9652F5AF5CF214D + 2B883EBB5F6C1D128DFDCB53799CB5802C8AE655A0B9C19A07A2C19A7794DE5D + 97FAC200000000207285CDD6D35610066DA6A9AC9867CFECDA1171AC889CD0D4 + 05240908B2BC5860614558594A0B489AAA8A5F0CD64C7D5100000000102BBDBB + 5D446EADB4823068B339F1DC8AD00AD2D80AD354D50CEB5959DA9AC19A0F5B62 + 09000000006DF33D9BB1A7AD200CDA4CDF0AF2C426FFC5299CCDCAD2E4833577 + 47833535B40000000080B6F9B6CDD8A315A479A1FB617ED40A726E9617FA636F + C38AF3A37915AC2C4D3B58F3F2D4170500000000A394DE6D12119DAFC7569034 + AA2B4C5734B5C2B4F190C0529833ADE78595A569076BDE597A7743EA0B030000 + 008049E856105A41D20EDA5C10B5823CBA897FF1DC84F32A4258410B48B35515 + FBEC9B7CAB95540100000040DBE7566CB6EA705A41D2CEADD00E898B9A58613A + 37D1BC8A65F67F54FF0F335C334D0B8896537D3DF54501000000C0644AEFB432 + FC27F61CB3C766F0B115A41973466C0539C6D698F62EAC8857966A584150D15C + 0BC8FEA805E4AAD23BADAE0000000080B6BBD29E636805695E082B165858B1BC + 89B9158D8615595E6845C5E9CCAB481656C42D20DF497D510000000030453FB2 + EA70B682B46385E9639BF817363DAF225E594A0B48FDC2A4DC03510BC846FB66 + 0700000080D62BBDDB6BAD20F156105A419A13569886AD20E76779A1CFF3BD09 + 2BCEA8B480305CB319710B887E73FFB0F44EFF1800000000BAE207955610C28A + 74732B568AC8C97D0A2B74C509F32AD20CD6DC1FB580E8345D00000000E8929F + D85690D00AA2D5158415E95698EAF28CEE8715595E68407116F32A92B480842D + 20FA4DFDB0885C93FAC200000000603A4AEFB49AE2AA682B08AD2069E6562CB2 + 2284C7D4FD2F6BCA49957915B480A46901B9B2F44EFF1C0000000074CD0FEDB9 + 469F6F5861DA9C5068108715E76579A185089D0F2B740B08F32AD2B5808495A5 + BAF20700000000BAE8C722B2C55ADCD90A92AE1524AC303DB90F61C5B923C20A + D4ABDA02A25B40AE4D7D51000000003013A577DAFEF1536B0589E75610583417 + 568415A6CB44E4CCBAFE658D0406595EE8BFE73CE65534EAB09544E937EF1EFB + 66BEBAF44EC30B00000000E8AA9F545A41A8AE4837B7E2B175FE8B9A70BC88AC + 88E65584B002F58715F1BC8A1FA5BE280000000018432B886E39A41524DDDC8A + B0C2F45175CDAD682AAC58CFBC8A642D20FBA295A53A3917000000003AABF44E + 6756DC1CAD300D61058145F3732B96D9328DCE86156757C20A828A7A856FD4D0 + 02A2DFC4D7597F170000000074DD55563DBE27DA0A8266E7562CB2B0E2B42E87 + 15D579150CD7AC5F755E05833501000000F4A91564BB55916B3539AD20E9E656 + 9C57D7BFA456595EAC1691E346CCABA0BAA2FE7915FBA279153A84060090169F + 7D00008C41E9DDBD227277656E853E031158D42B3CCBCF8BE6563C3ACB0BFDE3 + B16AA2C2E1C4A80544C30AAA2A9A6B0109F32AEE2DBDBB3FF58501007EF619C8 + DCA6EEE3A50B00B4C3A815A6A85F082B165851C20A5BAA31564D0407A7456145 + 6801E103BE991690BD1656E8373100203D064DF7EB8D1200207D2B888615AC30 + 4D3BB7429FF74FE96258F1A8685E05C3359B6B0189E755105600403B2C8BE637 + F179D8FDC319BF860090D6F522B29915A64954C38AB3C6FD2FD07F786DB2BC98 + 6F9B409857916665A9268CDB44E486D4170500F8993516E087F09ECFC36E0915 + 157A305BCEAF1F62595E84EFE9F87B3BBC188CFF5CF5C7C9DA7AAB5F874AEFD8 + 780018FD7EC8F24217099C3E628529F7E87A3D626E45A7C20A1139D6DE22C5F3 + 2AF84D539FC395B04213C65B4BEF34B400F0AF87C989CCF6FE3427F15F4FF9EF + 6EFAFFDB1CFB700C16457F7E51E5CF877F761C9A873E4BB1CFA6F87FBF24FAF9 + E2E82123FC7CEE88BF277CBEC55584F3A34A8A1536C3E918FB79A8AE4037AB2A + 9658F0B42ECB8B9D95816EBCD1EBA6F89E12EE0F8BEC6BB1FD9A2FB5AF151656 + ADB41FC3D7BC23041233B9871FAE9EF1B2BCD033DE0611B95D44EE10917B4464 + A395C01F28BDD3732030245A45FEDC6885A97E0FF019DB5C4B64985B714C9617 + 6B4AEFB4D2A51361C5C9D1BC0A7A749B9F57B1D34AA380C1C8F242EF374789C8 + 7344E4892386FBD6750FAAF3DE56F77DB34BFFFC510F02D5379675FEB9E9FEBD + E1E17671F490A33F5259D14D73ED81561F4C8F16914F89C816FBBCA5FCB87B46 + 0509E1FB36FC18E6AD859FC75FD5BF5EFD9C19F5FD3D9DEFF9F8F7D22F2A2BEC + F799AE09DC67BFEFF6463FDF93E5C59D22F23D11B95A7F6F96DEE95F03FAEC2A + DB7E18E656840099CFD87A85FB640877F57C7392B5E57422AC388379158D0A1F + 62FB2D59D4C3D335A92F0A68A05262911DDC5E666FAF57D81BED25D1DBF423CD + E8497D7F4AFDEF6FC335CC99C543C6446F338FF4D766FBBF3FD23F3B3CC0CC8F + FA3AF5476656744FF8F50E9515623F5F5D5999876E9A28748C838B89BEE2BFAF + FACF3BD2BF6F22A342AF38B038107DEDAF7C69DFF8D36C6ED98E2C2F74BDE3E7 + 44E4463D1F96DE11A8A1574AEF365A48B7BE723FE6A540FD42681BC28AD3C6F9 + FC39BFC1E19A6C026936AC08F32A6E4B7D51401DB2BC586833717E4B444E1091 + 555692BBCC6E968BA37BCF381F0C877C0F9BD3E26B99338B9FCFF67F7FA49FC7 + 0F3DF1C34D9BFE7B626A42C9EBC2A8CA62457430E621B0BB26FBDE9DA86A6A54 + 75D554FEF9D335518545A8B2083F1E8CC28B9F5559D879501F1E1E2F225B45E4 + BE2C2F3E2A22375371819EB9D62A6A5961DAAC10E287B9157A3697D68715595E + 843210E655A49957A11F4E37D2B7883EC9F262AEBDC5FC0DFB405A637F1C5752 + 2CB21BE6824AFBD990EF3F43F8FF3EDBB798731AF8DF4EE58106ED167EEDC20B + 98F995E187E88789C2CC897E1CF5BFA9D344C337E33691105A84F690DD36CB4C + 5BB4CFD132ED2C2F7E28229FD49F536D819ECCADD811CDADA015A47EA3E6569C + 9DE5C5BC713D83D659597142F4E0104A5ED1DCBC0AFD40BA25F5050163DC2C74 + A688FC81881C27226BAD922284148BA36034DC6FE2ED437C500D4793BFD6FCBE + 1AA6704F391CB597F1A0D73F733A700FA8565C4C547951ADB6D869FDFDDA36F9 + 7411B93FCB8B7FD6819DBCE44287DD68BFAF77594877B0812E02C823E6562CB3 + 251BF78DE31F3EBFC1E19A3C3034D70212866B6A3914D0F590E2421179B50DCD + 5C17851471AB473C97A25A49C17D07401D52BD55078EF47BF0B07D2656838BA5 + 764E5C6995893B6D50ACBE04F8EF22F2609617EFD17E73420B748DB635657971 + 83889C1A8515AC306D2EAC0873B996587745EBC38AB3A20789508A8DE6866B6E + B395564057430A6DF3788DAD7A3C2A9A491142D0706F89E7E1108A0200866ED4 + A0DFC3F699B9207AA058160517EB2CB8F8DF752D6A96176F17911B4AEF181A8B + 2ED12D88CFB417B7FBEDF73AD5FDCDCFADD0251BDF6F7B58718E8515F1BC0A1E + 229A9B57716BE99D96FD015D9B4971BA88FC85BDE939DA0E5121A408F7941080 + 726F01006072F1E76498DC1F1E2CC25AE5E5F65260AD0517FF5544EECAF2E275 + 22F200332DD0B1B915FA2CA4CF41CCAD68AEB222CCAD18EB90CD5AAA1DB2BC58 + 656F42C383052BDAEAA7DF88072CAC605E053A27CB0B1D94F95F44E46F6C0DE9 + 99B682EA383B38C5551571DB07F716000066F660117ACC57D967EDF122728A7D + 06EB0691BF17917F9FE54558D70BB499AE2FDD6C6145DC0A8266E756ACCFF242 + 7F6C6D654575B8260F14F53A3C62B8A60E99015A4F27068BC80B45E41576483A + CAAA299647AB8FE34A0AC5FD040080998B2B2DC257A8B658642F0756D88B027D + 99F0F82C2FDE66F32C78F8432BE9EF4D9B5BA16FF6995BD1AC38AC58624336EF + 1AC73FB40EEB473C64A05E21ACD863E54FB7A5BE20E048B2BCD060E2EF44E4F7 + ED83E5540B3B8F8A2A29E2D914B47C0000303EE173350E2BF4B3375449EBC690 + D3ACBDFB7F1391BFA2CA022D77830D8FDD1BB582A0B98AAD1056E8BDA3B59515 + 674561052D20F58BE7556858714FE99D7E93026D9E4DF1741BA079A20DD15C63 + 6F71E2F6312A29000068B6D2624EB4027C817D2E87819C5AF5785A9617FFB3F4 + 4E4BEE81B6B9CEC28A3D366493B915CD0ED90C732BF405E47766FB0F1D7BC543 + 9617732AC335791BDA4C0BC841FB86FCD970CDD417054C24CB0BBD37FCB588FC + A9059BA7D85C8A357610AAB68F71EF0000A0D937A473A3878EE5D13C8B53AD12 + F2BF657991DBCB07A0354AEFEE11914DF64CA4CF46CCAD68B6B2220CEED5B937 + B356C70D668D958E852178CCAB686EB8E65EFBC664B8265A29CB8B636C58D753 + 6DEBC749235A3E189C090040BB1E3E426B887E8E9F6CAB095F6D6D21FAD781B6 + B58254876C1258D42FB493690E704A96170BC6F10F1CB7132A7DE63C74343F5C + 93B002AD93E5C5B922F2DFED8DCC29F686260CD20C7BB0A9A40000A03DE27916 + 8BAD5D739DB570EA4B87A789C8DF6679A12F1D80B6B8D99E89985BD19CEAEC1B + ADCA3ABA8D332BD6DBCD2C3C7C501ED6CCBC8AFDF60DB9A5F46E43EA8B022AAD + 61CFB0219AEB6D3AF0DAA8E5834A0A0000DA2BBC48888771CE8BFAD3F5EBEFB2 + BCF89BD2BB07525F2C2022D733B7A2156185BE98BC6F36FFD03A82843346CCAB + 403D4249D3A1685E055515685B50918BC8BFB369E2275ADB4718A449F5150000 + DD10066F2E98A02D44E758E84B0920B5BBF505EE88B002CDDC23C2DC0ABD3748 + 6BC20A866BB66213089399D10A763F788588FC76B492542B2A68FB0000A03F6D + 2147D90C2A7D29F15FB2BCD0CF7C2099D23B7D3EBA69C4904D028BFACCA9049A + 8BEC9E206DAAACD00711866BA69957A161059515685350F1EB22F26B16541C1F + B57E30441300807E3C942CAACCB1D08793FF3DCB8B59BF510566E936E656240B + 334358A11557AD0A2B4EB0FE94EAEA41D4A73A5CF38ED4170488C80B45E4E5D1 + 8C8AD5956D1FDC170000E8CFB690E595C0422B2C742D399072234835ACA0B2A2 + B9CAAB9F0599595EE830FDD68415A7585811BF39457DE27915DA02F240E9DDB6 + D4178561CBF2E2021179D588A0826A2B0000FAA51A58ACB597975A55F97FCDF6 + 41059885DB456447656E059A0B31178C6323C8B8C38433AD7F8DB7A7F53B5CD9 + 04B2C7BE298164B2BCD072AF3F23A800006030260B2CFE6B9617FA6C0034AAF4 + 6E9F559C87B082B915CD0FD95C64ADE0E9C30AEB513F8BE19A8D3A5419AE490B + 0892C9F242CB3FFFDA820A2DFDD4B72904150000F4DFA896107D48D197187F99 + E505D5D64835B762B73D2BE93313D515F58B876CCE7A23C8386F1C7A535A19CD + ABA0B2A25E21198CE755305C13496479A1DFF7FF074105000083150FDD8C038B + 278AC88B535F1C06E9160B2B18B2D97C1B48985B716A5BC28A305C73A15D1C55 + 15CD0FD7BC2BF5056178ACAAEAF745E4740B2AD646C334092A000018EE9690A3 + 6CE8E62BB3BCD07302D0A45B19B29944D808A2CF02EB67535935B7A6E19A6113 + 08EA539D57714FE99DFE0834ED7C1179BABD3D5967EB4917D93D80FB000000C3 + 0D2C564681C55F6579A16704A011A5770F8BC8C395219B8415CD6E0A5A62CF07 + 3332CE0709ED4963B8669AE19A9A16325C138DB329DF7F6287907556F6A98713 + EE0100000CFB6125F4ACAF12916344E42411F903ABC8049AACAE60C866F381E5 + FCE81EA08165BAB062C470CD50FACDCDA899E19ADA8B7567EA0BC2B05849D79F + 5A0BD8D1F6F644EF01B4810100306C7160A1ADA16B6C4BD8C522725EEA8BC3A0 + DC65614518B2495051BFB9D1F7FF22FBDE9FF13F681C18AED9ACC3957915BB6D + DA2DD0A4C789C863EC06B4CACABC18A8090000AA2B0C97450337FF2CCB0B0D30 + 8026DC1C6D04616E45F31B4116590576D2B0422F80E19ACD8AC38A9D3AB322F5 + 056138EC90F1C7D1E60F3D843050130000C44239F8E268E0A6566416A92F0C83 + AAACA80ED9447D420E30D7BEF77F3664337558A117C070CDE62B2BC2BC8ABB4B + EFF4E740535E1A0DD4D4C307732A00004055FCD0B2C42A31B575F405595ECCB8 + 341C98AAD2BB1D22B2C19E9918B2D99CB0BE54F38153663AAB666E8DC3357968 + 6966B8A6F66031AF028DC9F242DF8ABCD00E1BA1FD2384947CDF030080AAB81D + 44579C6B50F1FB0CDB44437411014336D30CD9D4EFFBA5F6CCD07C5831C9704D + 34375CF38ED4178441F91D3B64C4ED1F545500008023AD330DED20EB6CD0E6C9 + A92F0E83707725ACA015A4B9F5A5616E858694492A2BF42D2BC335D30CD70C61 + 05C335D1882C2F7446C505B47F000080596C07596DEB4C59658A26DC5619B249 + 6545FD424019AA2BB4223B4958A1437218AE9976B8E6BDA92F0883F19B51FB87 + 1E36A8A6020000D3DD0EB2DC2A344F9FCDA600601A95151A563064334D40A92F + 37F5856792B082E19AE9866B6A39D35DA577FA4D073431ABE27C3B5CE82183AA + 0A00003055E185E6027B76D0CAECA3EC450850F790CD07585FDAA8EA46101DCC + 3F6DE30816CE64B866D2E19ABA8E0768C2AFD8A182A19A000060B6D515CBAC1D + E431595E687B2950A73B470CD94433EB4B17CC743ECDACC20AEB313B9BE19AC9 + 866BEA371CF32A50BB2C2FF440F12C3B54E8CFA9AA000000B3D91210AA2B74F0 + DED3525F187AEF9E687D291B419A31370A278FCDF262FE4CFE01B3717434648F + E19ACD0ED7D46FB65DB68A07A8DB99D6FEA1870AAA2A0000C038AA2BC2B0CD17 + 6579A17F0CD4595911866CB211A4D98D20F32D2F58D57458C170CDE68579150C + D744937E2DAAAA605529000098A9B83C7C89BDF85C33D3017CC0342A2BF64461 + 059515CDAD2C5E60CF0FFA7DDE685871AADD64426505C3359B1DAE7947E91DA9 + 206A95E5C56A1BA4AB87095ABE0000C0B8AB2BF48DEB73535F14FAABF4EE6111 + D9CE90CDA4EB4BA73D9B66B6E1C259D1C30BC3359B092AE2E19A77A4BE280CC2 + 19D6FEC1AC0A0000302E61ADE112DB327631AD20A8D95D1656E8B3142F7C9B5D + 5FAADFDBC73416566479316F82B002F5061607EC9B4C7BAE18AE89263CDFAA2A + F430415505000018673FFB227B21A22F46D80A823ADD6BADF4FA3C452B48B3DF + E73F1BB2D96465C531D19B561E609A1FAEA961059515A85596174BACB2227CAF + 33581300008C43DCCF1E66579C97FAA2D0FBB0225E5F4A7545B3EB4B75DE6563 + 61C58995E19A3CC0341B566C13910DA92F0ABDB7DA4A3343550515540000605C + C283CC229B5DC10A53D4E9EE11EB4B51AF5059A1CF11C7CFE47F3C53A7456105 + 0F30F50A254A07AD054413C1DB4BEFF80643DDE2AA0A2AA80000401DDB0216DA + 73C549595E688B395087FB2B1B4118B2D9EC469025595EE84BD046C28A30AF22 + 0E2B7888A94F082B18AE89263D21DAF8A3DFE76CFC010000756C0B5814B58300 + 63577AA7DB40B6441B419859D1FC46109D4D3365337AF0C8F26281555684B7AD + 5456D4AF3AAF82E19AA85596177A7F78141B7F0000404DC2B9223CC86858B126 + F545A1D7EEA9AC2F45B3732BB4C57CCAE6CE62B86678DBCABC8AE6E755EC22AC + 400396444105DFE70000A00EF1B680C5D6820AD465431456B011A4F98D206B9B + 082B74B8266F5B9B0F2BF65B58F150E9DDA6D41785DE0B3369C2AC0A5A400000 + 405D3DEDA115E4F4D41785DECFAD084336995951BF6A65C551D3F91FCFF4E163 + 4DB40584169066876B6A0BC8ADA92F0A83100792A1AA82EF75000050E7C38CB6 + 9A0375B681C41B41680569AEB242BFBF8F6E22ACD0C118948637E75025ACA005 + 044D586DDFE37C9F0300803AC50F332BB2BCD09F03757860C4FA52AA2B9A9B59 + D14858111E626801A95FF8060A2D201A56DC9CFAA230086BA3A0821610000050 + F703CDBCE8A106183B6BA5DF65CF5661C8266145BDE2562F9D7DD95858111E62 + 082CEA75301AAEB94344EE4C7D4118046DF72294040000750BE78CF050436505 + EA9E5BB12FAAAC407D421019AA2B566679A1E3246A0D2B5655FAD8D1CC70CD3D + 1A5494DEE9CF81BAAD88BECFA9AC0000004D0616409DAD205456A4A9ACF859AB + 5713033619BAD75C5011E6556858C1BC0A34452772533D050000520416409D61 + 05EB4BD3B4792DB0F997F58415595E2CB09586545634A3BA09E496D41784C1D0 + EF75BEBF010040D3387FA089F5A5545634A33A6453BB346AABAC0841056145FD + 42CA77206A03616D299AC22A27000090020F8FA8D383F62238DE0882FA542B2B + 6A0F2BD810D09CD006A2DF4CBB4AEF1E4A7D41188C7D5160C64D1C0000D42D9C + 397861823AE9F314EB4BD3CDADD09112533293B061E9880D015457D47FC3D66F + A62DA92F0883B2372A8DE3260E0000EA129F35F4EC415881DA94DE6DB58AF530 + B382DF6FF5AAAE265E5B6758B18CE19A492A2BF49B89B0024DDA1EDDC0092A00 + 00409DE2A082CD77A8DB062A2B920DD85C577758112A2B6803697623C88ED417 + 8341D1708C29C90000A04E7145457841A75F40DDAD2021ACE0C55CB36D20B586 + 15BA1795CA8AE6CBE10EDA9B6E20455841791C0000A84B1C546C2ABDE3DC81BA + 6DAA84158AC0A299EA8A75595ECCA92BAC58599959817A515981365556701307 + 0000E312BF983B60C3BDEF4C7D5118848D1656B0BE34CDFA529D83597B6505AB + 4BEB552D8923AC4093AA8387B889030080713B1C6DBED3B0E28ED41784C1AC2F + 25AC483764B3B6B06275B4BA3404150416F5A8B6816C4B7D41185C58B1CF7EEF + B1831A0000D4219C73F7DBD983B0024D5556E83997B0A2F93690F93607B3B6B0 + 625E657529EA4F9BF51B49D7EC004D87150C1F02000075BE980B61C55E9B2500 + D46D531456304CBED9C062BE756BD41256ACAAB481A0B93610066CA231A577FA + 7BEE5E526700005093EABC0A7D51B233F545A1FF4AEFB68F687946BDE2CA8AE5 + 53FD1F4C599617736DC026DB40D2AC716266059A76BDDDC8D9430D0000EA1CAE + B9D7CEBABB525F1806E3E1CA0B39CEB8F509B941082B345338A2E956462C6113 + 48D236109266A40A2BE2EA0A000080719E73F59CB15B447E507AC703239A0C2B + AAEB4B519FD09931AF89B0824D20F50B6973489C499A916252F22E7BDBA1BF07 + 499D0100C0B81C8A6655E879E387A92F08839B5B519D59C139B799CA0A1D2D31 + F6B06269B409843690FAFDD22610926624B0BD1256B0150400008C43DC021266 + 553C90FAA230289B1924DF8839233682D45259B1ACB20904CDCDAC60B8261A57 + 7AA78787BBAC3433AC312575060000E3DA02B2CF5E8C6C63F31D12AC2FD5B082 + 41F2CDB781AC9EEAFF603A964795155455D48FB0026DF0AD4A75053D7D000060 + B6AA5515DF2BBDD3332FD0641B08332B9A33A789B0225E5B4A58518FB8672A84 + 156C02412A37D8EFBFB01584E4190000CC4638E3EEB7F3C50E7B39023469CB88 + CA0ACEB8F5A8B6812CCBF2427F1C6B58B1826D208DA2B2026DE9E7DB31A21504 + 000060260EDB0362DC02A243BD8126E9EF3B6656342B84159A292C9ECADF3CDD + B022DE044260D1CC2610FD06626D2952CEADB8DE7E0FC6AD20DCD00100C06C07 + 6BEA0B91DB4AEFA82246A3ECF71C67DB74D515630F2B56450336C3FF96C0A23E + 61F0D0014BFE8054BE66D53DBBA35610000080D9B48084AA8A2FA6BE280CD6D6 + 4A6505814587C38A350CD84C5259415881D46EB7DF83BBA25610020B000030D3 + 1690BD56B5A90F8BB7A6BE280C7A6E85FE7EE46C5BAF901BC461C592BA2A2B18 + AED9EC4A27C20A24557AA70789FBED50B1C77E4F923E030080995655ECB6AACD + 1B4BEF38E72215FDBD4765459ACA8AA5E30E2B74C508332BEA17BE49C2BC0AC2 + 0AB4C1E7EDF72183360100C04C841771FBEC0588BED576A92F0A83560D2B14E7 + DBFACCAD25ACC8F2427B4A1650599164138886150CD8446AD7DBA1220C2322AC + 000000B319ACA91BC7EE4A7D6118B4ED953610CEB6CD5456CC1D7765C592686D + 296145FD0E576EEA3A2B0048A6F46E8BCDAED86E878C3068939B3A0000389270 + AE0DEB4AB5C5F48AD23BADD804DA326013F5AAAD0D44FF610CD74C5359B1ABF4 + 4E030B2035673775ADF4A115040000CC64B0A656556C12912FA7BE280C9EB681 + 5059D19CB8B262C9B8C30AD696365F55A1DF38CCAB405BDC62259BA1BA82419B + 000060BAEB4AF5C5C706117930F58561F0E2B082336D87076C2E8F6656505951 + BF38ACD0074320B9D23B3D607CDB0E19BBECD0417505000098CA60CD5055A12F + 3E3E587AC7F9016D9B59A1F87D59FFEA52FD5A36CEB062456566059AABACD09B + 3AD01697D821638755571056000080A9AE2BD537D90F8BC84DA92F0CB0D666DA + 409A3127FA9A37EEB0E218ABAC88E75660FCE295395456A08D1EB0AFAD76E860 + D0260000984E5545597AA72F3C80D476595811CEB29C67EB555B65C509235697 + 1258345359C1DA52B446E99DFEBEFC50545DC11A530000309DAA8A6FA4BE3040 + 95DEED8F2A85431B089A995B31D699152789C8422A2B1A13820A4DFA18B089B6 + B9C10E1BFA7B93EA0A000070A4AA8A9DF6A2E39BA5775A9D09B4C58E4A6505E7 + D97A84FC60EE58C38A2C2F34A4585719B089FAB00D04AD663BD12FB1B5635457 + 000080AA70963D606FAEB7DA8B8ECFA7BE3060442B08332B9AAFAC583CAECA8A + 5522B2A8326093C0A25E5456A0ED2E17918D76F8D04308D5150000A01A56C4B3 + 2A7E527AA78105D0C6CA0ACEB1CDF8C5FA522B8A987558B166C4704DC28AFA1C + AE84150CD844EB94DE6D1191EF47B32BF6515D010000A22AE130AB2254557C24 + F58501135456D006D2FC4690B996318C25AC605E4533E26F92837693677529DA + EA5F2AB32B345CE3260F00C0B08573ECBE6856C5F5A577BA4D0C689BDD23DA40 + 38CB36B311646C6145751308EABFC11FB0B042D33EA0754AEF1E12919F32BB02 + 00004CB001442B31F5BCF09ED417064C407F9FB2BAB459A1BA622C61C55AABAA + A0B2A2D9E19A1A56EC620F355AEE4323368370B307006098E2AA8A1DF642E3BA + D2BB0DA92F0C98C09ECACC0ACEB01D6B0339AA525911FE45A8473CAF827239B4 + 5AE9DDFDB6CA7493957A32BB02008061FAA5176E5155C57B535F1830093DBFB2 + 0DA47E213F88C30A2D86185B6505C3359BADAAD037D48415E882F7D861648B1D + 4ED80C0200C070AB2AC20610DD1A761555156839066C362F640A630B2BE6552A + 2B50FF26107D43FD60EA0B02A6585D712DB32B000018AC7856455C55F181D417 + 064CA10D84CA8AE6C49515B35B5D9AE585A61DCBA8AC680C9515E8AA775BB846 + 75050000C3AEAAD86EF3ACBE63C3B8812E0CD8E4DCDA7C2BC8AC67562C89820A + AA2AEA17AF2CD5CA0A6EF0E8043B8C7CD74A3EF5904275050000C37AD916AF2A + D517181F4F7D61C00C2A2B38BBD66BAC033697442D205455343BB3629F95D503 + 5DF131AB06DA120DDB24A50600A0BFE2B3EB9EA8AAE20BA5771A5A005DD90612 + 07159C5D9BD90832EBB06271A5B282C0A299CA8A1056E8431FD0097628B9CC0E + 29DBEDE6AFBF97092C0000E8AFB8AA6293BDB8B824F5450153145EAE5159D19C + B16D035952092AD05C65C596D23BFD39D025DE0E29F12A537E1F0300D03FF1B9 + 55FBFEB75A0BF3474BEF74E036D0C5B002CD54558CADB2226E0121B0A857D804 + A25F94CEA1734AEFB65B8FEA437668D1C30BD5150000F47F55A9BEA8D00D61DF + 4E7D61C034704EEDF0EA520D2BA8AC485359415881AEBAC20E2BAC320500A0DF + E7D6FDF662628B0DD57C7BE99D7EEE035D116FB0A30DA4D9B0428B22C6125610 + 54D42B1EE612AA2BB625BE2660464AEFB49CEE2DD1B04D3DC4B0CA140080FE38 + 6C2FD7C2AA52DD0676AB885C9BFAC280199C5B690349B3BE74D23C62D2B20BB3 + 90E19A8D89838A0376E307BAEA4611B94544D688C8721159140DEBE53E020040 + F7CFACFBA3A19A1B44E44DA5773CECA18B34B0A0AAA239E15960D6332B34AC60 + 5E459AC082B0029D658795375B7585B634B1CA140080FE0DD5DC6673AAAE28BD + D3CF7CA08BF4F7336B4B9B75C4CA8AA98615BC094D5359A1C30981CE2ABDD3DE + D5CBA3619BBACA9476100000FAB5AA54AB2A3E91FAA280315656704EADCF9C71 + CEACA85656105A34336053030B563EA10F3E61C336375AB5907E18306C130080 + 6EB77FECB21711FA62E283B60D0CE82AFD3DCD80CD668D25AC20A048B302EA80 + 7D08009D567AA76F5DDE110DDBD4DFD754570000D0DD73EA3E7BA9A62F22EE13 + 91EFA4BE30608C6D206866B8A68C63C066187A4160D15C5545A8ACD03E40A00F + 7E2222B789C86A11595619B6A9B8BF0000D0ADA19A9BED45C4EB4BEFF4410FE8 + B250F54B60D16C60317FB69515D57F20EA15B7811056A0174AEFF4F7F4EBAC1D + 6493BD8D09ED200000A03B55153A7F4A5B3E1E16916B4AEF6E4F7D61C018E859 + 15CD9BF580CDA9061A187F7585EEAD067AA1F44E876C5E62BDADA11D44DFC4D0 + 0E02004077DA3FC250CD07ACCD13E8036656B4D054820852A6661D8E3E10F49B + 06E893CF88C8BDF63666BBBD9D61D8260000DD5B55EA4BEF34B400FA80B368F3 + E68C23ACE0172ECD07C2BED23BFEDBA3574AEFB45AE8F5B6E26CB3BD9DD1B734 + 54570000D05ED5A19AFA39FE85D41705D4306093F368B341C5AC6756C49351F9 + C5AB575C7AA46F9C81DE29BDBB45447E68ED20DBEC2D0DED200000B4BBAA6297 + B571EAE7F73F95DE315B0D7DC219B4C39515A44CF58B03A1C3965E037DF54E5B + 75F6B0BDA5D18A0BDA4100006897C31654ECB5F64DADAAB843076BA6BE3060CC + E27328CFBE2D317706C346F885AB4FFC0DC20A28F456E9DD760B2CB48C7493B5 + 83E8BD86EA0A0000DABBAA7483AD2A65A61DFA86F3670B4DDA2362E8274F3760 + 13E8B32B45E44611592922CB44649188CCB392300D5259950C0040DAF3E8016B + 4DDE66D590DF2EBDD335E400D08ACA0A2DFBA2AAA2598415E83D1B20FBFAA81D + 64BBDD6F0847010068D750CD4D5655F191D417056038A6125684D582E1018287 + 88FAC4FF7D690341EF95DE6949E907A3ED203ABC8B6A2E0000DAB3AA74AB0DD5 + FC58E99D565800C0381C1E4758A13729828A66F1DF1A4372850DEBD29DEDDB2C + 20657D140000692B7CF746AB4AB5F5E3EBA92F0C406F4CE905FD54C30A2A2B00 + D4C28674FDCFCA7610ADAE603B080000E9866AEEB2AAC70744E40DA577FAE700 + A05595153BEDA121041668061F08188CD23B0D293E516907613B08000069AA2A + F644AB4A6F10915B535F1880E1994A58B1CBCA33C25B4EAA2B00D4E15211B9B3 + D20E12DF77000040FD5515FBECFC1F866ABED5866203C0B81D1E4765C5FE4A2B + 08DAB15616E88DD2BB83957690B01D84761000009A1BAAB9C7866AEACB834B4A + EFB4BA02E8BB39A92F60400E473FEE1F4765C53EBB7931B7A2397CC360704AEF + 74DAF8A7AD3F760BED20000034E65034543354557C2EF545010DBE280ECF5FFA + 23CF622D70C4B0C2CABE1E8C5A41985B01A04E5F1091BBECBE433B080000CD0D + D5DC6D2F0BF4A5C1BB4AEFF4A50100D4515571781CDB40C492D5EADC0A8CDF9C + E88B36100C52E99DDE6BFED6D6A46DB4373CA11D040000D4B7AA340CD5BC5B44 + 7E94FAC2800495155454746C6645082BAA732B082CEAC3370A06ADF44EDFE87C + 36DA0EA26F7A68070100A0BEA19A3BA355A5AFB75952C0504CF5B918B3172FED + 98F5CC0AB16177B481342384140B125F0790DAE745E49ECA7610BD0F11960200 + 307B7119765855AA67FE1F94DEE9E72F30D4CA0A5E1A37E38867FAA98615E121 + 81369066D00682C12BBDD3A4F5EF2AED20FAE687373D00008CC7C1A8AA220CD5 + 7C5FEA8B0212984748D1A8B1CEAC0803EE28C1AE579CE6515981C12BBDD335A6 + 9754B683C49B890000C0EC5695EEB655A53AD8FA93A577FA736068C273318145 + 07DB40F6D80D8D7915F5A9AECA5998F87A80B6F81711B9D74A53B757DA410000 + C0EC866AEEB00A46ADAAF86AEA0B03125950791E43872A2BC2247E828A7A85A0 + 427F5D16A5BE18A00D4AEFF4FEF30FD60EB2C94A5519B60900C0EC5795EE8A56 + 95BEB1F44E5B4280215A5899574160517F55C5D82A2BF6562A2BC2BF08E3F78B + D5A5595E309516F879607187887CD34A54B53C95ED2000008C6755A9562EDE2C + 2237A5BE3020215697A66B459BD0541F863565A50DA47E73A25F17FDA21504F8 + 571F1491FBA27690306C93FB110000B35B55FAE6D23B3E4F31647165058145BD + E2E287FDE30C2B082AEA472B083042E99D1EAADE5619B64975050000D37F93B9 + C7D682EB7AF0AF94DEE98FC020657911363112523427E40A936EF99BEA7ACCF0 + 06938782FA85A042D7E7505901FCB2ABAD4C7595882CB3406FBE7DCFF0010300 + C0E44255453C5453075903431FAE192ADB394FD62B9E571166E7CCBAB222BCBD + A4BAA23E71D951082B16A7BE28A04DAC44F50D76B80AC336E3CA2F000070E4A1 + 9A6155E97BAD721118B21056D006D2C56D20A57787AC5C2C4E42508FB95158B1 + 34F5C5006D537AA76F822EB1D2D5ADD12A53020B0000A6BEAA54D782FF20F585 + 012DA0D5EC54563427AEAC987403D174B64DEC8C5A41C2BF04E355ADACD03277 + 008FF4B9A8BA6247B4B10800004C5E5511866ABEAEF46ED2B79AC0C0C20AAA2A + 9A1BAC195E328EA50D44ECE6461B48FDE65850A15FCB535F0CD046A5777A3F7A + 57346C9355A600004C3EC42E0CD5D4AD5A3F29BDBB2BF5C5012DACAC508416CD + 051607C63160330E2B7818A84FA8AA0895158415C0C47E2422778BC81AFB5E09 + C336F9800100E05F1DACAC2ADD60813F809F5B64CF5E9C219B6F0399FDCC8A09 + 2A2B082CEA411B083005A5777AF87ABD55576CB67B14C3360100F8B9F8616077 + 3454D395DEE9E726809F5B5C9959416051AF384F187B1B48FC20C00341BD332B + 18B0094CA2F4EE1E11F9A195B46EB3D9157A2823500500E05FAB2AE255A55F4A + 7D5140CB2CB1672F066C361BA48E75C0E66EBBE1F110D05C604158011CD97B2B + C336F7D9BD0A0080A1AA0ED5DC6295886F29BDD3601FC0BFD2672EC28AE6AB2A + 0E8EB3B26277A5B282C062BCE2BDBEB4810053547AA707B04FB3CA1400805F38 + 6C9F851A4C6CB70AC4DB45E4FAD41706B4B4B2823690E6E755ECB7B6EEB18615 + 0415F58AC38A15A92F06E8882F8BC8FD23AA2BB8570100865C55B1D33E1BB5AA + E2F5A577ACF906465756C461059AB94769D5978C2BACD8135556A01ED5CA8A95 + A92F08E8022B697D4B65D8A61ED208570100431DAA19AF2ABDA2F44E876B0218 + 3D6033DE064260517F0B482D6185BEA9A4BAA25EBF14566479C1370B30353788 + C8AD36406C7B65D8260000431186D6EDB0AA0A9DEBF4F1D41705B41895156986 + 6B6AE7C6D82B2B082A9A0B2B1688C8F2D41704748195B6BED10E659BADF455AB + 2B985D010018E250CDB0AAF483A5771AE203983CAC88AB2A082DEA515B6585BE + A564C066B361C57CC20A60EAACC4F50A1BB6B9CD125B866D020086E0F08855A5 + F789C8B7535F18D0B16D200415F5B7801CB4FBD4D8C30A828AFA846F8CB8B262 + 55E26B02BAE6E3D12AD39D766863D60E00604843353747433535B40730BDCA0A + D4DF0632F6CA8A786645F897A19ECA8AF91656AC4E7D41409794DE694AFB212B + 7DDD6AD515B4830000865055B1275A557A6DE99DAE2B053039AD64677569FDAA + 95151AAC8E2DAC086F27E3120ED4DF067254EA0B023AE85BB6CA340CDB649529 + 006008ED1FF1AAD2B7A5BE30A0436145DC068266028BDD758415BC9DAC5748F3 + 421B089515C03459C9EBEBECB0B6255A65CAFD0B00D0D755A5BB6D5E93CE6D2A + 4BEFB41504C024B2BCD0B5A50B2BAB4BD14C65C511DB40F4CDFD4C2B2B50FFCC + 0AFDF55993F89A80AEBA434B60ED7B4813F345F63D456A0E00E893EA504D9DDB + 54A6BE28A043F32AC2F9703A2FF23133715831D6CA8AFD9599150416F5985399 + 5BB136F505015D547AA7F7A87FAAAC328D43570000FA5255B1CB2A09755ED33F + 95DE1DF12100C0CF2CB767AEB8B282975A5D1BB0597A17525BC28AFA5159018C + 41E99DF6ED7ED10E6FDB6CF018AB4C01007D70D83ED3F6DA7CA68D5655784DEA + 0B033A1A565059D1B23690E9FE82E83F906D20CDCDACD06F9C55595EE8EC0A00 + 33F379ABAED86825B2610D3300007D5A55BAC15695F219074CDDCA4A58415545 + 3DE2FC208415FA1271AC6185DE0C19B259BFB80D4407BEAC4A7D4140575929EC + 3F5B758596C8B2CA1400D087B79307ECB0BFCD56957EA7F44E37610198BAD595 + 99668415F589838A3014B8B6CA0A0EF9CDCCACD0AA0A5A4180D9B94A44EE8E56 + 996A7505AB4C01005D555D55AA55151F4A7D5140472B2BB4AA823690E6DB40F4 + 3C3EF6B082219BF58BDB40B4B2E2E8D417047499CDDC09AB4C19B60900E8CBAA + D23054F363A5771AC60398791B089515F50B41C5C1D2BB3D4D545670D01FBF6A + 65C5B1A92F08E8BAD2BB7B45E407562ABB3D1AB649F00A00E88AC3D11BC91D56 + 55A1AD1F5F4F7D614047ADA8CCAB20B0A87F0B88DEC3B64EE57F34DDB042135C + 6656341756CCB3CA8A75A92F08E889F75AA9ECA6A8BA426F9800007469A8E62E + AB14D48AC13794DEE99F03307DABA2B08236907AC52D205A15565B5811DE4412 + 583433B3E2A8D41705F441E99D0E21FB9495CC6AA2CB2A530040D7AA2AF644AB + 4AAF17915B535F18D0F1B082019BCDCFABA8ADB222CCAC4073732B9859018CCF + 57A255A60CDB0400744138E457876ABEB5F48ECF2F6006B2BC98175556849915 + 68666D692D618526B9B48134DB06A295156BB3BCD0761000B3547AA707BD3745 + AB4CB5949655A600802E0CD50CAB4A1F12912F95DE69F00E60E6C33517542A2B + D0CCDA52BD8FD51656D006D25C65857E032DD2C022F505013D729388DC4C7505 + 00A0230E55866A6A55C567535F14D093B0A23A6013F50716B58615BC816CA6B2 + 22CCAD607D293046A5777A0F7BA31DF658650A00E8C250CDB0AA54876ABEABF4 + 4E2B0301CCDC1A2A2B9255566CAF23ACD04497CA8A34951527A4BE20A04F4AEF + 1EB6556F0F59BACBB04D00409B579586A19A778BC88F525F18D003EB465456A0 + FE019B07AC4AAC96B0220CD8E4305FAF3995CA8A63535F10D0431F1FB1CA9401 + C20080360ED50CAB4A5F5B7AC7DA6D60F6D6562A2B50AFB8B26247139515A8C7 + 9CCA3610C20AA006A5777AF8FB60B4CA94619B0080360867ED305453AB2AB422 + F007A577F7A5BE38A0476D20F3A34D205456D423EECAA835AC086F1D69056946 + BC11E4B8D41703F4D47744E43E2BADDD61F739866D0200523B386255E97B535F + 14D0B3CA8A10563060B35ED59915BBEA0A2B68036946F866996F61C5BA2C2F74 + 760580312ABDD31BE6EBACB4360CDBA4BA0200904ADCD7BDDB2AFFB402F093A5 + 77539AA00F605A332B9857D16C58B1B7F44E2BC66A69038907D071906FAEB242 + 830A368200F5B853447E6A25B65A6AAB3750AA2B0000A9876AEEB0CA3FADAAF8 + 6AEA0B03FA22CB8B3913545660FCAA2D207A4F933AC28AFDF675203AC87398AF + 7F6EC5420B2B8E4F7D51401F95DEE97DEC9FACBA221EB64960010048B5AA7457 + B4AAF44DA577FAB904607CF32A16566656A03E6194C4013B6B8F3FACB072E9ED + 76030DED20A84F3C6453C38A13535F10D057A577DA02E2A355A65A7ACB2A5300 + 40CA55A55AF1778B88DC98FAC2809E591B8515CCAB6876B8666D9515EA267BE3 + 483B4873EB4B431B08951540BD4A2BB5AD0EDB040020D5AAD2375A052080F139 + 7A44588166866BD65359616EB57EEE38B0C0F885746F6EB4BE94CA0AA04636EC + E7EDD12A53AA2B00004D0FD5DC63157E5AE9F7B5D23BADAE00305EC7D2069224 + ACD86FED6DB5851577D9013EEEE7E6105F8F6A58717C9617FACD04A03E57DBC0 + CD306C534B71995D0100A85BA8AA88876A7E32F545013D6E03D1EA752A2B9A11 + B781D41A56DC6F61C5DE68BD1FEADF08A261C512113926F505017D567A7768C4 + 2A533D3C525D01006862A8665855FABED23BFD0C02504F1BC882CA2610028BFA + 2BC7F43EB7ADB6B0A2F44ED3DEFBA235A6BC716CA6B242BF9916D30A02D4AFF4 + 4E43D9EF5B096E5865AAF73B2AC900004DAC2ABDD73E8700D4D706122A2B0829 + EA7378441B889EAD6BABAC503747732B6805A957757DE9C9A92F081888F75B09 + 6E7595290000750CD5DC150DD57C9D6DE1033066595E2CB4D5A5D5CA0AD4DF02 + D2485871BBB582B0C2B4D9219B6C04011A527AB7CD7A8519B60900A8C3E14A55 + C5369B97F493D23B9D1107A01EEBECB92A84150415F507B2A10D645BE99D86B3 + B58615F75059D1786545585FBA3EF5050103F2B5CA2A53866D0200C6E9603454 + 73937DE6BC33F545013D774C1456E8F3309515CD555668E598D41D566CB052B5 + 30B782CA8AE636821C97E585CEAE0050334B7EDF6037D62D76DF0B8385092C00 + 00E31838B73B5A55FAD9D2BB294FCA073023C7B1B634D9BC0ABDCFD51B56D890 + CD072A1B4138B8D7276E03D1A0E284D417040CC8CDF6C52A5300405D55156155 + E925A92F0A18C870CD10565055D1EC2690FAC30A736B1456D00A52FFDC8AD00A + A2EB4B4F497D51C05094DEE97DED4DAC320500D4B4AA748B7DC6BCA5F44ECFD6 + 009A0B2B42650581453DAA9515DAEED648587187CDAD88C30AD4636E65230873 + 2B800695DE6955C5572D0DDE16AD3225B000004CD761FB0CD96B157B0FDBF0FA + EB535F18301027446B4B67F33C8CA9892B2BF4C5DF94CDE617A73A6493B915CD + 5456681BC849A92F0A18A04F45C336E3EA0A0000665255B1335A55FAFAD23B3E + 53809A6579B1C4D696EA4B60AA2A9A9B5971C0CECE8D85150FD84020FD97F286 + B1D9B915A76479C13715D0A0D23B3D54BEDF5699326C1300305DF1A17D4F3454 + F38AD23BFD6C01D0CC2690C595CA0A9EAB9AD904B2DFEE7BF58715A5779BEC5F + 166F04E1C05EFF46100D2B965BAF1580667D4F44EE6395290060860E8D5855FA + B1D417050CC8F1D1DA5236813413D0C69B8FF4DE3765B3EDD189876C125634B7 + BE54CB974E4D7D51C0D094DEE98DF6B5D1B04DAA2B0000D36DFFD003FB56ABAA + F8B06DD903D08C93A2B082AA8A66E7556CB0C1F58D85153A64938D20CD08732B + 165AE9D269A92F0818A8BB45E4EA6895A996F2525D0100984A29F43EFBECD868 + 957ADF4C7D61C0002B2BD804D2ECBC8AB009442BC9A4C9B0220CD9642348F343 + 36595F0A246089F03BEC86BB291AB6C93D10003095A19A6155E9EBAC620F40B3 + 9B40A8AC684675B8A6DEF71A0D2B368CD808C261BD1ED5B0E234866C026994DE + E941F3F356C2BBD54A7A99DD030098ACAA624FB4AAF45AAB5006D0902C2F16D8 + DCBFB00984B0A2D9B042CFCD8D86150F4661855E0487F4E6E656ACB032260069 + 7C31AAAED81185B600008C6AFFD8190DD57CDB747BB701CCDAB136FB2F6C0221 + A8682EACD86F416D736145E9DD5EBBE186B08232E8E63682E8371A732B80444A + EF34A8FD272B690BAB4CA9AE00008C3AA8EF8E569596A5773AA41940F3C335B5 + 429DCA8AE666568479159A1B6C6EBAB242DD3E62230807F57ACCA96C0421AC00 + D2BA4644EEB44169DBA355CEDC030100125555ECB0CF0A7DC9E7535F143050EB + 595BDAA810568436107DB9D7785871D7888D20A8AFB222DE08727AEA8B0286AC + F44E03DAD745AB4CB5C49755A60080B8AA62971DD2B57DFA1D569907A079278E + 082B082CEA51DD04B2C9BA321A0F2BEEAB6C04D18B42BD81C52F3682D8A01800 + 8994DEE95BB2EF591FDE36BB1F86EA0A020B0018A6C3F659B0375A55AA0335AF + 4A7D61C08085CA0AAD54A705A47EF170CD7B67F20F184758110FD90C95151CD0 + EB13CFAD5866DF7400D27AFF04AB4C0100C3535D55BA395A55CA4B3D20812C2F + 968BC85AD69636E2F088E19A5AE09024ACD8185556305CAEB9CA0AFD465B2A22 + 67A5BE2860E84AEFF4ADD9C72DBCD5525F569902C0B00FE907EC7CBCCD2AEFBE + 6B957800D20DD7D4997F0CD76C461C5684A51CCD8715A57707A2B915E1708EFA + C4732B18B209B4C7E522727FB4CA54EF89CCF10180E119B5AAF403A92F0A18B8 + 53A34D20AC2DAD5F985711DA4074135292CA0AB169F86C04A95F1802C3904DA0 + 654AEFF4FEF7A668D8A60E5463D826000C77556918AAF931ABC00390CEC9F6EC + 14866B8EEB3918535B5BAADD18D336AE5FA4EA4610AA2B9A1BB2795C96176B52 + 5F14809FB959446EACAC32A5BA020086211CCEF75A85DD26ABB8FB7AEA0B0320 + A74461456801A1BAA2FE4D20FBEC9EA8F7C3646185DE88595FDA9C38AC606E05 + D012A5777AEF7BF388619B545700C070866AEE8A866ABEC12AEF002492E58556 + A49F106D02096B4B519F78B8E60333BD0F8E2BAC8837823054AE99CA8A79D190 + CDB3535F14809F2BBDD3AA8AAF586FDED6689529F745001846554558557A8388 + DC9AFAC200FC6CB8E6D2685E052D20CDB5C4693E70CF4CFF41E3FA85DA1CBD41 + D48B62664533EB4BC390CD33535F10805FF22F5175C58EA8BA0200D0DF837975 + A8E69BADE20E405A67D83353A8ACA005A4B9B5A57B9387157623BE3D0A2B3459 + 46FD433617D837DEFA2C2FB42504400B94DE6909F07BADEA4CAB2B18B60900FD + 141FCAF7D83D5F2BEB2E2BBD9B518F36805AE65554D796A23EF170CD7D363262 + 46C6F90B754765230887F2E6E6562C672B08D03A578AC8BD560ACC2A5300E8AF + 4395A19A5A55F1E9D41705E0116B4BC326102A2B9A0B2BF6D8CBBBE461859677 + 3064B3D9B915F3AD9C6999883C2AF54501F857A577FA96EDB5AC320580410CD5 + 0CAB4AF59EFFAED23BFD63008959F57918AE196F0241739B401E9EE93F4C1F76 + C7658325277158A15FFC66A8C79C28AC606E05D04E1AE25E2D226BAC026A7154 + 7EC8BD1100FA375453EFFB3F4A7D61007E61BDBDD88D3781A0B9E19A5B4AEF74 + 964FF2CA8A87466C0441FD732BC290CDB3B3BC1867F804603CF37CDE5159654A + F51900F46BA866BCAAF41F4BEF98DD06B4C759B60984E19A69C20A1D1521C9C3 + 8AD2BB6D56FEC6FAD2665B41C290CD15CCAD00DAA7F44EEF8B9F8B56996A6930 + F74800E8AE503D1C866A6EB332E71F96DEDD97FAE2003C625E05C3359BBD3786 + 79155A7576F76CFE81E3FEC5BADD2E2A6C04E120DEECDC8AF3525F148091BE68 + D51561D8A686BABC790380EE3A386255E9BB535F148047D05679866BA699E533 + ABB5A575841577563682847405F588C38AA556E604A0654AEFF4BEF8369B86BC + C54A86A9AE00807EAC2AD57BFBBF5895318096C8F2629D881C158515CC0C6BAE + EA2C6C02D120B73561C53D23866CA21ECCAD00BAE55AAB3EDB6883D8F6D8CD9C + FB2400747BA8A61EC6BF9CFAC2003CC2E995E19A8415F58B3781ECB136E8D684 + 15612308732B9A6D050961C54AE65600ED547AA7F7C3D7DB7D9255A600D0EDF2 + E65D5629A755156F2ABDD3B32F807639DB9E91E2B002CDB5803C547AA7F7CA19 + 1BF72FD883363C2EF46373006F6E6EC5624B0E1F93FAA2008C567AA793E2BF63 + 29F3B64A7505F74B00E85655850ED5BC45446E4A7D6100463A83E19A49866B86 + 4D205A513C2B736BE8CBBE2F9A5B416051BFEA90CD73525F1080497D305A65CA + B04D00E8DEAAD29DD1AAD23758E51C8016C9F262916D0261B8669ACA8A3D36CF + 7256EA48976E8B36823064B3F9B915676579A1DF94005AA8F44E038A8F5B251A + AB4C01A07B4335B75985DCD74AEFB4BA0240FB686BFCF24A58817A85FB649857 + 716F1BC38A3BA3B9155456D42F84150B2CAC58417505D07A5F1791FBA355A61A + F072BF0480F60A55153BA2A19A9F4C7D510026748E6D4B64B866F36D2021ACD0 + B36EEBC28AFBA28D20E16D21EA9F5BB1C092434D101F9BFAA2004CACF46EBF0D + DBD4EA0A866D024077866A8655A5EF2FBDD3761000ED746625AC20A868EE5EB9 + CFEE970FB731AC78A05259C1E1BB7E73A2B915FA4D796EEA0B0230A596B91BA2 + 55A654570040BB876A86AA0A2D6DFE5EEA0B03305A961773A34D2061B826F32A + EA150FD7D4FBE56DE398E7534758B1253A78D387DD5C65C5BC28AC589FE5C5BA + D417066062A5777A5F7C73346C73A785BCDC3301A09D551561A8E6EB4AEFF48C + 0BA09D4E139195D1BC0A5A409A6B0109C335F5A59CB42EACB003F82DD146100E + DECDCFADA01504E880D23B0D292EB3416D5BA355A6DC3701A03D87EF3054534B + 9AAF1691BB535F1C80499D6B5B12092B9A539D5771D738FEA175ED9ABD2D9A5B + 11CA9A3978D7AB3AB7E2D1A92F08C0947CBAB2CA54835E66FD00407AE1E0BDD3 + EED17AAF7EBBBD9803D05E6747F32AE6D5F8CC8B5FAE420BF7CCDD36C772D6EA + FA85D324858D206956982EB224F131D6AF05A0C54AEFF486FE9ECA2A53AAD200 + A01DAB4A77DBBD592BE03E577AA73F07D052F6FC734E34AF220CD7A4B2A25EA1 + 656EAFDD37B5656ED6EA7A98BDDF2E52C30A4A9A9B11C28A85F6CDB95644CE4A + 7D5100A6E44A11B9C74A8C19B60900E91D1CB1AAF48BA92F0AC094E655ACB2E7 + 215A409A0F78F50C7B57E99DFED8DAB0E2211B44C4DC8AB4732B9E90FAA2001C + 59E99D1E8A5F6B29745865CAB04D00483F54738B55BEBD755C876F00B57A0CF3 + 2A92B6806877C5CDE3FA87CFADF1E0AD4336995BD1AC3995B915FACD0AA01B74 + 15DE4FACBA625BB451897B270034E770F47670BBDD936F1791EB525F18802979 + 9485158BAC0584B6F8E6EE9B615E85DE33C7A2CE5FBC9B478415687685E92959 + 5E1C9DFAC2001C990D6C7B6765D866B87F0200D2AE2A65F031D072595E2CB0E1 + 9A615E853E1731AFA2B916901056E80BB8D68715778C985B81E65A4196DA7E61 + 5A41808EB0C16D9FB556BA6D760F65EE0F00D42F54B11DB0976D61A8E6374BEF + B40D0440FB6950B1C29E83E2B002CDCDABD8652FDE5A1F56DC6B07ED50CACC61 + 3BCD0AD3C7A7BE2000D3F225BBC96FB4EA8AB0550900D0DC50CDB0AAF4C3A92F + 0AC0943DD69E7F9857D16CC87BD02AD234E8BDBDF44EEFA3AD0F2B42DFB55E34 + 6145334299D37CFB26D57EAD73B3BCD05228001D6003DCDE62A5C75B2CA16650 + 310034BFAAF4C3A5773B535F1C80297B7434AF82AA8A661CAE0CD7BC719CFFF0 + DAC20AEBEDBBD12E3ABC1964505CB32B4C97DAEA9EF3535F148069B9DE5AE9E2 + 55A661D82600A09EC37618AAA9956DF7690B48EA0B033035595EACD1797D510B + 4818AE496051AF781388BE60BB6D9CFFF0BAA7A3DE18CDADD0FF13CCAD686ED0 + 665861AA7D5BCCAD003AC4C2DED7555699525D0100CDAC2A0D4335352406D09D + AA8A15D1704DB680347BFFDC3BEEE19AD2C02FE2ED76E367055FF361C5FC786E + 459617FAC7003AC206BA7DCB4A91B7462D75DC470160FC55157BAC7D592BDAAE + B5EA3600DDF198112B4BA9AA6876B8E6363BB77626ACB8370A2B58C1D77C2BC8 + 22FBA65D636923806EF950659529C3360160FC076DBDB7EEB44A36BDE7BECDD6 + 4903E8802C2FE6DA70CD6A588166866B8695A5378C7BCD73ADBF88A5777AB8BE + DB2E3E2E61E603A0B915A64B6C85E905A92F0AC0F4D860B78F46D515AC320580 + FA866A6A45DB174AEF34B400D01D6788C83A9B57110FD7A4B2A2B97915BBC73D + 5C531A4A9CAE8BE656844336EA576D05393FCB0BBE6181EEB9C206BD8555A67B + A381C50080993B64F7D47855E9E7535F1480697B4234AF425FD6B209A47EA100 + 21B480ECB211109D0B2B6EAECCAD20AC687685696805394644CE497D6100A6C7 + 06BC316C1300EA1FAAF98ED23B9D5D01A09BF32A16DBF30F4145330EDA7D748F + DD4BC73A5CB3A9B0420714EDB4FF131CB0D3AD30D556908B525F148019DF47AF + 8F5699EAFD94EA0A009899F86DE00EAB5CBB4B44AE4A7D6100A627CB0B6DFF38 + CDC20A5696365B5511425F3D97DE65EDCBDD0A2B4AEF365A0F60985B110ED81C + B29B6D05D1D2A827A6BE2000D36783DEDE120DDBDC65AD7584BF00303DF1017B + A7DD53B5AAE2B5E31E0C07A0114FACAC2CA505A419F11690DD36FA61EC9A9A92 + 7A4DD40AA261051F06695A418ECBF2E2ACD4170660FA6CE0DBA5235699125800 + C0F47BACE355A5DFB3C00240F73CD6E6F38579156C016936ACD867CFF9B7D4F1 + 2F69EA17F37A4BAFC30A530ED7695A415689C893525F148019739555A67A4F25 + FC0580A90B93EBE3A19AEF675529D03D595E68F5F8A32DAC082B4BD90252BF6A + 0B883EE7DFD9E5B0E256FB50885798A21973A315A65A22C50A53A0A34AEFF41E + FA6E6BADDB32622D3400607AAB4A3F5E7AA7B3800074CFE3EC656C756529EAAF + 508B876B6AD5AF8E7EE8665861732BEE8F56988656100ED7CDB7829C402B08D0 + 693F1491BBED43410FD8AC320580230B87EB78A8A69E4D2F4F7D6100C6B6B294 + C19ACD381455A9690BC84FEBAA4E6BB2A7E7C7512B88A6DA1CAC9B6F0559665B + 419E9CFAA200CC4CE99D7E38FC63659529C3360160EAAB4A375B55C51B4BEFF4 + CF01E8982C2FF439F67C6B01092B4B9957D1FC4625BDA7DE50D7BFA8C95FD0EB + 46B48270B06EB615246C05B920CB0B5247A0BBF46DE08F6C30DCB64A08CC7D15 + 0026AEAAD86E551537D635100E40231E2322EBA295A5A10584679CE6E755DCD1 + 87B0E236FB80885B41385437DB0AB2D8D2C7E344E451A92F0CC0CC58A9DDBB2A + C336C37D1500F0C883F5BE6855A9DE3BDFC4504DA0D32EB08A715696A69D57B1 + A5CE6D4A8D8515A5773B2B5B41780B98762B08AD20408795DE6945C56758650A + 00531AAAB9C7EE957ACFBCACF44E430B001D6415E24F8C5696D202926E65E955 + A577B52DCF68FA17F5471656C4876AA4D90A72A1F57A01E8AE4BAD25245E654A + 750500FCAB43D150CD5055F1E9D417056056CE119163AC058495A569E655ECB1 + B042473DD4A6E987551DBEA16F03690569D69CA8BA6291A590478BC8E3535F18 + 80992BBDD3FBE85BA2619BCC04028047F655EFB652651DAAF96E5B030DA0BB9E + 642D204BED652C2D2069E655ECB0510FBD092BEEB7AFD00AC20AD3E6D00A02F4 + D30DF641B171C4B04D0018AA514335EFB6F5CF00BADD0272E18895A568765EC5 + 6E7B51A6D56AB569F417D606197DDF52983DD11B40D46F4EA51544D3C8276679 + A19516003ACAFA045F6F1F169B2D0CA6BA02C090C54335C3AA52AD407BADAD7F + 06D05DE78AC8B1B480249D57115696FEA4EE41C52952A8ABA2AD201CA89B15B6 + 822CB26FF0B5227251EA8B02303BA5773A30EE9BD12A53866D0218FADBBFD053 + BDCDEE8D5A51715FEA8B03306B17472D206C01491756ECAC7B5E45AAB0E2761B + 7014B782B015A4D9EA8AB815447BBE0074DF4746AC32A5720DC0101D1CB1AA54 + 675570D6043ACC9603D002D28E39407AD6BCB5EE7F69E3BFB8A5779AC6D00AD2 + 8E5610FD467F6C96171A5A00E8305B0FFD611B20B7D53E48A8AE0030F455A57A + 4FFC8CAD7B06D06D8FB32501CBAD523C54555059D1DCBC8A7D76C6D410582B7B + 6B952A89FA31AD20C9C45B41422BC8D3525F1480B1F8A60D31DE68F7D8B87A0D + 008638547383AD7906D07DBA1C405FB2D20292BE05E4C74D54ABA50A2B6EB2B4 + 7BA7A5334CAE4FB71564A5F57E01E838AB5C7B9D0D92DB62C38F0884010CE9CD + DF7EBBF78555A56FB235CF003ACC96025C400B486B5696D63EAF4252FD02DB7E + EB9F5858C120B834AD203A6873B17DC39F91E5C5FAD41706602CEEB00F9078D8 + 26D51500FA2E0CD50C55157A0FBCC55E9001E8BE0BAD223CB480B005A439D595 + A53B6C0E65ED52A6513FB083346FFED2B782AC1191A7A7BE2800B36725796F89 + 866D860A36EEB10086F0D66F67B4AAF40DB6DE1940F75D5C6901D1E758828A66 + E7558495A5B736350728655871431456D057DDBC6A2BC893B2BCE01B1EE881D2 + 3B2D7FBEC4061FE97D96619B0086305473B7DDF3F4DE7779E99D565700E8B82C + 2FD6D870CD6A0B08CF2ECDCFABD0AA8A1F35F4EF4D175694DEE9CC8A6BEDFFB0 + FE1FE720DD9C503215B7829C20228F4F7D6100C6E6B3565DB1315A15CD1B4600 + 7D7468C4AAD28FA7BE280063A315E06B466C0141738170D802B2C38A0E1A917A + 28C9F7A2AD209429A71BB4A9AD20AB45E419A92F0AC07894DEE9AC8A77DA8039 + ADB460FB12803EB77FC443353F507AA77F0CA09F2D208415E956966AC1C15D43 + 092BAEB772BDD0534D2B48F3833617583995B6823C21CB0BADB200D00F3AC8F8 + 6E569902E8A9B88F7A87DDEBEE1591EFA6BE3000E391E5C5E922A25F2BAC225C + 2BC3690149B7B2F487B67DAEFF6185F512DE1495288715A61CA49B115A411659 + 59954ED865D026D013A5777A88FF472B89D68173FAA6912A36007DACAA084335 + 5FDBE4411A40ED9E6115E05A094E0B48DA95A5FAE2EBAA262F20756585FA7665 + 2B086FFDD2B4822CB5F2AAA7A6BE280063A541C50F2BAB4C098601F4A5AA221C + A0F51E77B5559301E8812C2FB402FCC9510BC8027B764133E216905D76AFBD59 + 0616565C1B8515B482A419B419B7829C61E55600FAB3CAF4DD235699EABD1600 + BA7E808E876ABEDDEE7900FA41838A632A2D20E1F905CDAE2CD57BED2DA5775A + C5369CB0A2F44E0721DD62BD86BCF16BDE5C4B28432B884EDA7D56EA8B02303E + A5779A84FF8B0D9EDB1ADD6B690701D0F555A55BEDDEF679DB3407A03F9E1EB5 + 803058B379710B883EABFFA0E90B481E5644AD20612B08AD20CD9B57A9AE7872 + 96177A4300D01F9745AB4C19B609A0CB42554518AAA9F7B62FA4BE2800E393E5 + C5092272AE3D9B2CB16715066B36A7BA0544CF8ED7C940C38A6B2C19672B48DA + 5690C5566675B4883C2DF58501189FD23B0D82DFC42A53003DA9AA885795FE53 + E99D06B000FAE3D922B2CE2ABF17452D20687E65A93EA33F64DB9686175694DE + E9F4E65B690549BEC674919559E9101BB68200FD7393B5DD6DB45941545700E8 + 92C376468C876ADE2E223F4D7D6100C627CB8B79F6E2340CD6D48A6FAA2A9A15 + 82E1D002F2DDD23BFD73C30B2BCC376905491E562C88B6829C93E5C529A92F0C + C0F8D887CC1BA255A6A19A8DEA0A005D5D55FABA14076800B57A8A881C6B15DF + 4BACAA82B0226D0B886E5B92218715712B086FFBD20FDA5C6BE557007AA4F44E + DF445E61E57CF12A53020B006D15AA6DC35BBE6D760FFBB60D6A07D02FCFB2A1 + FFFA4CC260CDF42D205BAD3277B861857DD8DC6465261A56D00AD2BC6A75C553 + B2BCD0F00240BF7C64C42A53DE4C02E8DA50CD0FA6BE2800E395E5C57A066BB6 + 6F0B48E99DDE7F871B56986F595AAEE57DB482A46B0509833675AFF133525F18 + 80F12ABDD392BE0F45C336C33D97EA0A005D5855AA55151F29BDD3B01540BF3C + CF2ABC57D833098335D3B6DC690BC80F2591B68515D7D8C1995690F4833697DB + 5E63C20AA09FBE6D539D3746156DDC7301B44D2847DE6B8766BD67DD2722DF48 + 7D6100C62BCB0BADEE7EAA3D83E8CFA9AA685E68B9DB67618506C4374A22735B + D84B7DBD7D1869D9096FFAD255572CB15690B3B2BC382BF5850118AFD23BFD20 + 7A9D0DA8D3417554570068FB1BBE2DD1504DBD8701E897E78AC8D1B480B4A292 + 6D8FBDCCBA3A65155BABC28A682B48DC0AC2C139EDA0CD3576E300D03F7789C8 + 75B6FE2F84C4545700685B554518AAA9F7AA6B45E48ED4170660BCB2BC986383 + 35B5AA62993D8B3058335D40BCDBEEBBDF9384DA1856845690EAA04D34FBFB62 + A1955FE90DE3A22C2FB46F0C408F94DEE9BDF5ADF6A6B23A6C93FB2E80361C9A + C334FACD3654F36D76EF02D02F1788C82956D9CDBAD2F46D773B2DACD0975AC9 + B42EAC28BDD3FF283FB2B77C9AE8B0522F4D2BC8FC68D0E6D136EC0640CF94DE + 6938FC051B58A77D89DC7701B46DA8E6361B08FCA5D23B0D2D00F4CFF3A3C19A + 5A55C160CD7455157BEC59FC1A7B364FA675614534F86DABB58268A24E5972B3 + E6545A41B4BAE299569E05A07F3E17AD320D556DAC320590D221BB17C5AB4A5D + EA8B02307E595E9C21228F8D066B6A85375515695B4034ACF88E24D6D6B042CB + 4D36DB0754DC434D60916ED0E64922F2A4D4170660FC4AEFF481E01DF6E63254 + 57303308401B0ECC5BEDDEF48ED23B3D1302E89F178AC8BACABAD2B63EA70EA5 + 05646BEA161069EB6F02FB30FACE88AD2048575DA16559CF497D51006A739588 + DC190DDB64952980B6AC2ABDD3EE51007A26CB8BA3EC856818AC19AA2A90BE05 + 44038BA4DAFC1B41278F6E8D06BE71684E575DB1D4AA2B1E9DE5850EBE01D033 + A577872AAB4C19B60920F5AAD2CD764F7AADDDA300F4CFAF44EB4AE3AA0A5A40 + D2DD7BB7B5A105A4ED61C54D36F02DB48230F0AD7973EC86B1C8CAB2D6599916 + 807ED29EF02BEDDE1B2ADBC24626EEBD009A5C551AAA2AAEB4C00240CF6479A1 + 2F449F29226BAC929B75A5E9EEBD072A2D20BA263AB9D68615A577FA1FEC1B96 + ECC4FDD368BEBA62A19565E98DE462D69802FD64EB00DF1D0DDB8C2BDB002045 + 55C57B59550AF4D68B44E438D695B66AFBD27611F971EA2D20AD0F2BCC0FA256 + 10FAA7D3B682C46B4C5F90FAC200D4A3F44EABD93E5519B649651B80A6DEEC69 + 55C5369B9F73791B7AA6018C5F9617FA7CF13C9B8B17AA2A58579AAEA26D9F05 + C55B6D33672BB43DACB84344EEA9942373604E3B6853AB2B9E95E545DB7FEF00 + 98B9AF5875C5C6689529613180BA0FCBFBED05D5660B4C3F99FAC200D4E6F922 + 72BC5555683B888617545534EB70A5FD6E87DD7F5BD102A25AFDC069C394BE66 + 09BB263D0CDA6CC71AD31345E4E9A92F0C403D4AEFF481E10D5682BDC5EEBFAC + 3205506709F2C14A55C5674BEFF4DE03A067ECA5E70BA275A55455A473285A15 + AD0502DF6DD39AE8568715E6877658A615A45D6B4C350D05D05FB7D817AB4C01 + 347158DE17555568507A69EA8B02501B1DAAB93EAAAA08EB4A092BD20ED6DCD2 + 962D209D092B4AEFB40CF0BA1183363930A719B419D6989E95E5C563535F1880 + 5A2BDBDE60ED20AC3205D0C460B7ADB68DE843A5777A78FEFFDABB0FB0CDEAFA + CEFF1FEA3033CCC0CC30B4A1238A8022164045458DA29EA39EA8B19B58B32631 + 65D76C92DDFC93DD7FF6BFD7EEFE63C35853B06003158F7A0E8A0504A417E94A + EF9DE97D8099BDBED9EF2FFBF378DFCF3CE5BE9FD3DEAFEB7AAE8101CD313373 + EEDFF3F97D0B806E7AA55F7E86AA0A3680D4FBFEDDEC2D208FF846CEC6687C58 + E1CEF70F305A41EAFDBDB27334687389EF4506D05165912FF7F7EFA31E18333B + 08C0A885C16EEB7D0B9105A497D6FD5000C62349B3E3251D2E694FDF36485545 + 7DB6461B98EC9C775E59E48DDA00D796B0E23ABFD9AB0E7AE3B03CBBE235A6F6 + 827966926607D7FD5000C6EA1BD12AD375517505008CEA562F4CA0B760F473BE + BE1E4077D795DAA5E742BF040DEB4A31BBB656AA2A56FA26CE4669C56F8CB2C8 + D77BFF4C18B4690950A3529F1ED8C1BF4275C5425F63FAEABA1F0CC0F894456E + A5D95F8E5699326C13C0288409F4E1A06C955CF77AEB2F800E4AD2EC18494FF7 + ED82F10610D4DB82B7D6E794DDAF8669D36F8E8B18B4D998D91573BCBAC25E34 + C72769663D6700BAEB52FF0063952980511E94C304FAD51E887EC2E7E500E8A6 + D748DACB2F3DE7465515B480D4F30EDEE29750F63DF6B9659137EE5CD7A6B0C2 + 867D3CE0C90F7DD3F586153BFB0BC65E347BFB8B0740477949F6477C42BF9509 + 525D01605455156B3D08BDB989B77A00462349B323251DEB979D6156850DD6C4 + ECDA166D01D9E4EF603BDB5DA3066A4D58E149FB4F3D7D0F53E9B9D9AB7F8DA9 + BD705E94A499BD740074D77D92AE8F5699DA071CEF600033A9AA08377A16847E + AA89B77A0046E6B55155453CAB82AA8AD9F76465B0E6256591DBD9AE715A1356 + B82B870CDA447DD515B6C6745F1F9603A0A3FC9B88CF46C336098D014C47F546 + CF02D04BCB22B7F70A800E4AD2EC0849CFF275A5F3A375A5A8B7B26DBD7F6FFD + 733554ABC28AB2C82D79BFD13FDCACC79132E47A84419BA1BAC25E3C2F4DD2CC + 86E400E8A8B2C8ADB2ED6C9FD8BFDADFC3B4E40198EA2139DCE859406167BBD3 + EB7E3000B35655C1AC8AE6CC0B5AE363166CDC4223B52AAC70E73168B331D515 + BBF8245FABAED85FD26FD5FD6000C6EEFB921EACAC32653B1380C91E929FF4AA + 8A355E55717659E4F62E01D041499A1D2EE938BFDCB44B4EAA2AEA0F8CB7F8F7 + D2F63DF58F9B3CD8B88D61C575959E696EF5EAAFAE58E0FB925F91A4591B7F4F + 0198A4B2C82D24FE9CDF86AEF2DB51DEC30026234C9F5F17555594753F1480B1 + 7ABD0FE4A7AAA2396D789BFD3D6C2D2097ABC1766CE941F93C2F41DEE01F7A8D + 4D837A505DB1AB5757EC29E9606B07A9FBC1008C9D0DDABCC727F8336C13C074 + 4A8FAD9DECCB6591DBFB0340776755C455156C00694E1BDE6A0B2A9A3E2FA875 + 6185BBC493A0B81584C0A2BECD20BB797585BD885E95A4194929D0615E2E585D + 651A8263020B008384D2E3751E745A3BD965753F148059ADAAB01672AA2AEA1F + ACB9CECF6F3F53C3B535ACB857D26D9ECC3368B3FEB022CCAEB035A687D82AD3 + BA1F0CC0D83DE2A5838FF9BB38B4E585FDDD0030A8AA6295BF3F4E2D8BDCDE19 + 003A2849B3A75155D1E8EAB67B25DDAC86DBB1C52BF47E3CA0BA8203727DB32B + 768B6657B0C614E8387F0F9F36649529000C1AE8B6D6AB2AEEF02F00DDAEAA58 + EA83F8A9AA68CE7B789D7F0F7D4E93076BB63AAC70BFF0033283369B33BB62BE + 57573C2549B3E7D7FD6000C6AB2C720B28BEE9B7A4AC320530EC362F9E3C1FAA + 2A1A7F4806303D499A1D2DE9596C0069D47BF8093FA7ADF5EFA15BD186D7DAB0 + A22C72EB913E3F1AB4195A4150CFEFA3505DB1D0F728A7753F148059F153EF3D + 5FEE693D956E0006F548AFF5B6B12B7DB82680EECA2A55156C00694668BCC143 + E3F3CB22B77772E3B536AC70177932141F90092CEA116F06B1EA8A2392343BB1 + EE8702305EDE737E6A65952973840054AB2A56FA7BE20BDE4606A0839234B339 + 15CFF0AA0AABBA66564533D6956E8AAA2AECC2BF15DA1E56DCE58336ABD5157C + 08D6D30AB2B3A7A70BBCBAE2B5753F18805971BBA45BFCD6D43E08A9AE00FA2D + 2E3BDE14AD2AFD4159E4F6D700BAEBB7FDFB00AA2A9A595571A3AF9F6F855687 + 159ECCFFC8FF1FCFA0CDFA556757587505B32B808EF3DEF3537DD866187CCC2A + 53A0DFB6462BF296FBFBE17B753F1480F1F173FF91545534AEAA62B35F2685C1 + 9AAD399BB53AAC70D7F88760BC3A8F0372FDD515CCAE007AA42C722B2B3CCF6F + 4F791F03FD555D91B7DADF0BD6FE610766001D94A4D90EBE0184AA8AE6BE8BEF + 93749D5AA4F561850FDA3CD77F01B8CD6B6675C549753F14805971A6DF9E8661 + 9BE17D0CA0BF2BF2EC7DF0800FD604D05D2FB38D8054553472C0F13AAFAA287D + D6586BB43EAC703F8F066D86DB3CC28A7AAB2BE2CD20AFF5B415408795456EC9 + FD17A355A6CC1202FA7B9317FAA3ED7DF0B1B2C8EDD00CA0839234DBD967D5ED + E5E77FFB3E80AA8AE65455ACF1B96297AA65BA1256DCEFC34256FB2F0887E3E6 + 545758BA7A98A493EB7E2800B3E2327F27B3CA14E89FEAAA527B0FFCAA4DC3DC + 004CCB6B241D54A9AAE8CAF7996DAF705BEF55153F2E8BDCFEBA553AF19BC887 + 84FCD87F21381C37B3BA2249D2AC13BFDF000CE7B7A71FF51585F64EA6BA02E8 + DF4D5E381C5B5BD83FB469981B80A949D2CC6653BC4AD252AA2A1AB78D69A357 + 5558707C815AA84BDF3C5EEF8763FB05A1BAA239D515F33C653D54D26FD5FD50 + 00664518E01456995A7B1E0132D0AFC3B10DD5BCB02C720B2D00747B55E9013E + AB6E5E34AB82A0A23E5BA3AA0A6BC7BBA22C720B8F5BA733614559E4F60BF2C3 + 688DA9FD3D87E3666D06798DF7B401E830BF45FDACDFAADA3C21DEC940BF0EC7 + 2BFC02E9EB753F1480F149D26C890FD6ACCEAA20A8A8CF560F8E3745ED783F52 + 4B7526AC7097B0C6B43176F05475174F592D6D3D9855A6403F94456EEFE1221A + B669B7ADBC9381EE57558455A55FF78D6D00BAEB4D92F693B467545541FB47B3 + 861CDF2CE936B554A7C28AB2C897FB7037D69836C30E036657BCD27BDB00745F + 316095291B01806EAFC7B33FEF0FB6B53F1AC0E42469662DDE2F94B4C4CFF973 + 68FF68C4FBF889A8AAC2AADC8AB2C85BBB46BE5361853B375A636A1F9CAC31AD + BFBA62D7A8BA6299A4ACEE0703306BED799FF5EA8A559EF2535D01747F55E9C7 + CB22B73FEB00BAEB7724EDE3E77BBB88A4AAA219C1F1E3D1FBD836315DAB16EB + 6258719B7F59750553E89B555DB1C0AB2B5E9EA499958B01E8BE1B24DDE5B7AD + 61D8262132D0CD55A53654F7164977D6FD6000C62749B3E7483ACEAB2AEC7C4F + 5545F3AADC564AFABE6F696BADCE85155EE6F2834A750543DDEA1FB6B9ABEF5D + B6F4755F496FACFBC100CCDA3BF9A3DE0EC22A53A07B551561A8E64A1FAA796A + 9B4B8E014C2C49B31D7D56C5DE3EAB62AECFA8B3333F614533AADC567B959B8D + 4768B5CE8515EE6AFF05628D69B3DA41E644D5152F4AD2CCD61C01E83E1BB677 + A9DFBAC60390ED9DCC7B1968F750CD4DD1AAD29F95456E974500BAEB14494778 + 55C5EE545534B2AA6285A4B3CB22B7F773AB7532AC288B7CB3AF31B5949F9579 + CDA9AE089B41F6F41E37EB7503D08F55A65F8C5699326C13E8DEAA52FBF3FD8D + BA1F0AC0F8F890FCD4AB2AF6F0AA0A6BF766564533AA2A367A78FC5857861C77 + 32AC7017456B4C5999D79CD9157175C57392343BBAEE0703307EBEC2F04C5699 + 029D3B188772E3AF96456E7F0FA0BBAC8DFB40498BBDBD3B0CD544B3AA2ACE2D + 8BDC066CB65E677F73F91A530B2C5679EA6FBF801C8AEB13FAD876F114D6D258 + AA2B807E39D7571A8655A6CC1402DA7B30DEE24335C3AA523B7301E8A824CDF6 + 93F432BF705CE8C3F3A9AA684E4BDEC6A8AAE227EA88CE8615D1C19809F4CD9D + 5D61BD6E4725697652DD0F0660FC7C95E1C77D081FC336816EAC2AB53FCF1F63 + 5529D0796F95B49F0FCBB7B66E569536E79DBC391A747C7159E4F65EEE84AE87 + 15B63AEB46FF30DDE0B7001C8AEB9F5DB173545DB154D21B9234B3100340F7DD + E9AB0D43904C7505D0FE55A5B69E1840472569666B4A8FAF54553054B35EDBFC + EBF168D0B1BD93CF5187ECD883A16E677BEF4E3814535D51BF9D3C8DDDDDAB2B + 0E95F4BABA1F0AC0F8F94AC353A3619B6108324132D0DE55A5FCD905BABDAAF4 + 2DD1AAD279DED64D5545FD9EACBC937F5116F9DDEA904E8715EE0649F7FA00A8 + 5072CC2D5E73AA2B167A4A7B4A9266566901A0E3CA225FE9FD948FFABB39B4E9 + 115800ED5A557A9EFF7906D05D49B4AA74815F385255D1BC77F263920A754CE7 + C38AB2C82D98F85EB42E8F92E366AD329DEF13850F60D826D02BDF1CB0CAD43E + 78013453A8AA58E76D5CF6E7F78CBA1F0AC0F82469B6D0C38A7855295515CDAC + AAB851D26DEA98CE8715EE8AE8068F816ECD10AA2B768BAA2B5E94A4D921753F + 1880F12B8BDC82E32FF8CAC33057887733D0FCA19A6155E9E96591DB8D1E80EE + 7A9B5F282EF6F66D569536B3AA62B95DCE7BAB6DA7F4E2379BEFFDFE81A74E61 + 8D29D515CDA9AE98E79385F7F5972280FE04C9F7B1CA1468CD50CD5055F1804D + 9CAFFBC1008C4F9266474A3AC987E1B3AAB459B67A80BCDE2F7C6E9674933AA8 + 176185BBC07B79EC46C0C20B6EF0EAB783BFF4C22A53ABAE383649B317D4FD60 + 0066AD4DEF239555A60CDB049A5B5511866A7ED4FFFC02E8A024CDEC8CFE76BF + 485CE46DDBB47F34C356AFAAD818CDAAC8BB5855D1ABB0C207409D175557D881 + 981BBC7AEDE05FBB780F9C4D18DE47D29B9234B39F03D07D76437BAD7FD8AEA9 + 6C6DE2FD0CD427FC197CB232C0ED7A1F5C0EA0BB4E9174945F242EF08B45BB60 + 24A868CE56A60D5E557187A4EBD451BD092BDC4FA303B1A5514C9FAFDF0E3E51 + 784EB4CAF4304959DD0F0660FC7CE5E1E72AC336C3D62600CD1AE0667F4E3FC3 + AA52A0BB9234B370E275D1AAD23054335C32A23E5B076C00F94E972BDD7A1556 + 9445FE80F748C7D5159D2C9969F12AD33DBC37EE95499AD98F003AAE2CF2B5BE + B5C90621132603CD1AE0B6311AAA5996456E7F46017497B57F1CE41788BBFB85 + 22AB4A9B5555B1DEAB2AEE9174B53AAC576185FB21D5158DB4934F180EAB4C97 + F9CB12403F947E6B5B1DB609A01ED5A19AF6E7F3FB753F1480F149D2EC982143 + 35A9AA685655C55AFF7EF6ACB2C8EDE73AAB8F61C5EDDE6F1956E585D915A84F + 7801EEE42FC505FE923C2149B367D7FD7000C6AF2C726BFDF874B4CA9441C840 + FD433537FA9F47FB73F9E9B2C8EDCC04A0839234B3EF0BDF21693F866A367E56 + C54A9F1D74B93AAE776185F759165175C5A6A8BA02CD58653A3F1AB6F99624CD + 2CC400D07DB676EB4E7F3FAFAD0CDB04303BB6F99FBBCDD1EDDD9D5D5D8B07E0 + DFD89C8AA7FA504DABAA60A8667367552C97F4EDAE5755F432AC70BF94748BDF + 1658CF0FB777CD1BB61956991EC1B04DA01F7CEDD6472BAB4C793F03F55455AC + F7A1B7D6FEF191AEAEC503F0AF551556D19CF8452143359BBF42FA9E3E5455F4 + 36ACF00FDCEF792A65B70654573477D8A64D227E15C336817E288BDC866C5E12 + 0DDB0CEF67569902E315FE8C5527CD5F5416B9FD08A0BB7E4FD201D1504D9B23 + C750CDE656559CE5EDB39DD7CBB0C25DEBA9D4AACA66100EC3CD19B6195699DA + CBF39D753F148059F3A5CA2A53660B01B3BBAA745D5455717ADD0F05607C9234 + 7B91A4E73254B3151B4056FAAC8ACBD413BD0D2BBCC7E7DB517545E88DA6BAA2 + 5EE1C5B8B3BF2C1746C3364FA8FBE1008C5F59E456E6F80D1FEA672B13D9DC04 + CC6E997118AAF995B2C8EDCF1F800E4AD2CC2A997F47D2BE3E54731E43351B65 + 6B9FAB2A7A1D56B82B25DDC7EC8A460FDB9C170DDB7C6B9266567101A0FB7E26 + E98101AB4C793F03A3B76DC0AA52FBF3F7F3BA1F0CC058D9F68F43BD927981CF + 8DA3FDA3B95515F748BA543DD2EBB0C253A9EF54665770186EEEB0CDC36C3B48 + DD0F0660FCCA22B777F1C718B609D432BCCDFEDC7DD4FF1C02E8A024CD8E91F4 + 129F0F170FD5A4AAA29955158F49FA669FAA2AD4F7B0C2593AF5A057576C887A + A3390C3773D8E6CB9334B3041840F7DD25E9579555D3BC9F81D10FD57CB27220 + BEDE6FF0007450926676BEFE5D49FB4B5A2C69BECF8BE37BC3E65655DC25E90A + F54CEF7F439645BEB9525D41A97133876DCEF797A9BD547F2F4933125FA0E3CA + 22B7F7F0277DC8DFCA681832EF6860F44335C381D8FEBC7DC6FFFC01E8A6374B + 3AC22B9717F89CB8D0FEC119BB1941C5133EB32BAEAAB09FEB95DE8715EE622F + 798C37837018AE5F7861EE5419B669656BAFA9FBE1008C5F59E4F65EFEC98055 + A6B48300A33D10AFF6A19A6559E4F6670D40072569666DD5AFF079707BFA7C38 + ABB4A0FDA339B6FA05FA7ADFCC7487A4ABD5438415FFE7306C1FD25457B46BD8 + E6EB9234B3E00240F77D6BC02A53363701A31FAA697FCEBE57F78301180FAF4C + 7E8FA4653E547377AF60B68B41346B86D0A6BE575518C28AFFEBE7FE21CDEC8A + E609D515BBFA4BD55EAE075A3B48DD0F0660D6DAF54E8B2AE02C6066D82630FA + A19A9FEADBF036A0677E5BD2D15EA96C15CBB47F34B7356F9D5FD2DC22E91AF5 + 1461852B8BDC3EAC73AA2B1A29BC40ABC3369F97A4D98BEB7E3800B3E20A5F35 + CD3B1A186D55C55ABFB9BB55D22FEB7E3000E391A4D941F68357282FF28A65B6 + 7F34BB35EF514967F679331361C5AFBB305A93C7EC8A66B783D84B765F5B659A + A4990D0602D0616591DB07F8472AAB4C433B08EF6860EA414518AAB9C22B4B3F + E67FCE0074B3FDE37D920EA8B47F105434B7356F856F66BA513D465811A1BAA2 + 35ED20737C72B1BD6C0FA61D04E88D07BD1432AC32DDEC371061FD2280C9DFDC + 6D8A6EEECE2D8BDC424000DD94F980FABDBD42D9DA3F18AAD91CE11CF378A5AA + E2DB7D0F91092B7ED305D1EC0AAA2B9A5B5D31D7876DDA4BF785499A9D58F7C3 + 01182F5FA5F8B901C3367B5B1E094CC3D6A81F3A0CD53CA3EE870230D6F68FD4 + 2B9269FF68CFC0E32B7D5E45AF11560CAEAE38CB6FEED6FACD036145F3020B2B + 5D9B2F69B1BF7CDF9EA4990518003AAC2C72FB10FFAEDF38D8CD03AB4C81E90D + D55CE5AB4AFFC987D802E89824CDECCCFCFE01ED1F61A8269AF56EDE18BD9BBF + E39734BD4658317C76C50395BE68028B66B6832CF489C687D20E02F4C60FBC25 + 24545784963D00C36DF3602F1EAA79B7A4ABEB7E300063F3C64AFB875DECD1FE + D1CCAA8A4DFE6EB6AA8A8BCB22BFABEE076B02C28A01CA22B7DF2CDF8EFAA2E3 + 9B3B34AF1D640F9F6CFCA224CD9E57F7C301182F5FADF8A968D826AB4C81C9DF + DCAD8F56957EA4EFFDD04057256976B8A4D7D0FED1CA8A37AB200561C5842E96 + 747FB419848370F3DB41F697F4CE24CDEC650CA0DB7E25E9F6CA40E4306C13C0 + 6F0E6E0B4335D7781BD5A57E2806D031499AED5469FFB0C1F4B47F344FFC6E0E + 156F3F2A8BDCAA474158319CF76F7E33AAAEB09B3BFAA29BD90EB29BBF84AD1D + E43049EFA9FBC1008C97DF067F2C1AB649A80C0CF7E480A19A5FA01F1AE8ACB7 + 4B7AFA80ED1F767626AC6856FB47B5E2EDECBA1FAC49082B2676A9F77386EA0A + FBA0A75CB279D515F6F29D17B5839C94A4D90BEA7E3800E35516B97DD375D180 + 963D569902130F6EFB9A0F1407D031499A3D53D22BFC4C6C9BF368FF68F61AE9 + 8D51C5DB77CB22B7F7341C61C5F6FBA2CF88A6CE535DD1DCEA8A5D7DC2B1B583 + ECE7DB41ACDA0240B79DCE2A536052EBF0C2E0B6077C4D3B808EF1CD785661BC + 4CD25E6CFF68C51AE9505561E3077E52F743350D61C5F6D994ECDBA2EA0AA6CE + 377F3BC85EBE1DC47AF500745859E416227FCD6F8B099581E183DBE2A19A9C63 + 806EB2A0E229DEFE616762DA3F9AFD6EDEE46717BB183FD3CF348810566C4759 + E476E83D93EA8A566D07D9D34BDF4E4CD2ECE5753F1C80B1B35BE2072BC33659 + 378D3EDB565987174A8CAF93746FDD0F0760F492347BB16DC68BDA3FEC4C4CFB + 47F36CABCC115AE103C32FA9FBC19A88B06272ECC3FD463F08DB6F2A0EC2EDD8 + 0E62ED206F4ED2CC5EDA003ACA6F893FE6B7C6ABFC1699619BE8BBD0FE110EC3 + D62EF519866A02DD93A4996DFC789B6FC65BE2ED1F56714CFB4773B733C57384 + BEEEE30750415831F9A9F3DFAC5457D86F2886B8357B3B88B5831C2CE903499A + F1A206BAED2E493755866D122AA38FAA83DB56FB61D806B759E511800EF133EE + 07251DE29BF1ACFD83A0A21DAB4AED22FC1ABF18C70084159377B3A42B2B65C6 + 61EA3C9AB71D24B48358CFDE71927EBBEE8703303E7E5BFC0F7E7B1C6F7022B0 + 409F876AC6AB4A59870774D31BFCAC4BFB47BBE60885AA0A9B55C1B6C921082B + A676103ECB7F535166DCAE76907D25BD3649B323EA7E3800E35316B9DD20FFD8 + ABE0E255A6BCA7D1F7A19A9FF0195C003A2449B32325A5DEFABCD8CFBE0415ED + A8AAB04AD00BCA22BFB3EE076B32C28A29288BFC6E491732C4AD55DB41423BC8 + 81DE0E62210680EEFA56346C33AC32E5C6027D511DAAF9985786DE5AF7830118 + AD24CDACEDF9F7FD8C1BD694CE89B67FA079EFE61024AFF020F93B753F58D311 + 564CDD77FD371765C6CD15D633D9CBDA5EE47B783BC8D37CA513808E2A8BDCDE + C9FF1C55C18519435457A04F13E6D7474335ADAA82DFFB40F7BC5FD2117EC6DD + C3DB3F5853DA8E39425601FABDB2C82D50C604082BA6A82CF247BCEF93216EED + 59673A4FD2222F913B3949B393EA7E38006375B5AF67A40A0E7D3F0CFFB82C72 + 0BED0074489266AFF435A5FBFA19D7CEBAB47FB46755E9FD92CEA9FBC1DA80B0 + 627A7EE865C65457B4A31D64572F8D5BE22B9DDE91A49995CB01E8201F54F5F7 + 5115DC86A81D84F734BAAA7A187EC8DBA20074489266B6E9EECDAC296DE5AAD2 + B09DE9AB6591DBDF633B082BA6A12CF27503569932C4AD99423BC81C5FE5B4D4 + 573BFD01EB4C814E7BD82B2CE22AB8B0C189F734BA5A551126CCDBEFFFCF7B5B + 14808E48D26C175F537A50B4A6D45A9E092A9A2904159BA355A5BF947479DD0F + D6168415D3678336EFF2DB0BABAEA0CCB8F9ED20619DA995CC3D4BD25BEB7E38 + 00E3E13DFA9FF7DBE515952A38A0EB13E6ED7C726DDD0F0660E46CF6DA51BEA6 + 349E5341FB47B3B733AD8FB63359550567914922AC9826BFADF85A65881BB776 + ED59676AA573AF4ED2ECD9753F1C80F1288BDC0E07B9BFA7AD0A8E55A6E8FA61 + 384C98FF88B74301E88824CD5E2AC9BE5853DAAEF68F3848FE39DB99A686B062 + 667E21E9FACA10B71058A0B9EB4CADB7CF66561C20E9DD499A59091D806EFA81 + 575754876D025D1BAAB9C6DB532F2C8BDC7E04D011499AD97AD2B7495A16CDA9 + B04B38DA3F9A6BD076A66FB39D696A082B66C06F2DBEE1B718ABFC37232BF29A + BFCE746EB4CEF42992FE88F915403795456EDFC8FD435405673DFDBCA7D1155B + 070CD53CBDEE870230F239157FE433D7E23915AC296DD776A69C2079EA082B66 + EE0E49177869CFDACA103734B31D2404168B7C7EC57324FD4EDD0F07606C6E96 + 745BF49EA60A0E5D6AFFD8E08761BB38F97259E4760E01D01D1F90F4749F5361 + B3D79853D18E55A59B3D485EEE73847E54F783B51161C50C79294F3E64881B07 + E1E6AF330DF32BD224CD8EABFBE1008CAD0AEE63D12A53AAE0D0A5C370E885BE + 5FD2C5753F1880D149D2EC55925E52995341FB477B82E4555ED9797A59E4F6BE + C61411568C8097F47CD74B7CE215791C849BBFCE748197D4D9FC8AF7256966D5 + 16003AA62CF2153ED88AF734BA7218DEE287E13061FEEF19AA09744792664FF3 + CADFFD7DD6DAEE7E7625A868F650CD272B4335AF92744DDD0FD7568415A363A5 + 3DF77AA98F95FCB0CAB45DF32BACB4EE30491F627E05D059A7475570EBFC9B3D + BEB9439B27CCAFF1C3F0D5921EA8FBE1008C469266164C7C50D2C13E632DCCA9 + 20A868DF50CDAF13244F1F61C588788FE8575865DADAF9157B7A899DB582BCAB + EE870330B6F77475E534ED2068FB61F841499F67C23CD00D7E696603359FEA97 + 6976A9C69C8AF60DD5B4B3C6D96591DF57F7C3B51961C5685DE5AB4C19B6D9EE + F915A724697652DD0F07602C2EF41BE8B0CA94194368FB61F8ACB2C82DB800D0 + 0D6F9574BC0F815FE4732A6C23085515ED1AAA69214551F783B51D61C5089545 + FEA4DFDA85216EACC86BDFFC8ABD7C7EC5BB9234B31F0174EF3DFD51866DA203 + 87E1C73C7863C23CD011499ABDC07EF0CBB3257E99C640CD66AB0ED55C196D67 + B2BFC70C10568C5859E4B6CAF4A73EC46D75D40EC241B8F9F32B76F3523BEB0D + 3CD4E757588801A05BEE91F4CB4A151CD51568E361F8136591DB190340CB2569 + 76A0A4DF9374A00F7F674E45FB866A863942BF907465DD0FD7058415E3917B0F + 6975881B07E166CFAFD8259A5F61A57747F97023001DE2BDFD9FF46FF658398D + 36187418FE95A4DBEB7E30003397A4999D3FFFD82FCBF6F6CB330B2A9853D1CE + A19A5F65A8E66810568C4159E45651F175EF255D1DB583306CB3F981C5AEDE1B + B8C84BF04E4AD2EC4D753F1C80D12A8BDCBEE13B275A654A151C9A1E54540FC3 + A7325413E80C1BA8F974BF2CB34BB3B97E894650D19E3942ABFC7BBFEF335473 + 74082BC63BC4EDE6A8CCD87A4C19B6D9FC3F0F3B45F32BAC577099A4D7276966 + 838E0074CBB7FD9BBEB0729A55A668C3504D0BD8CEF18B11002D97A4D9DB249D + E897648BFDD2CC2ECF082ADA334768AD9F25EEB60D20753F589710568C89F790 + 7ED90FC20C716BDF869039DE2BB8D47B07DF9BA4997D8800E888B2C8ED9DFC8F + 03AAE0784FA3494255C5BAA8AAC28236002D97A4D94B24A57E3916066ACEF1B3 + 28DFA7353F480E156F2BFDDDFCA5B2C82D58C688F08760BC6E91740165C6AD9E + 5FB187EFB83E4CD29F307013E89C6B7CE0E663FECDA0DD9030BB024DABAAD8E0 + 25C63667E5731EB40168B124CD8EB0ED7395819A21A8A0A2A21DEFE63047C82E + 3D2E91746DDD0FD735841563E4BDA4DFF4D562A1CC988370BB028B79D1C0CDA3 + 7DF811808EF001581FA9AC326528329A605B74180E25C67749BAAEEE07033033 + 499AEDE1732A0EA90CD4644E457BC28AB0467AB92F56F81A4335478FB062CCCA + 22B79B90AFF9417855545DC1B0CD760DDCB41EC2FDACA73049B377D4FD700046 + CADECF577B155C5865CA7B1A751AB4AAD44A8C3FC2611868B724CDAC72E2CF24 + 3D351AA86997630415ED7A3787A19A7686F87A59E4165A60C4082B66C7CF25FD + D2CB8CAD54888370FB066E5A0FE15EDE53F89A24CD5E5AF7C301186915DCE7A3 + 619BF12A5360B685B34175A8E6456591DB8F00DAED83928EF34BB0457E296641 + 05ED1FED7837C76BA4ED9D7C93A4F3EB7EB8AE22AC98BD619B5FF283F08A4A99 + 31DA317073B7CAC0CD7724697664DD0F076034CA22B7DBEBEFF8C16375142AD3 + 0E823A0C5A556A43BB01B45892666F92747265A0A655F11254B477E0F117FD7B + 3D8C0161C52C298BFC76493F8A0EC2765BC2D4F9F6B483ECEC814518B879A8A4 + 3F4CD2CCDA430074C3395175455839CD8C21D4D9FEB1CA07B79DCE8479A0DD92 + 347BB1A4CC830AABD65DE0D5BB76C624A868D7C0E3D5DEFE717659E477D4FD70 + 5D465831BBECD68EA9F3DD18B86981854D71FE7092669688036839BF1939359A + 31C42A53CCB650621C0F6EBBDFDB4901B49457E3FEAEA4837CA0E642BF040B41 + 0561457BDA3FD6FAF77236F0F8BB753F5CD71156CCA2B2C8D77B3B48983ACF41 + B87DED20BB440337F797F40C5F69CA870CD09D95D3B7F94184EA0AD43D54D3CE + 0B0CD5045A2C49B3A5BEF9E3D068F3C75C066AB6CAD64A6B9E6DFF388D8AB7F1 + 23AC987D5749BAC2CB3A433B08C336DB1558ECEA3D8621B078BEA7E500BA316C + F3E39555A684CA980D836EEE6E90745FDD0F06607A9234B3EA897FEFD5B8FBFA + 404D367FB477FBC76AFF1ECE066A5E5FF7C3F50161C52CF3DB91AF7822B7DCCB + 3CC3D4790EC2ED092CE678AFE152EF3D7C759266AFAEFBE100CC5C59E4766B72 + A1CF185A1385CA0416187750511DAAF9290FD000B44C92663BFA8AD267F8E68F + C55E9DCB40CD76B6E68510D902E4337837CF0EC28A1A94456E377667D217DD4A + 3B5436842CF092BE0324BD2D49B313EB7E400023713A1B9C50C3E0B6F8E6CE06 + B7D9E118403B7D40D209D1E68F10545051D1AE77F396A835CFCE055F2A8BDCDE + D398058415F53957D22FA39BBB4D51750581457B3684CC8D3684D8D0A4F72669 + 7678DD0F086066CA22DFEC557071CB1EA132C6A53A54D30EC40C6E035A2A49B3 + 374B7AF980CD1F5454B42F44DE146D66BA4CD2E5753F5C9F1056D4A42C723BF4 + 9E36A41D04ED0B2CF6F45EC4C324FDA90F5302D06EB68181963DCC6655453810 + 7FD6CF09005A2649B357487ABDA403BD5DB81A541056B4AFFD236C66B235D254 + 59CE22C28A1A95457EA7FDE00793D00E425F743B3784CCF3A149D693F8545F69 + 6A3F07A0A5FC40F2F1CA3BDABE81A4020EA3B22DBAB90BFDD077FA604D002DE3 + EDC0EF94747065F3875D6ED1FED1BEA19AEBBDFDE3410F2AEC1D8D59445851BF + EF49BAC3DB41D6FA8185ED20EDDC10322FDA10728C0716F6CF00B4D79DBECA34 + 54576C8EDED1C04CB0AA14E89024CD8E94F43E828A4ECE10BA52D245753F5C1F + 1156D4AC2C720B27FED9FB53690769774BC81C1F9EB4C4038BE748FA5092667C + 3801DD5965CA40648CC2B64A55C51ABFB4B8849B3BA07D9234B356E00F793B30 + 2B4ABBB5FDE3011FAAC9F7663520AC68061BB4F9E3CA2037DA41DABBD274771F + A6641B425E2CE93D753F1C8019AF32BDCC0F2D6BFD10C3EC0ACC5458551A0FD5 + FC62DD0F05606A9234B30A8AFFE86DC00415DD6AFFB0F7F257CA22B7EFD15003 + C28AE6DCDC7D4BD2DD95ED20B483B4471898B4B3AF345DE843952CB0382549B3 + 37D4FD800066E40B1E28AFACAC32E5FD8C519419DB67FF196591DBDF03688924 + CDACCDE32F243DDDE796593B302B4ABBD3FEF10B4917D6FD707D4658D1106591 + AFF776101BE062B778EB3DD9A3E4A87D81C54E5160B1B74F837E639266AFACFB + 01014C4F59E41BBC022E5457C4813230DD32E350556165C6E7D5FD6000262F49 + 33AB9CF8B0A4677AFBEF12AFAE0D4105DF67B5BFFDE35FCA22B7CF7AD4843F44 + CD729DA49FB11DA4332B4D2DB0B0D2C07D7CD8D23B93347B61DD0F0860DABE1D + 5557D8FB9955A618D550CD8FD30F0DB487CF23FB1349CF93B4CCDB7F77AFAC28 + 45BBDECB5BFCB27885B77F7C99F68FFA115634AF1DE4EB513B08DB41DA1D5858 + E23EB71258BC3749B367D5FD8000A6AE2C723BC89C35A05D8FCD0D98EEED9D55 + 55DCEC5B6700B4C71F487AA10715D6F6BBA012541056B42F40DEE897C516505C + 2EE9E7753F1C082B1AA72C722B09FD276F07591EF54673E3D2DE0A0B1BB2B4A7 + 0F5DB229D17F98A4D9D3EA7E4000D3128621C7ED7A54BF613AB7776178DB27FC + B202400B2469F65E492FF3B964715061673E828AF6B77FDC6773AAA8766B06C2 + 8AE6B6839CEBA5A196F0B11DA49DC2FC8A5D3CB058E4C3970EB7D2C124CD6C96 + 058016F1DED5D3FD4063D515BC9F31D5E16DF1AAD20BCA22B7416E005A2049B3 + B7497A95CF23DBDBE79359DB2F414537DA3FECB2F88B6591DB85311A80B0A281 + FC86E50C4977B11DA43381C5AE3E1D3A04164748FAF324CDAC3D0440BB5CEA61 + 727533083091EAA1D87E0F7DB5EE87023039499AFDB6A4D74B3AC8838A3DBCDD + D7820A367FB47B7ED02A7F275FE49FF16808C28A66B783FCA34FA2B574CFFE9E + 7690F6CFB098EF6BAD6C6AB4B582FC45926616600068092F0DFDBC87C9762B4E + 7505A6BBAAD44A8F01345C9266AF96F4A64A50112A2A082ADA255CFC562BDDEE + F1A19A5C3E34086145B3DD28E99CE8066F43B4CE940371FBFEAC850A8BDD7DBD + 950D653A4AD25F256966FD8E00DAE3062F170DD515F64D2761328679D22F1CD6 + 45A5C6AC2A055A2049B357487A87A4437C60FA9E5E516197500415ED9D53B1A5 + B23EFA1F69CB6B1EC28AE6B7837C4BD26D95769010561058B4B725240E2C8E91 + F497499AD9071F8016F09B974FFAB04DAA2B3099AA8A0DFE7BC57ECF7C8AE16D + 40F3256976B2A4DF25A8E8FCFA68BB1CBEB6EE87C36F22AC68B8B2C8377AB9F1 + 033ED06D5D7483C781B85D7688028B3995C0E2595E6161258500DAE10E9F1A6E + 37E5BC9BB1BD49F3E106EF2E5F570AA0C19234B3D5A4EFF1D5F30415DD6BFF08 + E1B15D0A7F93AD4CCD4458D1026591DF22E9BBBEE26C85278161A01B7FB0DA1D + 582CF0B557B6FEEAD93EC3C27E1E40C3F9C1E6E35457608A03DC3ECEA11868B6 + 24CD4E94F47E4987FA60F445BED98DA0A2BD4250B1255A536A97C19FF5CB6134 + 1061457B7C5FD24D7E285E156D07E150DCDEC062E728B0D8CB038BE74AFA8F49 + 9AD9872180E6B3D903B7535D81ED54558483F10DFE390EA0A192343B41D2EF4B + 3A4CD2BE5E5111820ABB6C22A86877781C3632D925F05965915B65051A8AB0A2 + 25CA22B714F07392EEF7038FCDAFE050DCADC02254583CCF2B2C082C8086F31B + F253A320D96ED00992513D1887BEE8CF50550134579266C77B5071785451619B + DC082ABAF13EDE1855B95D23E9ECBA1F0E1323AC6891B2C8AD37FA6B7E93176E + F16807E94660B15B14581C28C93E2CA9B000DA6185DF988735D304C988FBA2D7 + FAEF8D0BCB22B7BF06D040499AD965D1BFF3A0C22A2A082ABA35A76273B4A6D4 + BEA7FA7C59E41660A0C1082BDAC7569D5DE689E02A4F08ED0F1A814537028B85 + 5160616588041640C3F94DF967BDBA225E33CD7BB9DFED1FD57263BB6C00D0DC + A0E2835145C5625A3F3ABDA6F4B4B2C869C96B01C28A96F15567A749BAC793C1 + D5D1FC0AD699B6138105D0726591DB6DCD957E10B2DB73AA2BFA295E556A9709 + 6BBC75F37B6591DB67358066B67E0C0A2A6CD53C4145B7D6943E145DFCA20508 + 2B5AA82CF295BECED4E6575076DC8FC0E22F9334B30F4D00CD759A57BDADF41B + 75DAF4FA69ABFFDA87AA0AFB3DF183BA1F0AC06F4AD2ECF90415BD088EC39A52 + 1B88FDD5B2C8ED9FA105082BDAEB5A1F0A13E657B0CEB4DB8185A5FE7FC55A53 + A0B9CA22B7F7F04FA321C86C6DEA97418763AB80FC4259E4F673001A2449B393 + A21915FB1354747A1BD3A37EC96B438E2D48464B1056B4BB47FADB927E59995F + C1C1B87B81C5DE1E58583FE57F4ED26C6EDD0F0960A86F0DA9AE403F84C371A8 + AAB00B852BEA7E2800BF2E49B393257DC0D79386AD1F0415DD0A8EE33915F62E + 3EA32CF25BEB7E384C0D61458B95456E07A2CF7852F8A82787F1FC0A746B4B88 + AD357DB6A4BF4ED26CF7BA1F12C0D035D367F83BD9AA2B0891FB5955B1CA4B8E + 3F49B931D02C499ABD52D2FB2A41856DFD20A8E8DE9C8AB0A6D46654FCA8EE87 + C3D4115674639DE9977CB26D985F618765E65774B7C2E23849FF4F92667BD4FD + 900006FA991F8E5644D515F64E463F4A8EC34DDE5DDE1F0DA02192347BADA4DF + 957428EB493B272C1A78BC32A7E24E49FF443B5E3B115674C38592CEF712A778 + 6D1E814577028B39950A8B6325FD4D9266F6F7009AB7B5E9337E485AE5EF64AA + 2BFA3571DE7EED3FEE2D9B001A2049B337487A5B25A8603D69776CF3CFDA30A7 + E231AF3EFF6C59E4165CA085082B3AC04B4CBF2CE936E657F42AB038C62B2CAC + DA0240B3DC24E95E3636F5AAAA62931F90EDD7FC3A6F0502D000499A5948F166 + 4987105474FA3D1C6F62B24BDCB3CA22BFB1EE87C3F4115674844FB6FDB42788 + 8FF98189C371776758ECE581C5D37DADE911753F2480DF08913FEA37EC71C51B + 01727707B9ADF75FEB87FD268F5F67A0019234B3F914BF4D50D18B9941A1BAED + 214957492AEA7E38CC0C61458794456EBDB15F677E45A7038B9DA20A8B10581C + 29E9CF93347B46DD0F09E0D73CE437ECF12A53DEC7DD3C206FF25F63ABA638AF + 2C72FBFC0550A324CD764CD2EC43925E2DE96049FB48DA53926D5523A8E85E1B + 5E3CA7E26E499F2B8BDC7E1E2D4658D13D3F91F4732F7D0AC3DD985FD1BDC0C2 + 2656DB4690259296497AAAA43F4BD2ECF9753F2480FFC36FD63F3364D826EFE3 + 6E88AB2A56F8AFF537EA7E28A0EF9234B330E2C3925E5E092A4245857D0F4450 + D1ADE1C6614E852D1FF87459E4F64E46CB11567473B0DB693E81FC614F18995F + D1FDC0627F494F91F4415FC905A001FC86FD877EE3CEFBB8BBAB4A57FBAFF137 + 7C7D2D809A24696681C47F927492A4833CA8D8C32B2AACA596A0A27B732AC216 + 26AB2EFF7659E437D4FD70180DC28AEE1E8EFFC1E757582914E5C7DDB283FFD9 + 0D8185ADDC5AEC81C5E1927ECF275E036886B3BC2584619BDDBDCD5BEE158DB6 + B616404D9234B3F3D0DF4A3ADE830A5BFB4E50D1DD7770BC85C9DEC197D9B742 + 753F1C4687B0A2DBF32B4EF784D14AA23820774F35B0B08151FBF94AAEB72469 + 667BC401D4CC77BB87769078D866D8098F76AF2A5DE5BFB61FF3C1AA006A90A4 + 9985137FE3EBDD0FF4ED690B7D38394145772BDBC23BF82E49FFE89FB9E808FB + 838BEE3A4FD211FE929E5379513354A81BC2AFA53CB008BFBEF6E3EB9234B3DB + 84CF787B1080FA5849EA1DDE33BD7B7478B6DE69C3FBB89DAB4AD7F885C0CD7E + 5006508324CD8E96F447DE126B95A68BFD5D1BCEBFA18D16EDB66DC03BF8519F + 53F1C9B2C8AD250F1D42654587F90DCF97FC10F590278F9640B23EAF9B81C52E + 5EE6B8C857731DEC83A5FE2A4933FB7900F50EDBFC7B7F17AFA86C6B423B7BA4 + C3504DFB35FD38AB4A817A2469F64249FFC1B7A31DE0DBD21644A1304145375B + F0D679586C6DEF5F298BFC96BA1F0EA34758D17165915B3871AA278E36BF62B5 + 2791562245097277846A8A1058ECE903A5AC24D23684FC9724CD6C1027809A94 + 456E2D203F8EDEC50CDBECC650CD73CB22B7DB3D00B32C49B3C4868B7B45856D + 475B125554842A62828A6EBD83E3B0D8E654FCD4DEC3753F1CC683B0A207CA22 + B7C4F11F3DB078D48781C58105BA1558ECECB7097BF86029EBDB7C9607163680 + 13407DCE886609D9BB985942EDBDD10B433559550AD42049B37749B2AFC306B4 + 7E1054747B56D04AAF6ABBC966F4312FA8BB082BFAE37249DFF743F2724F2443 + 093287E46E5658ECE683A5F6F6B2C8A324FD659266CFABFB2181BEF2C15FA746 + ED20E15D4C7545FB0ECA36D0EDB36591DBCF019825499AED94A4D99F487ABDA4 + 437CB8F8629FDDB5AB07150CD3ECE6FB3754B55985E2BD3EA7C27E0E1D4558D1 + 13DE4BFB6D4957FA4DD08A68223D8145B7849B845061B1C0FB372DB078AAA43F + 4ED2EC35753F24D063D6577BCD80D63C028B660A2D934F5406BAD93CA8EBEB7E + 38A04F9234B333CD5F4B7A99CFE6DAD75B5FE74541052145B7574587819A1616 + DBF734E830C28A1EF1DB9FCFFA44FA877DE0A605161C92BB1B5884D5A60BBC8F + 7399974BFE2EAB4D815AC3E34FD10ED2CAA19A6BFDD7CC7EED3ECA504D60F624 + 6966972EFF55D20903820AAB28A59AA27BB60E19A8F92D4957D7FD7018BF1DB6 + 6DE373B66F92347B8AA7D287FB37AF8BA2173DFD7DDD7CD10F2A9FB397FD45F6 + 4D5359E4760807308B92343B51D2BFF777F17EDEB665D550DC0C3633A858ED41 + FFED92BE50167959F7C3017D91A499CDDEFA77D1FB32CCA708EF4C828A7E5454 + DC2DE927923EED6D95E8382A2B7AA82CF2DB247DD1BF590D0337ED45C0C0CDEE + FE390F1516F3FC1622AC363DD9076F5A9B0880D975990F077BC42BDD680769F6 + F68F35FE6B7597A41FD4FD70405F2469F64A497F16AD265D1A85BBD6F24A50D1 + FD3915AB7CD693B5DFFD3341457F1056F4D785965B440337ADB48A819BFD18BC + 39AFB2DAF4D91E58D8004E00B3C45B083EE2C1F163FECDB00516BC879B575511 + CA8FED33F37F32791E18BF24CD76F096D5F744AB49F78A367E58504145703F82 + 0AAB6ABB47D2C7CB22B7C1D4E809C28A9EF283D69995819B6C08E9CF6AD3B9D1 + 6A530B2C2CA8F870926636B00AC02CF143D76903DEC3545734E7B0BCDE7F6DEC + 56EF7B65915B6801608C9234B3AA890FFBC68F432BAD1FAC26EDDF4063DBFCF1 + B9B2C82DDC478F1056F498CF29F8B4F7DF3EE4ABD836FAE18C8372F7038B419B + 42DE6F7BCBED36A3EE07057AE45249D756061FF31E6E4EFB4798F363C3A9BF5B + F7C3015D97A4D93E3E48F325D16AD245BE9AD42A449951D1AF8AB6FBFC82F5AA + BA1F0EB38FB0A2E7CA22B743D8C73CB10C7DD30416FDD91432C76F296C53C8FE + BE292493F417499A59F50580D96907F9B81FC81E89DA41C21C21DEC3B3AB7AAB + 170612FF0FDA3F80F14AD2EC386B4D95749C577EEEE395A061103C0388FB3150 + 739DB7A95BEBDD7992CE66FB523F1156C00ECA362CECF31E583CEA87B378E026 + 2F87EE565884C19BF3FDD6623FBFC57891A4BF4BD2CC0E0A00C6AC2CF24D1E58 + 84F915AC33AD774DDE96E8B06C2D3AA795456ED58700C62449B3D74AFA53494F + 9774A0B7AADA204DBB3C6190663F828AC7BDBA7085BF7BAFB3A5006591DB3F43 + 0F115620B8DC7716DF573928B321A4DB42603168F0E6B1B6E23649B3E7D7FD90 + 401F94457EB3AF64637E45BDED1F5BA23915F66B7185A48BEB7E38A0AB9234DB + 2949B30F4A7A676590A6B5AAB2F1A35F338236440335ED32F51365915BC5377A + CAFEF003FF5A869CA4D9F7BD1560CE909E40C2ADEECFB1082D223BFBEF01FBBD + F047499A59B5C53728C103C6EE7449C7F84DE2AE95433A87F5D95F9367D3E7FF + 81771F301E499A2DF66A8A63FD0CBA97B77DCCF5734878EFF1EEEBFE8C20AB30 + 5C5DD9FC61D56DE831BEF9C4BFF112AB2F78C9557CB3C7FC8AFE0EDEB4DB8DC3 + 25BDC9E75858BB088031F19908FF5F3447C80E6ECC119ADDA0221C96EDD7E0EF + 7C183580114BD2CC028ABF9374BCB7A0EEEB2DA9F17C0A42DA7E6DFE78C4DFBD + FF5216F92D753F20EA4758815FE3A5569FF00D2116583099BE9F8337C31C8BC5 + 953916FF2D49332BD10430DEC1C79FF0B6BC4707CCAFE03D3C3ADB2A43DDD6FA + 61D9FE7FFFF9B2C8EDFFFF00462C49331BE6FDEF7D75FA413E9F22AEA8609066 + F755DFBD8FFADCA6B3245D54F7C3A11976D8B68D330F7E539266B6D3FA6F7C3B + C432FFA63524DDA4DCFD2BCB0BFDDB76DB78B7AD902A8BFC9CBA1F12E8B224CD + DE28E9AD920E8D26E2EF16DD366274B77A76585EEDAD1FD627FDADB2C8CFA8FB + 0181AE49D2CC2E436C3EC5497EBE5CEAF3B2C219336E4945F787196FF68A8A47 + FD7CF9230F8AEDBD0C70D8C1606591DF29E9339552E4B04A8F0A8B7EB585CCF5 + 69DC4B7D3AF75325BDC78661256966070B00E37196B7E53DE061E13A3FD8D93B + 98159AA3AFA878CCFF7F7DB505B2753F20D035499A1DE86D1FBFE521ECFEBE3A + 7D779F914550D1BFD63BBB0C5BE9EFDEEB7CF3124105FE0D951598509266AF96 + F4EEA8973094E8F181D2BF037DE8E75EE3877A6B13BA49D2A7CA22B7B23D00E3 + B985FC7B0F090FF283BDCD94B19FA74C7AB4418585F337DA16A4B2C8ED7D0760 + 4492347B89A4B74795628BFD5D1686BA53B5DBBFAD4B613DB4B5DDFD52D27F2D + 8BDC8279E0DF105660BBEBA47C95D4EB3CB0D8C76FD92945EE8FF09278326A0B + B10F981551C9F4D7CA223FBFE6E7043A2949332B91FE9FD14ABF7013495FF7CC + 828A2D51506187E5DB24FD6559E436A709C0E8CE91BF27E9155E4961B329F6F4 + B95816543044B3BF1515768EB4CBAE3B7C98B1B58100BF86B002DBE5A5FEB656 + EAC5920EF6768090861358F4738EC516FFA059150D443ACFB6C97023098C9EAF + 0F1E3447C82A2C38E84FAFA222BED5B3C3F27F2E8BDCDE6900462049330B263E + 24E919D15AD285D16AE610B6F2FEEAD7197243D4FA71A7AF28FD45DD0F886622 + ACC0A4F8CACABF96749CCF2DB00F1C4A91FBA77A2B19B7853CE46D219F2D8BDC + F6630318A124CDECFDFB6751AF77BCE28FC0627A4145B8D5FB9BB2C8ED3D0660 + 0492343BC92B73431BF162AF080BADC4E19DC57BAB3FEFDFC7BD3A7795B7125B + 50F14F6591DB651730106105262D49B3C53E18E969920EF052640B31082CFAF9 + A1136F0B59EB2979BC2DE4C7753F28D035499ABD54D2FBA36F00E229FA041693 + DBFA1107157658FE2F6591DB206900A369FBB059672FF3B3E2D24ADB471C54A0 + 5FEFDF4D3EB0FF616F21FEA67D9545CE37A3188AB0025392A4D9C15E8A7CB8DF + EC2D8E020B3E7CFA65505BC86A6F0BB1D2BE9F4BFAE7B2C8ADFA02C0882469F6 + 7A5F697A7034F898C062FBEFA9304C330E2AFEB62C72FB7B003394A499B5A8FD + A1A4A325EDE7975A0BA39635DA3EFABBA2345C6C3DE2975A3FF433229B3F3021 + C20A4C599266D67BF861EF9DDE2FEA9DE6A0DC3FD56D211BA26F061EF28175FF + 5216F90D753F28D025499ABD59D21B7C43C83E7E7369E5D50CDDFCBFC2BBC90E + C31B2B4185BD9BFE5F665400A391A499AD237DB387A8FB446D1FBB55CE87BC9B + FA17548461C67699656DC297D996ABB2C82DC000264458816949D2EC8592FEC0 + 7BA7F78B4A9129EFEB9F416D21616FF6233EBCEE6C6F0DE185038C409266F68E + 7D8BA4D757028B101CF739B018B472D9AABE1EF3A0E27ADBAE42D5173073499A + 5948FA3E492779C56DDCF661D5149C0BFB299E6FB62E5A0F7D836FFEB07967C0 + 76B1C501D375B1ADABF4178F7D436A2F9D8DFECDAA7DD3CA37A5FDB183BF4B76 + F26F92E67959FADE3E8CF508FFA6EA6F9334B392750033E4C1DF19DEF37B9757 + 32ADF4A0708B1F12FBF82E1E344FE7B16890E60F24FD37820A60E69234B3768F + FF2EE9146F0F3E201AC05EADA8403F838AB0A2D4066ADE2EE97F1154602AA8AC + C0B42569B6A3F74DBF212AFBDBC33FA02C49A7DCAF7FAA379A83866F7E8BE19B + C0E82469F60A49BF1B55582C1A30FC78871E55783D1E0DD20CEF1EABF0FA3253 + E78191557659CBC76B3CA0D8DBAB2942DB07DB3EFA2BBC87E3A0E2010F8BADA2 + C2CE81C0A4115660469234DBD927D39F121D9417FA87555F0EC9D8FE50BB78F8 + A6DD005FEA839548D7811148D2EC05923EE0EFE1FDA2C0628EBF8BBB7ABBB96D + 406F7458A9BCC2DF375601F8D1B2C8EDB00C60069234B3568FDF97F44C1FF0BB + 975F54CDEDC1FB06138B03E30D5145C51DFE0EB6163C604A082B3063499AD987 + D39F487A911F94977A60117F68A1DF5516E11B88B5FEE1F5B04FE2FF5A59E4D6 + 5204608692347BBAA4FFE0EFE17D7DC0DD82685DA0BD8FD5A16F22AA955C7130 + FA981F92AF90F4F9B2C8EDE701CC409266AF92F4466FF11C3444934BAAFE8A83 + 8A8D5ED5F6A0B7297EBA2CF24BEA7E40B4136105462249339B53F057929EE31F + 624BFD038CC0A2DFAAC337C33713ABBCCAE2415F71FA85B2C82D85073003499A + 5955C57F9274486575E0DC0E7D33118714210CDDE06D1F2B7C8E92951DFF5359 + E457D6FDB040DB2569B687576E1DEFEF95504D11AAB718A2D96FF1396FA39FF1 + 1EF2A0E24B92CE61C03AA68BB002A3FE30FB1B49C74443964260611F620416FD + B56D8232ED87BD44F0AB65915F5EF783021D098FADDAEDD9FE8D8585C7F67E9E + 37A04C7B8716879F612ECE3AAFA6082B93AD9AE24BAC2505662E4933DBF2F176 + 0F40F78E2AB6E6F66C2E0E267E2F87F7F16A7F0FDFED43A0CF22A8C04C105660 + A49234B343F1DF4A7A9A07164B3CB0883FD0D04FC306E0ADF2926DBB09BDD0BF + C960523F30F30178A7F8269E65FE4DC6A228400E55164DBF0D8D675284C0331C + 8A3778E8B9D22BB56C88E667CB22BFB9E667065A2F4933AB9A788FA41746A1E7 + 9E43AA299AFC0EC1F8CF754F4441C5231E547C4FD257CA22B77736306D841518 + B924CD967960616BAC967960519D4C8FFEAA56596C1830CBC2AA2C2EABFB4181 + B64BD2CC6E43FF2C1A801CDA42E6F93B39CCB268D2371CDB2AEF8AB8926273D4 + F21182CE477C95F6C56591DBBF03600692343B41D23B241D16CDA6A85653343D + E8C4EC05159B3D38B677F13D927E2AE973BC8F310A8415188B24CDEC03EEAF25 + 1D2A697FFFA023B0C0A09EF390C8573786D8E0CD2F96456E410680694AD2CCDE + BBAF939446FDE6E18634CCB2D8B9D2AEB7438D01451C68C6ED1E6148EF1A6FF9 + B077C5F7259DCB004D60642D64B606F9C543AA29EC5D413505E2335C5851FFA8 + 07153648F36365915B8001CC186105C62649B3A324FDB927F3FB4581453CE40D + FD36D12C8B504A786659E4E7D7FDA040DB256976B0A40FFA3B39B4852C8CBE11 + 096172B5D2628759AAA08887663EEEEF84105284B9142B3CA8C8255D4498098C + 46926627FA6C8A43A36A8A309C976A0A0C0A2A2C9058EB156EB622FA2A49FF8B + F018A3445881B14AD2EC595E827C68145858724F6081896659C4EB07E3817996 + DC0398A624CD76F4C19BEFF16F484295C582680067A8B41836887387190613D5 + 168FB88A628BBF03C24C8A1052ACF4B936674ABA91B936C0682469667FF6DF2D + E905BEF2380CE48DE7DB504D8120BE600A4185CD0BBA4ED27F2F8BDC2E9C8091 + 21ACC0D8256966ABAE3E14ADD25B14F54B93D263A22A8BB595E179850D6D62B2 + 343033499AED26C96E52DFECDF9C2C8EBE4109A1453CD362C7CA372CD5F776F8 + FB6D9368EF087FCEE3368FCDD13C8A30C766B57F5DE05FF7F2671F189D24CD4E + F67740986913AAADA8A6C020F1196D9D0715F74BBA49D27F2B8BDC2ADF809122 + ACC0AC48D2EC45927E7F40601127F640B5CA624B5465110670DA87E297CB22BF + B5EE87053A125A1CEBDFB0EC5B690D89438B6AB545FCDEDE610A01C513514011 + DA3C4215C5FA28A4B8DA038A3BA9A200462B49336B03FB3D49CFF53FF77B7958 + C96C0A0C13B77EACF7763CBB44BA45D2DF95456EADBBC0C811566036D7E8BD4C + D27B251DEC8185951E1358607B55168F473DEB61FAFF8392CE93F4F5B2C8ED1B + 1D00336F0FB177F3C95E71115A43C210CEDD3CB4A8565B0CFB66A6BAC9230E28 + 429BC7463FF486560F1BCC76B9DDD4115000633B8B8561BB0744555556514535 + 05B61754848A8A155E51719B5754D85F0363415881D9FE903CC5274D1FEC693E + 810586896F659F18B0E6D452FCBB247DAB2C72BB810530BA8D00074AB216BE13 + 8684163B471B44E2C022FCB9AD0ECB0C6D1E1BA35914D77805850D665B5E16B9 + FD59073006499A3DC5AB298EAAAC310E9BDAA8A6C0F6828A505161F383EEF019 + 15760E03C686B00275041689EFEF0E8185951E12586098F88636AC300CAD21CB + BD35E41792BE5216B9952402189124CD76F26F6AEC9B1BFB66E7A9DECE177F73 + 537D6FC71515F667768DDFC0DDEAABEDAC3A6A15F32780596BF57AABA497FA2A + F930543754538481E79CBFB0BDA062850715774AFA9FB4E362361056A0CE32C4 + B7562A2CC287261F98A80A2FAAB8CA22ECF65EE50338ED03F4275E6961FF1CC0 + F85A46768BCAC6435B88FC606B7F4EB78441B9FC7904EA91A4D90B7D1E8D6D64 + DBDB5B3EC2E69FF067976A0A4C26A8581905151F298BDCE68701634758813A0F + BB997F881EECB7760416D89EB8BC3C6E0D59E389BF85165692785659E4E7D7FD + B00000CCB624CD6C2ED8BB7C4DF1BE5E1D150668EE36415514500D2A36441515 + 76BEFA5859E4D7D7FD80E80FC20AD41D58FCB6A4DF89020B5A42309D019C9B2B + AD2136CFC23E4CBF5A16B9F5550200D069499AD9D9E94D925E11B57C2CAA0CD0 + 0CD5148633162613543CE81515A796456EB38680594358815A115860440338C3 + 076BBC3564B97FC05E28E9CCB2C8ADFA020080CE49D2EC051E541C5669F9985F + 69D7A2E503530D2AACA2E21FCA22BFAAEE0744FF1056A06981C5410CDDC4885A + 43D67A8FA50DF3B3C19BE748FA5E59E4F6EF0100D07A499AD9E69EB74B3A2EDA + F2516DF9608026B687A0028D445881A606166186058105262BAEB278C2077056 + E759DCE903382FA9FB61010098AE24CDE6FADCAF9325ED37A4E5230E29384361 + AA41C5DD1E545C59F703A2BF082BD0B4C0E2F5130CDD0CE58BC0F6AA2CB6456B + 13E355A72BA27916DF2C8BFCE6BA1F180080296E543B45D26B255955C5520F29 + 16FA79690E2D1F185145C5A7082A5037C20A3431B078ADAF351D5461416081A9 + CEB388579DC6F32C1E9674B9575AD8073300008D95A4D9B17EA1F3340F299678 + 4831DF430A5A3E30150415683CC20A34F5D620F11ECC30C382C002A39C671142 + 0B9B67F190A4F37DDDA9CDB90000A03192345BE621C5F37C78E6123F1785B914 + B47C602641C57A9FF115828A4F97457E45DD0F0818C20A3439B07895A4774681 + 85953912586014F32C36474338436871BFA49FF8104EFBF00600A036499A2DF0 + 0D1F2FF14AD3BD3CA4D8DDCF43F12A52420A4CD656FF8A838A07A219150CD344 + 631056A0E981C5CB24BDDB6758C48145B845E08319D39967F16434CFA2BA39E4 + 5E493FB0ED216C0E0100CCB624CD2C8048FDD26659343C734174060AC3C769F9 + C04C828AB8F5E31365915F5BF7030231C20AB421B03849D2073CB0D82F2A7DDC + 35FAA006A633CFA21A5AAC89420BFBE02E249D5716392F4A00C06C5DD2BCD6CF + 3CF1F0CC7903E65218820A4C467C593328A8F85859E437D4FD90401561055A21 + 49B31324FD81A443BCC2627125B0A0FC11331DC2196F0E89438BDB259565915F + 50F7030300BA2949B3E37D85FB533CA4581C0DCFDC6DC0F04CCE3C986950F180 + 07157F5F16F9AFEA7E486010C20AB4469266CF96F4C75185451C58B0A20BA3DE + 1C520D2D6E93F4FDB2C82FAEFB810100DD90A4D9D11E523CC3DB3DEC6CB3879F + 6FC2EA76E652605441C5BA28A8B8D3838A5BEA7E486018C20AB44A92664749FA + B00716FB4781859546125860D49B43068516B77AA505A10500605A92343B5CD2 + 1B241D175552ECE1C333C3860F0B2938DB6014E79ACD1E542CF7A0E20E49FFAB + 2C720B2C80C622AC40EB24697698A4BF90749807164BFCC33D7CB0F3A18E9908 + 551693A9B4385BD245CCB400004C469266077A48F15C5F43BA38DAF0B19B5FBE + 844A0A866762A641C51303820ABB74F91F6591DB1634A0D1082BD04A499A1D20 + E9AFBCB73304160BA20F79020BCC4478316E2FB458EE332D6C7BC80584160080 + 419234B3B3CAEB259DE821C592A892626E747E617826461D54ACF5F38A851337 + 7B50F170DD0F094C0661055A2B49B3A51E581C19ADF68A030B6E2430EED022AC + 3C5DEE43AA7E24E9DCB2C8EDDF0300F45C92663614FC75925E3020A488D790C6 + ED1E9C5D305DF1B6B34D7E4E79CC838A1BBDF5C3CE2C402B1056A0D59234B30F + FC3F9774AC07164B7D7AB6955212586036428BB0F274950FADBA4FD24F259D53 + 16B9FD730040CF2469B69FAF207DC180768F5049414881518A87856FF2B34908 + 2AAEF5619AABEB7E48602A082BD07A499ACDF32D21565A794014588429DA0416 + 187768B1D9438BB55168F190A49F49FA6159E4F67300808E4BD26C9957529C10 + 8514712545B5DD839002A30E2A367A50F1A85FA05C26E99365915B4528D02A84 + 15E88424CDECC3FF7D925EE681C5DE7E38985BB9B900C6155A3C5E092D567B8B + C823922EB5B9166591DBA10100D031499A1D222995F4BC01DB3DAAED1E841418 + 4750F1B80715AB3DA8B857D2F9923E5F16B99D4F80D621AC406724696637156F + F1B24B9BB6BD8F975CCEF5434298AC0D8C2BB478B2125AACAB6C10B9C6DB43AC + 6F1400D072499A3DCD7E8856902EDACEE04C420A8C52584D1A07150F7B50F143 + 49A797456EFF0C6825C20A744A9266761078B5A4B7493A48D2BE1E58845B0DF6 + 9563DCD3B743A54598C2BD31DA20125A446EB1419C922E2C8BDC0E1900801649 + D2CCC289D7483ADA87668690623E21056649B828D9E21724ABBC9AF31E49DF91 + F46DCE18683BC20A744E9266761878A1A40F4481C5223F40D8E181C002B3155A + 84DB8E7883C83A3F50ACF4A1571748FA3143AF00A035E78B53241D1185140BA3 + 90C22E460829301BE78C27A3A062A557545850F155AFE2B47308D06A8415E8AC + 24CD9E29E94F3DB0D8CFFB47778F6E3B384060B6428B411B44E21611EB2DBD42 + D24FCA22BFADEE070700FCC65CAC97FBD7411E52ECE9EBD2E7FB06325690A28E + A0629D9F236CA8F7DD92FE59D2456591F30D1E3A81B0027D187865AB4D0F97B4 + BF1F30164481059B42305B078B70B808078C701B125A4456472D22B645E4E765 + 915BC00100A84192668BBC8AE2255EA51986662EF0F6D2DD2A9514841418A770 + 9678220A2AECDCF0A00715A796457E5DDD0F098C1261053A2F49B3251E581CE3 + 81C55E5EB269870C569BA2EE619C5B7CAE45A8B6581DDD925C2CE9A76591DB5F + 030066419266874A7AA5A4E37DBBD8A201EB47434811B77A7096C0B8C433B136 + FB7961B9A40724DD21E9EFCB22BFB3EE8704468DB002BD90A4999569FE91A413 + 252DF389DDF16A533685A0CEB916E196246C11A90EE4BCDE675B5C410F2A008C + 6D1EC5F1DEEA71B45751EC396068E62E514811CE0D841498ADA062939F0F4250 + F12B49FF7F59E436AF02E81CC20AF4469266760BF20E49AF927480DF96844D21 + D53E53A0AE1691B0FA34545BAC8D665B58A9E74592CE2B8BDC267E0300667E99 + F152FF3A306AF558E8E783EA668F7056309C17305B4145584DBAC6E75CD980EE + ABBCF5C37E0EE824C20AF44A92663BF96AD3B7FAA1641F2FEF0C659D0416684A + 8B483C9073A3977CAEF56A0BBB51B941D2F992AE649016004C6BA6D56F79C5E5 + 5E035A3DAAF328D8EC81D9B6350A2A36789BA85D54DC679716924E2B8BDCCE08 + 40671156A0AFA59ECF93F4C168B569BC29243E94004DD82212AA2DC2FAD3B8DA + E201AFB6389F6A0B00182E4933FB6C7FBEA493253DDD876E872A8AF9D1C54568 + F5606826EA10575C3EEE9FFB7651619FF1F74AFA8EA4B318C28D3E20AC406F25 + 69661B423E2CE9505F6D1A3685D86D0A9B42D0A416917820E7E3956A8B789388 + 555BFC5CD2E56591DBBF0F00BD97A4D93EDEE6F1021FB4BDC8038A78F56868F5 + 601E059AB4F163BD5F4CD84C8A7B247DD9076FF30D1C7A81B002BD96A499957E + FE071FA6B5BF0FDEAC6E0A61F026EA145ED271683168B645082E56F9A1E6121B + CA5916B91D6E00A08F5514CFF1B5A3CFA85451ECEEB32886B57A18420AD4BDF1 + 637DB49AD43ECB3F5D16F9D5753F24309B082BD07B499AD981E5FD925EEC8337 + C3A610066FA28DD516A14D24AC40BDD9DB442EA6B715404FAA285EE25514CBA2 + 8D1EBB57AA2868F54093377EACADAC26FD4859E477D5FD90C06C23AC00FECFE1 + C60E2CAF97F4061FBC193685CC8F6E5D38C8A0A9D51683665B5457A0DAA1E772 + 491796456EABCE00A0139234B3E0E104492F947454B47674C176AA2868F540D3 + 06696EF2CB86C73CA8B856D2C7CB22B7CB07A077082B805F1FBC6983B73EE081 + C5BEDED71A066F32C7026DA9B608BDAE8356A0AEF2015D97DA7C0B76B30368F9 + ECA9177950B1D4038AD0E611AF1D0D551421A0A0D5034D1CA4196FFCB0D5A43F + 93F42F5445A2CF082B80C1879F3F9374B807167B55066FC63BD681266F120907 + A0412B50D7782FECAF3CB8B884031180A64BD26CB157509CE803B2AB6D1EA18A + 6297A895335E3BCAE7379A16546CF6A06265B4F1E32C49DF65E307FA8EB00218 + 204933ABA8F890A467FBE0CDBDFC30648720E658A0E9C28B7DEB76DA444270B1 + DADB44AEF2F9163730691C40532469B6ABAF1CB7EAC763BCEA718F216D1E5451 + A04DF329B6F867B15D1E3CE441C53FFB9C293E87D17B8415C010499A59E9E8DB + 259DE243BAC21C0B2B2D658E05DADA26F24425B888DB44D67A9B884D1EBFC20F + 4B77D6FD3F00406FB7793CC3030ADBEAB1B81250CC1B322C932A0A34D9B6CA7C + 8A753E9FC23E77EFF4F914B7D5FD904053105600DB3F2CD96EF677F91C0B9B32 + CE1C0B74692867B8D989B7898435A8567161D3C7AFF4E0C26E7D00606C92347B + 8A6FF278AE7FE6C68332E33914F1B04C367AA0E9B655828A8D5155E3FD3E48F3 + D4B2C8ADC2028023AC00262149B3A749FA53498748DACF6F78C21C8B5D2A3739 + 40DBAA2DE2369161C185555CDCE2C185CDB7B0BF0780194BD2EC509F41F11CAF + 64DC63C8A0CCD0E611020ADA3CD0B6F9145B060CD2FCA9A42F31370AF84D8415 + C0D4867AD91C8BE3A239160BFD20C51C0B746D9B4868130983BFD64783396D08 + D88DBE0AF58AB2C82DD80080494BD2EC20DFE26101C54195168FF97E1930D11C + 0A3E6FD106F167EB66FF2CB5CF50DBC4759FA43324FDA02C72FBE7002A082B80 + A9CFB1788BA4570F98633167C04D0FD0E6369127870CE6AC0617D779C5C555DC + 0C01D84E05C5F11EFA1FE481FFF6020AE650A0ADE2B68FCDFEB9190669DE2DE9 + D365915BFB078021082B80294AD26C075F9BF6DE688EC5E2688E45DC16027429 + B8787C12C1C5B5BE55E46A820BA0DFFCF3F208DFE411AA12C39AD1B8C5635805 + 056D1EE8CA7C8A35D120CD9B247D823950C0F6115600D394A4D9C13EC7E2089F + 63B1C46F88586F8AAEAE410D3DB7A1E262CB80E0229E7171BD85165E7161FF0C + 40C72569B68BAF17B5D5DFC77A0562983F51DDE231A8828280025D082A4255E2 + 06FF3C7CD4E753FC4CD217CB22B79F07B01D8415C00C24696607AFF779A585B5 + 852CF55BA3B0DE94B610747D30E7441517EBA275A87693F40BAFB8B00A0C001D + 91A4D99E1E4C1CEBEB46F7ACB477CCDDCE904C020A7441BC227CD87C8A1F329F + 02983CC20A60869234B31BA1574A7AAB071661BD69E8BF65BD29FAB451A43AE3 + 226C15591F0517B779BBC89565915B492C80F6B5771CEAAD1D474B3A6C82F68E + D01E494081AE8A3F0B9FF0CFBD41F329ACDA10C0141056002392A4D991BE2DC4 + 0E70FB56DA4242892B6D21E863C545BC0EB53AE7E29EA85DE496B2C8F950021A + 2849B325DEDE7194FFB8A4124E84F68E78FE441C50D8671F0105BABC9634B47D + 84F9140F7830FFA9B2C8EDEF014C11610530FA52D8DFF769E761BD296D21E893 + 61C145A8B808732EE2E062BD1FEE96FBC1CEBE6E60CE05509F24CD2C6CB710FE + E9FEE381138413A1BD63E7E8ABBA66D4F0D987AEAF255D2DE9119F4F71B6A433 + CB22B77F06601A082B80F1B485A492DE20E98068BD69D81612AA2C0C0737F425 + B8888773861BA8784067B5EAC20E7CB7586821E99AB2C8ADDF17C0982469B6D0 + 07465B30F1544936447A81B73486B68EB94386630EDAE0414081AE0ADF3C8520 + 7E93CF685A11CDA7384DD2C565915B9801609A082B803149D2CCFA78FFC0DB42 + F6F192D9857ED0635B08FA1E5C84DBA8EA80CE507511665DACF3AF87BC5DC4C2 + 8B9BA8BA00662649B37D3C9C788A8713CB2A5513219818164EC4B327ECCBF099 + 86BEB57D6C8C2A031FF490FD9365915B8B23801922AC00C6DF16F27E4927F87A + D3EAB610866FA28FC207CFB6212B5127AABA08AB516FF70D231660DCC1ED1530 + 5C9266BB79A5C4113E0CF3291EA00F0A26C2CC8941E14475F604D513E873DB47 + BC96D4E6539C2FE94B84E9C0E8105600B3B72DE42D7E73B5B76F0B096D21BB0C + 38F8017D0C2EAA732E060DE91C145ED861F197927E25E9465A46D067499AEDE4 + 9F35877A3071A8B7240E6BE788AB2626AA9C209C405F55B77D84B68FB096D4E6 + 537C45D279AC2505468BB0029825499AD94DD61F493A3CDA16B2D00F8DE18048 + 6081BEDBB69DB5A84F7870312CBC58EFB75CBFF4725C6B19B11612A0ABC1840D + 733E24FA3AD883893894A80613C3AA26AAE18421A0409F0DDAF6B1366AFBB8CD + B77DDC51F783025D445801CCA224CDEC00F94E4927FB01D3DA42AC55647E347C + 33EEFD05FA6C7B551771CB48BC65249E7911C20BABBAB8D5BFEEA36D042D6DE5 + 58E661847D1DE41B3AE60F0925E26062E7289C08C144BC9D6A50751F9F41E8BB + B89A624BB4EDE351AFA6B880B60F60BC082B805996A4991D0A9F2FE9BD7EF0DC + C7DB426CEA3AC33781A9575D4C145E84CA8B507D116EC56CE6C55D7E2B765759 + E4764B06344292667BF9E7C321FEE3415E91579D2D11071213554CC45513E1B3 + 85B60E60B0F833E6F1016D1FD66AF8650B2B08BE81F122AC006A92A4991D3C3F + 28E9193E7C732F6F0B61F82630F5AA8B6A7831A86D24B48EC42146F8D1028C7B + 7D489ADD98D924F787CA22B77918C038ABEDF6F70A8903FDAF0F8AC2EB104884 + A197D5F91271B5C4B03913B47400D31BA219DA3EE26D1F56A5F7E9B2C8EDF302 + C098115600354AD2CC0E9DA9A4CC6FCF967A95C5FCA8CA82E19BC0CCC38B38C0 + 888776C65518E1C7F0B5C90FAA36F3E211498FF9AD9A7DADB0C19E6591DBBF07 + 4CE65DBFAF0FBA0CA1C4011E5257B77054AB25060DBE1C366382600298D96748 + F8ACB077FBFACAB68F1F4A3AB32C72FB6C00300B082B800648D2EC6992FEC027 + B7EF5319BEB96BA5B718C0CCC28B38C0A856613C3EE46BCB8080634B3468ED31 + 2F115EE97FBFDC0FB9ABCB22B7FF5EF467E0E53E1E3E1FE85573CBFCC789664A + C4ED1B83664B54DB38866DE7E0330298F910CD4DD1BB3DB47DFC93A42BCB22E7 + 1B276016115600CD2A077EABA497FBC1B63A7C932A0B60B4E1C5B010A35A8D51 + FD31841A71C811FF5C0836C2D72A0F31560C08344285067DCF2D92A4D90EFE8E + 0EF3244228B1FF90B5A0C3DA37B6375BA23A63C2104C00E31BA2B9C187683EE6 + 6D1F575B505116B95557009865841540F30EC0CF96F47EBF95B31BBAC5DEBF3C + 2F1ABE4995053033F1875F082DE2836B1C64545B4AAAD519C3C28DEA5FC78146 + B54AC30EC68F4621C683DE7EF22825C7F54AD26C71344B627F0F259645ED7A83 + 2A25A6124A0C6BE160330750CF10CD47BCEDE34C49E7501D07D487B00268A024 + CDF690F42E492745C33707AD38A5CA02186F88117E9CE8AB1A6854BF86851A13 + B59FC4F333967B70F1505492FCAF733328499EBE24CDE678083CD7DFADBB7B30 + 6CEFDFB08D6399FF5C187239289418B481231E76396C4528D51240FD4334B7F8 + 90E57888A66D89FA6C59E4B6350A408D082B8066AF383D41D27B7C10DBDE5195 + 851DAEA9B200664FF5C372DB043F4E35D098CCFC8CEA30D0CD5EAE1C2A301EF2 + 2D26F6F7CBCB22B77FD60B499AD9FB70AE070FBB475FA1226DBE7F85BF5EE03F + 867940215C88BFE21062D8A0CB892A2526B32294F73630BBE2F7F1135E4D511D + A2F9231FA2690106809A1156000D97A4990DDB7CB70717FB46551676F0A6CA02 + 6886411FA65309344270B16D3BAD25832A300605196BBCFA22B4963CE65FFF3A + F8B36907710F6743E810C2851038EC1E850D219008FF7CF74A2543F5C76A75C3 + 647EACFEF74CB67D83500268CF4AD2504DB1C2DF95F7FA10CD5F50B106340761 + 05D09E09F32FF2D690FDA32A0B3BA85365017423D0A8FEF5B06A8C6121C6A030 + 239E8F11FFB8DE7BB357FBD79AE86BADF76EDBBFB3210420D33DC0FBDACEDD3C + 7858E861EB12FF5AEA5F8BB753B5309DE061D0D70E438286413F124A00DDABA6 + 082B49577B986BD5681749FA7259E4F673001A84B002689124CDF6F1E19BCF8A + AA2CECF0CF2C0BA0FB33333460F8E7B076926A6BC9A03919136D3B897F2E547A + C4D51B4FF83358F011DB25FA714E254C8DD772C62D15F13F1F14380CDA9031E8 + AFAB81C2A0568C4161C354FE3AFC3D80F655538495A42B7C88A6CDFFF992A48B + D9C80434136105D032499AD981FEA592DEE65516E156922A0BA0DB263BFC7332 + 033F27FAEBEA8F718B4A1C96549F49956FF0E320615095C4CE9398F7B0BDC061 + A22195130DAFACBE1B07BD2B797F02DDA9A618B492F45F58490A341B6105D052 + 499AD99690F74655164B7C8A3D551640BF0C0B31C28F93DD66520D3AE29F1BF4 + DF55FDBFAD01D5083B4CA3BD625875C3A0FF1B55C3DE75BC03817E98A89A220C + D1FC9AA49FB19214683EC20AA0FD55162F91F47666590098C21693F8AF87CDCD + 98CC8FC30CAA6A1814444C75F603EF3100D3A9A6B08D49D7483AAD2C72ABAC00 + D002841540776659D88AD3674BB28A0BAA2C004CD6B611FDFC742A1C781F0118 + C7A68F75956A8AAF4B3A8F6A0AA05D082B806E6D0C79B1A4774655168B7C02BF + 4DE2B789FC5459000080AE5553846D4761D3C772AFA6B8D66753504D01B41061 + 05D031499AEDED5516CF19B231C45A43A8B20000005DA8A6D852A9A6B04D1F0F + FA6C8AF3A9A600DA8BB002E86E95C5495E65B12CDA18B2C06759C4551686D002 + 0000B4A59A22AC57DE1C555384D9145748FA7259E4165A006831C20AA0C39234 + B3D915EF9274625465B1870FE00CB32C2CB4A0CA0200003455F886250CD00CD5 + 1461D3C7233E9BE24B922E2D8BDCC20C002D475801745C9266563D71BCA4774B + 3A20DA1812575984019C86D002000034ADE5636BB48ED4AA2956F96C0A6BF9B8 + 58D257CB225F59F7C302181DC20AA0279234B38A8AB7F910CEFD0654598435A7 + 5459000080A6AD23DDE2EB48D744D514F748FAA2A45F94456EFF1E800E21AC00 + 7A2449330B218E95F43E49074755160BBDCA624E656308A105000068CA3AD255 + 3E9BC2AA29CE919497456E5516003A88B002E8A124CD6C33C81B25BDD26759D8 + 00CE3DA32A8B5D3DB060CD290000A87B80E61A6FF97858D2CD924E2B8BFCF6BA + 1F16C078115600FDAEB23852D2FB251D26699FA8CA625E3480932A0B0000305B + 2D1F4F560668DA1C8A47BD9AE24C49E796456ED516003A8EB002E8B924CD7693 + F41A49AFF359165665B1C8AB2C76ABAC3925B0000000E36CF9D85459476AD514 + 9748FA06EB48817E21AC00F0AF92343BD837861CE3AD218B7D00A7B58CB0E614 + 00008CBBE56343651DE95D3E40F33A066802FD435801E0DF24696681C44B7C6B + C87E3E80735165CD2903380100C0385A3EC200CD87247D4FD2D965915BA50580 + 1E22AC00F01B9234DBCB038BE77B95C5B035A7B486000080C908DF740C6BF908 + 03347F21E9AB6591DF57F3F302A819610580819234DBD1D79CBE7BC09AD3795E + 6561A1055516000060B22D1F8F7BCBC746DFF2115A3EEE9174BAA4AB69F90060 + 082B004C2849336BFF78ADFD655465110670CEF5C062E728B020B4000000D596 + 8F2706B47C3CEAD514DF95744E59E4F6CF00E05F11560098CA00CE77497AA6AF + 395DE25516F37D6B4818C0496B080000FD36682E4575CB8755535C26E98CB2C8 + 6D460500FC1AC20A009396A4998511274A7AA7A46595019CB4860000D06F83E6 + 526CF690226EF9B8C35B3E6EA4E503C030841500A62C49330B273249AF885A43 + F6F4D610ABB2606B080000FD122A29B67A48B1255A45BAD25B3E1E9074A6A40B + CB22B77F07008622AC00306D499A1DEE5516477B95C512DF1A62AD216C0D0100 + A05FC333E3B914EBA255A4564DF12349DF2F8BDC2A2C0060BB082B008CAA35E4 + 1D435A43E644F32CA8B20000A09BC3331FF790225E456A21C5553E978255A400 + A684B002C048246936DFB786BCCA5B439654B686ECEAA105AD210000746778E6 + E3D1F0CC3097C25A3E6E93F435E65200982EC20A002395A4D98192DE22E93995 + D690DDBDCA8279160000B437A4D856199EB9C1438A3097E27EABA490744959E4 + 56710100D342580160E49234B320E219DE1A62732D964A5AECAB4EE7F910CE30 + CF22041684160000B463C3473C3C339E4B914BFA4959E4D60E02003342580160 + 6C9234B32A8A174B7A73B43564D83C0B0B380CA1050000CD0A29E20D1F1B3DA4 + 88E7529C2BE97B65915B7505008C04610580B14BD2CC2A2A5249AFF4D69078D5 + E9DC28B4B0C082CD21000034670D6975C3470829ACE5E352ABA6607826807120 + AC00306B9234DB5FD21B7C7B48759EC56ED1104E36870000D08C35A46178E6EA + 6878E6B592BE25E9F6B2C8F96602C0581056009855499A59007184B7861CE3F3 + 2C2CB4B0EA8BF995D082219C0000CC6E48F16425A488377CDCEAC333D9F00160 + EC082B00D4224933AB9E3856D25B251D16CDB388430B1BC249680100C0EC8614 + F1860F1B9E799787145797456EFF1E008C1D6105805A2569B6B3B78558A5C501 + 95219CF37D9E05A1050000E30D29367B25C5DA28A4B8D7DB3D2E650D2980D946 + 5801A01192349BE39B43DEE89B43960CD81C42680100C0E8438A504911D6903E + 20E9DB922E2A8BDCFE1D0098758415001A254933ABA678A9A4D749DAC7430BDB + 1C42680100C068428AC72BED1EAB7CC3C74392CE92746159E4F6CF01A0368415 + 001A2949330B275EE62B4FC3E690B0EE745E34D362A7687B8821B80000E03757 + 900EABA40821452EE982B2C86D452900D48EB00240A325696603375F2EE9351E + 5A2CDE4EA5857D19420B00401F85C37D08299EA85452AC1D1052582585FD3300 + 680CC20A006D0A2D4E8E2A2D06851683569E125A0000FA1E52AC8F420A5B434A + 4801A0F1082B00B471A6C58B07CCB488DB43426811DA43082D00005D9F47B12D + 0A29AA2B484325C5831E525C4C4801A0E9082B00B45292667325BD40D2EB25ED + 5FA9B4983F20B408D51686E00200D0A590E2C9ED8414F7FBE04C5B416A332B00 + A0F1082B00B45A926616483CD7438B832BDB432CB4B05063D7681827732D0000 + 6D1657516CF5568F2D03DA3D6C05E93D5E4971392B4801B40D6105804E48D2CC + 8288A3ED2FFDC7105A2C8C428B41C33869110100B42DA408EB472D80D8188514 + 2BBD92E27649DF95747559E456710100AD435801A0539234B3E0E110DF20F2C2 + 28B4D8C3438B78ED69A8B6B0FF0CD5160080A60FCD0C21C566AFA45817B57B58 + 25C54D92BE2FE986B2C8EDDF0780D622AC00D059499A2DF6C0E2D5BE41649187 + 16611867B54584819C0080266FF6D8EC951421A458E921C555927E20E9D6B2C8 + 39DC03E804C20A009D97A499B57F1C27E91449470C18C63977C0EA53665B0000 + 9A323473B30FCDB490627514525C20E9276591DF57F78303C0A8115600E8638B + C88BFD6B7134D7A2BAFAB43A90936A0B00C06CCDA388377BAC8F428A15921E91 + F4430B2ACA22B7BF07804E22AC00D04B499A5938F11C49AFF22D22A1456441D4 + 223267C8FA53820B00C0B8E65184A199F1FA510B25EEF57914B6D9C3FE390074 + 1A6105805E4BD2CC0288C324BD48D2491E5A4C546D51DD2462082E00003369F5 + 88E751AC8F420ADBECF14B49674BBA9ECD1E00FA84B002005C9266F37DB6C52B + 243DC5438B89665B506D0100988C70E01ED6EAB1316AF50821C545927E2AE92E + 866602E823C20A00183CDBC25A435E20E9E468FD69B5DA624E659308D5160080 + 61551483568F5AABC7DA6868669847715159E4165800406F115600C0049234B3 + 6A8A674AFA2D494756665BCCF7E0A25A6DC10A5400E8B738A0D81A55516C89AA + 28D67A15858514B77A48717559E416640040EF115600C0E4AB2D96493A41D2CB + 25EDE5D5167B44D516A14DA43ADB8215A800D0CF2A8AB8D56343348F62A50FCD + BC58D27992EE288BDCFE330000475801005394A499851147497AA9A467454339 + E36A8B8956A01A820B00E86E1545DCEA11AF1EB590E221493F90746959E4F6F7 + 008001082B0060069234DBCB57A0BE52D2FE1E5C2C8C828B30DB82A19C00D08F + 2A8ACD952A8AD0EA71BDA49FB0D503002687B0020046B702F5085F81FAFC4AB5 + C5B015A861B6056D2200D0CE8D1E830666C65B3D1EF580E2E2B2C81FACF9F901 + A055082B0060C492345BE0ED213694F3F068B6C5A015A8B48900403B377A842A + 8A8D51154568F5B8C9438A6BCB22B77F0F003045841500303B43396DBEC5DE51 + B5C58221433969130180E60514836651842A8A3030F33149E74ABA44D2FD6591 + 73C806801920AC00805990A4D9CE3E94D3DA449E5B5981BABB8716D53691B8DA + 82E0020066B7CD230414F1468F5045B136AAA2B8C1377A5CC7DA5100181DC20A + 009865499A5975C571925E26E930AFB65838A44D64E701C18521B80080F1B679 + 842A8A8D03AA281E96F453499797456EDB3D00002346580100F5B6891C24E944 + 49274B5AE2D5160BA3A19C733DB4A86E1321B80080D106148386655667515C26 + E9224937B3D10300C68BB002001A2049336BFD78BAA4174A7A5E652867DC26C2 + 7C0B00987940B1AD1250C46D1E1BA2360FDBE8718BB779D8B04CFB7900C02C20 + AC0080666E1379A6575B3C2D0A2E768FDA44986F0100DB170EBA5BA32A8A780E + C5A0368FD5DEE6F1336BF390F400C3320160F611560040832569B68FA467FB36 + 9103A2F916719BC8446B50092E00F4CDA041994F56028AB8CD235451ACF04D1E + F6756B59E4F69F0100D484B002005A2049330B1F0EF535A82F8AE65B2C88828B + D02612CFB7D8A9125A105C00E85B4011CFA188B779ACF1368F6B7C0EC50D6591 + DBBF03006800C20A0068E77C8B237D30E70995F916F32BC1453CDF82E002409F + 028A417328424071ABA40B7CDDA8FD3D00A061082B00A0C59234B360E2681FCC + 79AC8716D5F91661A308C105803E04149BA30A8A75519BC79D922EF441993693 + 0200D060841500D011499A5985C5311E5CD866913DBDDA62C1048339092E00B4 + 6D8BC74401C5864A4071BF07145733281300DA85B002003A2849339B69F10C49 + 27493AC2AB2DC260CE105CCC19B20A351ECE69082F00D4553D31990A8AEAA0CC + FB7D0685CDA2B887800200DA89B002003A2E49B3BDA38A8B233CB4A86E14892B + 2E866D1531041700C61D4E4C35A0B03914041400D031841500D0BFE022CCB838 + 62C0469138B8A86E1521B800301BD513D52D1E21A0D8E82D1EEB3CA0B847D2A5 + 368342D2BD041400D02D841500D053499AEDE5C1C5893EE36261145CCC9F4270 + C19C0B0013890F9BD57022AE9E78C2AB27E22D1ED580E21649974BBA51D2C304 + 1400D05D84150080309CF32849C74B7AE624828BD02A42BB088089AA26E481C4 + A0EA89C7A3F68EEA9AD11050D80C8AABBC7AE2D6B2C857D6F8BF0B00308B082B + 0000BF2649330B289E2AE939929E57691589838B3903368B54830BAA2E80FE55 + 4D8460629B87125BA3CA89C72BED1D9B3C9C886750DC2DE94A4937F9FC09FBCF + 01007A86B002003054926616461C2EE959924E90B4345A873ACFBF769B60252A + 551740F7876156578A56E74E54C38938A0B0EA8907BD72C2C2893BCB22B76A0A + 0040CF11560000262549330B1D0EF07691E7798811AF439D376025EAF6AA2E0C + E105D08E6062A2968EEAD68E2D9570226EEF7844D275926E96744759E48FD5F8 + BF1100D050841500806949D26C91A4A7493ACE2B2FF6F0E0A2BA59A4DA2EB273 + 145C105E00CD6DE5986818E6A09913D5CD1DA17AE25E1F88798BB7752CAFF17F + 2B00A025082B00003396A499051087FA5691E74A3AD85B45E647732E26537531 + AC6584000318CFF0CB417326AA1513219808DB3A06B575C49513BF94F42B4977 + 49BABF2C72FB390000A684B002003072499A2DF13691677AE5C5A2CA80CE89AA + 2EAA2D2313CDBC20C400A6572D31AC95A33A6BA25A3511CF9CB080E24E6FE7B0 + 1FEFF775A2F6DF0900C08C10560000666BD6C553BD5DE4C828B8981F0DE81C54 + 751187173B0D082F0831D077D550627BD5127138F1C4906062D0BC09FBBAC7D6 + 87568209FBF700001839C20A00C0AC4AD2CC828903253D45D2333CC4880774C6 + ED22BB0E092F866D1B19F43528BC20CC40D75A38AAB325AAA1443C6362A26022 + 544D582071BBAF117DC08662124C00006613610500A056499A5928B19FCFB938 + C2B78D2C19D02E322CBCA8AE4A1D360363A21063507841A08136B4700CDAC811 + 574B4CD4CA615F2B3C94B0F912F7497A48D2636591DB7F170000B521AC000034 + 75D3C8BE9296F9EC0BABC2D8ABD232B26BF415C28B89428C1D07B4934CD452B2 + BD40833003B3D1C211DA38E2168E5029F1C480C197C3AA25AC8DE30EAF98B8D7 + 438947CB225F5BD3FF7600002644580100688524CDE67B60B18F871807F88F4B + A3CA8B38C418548111028C61ED24D58A8CA9B4981066605C2D1C83664BC41B39 + AA15130F7930718FB770D8DFAF60F02500A04D082B0000AD96A49905138BBC75 + 646954916161C61ED1D0CE38C088BF868518D5E19EA3083402828C6E1B164CC4 + C32E279A2BF1C490B912D5506285574ADCED032F430B07B3250000AD47580100 + E87A90B150D29E51A0B1B7071AFBF8CFC5C1C5AE513B49B5B564A709828D8902 + 8DC9CECDA8FE359AAD7A800A81842AA1C4A0168E6AB544DCC2510D25AC7D63BD + 574AC47325AC85635D0DFFBB0100981584150080BE8719BB7B05C69E950A8D10 + 6AEC36A42A230E36AAAD268336970C0A3558C5DA0CDBA610484CA69563580B47 + DCBE3168E0E5466FDB08D512F6D70F4B5A59163907360040AF10560000B0FD59 + 190B3DD058E47333967A65866D3159108519F1BC8C41014735DC1814664C548D + 616829196DF010FE7A501031E89F6D1B523911871313554A845062D5806A095A + 3800007084150000CC7CF56AA8CC88E766ECEFB333AAC33FAB4340275AC73AA8 + 12637BDB4BC2DF0FD2C66063DB2C050F83FE7EEB76664D6C1D5039510D25ECEB + C1CA7AD087CB225F3DE2FF3F0100D029841500008C4992663B7A90B1D82B32F6 + F7C19F077BB011D6B0861F4390516D33A90EFC9CEC5C0C4DE2C799041953F9CF + 4CF6C031287898286C1845F010870FC3FE3A544F0C1A8819428A8DBE16F4560F + 266CE8E5236591DBCF0300802920AC0000A006499ACDF500236C2F3944D2A11E + 6EEC16CDCA88B7994C6626C6A07918719811FE5A9358C13AD940637BA1C5B649 + FE7D7506C4A050611CC143358018F4D7F6B5CEDB37D6485AED3FDAD74AAF9EB0 + 8A090B2E0000C00C11560000D020499A2D8C428CD04AB2CC2B3106AD611D547D + 316CA8E764867B6EAFCD64AA9519D54A89F0E3A0ED19DB5BEB19BE46113CACF7 + 90614DF4B5D60389F5D15768E5D85416B9FDDF030000B380B0020080F66C2E09 + B33116FBB0CFD05EB2D4BF429831A802A31A64EC38C96A8C89B6954C145C4C34 + 47625838510D281E8F7E0C7F1DBE081E0000E830C20A00003A2249B37992E6FB + D7EEBEA964A1071CBBFB5FC75F718011028B417331260A2F34416831D9D68E6A + 454408271EF1F60AFB7AD4C307FBDA40F0000040B711560000D053499A55077B + C6C33EC3DC8C78256BF89AE3C1C4AEFE63083CE43FA7287CD8E6C183FDB825DA + 94B139FAFB0DFE155741AC2B8B9C430A00003D45580100000000001AC54A3901 + 00000000001A83B0020000000000340A610500000000006814C20A0000000000 + A026F9DF8B67E268D8E1131C0000000049454E44AE426082 } PopupMenu = pmDropTarget Proportional = True diff --git a/mangadownloader/forms/frmMain.lfm b/mangadownloader/forms/frmMain.lfm index 826f6cc4d..646ceebf4 100644 --- a/mangadownloader/forms/frmMain.lfm +++ b/mangadownloader/forms/frmMain.lfm @@ -3923,7 +3923,7 @@ object MainForm: TMainForm end object gbOptionRenaming: TGroupBox AnchorSideLeft.Control = lbDefaultDownloadPath - AnchorSideTop.Control = gbImageConversion + AnchorSideTop.Control = gbImageProperties AnchorSideTop.Side = asrBottom AnchorSideRight.Control = lbDefaultDownloadPath AnchorSideRight.Side = asrBottom @@ -4597,20 +4597,23 @@ object MainForm: TMainForm AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = gbOptionRenaming Left = 4 - Height = 50 + Height = 39 Top = 271 Width = 812 Anchors = [akTop, akLeft, akRight] + AutoSize = True + BorderSpacing.Top = 4 Caption = 'Image Properties' - ClientHeight = 30 + ClientHeight = 19 ClientWidth = 808 ParentBackground = False TabOrder = 7 object cbServerCreationTime: TCheckBox Left = 4 Height = 19 - Top = 4 + Top = 0 Width = 225 + BorderSpacing.Left = 4 Caption = 'Use server creation time over local time' TabOrder = 0 end From 8b1d7c81e9a0b30a5b26a81c08e10e8dfa3b8134 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Sat, 7 Feb 2026 18:04:07 +0800 Subject: [PATCH 23/35] Added: Save manga info to list when loading info Changed: Image creation time to server time by default --- baseunits/DBUpdater.pas | 18 ++- baseunits/FMDOptions.pas | 2 +- baseunits/uData.pas | 110 ++++++++++++-- baseunits/uGetMangaInfosThread.pas | 41 ++++- baseunits/uUpdateThread.pas | 235 ++++++++++++++++++++++++----- mangadownloader/forms/frmMain.pas | 127 +++++++++++++--- 6 files changed, 447 insertions(+), 86 deletions(-) diff --git a/baseunits/DBUpdater.pas b/baseunits/DBUpdater.pas index 72974708d..0929ca809 100644 --- a/baseunits/DBUpdater.pas +++ b/baseunits/DBUpdater.pas @@ -158,10 +158,13 @@ procedure TDBUpdaterThread.Execute; if used then Synchronize(@SyncCloseUsed) - else - if dataProcess.WebsiteLoaded(FModule.ID) then + else if dataProcess.WebsiteLoaded(FModule.ID) then + begin Synchronize(@SyncRemoveAttached); + end; + with TProcess.Create(nil) do + begin try UpdateStatusText(Format('[%d/%d] ' + RS_Extracting, [FIndex + 1, FItems.Count, FModule.Name])); Executable := CURRENT_ZIP_EXE; @@ -173,16 +176,25 @@ procedure TDBUpdaterThread.Execute; Options := Options + [poWaitOnExit]; ShowWindow := swoHIDE; Execute; + cont := ExitStatus = 0; if cont then - DeleteFile(currentfilename) + begin + DeleteFile(currentfilename); + end else + begin FFailedList.Add(RS_FailedExtract, [FModule.Name, ExitStatus]); + end; finally Free; end; + end; + if cont and used then + begin Synchronize(@SyncReopenUsed); + end; end; dataProcess.Open(FModule.ID); diff --git a/baseunits/FMDOptions.pas b/baseunits/FMDOptions.pas index 7d36d7eeb..85e2802df 100644 --- a/baseunits/FMDOptions.pas +++ b/baseunits/FMDOptions.pas @@ -127,7 +127,7 @@ interface OptionJPEGQuality: Integer = 80; // image properties - OptionImageServerTime: Boolean = False; + OptionImageServerTime: Boolean = True; // connections OptionConnectionTimeout: Integer = 30; diff --git a/baseunits/uData.pas b/baseunits/uData.pas index 2204c49b9..7c579dd69 100644 --- a/baseunits/uData.pas +++ b/baseunits/uData.pas @@ -55,6 +55,7 @@ implementation constructor TMangaInformation.Create(const AOwnerThread: TBaseThread); begin inherited Create; + FOwner := AOwnerThread; HTTP := THTTPSendThread.Create(AOwnerThread); MangaInfo := TMangaInfo.Create; @@ -65,17 +66,26 @@ constructor TMangaInformation.Create(const AOwnerThread: TBaseThread); destructor TMangaInformation.Destroy; begin if Assigned(MangaInfo) then + begin MangaInfo.Free; + end; + HTTP.Free; inherited Destroy; end; procedure TMangaInformation.SetModule(const AValue: Pointer); begin - if FModule = AValue then Exit; + if FModule = AValue then + begin + Exit; + end; + FModule := AValue; if Assigned(FModule) and Assigned(HTTP) then + begin TModuleContainer(FModule).PrepareHTTP(HTTP); + end; end; function TMangaInformation.GetInfoFromURL(const AURL: String): Byte; @@ -86,7 +96,9 @@ function TMangaInformation.GetInfoFromURL(const AURL: String): Byte; bmangaInfo: TBaseMangaInfo; begin if Trim(AURL) = '' then + begin Exit(INFORMATION_NOT_FOUND); + end; GetBaseMangaInfo(MangaInfo, bmangaInfo); @@ -102,11 +114,16 @@ function TMangaInformation.GetInfoFromURL(const AURL: String): Byte; Result := TModuleContainer(FModule).OnGetInfo(Self, AURL, TModuleContainer(FModule)); end else + begin Exit(INFORMATION_NOT_FOUND); + end; - with MangaInfo do begin + with MangaInfo do + begin if Link = '' then + begin Link := RemoveHostFromURL(MangaInfo.URL); + end; // cleanup info CoverLink := CleanURL(CoverLink); @@ -124,24 +141,47 @@ function TMangaInformation.GetInfoFromURL(const AURL: String): Byte; // fix info if (LeftStr(Authors, 1) = '<') or (Authors = '-') or (Authors = ':') then + begin Authors := ''; + end; + if (LeftStr(Artists, 1) = '<') or (Artists = '-') or (Artists = ':') then + begin Artists := ''; + end; + if (Summary = '-') or (Summary = ':') then + begin Summary := ''; + end; + if Title = '' then + begin Title := 'N/A'; + end; + if (LeftStr(AltTitles, 1) = '<') or (AltTitles = '-') or (AltTitles = ':') then + begin AltTitles := ''; + end; + FillBaseMangaInfo(MangaInfo, bmangaInfo); // cleanup chapters - if ChapterLinks.Count > 0 then begin + if ChapterLinks.Count > 0 then + begin while ChapterNames.Count < ChapterLinks.Count do + begin ChapterNames.Add(''); + end; + while ChapterLinks.Count < ChapterNames.Count do + begin ChapterNames.Delete(ChapterNames.Count - 1); - for j := 0 to ChapterLinks.Count - 1 do begin + end; + + for j := 0 to ChapterLinks.Count - 1 do + begin ChapterLinks[j] := Trim(ChapterLinks[j]); ChapterNames[j] := Trim(ChapterNames[j]); end; @@ -155,7 +195,9 @@ function TMangaInformation.GetInfoFromURL(const AURL: String): Byte; begin del := False; if (j + 1) < ChapterLinks.Count then + begin for k := j + 1 to ChapterLinks.Count - 1 do + begin if SameText(ChapterLinks[j], ChapterLinks[k]) then begin ChapterLinks.Delete(j); @@ -163,8 +205,13 @@ function TMangaInformation.GetInfoFromURL(const AURL: String): Byte; del := True; Break; end; + end; + end; + if not del then + begin Inc(j); + end; end; end; @@ -172,28 +219,41 @@ function TMangaInformation.GetInfoFromURL(const AURL: String): Byte; begin // remove host from chapter links if isRemoveHostFromChapterLinks then + begin RemoveHostFromURLsPair(ChapterLinks, ChapterNames); + end; + // fixing chapter name for j := 0 to ChapterNames.Count - 1 do + begin ChapterNames[j] := Trim(CleanString(RemoveStringBreaks( CommonStringFilter(ChapterNames[j])))); + end; //remove manga name from chapter if OptionRemoveMangaNameFromChapter and (Title <> '') then begin s := LowerCase(Title); j := Length(s); - for k := 0 to ChapterNames.Count - 1 do begin + for k := 0 to ChapterNames.Count - 1 do + begin s2 := LowerCase(ChapterNames[k]); if Length(s2) > j then - if Pos(s, s2) = 1 then begin + begin + if Pos(s, s2) = 1 then + begin s2 := ChapterNames[k]; Delete(s2, 1, j); s2 := Trim(s2); + if LeftStr(s2, 2) = '- ' then + begin Delete(s2, 1, 2); + end; + ChapterNames[k] := s2; end; + end; end; end; end; @@ -204,21 +264,39 @@ function TMangaInformation.GetInfoFromURL(const AURL: String): Byte; procedure TMangaInformation.SyncInfoToData(const ADataProcess: TDBDataProcess); begin - if Assigned(ADataProcess) then - with MangaInfo do - ADataProcess.UpdateData(Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary, - NumChapter, ModuleID); + if not Assigned(ADataProcess) then + begin + Exit; + end; + + with MangaInfo do + begin + ADataProcess.UpdateData(Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary, + NumChapter, ModuleID); + end; end; procedure TMangaInformation.AddInfoToData(const ATitle, ALink: String; const ADataProcess: TDBDataProcess); begin - if Assigned(ADataProcess) then + if not Assigned(ADataProcess) then + begin + Exit; + end; + + if (MangaInfo.Title = '') and (ATitle <> '') then + begin + MangaInfo.Title := ATitle; + end; + + if (MangaInfo.Link = '') and (ALink <> '') then + begin + MangaInfo.Link := ALink; + end; + + with MangaInfo do begin - if (MangaInfo.Title = '') and (ATitle <> '') then MangaInfo.Title := ATitle; - if (MangaInfo.Link = '') and (ALink <> '') then MangaInfo.Link := ALink; - with MangaInfo do - ADataProcess.AddData(Title, AltTitles, Link, Authors, Artists, Genres, Status, - StringBreaks(Summary), NumChapter, Now); + ADataProcess.AddData(Title, AltTitles, Link, Authors, Artists, Genres, Status, + StringBreaks(Summary), NumChapter, Now); end; end; diff --git a/baseunits/uGetMangaInfosThread.pas b/baseunits/uGetMangaInfosThread.pas index 3f2caef60..d2437ab31 100644 --- a/baseunits/uGetMangaInfosThread.pas +++ b/baseunits/uGetMangaInfosThread.pas @@ -16,8 +16,8 @@ interface uses - SysUtils, LazFileUtils, Graphics, Dialogs, uBaseUnit, uData, FMDOptions, - BaseThread, ImgInfos, webp, MultiLog, MemBitmap, VirtualTrees; + SysUtils, LazFileUtils, StrUtils, Graphics, Dialogs, uBaseUnit, uData, + FMDOptions, BaseThread, ImgInfos, webp, MultiLog, MemBitmap, VirtualTrees; type @@ -66,6 +66,7 @@ procedure TGetMangaInfosThread.Execute; var infob: byte; data: PMangaInfoData; + oldModuleID, searchText: String; begin Result := False; try @@ -149,7 +150,41 @@ procedure TGetMangaInfosThread.Execute; Synchronize(MainThreadSyncInfos); end; end; - + + if (FInfo.MangaInfo.Title <> '') and (FInfo.MangaInfo.Link <> '') then + begin + oldModuleID := dataProcess.Website; + if (oldModuleID <> m.ID) and dataProcess.Connected then + begin + dataProcess.Close; + end; + + if dataProcess.Connect(m.ID) then + begin + FInfo.AddInfoToData(FInfo.MangaInfo.Title, FInfo.MangaInfo.Link, dataProcess); + dataProcess.Commit; + dataProcess.Sort; + + if oldModuleID = m.ID then + begin + dataProcess.Refresh(dataProcess.Filtered); + + searchText := MainForm.edMangaListSearch.Text; + if ContainsText(FInfo.MangaInfo.Title, searchText) or (searchText = '') then + begin + MainForm.OpenDataDB(m.ID); + MainForm.UpdateVtMangaListFilterStatus; + end; + end + else + begin + dataProcess.Close; + dataProcess.Connect(oldModuleID); + dataProcess.Refresh(dataProcess.Filtered); + end; + end; + end; + if FFillSaveTo and OptionGenerateMangaFolder then begin MainForm.edSaveTo.Text := AppendPathDelim(MainForm.edSaveTo.Text) + diff --git a/baseunits/uUpdateThread.pas b/baseunits/uUpdateThread.pas index e92d97dcb..6edd1a79f 100644 --- a/baseunits/uUpdateThread.pas +++ b/baseunits/uUpdateThread.pas @@ -153,20 +153,26 @@ constructor TUpdateListThread.Create(const AOwner: TUpdateListManagerThread); inherited Create(False); FOwner := AOwner; FOwner.ThreadAdd(Self); + if FOwner.FCurrentCS = CS_INFO then begin FMangaInfo := TMangaInformation.Create(Self); FMangaInfo.isGetByUpdater := True; FMangaInfo.Module := FOwner.module; end; + FWorkPtr := -1; end; destructor TUpdateListThread.Destroy; begin FOwner.ThreadRemove(Self); + if FMangaInfo <> nil then + begin FMangaInfo.Free; + end; + inherited Destroy; end; @@ -185,6 +191,7 @@ procedure TUpdateListThread.GetDirectoryPageNumber; {R: Byte;} begin http := FOwner.module.CreateHTTP(Self); + try while FOwner.GetNext(Self) do begin @@ -197,8 +204,11 @@ procedure TUpdateListThread.GetDirectoryPageNumber; begin // TODO: GetDirectoryPageNumber.Result(Byte), do something with the result {R := }FOwner.module.OnGetDirectoryPageNumber(FOwner, http, FOwner.module.TotalDirectoryPage[FWorkPtr], FWorkPtr, FOwner.module); + if FOwner.module.TotalDirectoryPage[FWorkPtr] < 1 then + begin FOwner.module.TotalDirectoryPage[FWorkPtr] := 1; + end; end; http.Reset; @@ -222,16 +232,22 @@ procedure TUpdateListThread.GetNamesAndLinks; http := FOwner.module.CreateHTTP(Self); names := TStringList.Create; links := TStringList.Create; + try while FOwner.GetNext(Self) do begin try R := INFORMATION_NOT_FOUND; + if FOwner.InvertedList then - FWorkPtr := FOwner.module.TotalDirectoryPage[FOwner.module.CurrentDirectoryIndex] - FWorkPtr -1; + begin + FWorkPtr := FOwner.module.TotalDirectoryPage[FOwner.module.CurrentDirectoryIndex] - FWorkPtr - 1; + end; if Assigned(FOwner.module.OnGetNameAndLink) then + begin R := FOwner.module.OnGetNameAndLink(FOwner, http, names, links, IntToStr(FWorkPtr), FOwner.module); + end; if (R <> INFORMATION_NOT_FOUND) and (links.Count <> 0) then begin @@ -244,19 +260,26 @@ procedure TUpdateListThread.GetNamesAndLinks; try if FOwner.FIsPreListAvailable then begin - for i:=0 to links.Count-1 do + for i := 0 to links.Count - 1 do begin - if FOwner.mainDataProcess.AddData(names[i],'',links[i],'','','','','',0,0) then - FOwner.tempDataProcess.AddData(names[i],'',links[i],'','','','','',0,0) - else if (FOwner.isFinishSearchingForNewManga=False) and FOwner.module.SortedList and (not FOwner.InvertedList) then - FOwner.isFinishSearchingForNewManga:=True; + if FOwner.mainDataProcess.AddData(names[i], '', links[i], '', '', '', '', '', 0, 0) then + begin + FOwner.tempDataProcess.AddData(names[i], '', links[i], '', '', '', '', '', 0, 0); + end + else if (FOwner.isFinishSearchingForNewManga = False) and FOwner.module.SortedList and (not FOwner.InvertedList) then + begin + FOwner.isFinishSearchingForNewManga := True; + end; end; + FOwner.mainDataProcess.Rollback; end else begin - for i:=0 to links.Count-1 do - FOwner.tempDataProcess.AddData(names[i],'',links[i],'','','','','',0,0); + for i := 0 to links.Count - 1 do + begin + FOwner.tempDataProcess.AddData(names[i], '', links[i], '', '', '', '', '', 0, 0); + end; end; FOwner.tempDataProcess.Commit; finally @@ -291,7 +314,7 @@ procedure TUpdateListThread.GetInfo; // status = '-1' mean it's not exist and shouldn't be saved to database FOwner.mainDataProcess.Lock; try - FMangaInfo.AddInfoToData(FMangaInfo.MangaInfo.Link,FMangaInfo.MangaInfo.Link,FOwner.mainDataProcess); + FMangaInfo.AddInfoToData(FMangaInfo.MangaInfo.Link, FMangaInfo.MangaInfo.Link, FOwner.mainDataProcess); //FOwner.CheckCommit(FOwner.numberOfThreads); // todo: test if CheckCommit(32) is sufficient. FOwner.CheckCommit; @@ -313,9 +336,12 @@ procedure TUpdateListThread.GetInfo; procedure TUpdateListManagerThread.MainThreadEndGetting; begin - isUpdating:=False; + isUpdating := False; + if isPendingExitCounter then + begin MainForm.DoExitWaitCounter; + end; end; procedure TUpdateListManagerThread.MainThreadRemoveFilter; @@ -328,22 +354,34 @@ procedure TUpdateListManagerThread.ExtractFile; Sza, datapath, filepath: String; begin Sza := FMD_DIRECTORY + ZIP_EXE; - if not FileExists(Sza) then Exit; + if not FileExists(Sza) then + begin + Exit; + end; datapath := DATA_FOLDER; filepath := datapath + website; if FileExists(filepath + '.7z') then - filepath += '.7z' - else - if FileExists(filepath + '.zip') then + begin + filepath += '.7z'; + end + else if FileExists(filepath + '.zip') then + begin filepath += '.zip'; + end; if FileExists(filepath) then begin if FileExists(datapath + website + DBDATA_EXT) then + begin DeleteFile(datapath + website + DBDATA_EXT); + end; + if FileExists(datapath + website + DATA_EXT) then + begin DeleteFile(datapath + website + DATA_EXT); + end; + RunExternalProcess(Sza, ['x', filepath, '-o' + AnsiQuotedStr(datapath, '"'), '-aoa'], False, True); DeleteFile(filepath); @@ -377,8 +415,16 @@ destructor TUpdateListManagerThread.Destroy; TerminateThreads; WaitForThreads; Synchronize(@SyncDestroy); - if FThreadAborted then Logger.SendWarning(Self.ClassName+', thread aborted by user?'); - if not FThreadEndNormally then Logger.SendWarning(Self.ClassName+', thread doesn''t end normally, ended by user?'); + + if FThreadAborted then + begin + Logger.SendWarning(Self.ClassName+', thread aborted by user?'); + end; + if not FThreadEndNormally then + begin + Logger.SendWarning(Self.ClassName+', thread doesn''t end normally, ended by user?'); + end; + websites.Free; mainDataProcess.Close; tempDataProcess.Close; @@ -400,7 +446,9 @@ procedure TUpdateListManagerThread.CheckCommit(const CommitCount: Integer); begin FCommitCount := 0; if Assigned(mainDataProcess) then + begin mainDataProcess.Commit; + end; end; end; @@ -412,17 +460,26 @@ procedure TUpdateListManagerThread.RefreshList; if TModuleContainer(cbSelectManga.Items.Objects[cbSelectManga.ItemIndex]).ID = website then begin vtMangaList.Clear; + if dataProcess = nil then - dataProcess := TDBDataProcess.Create + begin + dataProcess := TDBDataProcess.Create; + end else + begin dataProcess.Close; + end; + OverwriteDBDataProcess(website, twebsite); OpenDataDB(website); end else begin if dataProcess.WebsiteLoaded(website) then + begin dataProcess.RemoveFilter; + end; + OverwriteDBDataProcess(website, twebsite); end; end; @@ -450,7 +507,11 @@ procedure TUpdateListManagerThread.CheckOut(const alimit: Integer; const acs: TC procedure TUpdateListManagerThread.SetCurrentDirectoryPageNumber(AValue: Integer); begin - if AValue < FCurrentGetInfoLimit then Exit; + if AValue < FCurrentGetInfoLimit then + begin + Exit; + end; + Lock; try FCurrentGetInfoLimit := AValue; @@ -466,7 +527,8 @@ procedure TUpdateListManagerThread.SyncCreate; FControlMargin := FormMain.ScaleFontTo96(2); FProgressBarHeight := FormMain.ScaleFontTo96(7); FStatusBar := TPanel.Create(nil); - with FStatusBar do begin + with FStatusBar do + begin Parent := MainForm; DoubleBuffered := True; Align := alBottom; @@ -488,7 +550,8 @@ procedure TUpdateListManagerThread.SyncCreate; end; FButtonCancel := TSpeedButton.Create(FStatusBar); - with FButtonCancel do begin + with FButtonCancel do + begin Parent := FStatusBar; Align := alNone; AutoSize := False; @@ -561,9 +624,15 @@ procedure TUpdateListManagerThread.StatusBarPaint(Sender: TObject); Rectangle(FProgressBarRect); if FTotalPtr = 0 then + begin FTotalPtr := 100; + end; + if FWorkPtr > FTotalPtr then + begin FWorkPtr := FTotalPtr; + end; + barPercents := FWorkPtr / FTotalPtr; if barPercents > 0 then begin @@ -578,6 +647,7 @@ procedure TUpdateListManagerThread.StatusBarPaint(Sender: TObject); FProgressBarPercentsRect.Inflate(-2, -2); GradientFill(FProgressBarPercentsRect, BlendColor(Brush.Color, CL_ProgressBarBase, 128), Brush.Color, gdHorizontal); end; + Font.Color := clWindowText; Brush.Style := bsClear; txtHeight := GetTextHeight(FStatusText); @@ -629,66 +699,88 @@ procedure TUpdateListManagerThread.Execute; cloghead: String; begin if websites.Count = 0 then + begin Exit; + end; + try websitePtr := 0; while websitePtr < websites.Count do begin - FThreadAborted:=True; + FThreadAborted := True; module := TModuleContainer(websites.Objects[websitePtr]); if Assigned(module) then begin website := module.ID; Inc(websitePtr); - cloghead:=Self.ClassName+', '+Module.Name+': '; + cloghead := Self.ClassName + ', ' + Module.Name + ': '; UpdateStatusText(RS_UpdatingList + Format(' [%d/%d] %s', [websitePtr, websites.Count, Module.Name]) + ' | ' + RS_Preparing + '...'); - twebsite:='__'+website; - twebsitetemp:=twebsite+'_templist'; + twebsite := '__' + website; + twebsitetemp := twebsite + '_templist'; try DeleteDBDataProcess(twebsite); DeleteDBDataProcess(twebsitetemp); if (dataProcess.Website = website) and (dataProcess.Connected) then - dataProcess.Backup(twebsite) + begin + dataProcess.Backup(twebsite); + end else begin if dataProcess.WebsiteLoaded(website) then + begin Synchronize(@MainThreadRemoveFilter); + end; + CopyDBDataProcess(website, twebsite); end; if not mainDataProcess.Connect(twebsite) then + begin mainDataProcess.CreateDatabase(twebsite); + end; tempDataProcess.CreateDatabase(twebsitetemp); // get directory page count InvertedList := False; directoryCount := 0; workPtr := 0; + if Assigned(module.OnAfterUpdateList) then + begin module.OnAfterUpdateList(module); + end; + if Assigned(module.OnBeforeUpdateList) then + begin module.OnBeforeUpdateList(module); + end; + if module.Settings.Enabled and (module.Settings.UpdateListDirectoryPageNumber > 0) then begin module.TotalDirectoryPage[FWorkPtr] := module.Settings.UpdateListDirectoryPageNumber; InvertedList := True; end else + begin CheckOut(module.TotalDirectory, CS_DIRECTORY_COUNT); + end; if Terminated then begin if Assigned(module.OnAfterUpdateList) then + begin module.OnAfterUpdateList(module); + end; + Break; end; - mainDataProcess.OpenTable('',True); - FIsPreListAvailable:=mainDataProcess.RecordCount>0; + mainDataProcess.OpenTable('', True); + FIsPreListAvailable := mainDataProcess.RecordCount > 0; mainDataProcess.CloseTable; // get names and links @@ -702,29 +794,42 @@ procedure TUpdateListManagerThread.Execute; module.CurrentDirectoryIndex := j; CheckOut(module.TotalDirectoryPage[j], CS_DIRECTORY_PAGE); Inc(j); - if Terminated then Break; + + if Terminated then + begin + Break; + end; end; if Assigned(module.OnBeforeUpdateList) then + begin module.OnBeforeUpdateList(module); + end; + if Terminated then + begin if not (OptionUpdateListNoMangaInfo and not(module.SortedList)) then + begin Break; + end; + end; UpdateStatusText(RS_UpdatingList + Format(' [%d/%d] %s', [websitePtr, websites.Count, Module.Name]) + ' | ' + RS_IndexingNewTitle + '...'); tempDataProcess.OpenTable('', True); // get manga info - if tempDataProcess.RecordCount>0 then + if tempDataProcess.RecordCount > 0 then begin workPtr := 0; FCommitCount := 0; + if not module.InformationAvailable or OptionUpdateListNoMangaInfo then begin Inc(workPtr); - for k:=0 to tempDataProcess.RecordCount-1 do + + for k := 0 to tempDataProcess.RecordCount - 1 do begin mainDataProcess.AddData( tempDataProcess.Value[k,DATA_PARAM_TITLE], @@ -742,7 +847,9 @@ procedure TUpdateListManagerThread.Execute; end; end else + begin CheckOut(tempDataProcess.RecordCount, CS_INFO); + end; mainDataProcess.Commit; if (workPtr > 0) and (not (Terminated and module.SortedList)) then @@ -765,16 +872,20 @@ procedure TUpdateListManagerThread.Execute; DeleteDBDataProcess(twebsitetemp); if Terminated then + begin Break; + end; + websites[websitePtr - 1] := UTF8Encode(#$2714) + websites[websitePtr - 1]; - FThreadAborted:=False; + FThreadAborted := False; end; end; except on E: Exception do MainForm.ExceptionHandler(Self, E); end; - FThreadEndNormally:=True; + + FThreadEndNormally := True; Synchronize(@MainThreadEndGetting); end; @@ -783,9 +894,12 @@ procedure TUpdateListManagerThread.TerminateThreads; t: TUpdateListThread; begin EnterCriticalsection(ThreadsGuardian); + try for t in Threads do + begin t.Terminate; + end; finally LeaveCriticalsection(ThreadsGuardian); end; @@ -794,7 +908,9 @@ procedure TUpdateListManagerThread.TerminateThreads; procedure TUpdateListManagerThread.WaitForThreads; begin while Threads.Count <> 0 do + begin Sleep(2000); // this will wait for a loop of high number + end; end; procedure TUpdateListManagerThread.TerminateCurrent(Sender: TObject); @@ -805,6 +921,7 @@ procedure TUpdateListManagerThread.TerminateCurrent(Sender: TObject); procedure TUpdateListManagerThread.ThreadAdd(const T: TUpdateListThread); begin EnterCriticalSection(ThreadsGuardian); + try Threads.Add(T); finally @@ -815,6 +932,7 @@ procedure TUpdateListManagerThread.ThreadAdd(const T: TUpdateListThread); procedure TUpdateListManagerThread.ThreadRemove(const T: TUpdateListThread); begin EnterCriticalSection(ThreadsGuardian); + try Threads.Remove(T); finally @@ -825,18 +943,32 @@ procedure TUpdateListManagerThread.ThreadRemove(const T: TUpdateListThread); procedure TUpdateListManagerThread.GetCurrentLimit; begin if FTotalPtr <> FCurrentGetInfoLimit then + begin FTotalPtr := FCurrentGetInfoLimit; + end; + if module.Settings.Enabled and (module.Settings.UpdateListNumberOfThread > 0) then - numberOfThreads := module.Settings.UpdateListNumberOfThread - else - if module.MaxThreadPerTaskLimit > 0 then - numberOfThreads := module.MaxThreadPerTaskLimit + begin + numberOfThreads := module.Settings.UpdateListNumberOfThread; + end + else if module.MaxThreadPerTaskLimit > 0 then + begin + numberOfThreads := module.MaxThreadPerTaskLimit; + end else + begin numberOfThreads := OptionMaxUpdateListThreads; + end; + if (module.ConnectionsQueue.MaxConnections > 0) and (numberOfThreads > module.ConnectionsQueue.MaxConnections) then + begin numberOfThreads := module.ConnectionsQueue.MaxConnections; + end; + if numberOfThreads < 1 then + begin numberOfThreads := 1; //default + end; end; function TUpdateListManagerThread.GetNext(const T: TUpdateListThread): Boolean; @@ -845,16 +977,30 @@ function TUpdateListManagerThread.GetNext(const T: TUpdateListThread): Boolean; begin Result := False; T.FWorkPtr := -1; - if Terminated then Exit; + + if Terminated then + begin + Exit; + end; + // Finish searching for new series in sorted mode - if (FCurrentCS = CS_DIRECTORY_PAGE) and (isFinishSearchingForNewManga) then Exit; + if (FCurrentCS = CS_DIRECTORY_PAGE) and (isFinishSearchingForNewManga) then + begin + Exit; + end; - if workPtr >= FCurrentGetInfoLimit then Exit; + if workPtr >= FCurrentGetInfoLimit then + begin + Exit; + end; Lock; try GetCurrentLimit; - if Threads.Count > numberOfThreads then Exit; + if Threads.Count > numberOfThreads then + begin + Exit; + end; T.FWorkPtr := workPtr; Result := True; @@ -867,10 +1013,14 @@ function TUpdateListManagerThread.GetNext(const T: TUpdateListThread): Boolean; CS_DIRECTORY_COUNT: begin if FCurrentGetInfoLimit = 1 then + begin s := RS_UpdatingList + Format(' [%d/%d] ', [websitePtr, websites.Count]) + - module.Name + ' | ' + RS_GettingDirectory + '...' + module.Name + ' | ' + RS_GettingDirectory + '...'; + end else + begin s := s + ' | ' + RS_GettingDirectory + '...'; + end; end; CS_DIRECTORY_PAGE: begin @@ -881,6 +1031,7 @@ function TUpdateListManagerThread.GetNext(const T: TUpdateListThread): Boolean; CS_INFO: begin tempDataProcess.Lock; + try T.FMangaInfo.MangaInfo.Title := tempDataProcess.Value[T.FWorkPtr,DATA_PARAM_TITLE]; T.FMangaInfo.MangaInfo.Link := tempDataProcess.Value[T.FWorkPtr,DATA_PARAM_LINK]; @@ -895,7 +1046,9 @@ function TUpdateListManagerThread.GetNext(const T: TUpdateListThread): Boolean; // spawn new worker thread if (Threads.Count < numberOfThreads) and (workPtr < FCurrentGetInfoLimit) then + begin TUpdateListThread.Create(Self); + end; finally Unlock; end; diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 8b4e6ccf7..0dddaf5a0 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -1117,13 +1117,17 @@ procedure TSearchDBThread.Execute; if dataProcess <> nil then begin Synchronize(@SyncBeforeSearch); + while FNewSearch do begin FNewSearch := False; dataProcess.Search(FSearchStr); end; + if not Terminated then + begin Synchronize(@SyncAfterSearch); + end; end; end; @@ -1181,10 +1185,16 @@ procedure TOpenDBThread.SyncOpenFinish; begin LastSearchStr := upcase(edMangaListSearch.Text); LastSearchWeb := currentWebsite; + if dataProcess.Filtered then - lbMode.Caption := Format(RS_ModeFiltered, [dataProcess.RecordCount]) + begin + lbMode.Caption := Format(RS_ModeFiltered, [dataProcess.RecordCount]); + end else + begin lbMode.Caption := Format(RS_ModeAll, [dataProcess.RecordCount]); + end; + SetControlEnabled(True); vtMangaList.RootNodeCount := dataProcess.RecordCount; ChangeAllCursor(pssInfoList, crDefault); @@ -1196,14 +1206,20 @@ procedure TOpenDBThread.Execute; if (FWebsite <> '') and (dataProcess <> nil) then begin Synchronize(@SyncOpenStart); + if dataProcess <> nil then begin dataProcess.Open(FWebsite); if FormMain.edMangaListSearch.Text <> '' then + begin dataProcess.Search(MainForm.edMangaListSearch.Text); + end; end; + if not Terminated then + begin Synchronize(@SyncOpenFinish); + end; end; end; @@ -3239,23 +3255,35 @@ procedure TMainForm.cbOptionGenerateMangaFolderChange(Sender: TObject); procedure TMainForm.cbSelectMangaEditingDone(Sender: TObject); begin - if cbSelectManga.ItemIndex < 0 then Exit; + if cbSelectManga.ItemIndex < 0 then + begin + Exit; + end; + if currentWebsite <> Pointer(cbSelectManga.Items.Objects[cbSelectManga.ItemIndex]) then begin currentWebsite := cbSelectManga.Items.Objects[cbSelectManga.ItemIndex]; settingsfile.WriteString('form', 'SelectManga', TModuleContainer(currentWebsite).ID); vtMangaList.Clear; + if dataProcess = nil then - dataProcess := TDBDataProcess.Create - else - if dataProcess.Connected then + begin + dataProcess := TDBDataProcess.Create; + end + else if dataProcess.Connected then + begin dataProcess.Close; + end; + lbMode.Caption := Format(RS_ModeAll, [0]); if DBDataFileExist(TModuleContainer(currentWebsite).ID) then - OpenDataDB(TModuleContainer(currentWebsite).ID) - else - if cbOptionShowDownloadMangalistDialog.Checked then + begin + OpenDataDB(TModuleContainer(currentWebsite).ID); + end + else if cbOptionShowDownloadMangalistDialog.Checked then + begin mnUpdateDownFromServerClick(mnUpdateDownFromServer); + end; end; end; @@ -3263,14 +3291,18 @@ procedure TMainForm.cbSelectMangaKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if not (Key in [VK_RETURN, VK_TAB]) then - cbSelectManga.DroppedDown:=True; + begin + cbSelectManga.DroppedDown := True; + end; end; procedure TMainForm.cbSelectMangaMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbMiddle then + begin cbSelectMangaEditingDone(Sender); + end; end; procedure TMainForm.ckImageMagickChange(Sender: TObject); @@ -3581,6 +3613,7 @@ procedure TMainForm.btRemoveFilterClick(Sender: TObject); begin vtMangaList.Clear; Screen.Cursor := crHourGlass; + try dataProcess.RemoveFilter; vtMangaList.RootNodeCount := dataProcess.RecordCount; @@ -3591,6 +3624,7 @@ procedure TMainForm.btRemoveFilterClick(Sender: TObject); on E: Exception do ExceptionHandler(Self, E); end; + Screen.Cursor := crDefault; end; end; @@ -3607,35 +3641,52 @@ procedure TMainForm.btFilterClick(Sender: TObject); Screen.Cursor := crHourGlass; checkGenres := TStringList.Create; uncheckGenres := TStringList.Create; + try edCustomGenres.Text := Trim(edCustomGenres.Text); if cbUseRegExpr.Checked and (edCustomGenres.Text <> '') then - checkGenres.Add(edCustomGenres.Text) + begin + checkGenres.Add(edCustomGenres.Text); + end else begin ExtractStrings([','], [], PChar(edCustomGenres.Text), checkGenres); TrimStrings(checkGenres); + i := 0; - while i < checkGenres.Count do begin + while i < checkGenres.Count do + begin s := Trim(checkGenres.Strings[i]); - if (s <> '') and (s[1] = '-') or (s[1] = '!') then begin + if (s <> '') and (s[1] = '-') or (s[1] = '!') then + begin Delete(s, 1, 1); uncheckGenres.Add(s); checkGenres.Delete(i); end - else Inc(i); + else + begin + Inc(i); + end; end; end; if pnGenres.ControlCount > 0 then + begin for i := 0 to pnGenres.ControlCount - 1 do - if pnGenres.Controls[i] is TCheckBox then begin + begin + if pnGenres.Controls[i] is TCheckBox then + begin if TCheckBox(pnGenres.Controls[i]).State = cbChecked then - checkGenres.Add(TCheckBox(pnGenres.Controls[i]).Caption) - else - if TCheckBox(pnGenres.Controls[i]).State = cbUnchecked then + begin + checkGenres.Add(TCheckBox(pnGenres.Controls[i]).Caption); + end + else if TCheckBox(pnGenres.Controls[i]).State = cbUnchecked then + begin uncheckGenres.Add(TCheckBox(pnGenres.Controls[i]).Caption); + end; end; + end; + end; if dataProcess.CanFilter( checkGenres, @@ -3651,7 +3702,9 @@ procedure TMainForm.btFilterClick(Sender: TObject); begin dataProcess.FilterAllSites := cbSearchFromAllSites.Checked; if cbSearchFromAllSites.Checked then + begin dataProcess.SitesList.Assign(cbSelectManga.Items); + end; edMangaListSearch.Tag := -1; edMangaListSearch.Clear; @@ -3680,9 +3733,13 @@ procedure TMainForm.btFilterClick(Sender: TObject); vtMangaList.RootNodeCount := dataProcess.RecordCount; if dataProcess.Filtered then - lbMode.Caption := Format(RS_ModeFiltered, [vtMangaList.RootNodeCount]) + begin + lbMode.Caption := Format(RS_ModeFiltered, [vtMangaList.RootNodeCount]); + end else - lbMode.Caption := Format(RS_ModeAll, [vtMangaList.RootNodeCount]) + begin + lbMode.Caption := Format(RS_ModeAll, [vtMangaList.RootNodeCount]); + end; end; procedure TMainForm.btFilterResetClick(Sender: TObject); @@ -3690,7 +3747,10 @@ procedure TMainForm.btFilterResetClick(Sender: TObject); i: Cardinal; begin for i := 0 to 37 do + begin TCheckBox(pnGenres.Controls[i]).State := cbGrayed; + end; + edFilterTitle.Caption := ''; edFilterAuthors.Caption := ''; edFilterArtists.Caption := ''; @@ -4056,6 +4116,7 @@ procedure TMainForm.mnUpdateListClick(Sender: TObject); begin Exit; end; + m := TModuleContainer(cbSelectManga.Items.Objects[cbSelectManga.ItemIndex]); if (not isUpdating) then begin @@ -4189,9 +4250,14 @@ procedure TMainForm.miMangaListDeleteClick(Sender: TObject); while Assigned(xNode) do begin if dataProcess.DeleteData(xNode^.Index) then - deleteNode := xNode + begin + deleteNode := xNode; + end else + begin deleteNode := nil; + end; + xNode := vtMangaList.GetPreviousSelected(xNode); if Assigned(deleteNode) then begin @@ -4199,12 +4265,13 @@ procedure TMainForm.miMangaListDeleteClick(Sender: TObject); Inc(deleteCount); end; end; + if deleteCount > 0 then begin dataProcess.Table.ApplyUpdates; dataProcess.Table.SQLTransaction.CommitRetaining; vtMangaList.ClearSelection; - UpdateVtMangaListFilterStatus + UpdateVtMangaListFilterStatus; end; finally vtMangaList.EndUpdate; @@ -5410,7 +5477,9 @@ procedure TMainForm.vtFavoritesPaintText(Sender: TBaseVirtualTree; TextType: TVSTTextType); begin if not FavoriteManager[Node^.Index].Enabled then + begin TargetCanvas.Font.Color := TVirtualStringTree(Sender).Colors.DisabledColor; + end; end; procedure TMainForm.vtMangaListChange(Sender: TBaseVirtualTree; Node: PVirtualNode); @@ -6872,11 +6941,21 @@ procedure TMainForm.edMangaListSearchChange(Sender: TObject); LastSearchStr := UpCase(edMangaListSearch.Text); Exit; end; - if (not cbOptionLiveSearch.Checked) and (edMangaListSearch.Tag = 0) then Exit; + + if (not cbOptionLiveSearch.Checked) and (edMangaListSearch.Tag = 0) then + begin + Exit; + end; + if edMangaListSearch.Tag <> 0 then + begin edMangaListSearch.Tag := 0; + end; + if (upcase(edMangaListSearch.Text) = LastSearchStr) and (currentWebsite = LastSearchWeb) then + begin Exit; + end; SearchDataDB(edMangaListSearch.Text); @@ -7267,10 +7346,14 @@ procedure TMainForm.CollectLanguagesFromFiles; SimpleTranslator.LangDir := FMD_DIRECTORY + 'languages'; SimpleTranslator.LangAppName := 'fmd'; SimpleTranslator.CollectLanguagesFiles; + if SimpleTranslator.AvailableLanguages.Count > 0 then begin for i := 0 to AvailableLanguages.Count - 1 do + begin cbLanguages.Items.Add(SimpleTranslator.AvailableLanguages.ValueFromIndex[i]); + end; + cbLanguages.ItemIndex := SimpleTranslator.AvailableLanguages.IndexOfName( settingsfile.ReadString('languages', 'Selected', 'en')); end; From 3601baa05c8cef16a80786424d7e815f274f6386 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Mon, 9 Feb 2026 18:26:57 +0800 Subject: [PATCH 24/35] Fixed: Kinks with reloading manga list after editing Added: Bunch of lock and unlocks in db processing to mitigate errors Fixed: Many many bad codes --- baseunits/DBDataProcess.pas | 1115 ++++++++++++++++------------ baseunits/uDownloadsManager.pas | 31 +- baseunits/uGetMangaInfosThread.pas | 72 +- mangadownloader/forms/frmMain.pas | 174 ++++- 4 files changed, 873 insertions(+), 519 deletions(-) diff --git a/baseunits/DBDataProcess.pas b/baseunits/DBDataProcess.pas index ada6fe984..579292de6 100644 --- a/baseunits/DBDataProcess.pas +++ b/baseunits/DBDataProcess.pas @@ -101,6 +101,8 @@ TDBDataProcess = class(TObject) procedure Save; procedure Backup(const AWebsite: String); procedure Refresh(RecheckDataCount: Boolean = False); + function IsSelectStatement(const SQL: string): Boolean; + function FindData(const Link: String): Boolean; function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; NumChapter, JDN: Integer): Boolean; overload; function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; @@ -231,16 +233,18 @@ procedure CopyDBDataProcess(const AWebsite, NWebsite: String); Exit; end; - if DBDataFileExist(AWebsite) then + if not DBDataFileExist(AWebsite) then begin - try - CopyFile(DATA_FOLDER + AWebsite + DBDATA_EXT, - DATA_FOLDER + NWebsite + DBDATA_EXT, - [cffPreserveTime, cffOverwriteFile], True); - except - on E: Exception do - SendLogException('CopyDBDataProcess.Error!', E); - end; + Exit; + end; + + try + CopyFile(DATA_FOLDER + AWebsite + DBDATA_EXT, + DATA_FOLDER + NWebsite + DBDATA_EXT, + [cffPreserveTime, cffOverwriteFile], True); + except + on E: Exception do + SendLogException('CopyDBDataProcess.Error!', E); end; end; @@ -248,49 +252,52 @@ function DeleteDBDataProcess(const AWebsite: String): Boolean; var tryc: Integer; begin - Result := not FileExists(DATA_FOLDER + AWebsite + DBDATA_EXT); + Result := True; - if Result = False then + if not FileExists(DATA_FOLDER + AWebsite + DBDATA_EXT) then begin - tryc := 0; - while not DeleteFile(DATA_FOLDER + AWebsite + DBDATA_EXT) do - begin - if tryc > 3 then - begin - Break; - end; + Exit; + end; - Inc(tryc); - Sleep(250); + tryc := 0; + while not DeleteFile(DATA_FOLDER + AWebsite + DBDATA_EXT) do + begin + if tryc > 3 then + begin + Break; end; - Result := not FileExists(DATA_FOLDER + AWebsite + DBDATA_EXT); + Inc(tryc); + Sleep(250); end; + + Result := not FileExists(DATA_FOLDER + AWebsite + DBDATA_EXT); end; procedure OverwriteDBDataProcess(const AWebsite, NWebsite: String); begin - if FileExists(DATA_FOLDER + NWebsite + DBDATA_EXT) then + if not FileExists(DATA_FOLDER + NWebsite + DBDATA_EXT) then begin - if DeleteDBDataProcess(AWebsite) then - begin - RenameFile(DATA_FOLDER + NWebsite + DBDATA_EXT, - DATA_FOLDER + AWebsite + DBDATA_EXT); - end; + Exit; end; + + if not DeleteDBDataProcess(AWebsite) then + begin + Exit; + end; + + RenameFile(DATA_FOLDER + NWebsite + DBDATA_EXT, DATA_FOLDER + AWebsite + DBDATA_EXT); end; { TDBDataProcess } function TDBDataProcess.GetLinkCount: Integer; -begin +begin + Result := 0; + if Assigned(FLinks) then begin Result := FLinks.Count; - end - else - begin - Result := 0; end; end; @@ -306,12 +313,18 @@ function TDBDataProcess.GoToRecNo(const ARecIndex: Integer): Boolean; Exit(True); end; - Result := False; + Result := False; + GetRecordCount; if ARecIndex > RecordCount then begin Exit; end; + if not FQuery.Active then + begin + Exit; + end; + try FRecNo := ARecIndex; FQuery.RecNo := ARecIndex + 1; @@ -322,21 +335,37 @@ function TDBDataProcess.GoToRecNo(const ARecIndex: Integer): Boolean; procedure TDBDataProcess.CreateTable; begin - if FConn.Connected then + if not FConn.Connected then begin + Exit; + end; + + try + Lock; + FConn.ExecuteDirect('DROP TABLE IF EXISTS "' + FTableName + '"'); FConn.ExecuteDirect('CREATE TABLE "' + FTableName + '" (' + DBDataProccesCreateParam + ');'); - FTrans.CommitRetaining; + FTrans.CommitRetaining; + finally + Unlock; end; end; procedure TDBDataProcess.CreateField(const FieldName: String); begin - if FConn.Connected then + if not FConn.Connected then begin + Exit; + end; + + try + Lock; + FConn.ExecuteDirect('ALTER TABLE "' + FTableName + '" ADD COLUMN "' + FieldName + '" TEXT;'); FTrans.CommitRetaining; + finally + Unlock; end; end; @@ -350,33 +379,38 @@ procedure TDBDataProcess.ConvertNewTable(const TableParams: String); end; try - qactive := FQuery.Active; - if FQuery.Active then - begin - FQuery.Close; - end; + Lock; + try + qactive := FQuery.Active; + if FQuery.Active then + begin + FQuery.Close; + end; - with FConn do - begin - try - ExecuteDirect('ALTER TABLE "' + FTableName + '" RENAME TO "' + FTableName + '_old"'); - ExecuteDirect('CREATE TABLE "' + FTableName + '" (' + DBDataProccesCreateParam + ');'); - ExecuteDirect('INSERT INTO "' + FTableName + '" (' + TableParams + ') SELECT ' + TableParams + ' FROM "' + FTableName + '_old"'); - ExecuteDirect('DROP TABLE "' + FTableName + '_old"'); - VacuumTable; - except - on E: Exception do - SendLogException(Self.ClassName + '[' + Website + '].Convert.Error!', E); + with FConn do + begin + try + ExecuteDirect('ALTER TABLE "' + FTableName + '" RENAME TO "' + FTableName + '_old"'); + ExecuteDirect('CREATE TABLE "' + FTableName + '" (' + DBDataProccesCreateParam + ');'); + ExecuteDirect('INSERT INTO "' + FTableName + '" (' + TableParams + ') SELECT ' + TableParams + ' FROM "' + FTableName + '_old"'); + ExecuteDirect('DROP TABLE "' + FTableName + '_old"'); + VacuumTable; + except + on E: Exception do + SendLogException(Self.ClassName + '[' + Website + '].Convert.Error!', E); + end; end; - end; - FTrans.Commit; + FTrans.Commit; - if qactive <> FQuery.Active then - begin - FQuery.Active := qactive; - end; - except - FTrans.Rollback; + if qactive <> FQuery.Active then + begin + FQuery.Active := qactive; + end; + except + FTrans.Rollback; + end; + finally + Unlock; end; end; @@ -384,8 +418,14 @@ procedure TDBDataProcess.VacuumTable; var queryactive: Boolean; begin - if FConn.Connected then + if not FConn.Connected then begin + Exit; + end; + + try + Lock; + queryactive := FQuery.Active; FQuery.Close; @@ -403,6 +443,8 @@ procedure TDBDataProcess.VacuumTable; begin FQuery.Active := queryactive; end; + finally + Unlock; end; end; @@ -561,36 +603,34 @@ function TDBDataProcess.InternalOpen(const FilePath: String): Boolean; end; function TDBDataProcess.GetWebsiteName(const RecIndex: Integer): String; -begin - if FAllSitesAttached then - begin - try - FQuery.RecNo := RecIndex + 1; - Result := FQuery.Fields[DBTempFieldWebsiteIndex].AsString; - except - on E: Exception do - SendLogException(Self.ClassName + '[' + Website + '].GetWebsiteName Error!' + - 'RecIndex: ' + IntToStr(RecIndex), E); - end; - end - else +begin + Result := FWebsite; + + if not FAllSitesAttached then begin - Result := FWebsite; + Exit; + end; + + try + FQuery.RecNo := RecIndex + 1; + Result := FQuery.Fields[DBTempFieldWebsiteIndex].AsString; + except + on E: Exception do + SendLogException(Self.ClassName + '[' + Website + '].GetWebsiteName Error!' + + 'RecIndex: ' + IntToStr(RecIndex), E); end; end; function TDBDataProcess.GetValue(const RecIndex, FieldIndex: Integer): String; begin - if FieldIndex in [DATA_PARAM_NUMCHAPTER,DATA_PARAM_JDN] then + Result := ''; + + if FieldIndex in [DATA_PARAM_NUMCHAPTER, DATA_PARAM_JDN] then begin Result := '0'; - end - else - begin - Result := ''; end; - if FQuery.Active = False then + if not FQuery.Active then begin Exit; end; @@ -605,12 +645,13 @@ function TDBDataProcess.GetValueInt(const RecIndex, FieldIndex: Integer ): Integer; begin Result := 0; - if FQuery.Active = False then + + if not FQuery.Active then begin Exit; end; - if not (FieldIndex in [DATA_PARAM_NUMCHAPTER,DATA_PARAM_JDN]) then + if not (FieldIndex in [DATA_PARAM_NUMCHAPTER, DATA_PARAM_JDN]) then begin Exit; end; @@ -627,15 +668,17 @@ procedure TDBDataProcess.AttachAllSites; var j: Integer; begin - if SitesList.Count > 0 then + if SitesList.Count <= 0 then + begin + Exit; + end; + + for j := 0 to SitesList.Count - 1 do begin - for j := 0 to SitesList.Count - 1 do + if Pointer(SitesList.Objects[j]) = FModule then begin - if Pointer(SitesList.Objects[j]) = FModule then - begin - SitesList.Delete(j); - Break; - end; + SitesList.Delete(j); + Break; end; end; end; @@ -651,42 +694,48 @@ procedure TDBDataProcess.AttachAllSites; Exit; end; - DetachAllSites; - FConn.ExecuteDirect('END TRANSACTION'); - attachedMax := 125; - tempDataProcess := TDBDataProcess.Create; - try - for i := 0 to SitesList.Count - 1 do - begin - // default max attached database that came with sqlite3.dll was 7 - // use custom build attached database with max 125 - // if FAttachedSites.Count=7 then Break; - if attachedMax = 0 then - begin - SendLogWarning(ClassName + '[' + Website + '].AttachAllSites.Warning! Can''t attach all sites, the limit of 125 reached.'); - Break; - end; + Lock; + + DetachAllSites; + FConn.ExecuteDirect('END TRANSACTION'); + attachedMax := 125; + tempDataProcess := TDBDataProcess.Create; - m := TModuleContainer(FSitesList.Objects[i]); - if (FAttachedSites.IndexOf(m.ID) = -1) and (FileExists(DBDataFilePath(m.ID))) then + try + for i := 0 to SitesList.Count - 1 do begin - tempDataProcess.Open(m.ID); // Check database structure so theres no errors if databases mismatch - attachedMax := attachedMax - 1; - FConn.ExecuteDirect('ATTACH ' + QuotedStr(DBDataFilePath(m.ID)) + ' AS "' + m.ID + '"'); - FAttachedSites.AddObject(m.ID, m); + // default max attached database that came with sqlite3.dll was 7 + // use custom build attached database with max 125 + // if FAttachedSites.Count=7 then Break; + if attachedMax = 0 then + begin + SendLogWarning(ClassName + '[' + Website + '].AttachAllSites.Warning! Can''t attach all sites, the limit of 125 reached.'); + Break; + end; + + m := TModuleContainer(FSitesList.Objects[i]); + if (FAttachedSites.IndexOf(m.ID) = -1) and (FileExists(DBDataFilePath(m.ID))) then + begin + tempDataProcess.Open(m.ID); // Check database structure so theres no errors if databases mismatch + attachedMax := attachedMax - 1; + FConn.ExecuteDirect('ATTACH ' + QuotedStr(DBDataFilePath(m.ID)) + ' AS "' + m.ID + '"'); + FAttachedSites.AddObject(m.ID, m); + end; end; + except + on E: Exception do + SendLogException(ClassName + '[' + Website + '].AttachAllSites.Error!' + + ' try to attach ' + QuotedStr(SitesList[i]), E) end; - except - on E: Exception do - SendLogException(ClassName + '[' + Website + '].AttachAllSites.Error!' + - ' try to attach ' + QuotedStr(SitesList[i]), E) - end; - tempDataProcess.Close; - tempDataProcess.Free; - FConn.ExecuteDirect('BEGIN TRANSACTION'); - FAllSitesAttached := FAttachedSites.Count > 0; + tempDataProcess.Close; + tempDataProcess.Free; + FConn.ExecuteDirect('BEGIN TRANSACTION'); + FAllSitesAttached := FAttachedSites.Count > 0; + finally + Unlock; + end; end; procedure TDBDataProcess.DetachAllSites; @@ -699,31 +748,37 @@ procedure TDBDataProcess.DetachAllSites; Exit; end; - queryactive := FQuery.Active; - if FQuery.Active then - begin - FQuery.Close; - end; + try + Lock; - FTrans.CommitRetaining; - FConn.ExecuteDirect('END TRANSACTION'); - for i := FAttachedSites.Count - 1 downto 0 do - begin - try - FConn.ExecuteDirect('DETACH "' + FAttachedSites[i] + '"'); - FAttachedSites.Delete(i); - except - on E: Exception do - SendLogException(Self.ClassName + '[' + Website + '].DetachAllSites.Error!', E); + queryactive := FQuery.Active; + if FQuery.Active then + begin + FQuery.Close; + end; + + FTrans.CommitRetaining; + FConn.ExecuteDirect('END TRANSACTION'); + for i := FAttachedSites.Count - 1 downto 0 do + begin + try + FConn.ExecuteDirect('DETACH "' + FAttachedSites[i] + '"'); + FAttachedSites.Delete(i); + except + on E: Exception do + SendLogException(Self.ClassName + '[' + Website + '].DetachAllSites.Error!', E); + end; end; - end; - FConn.ExecuteDirect('BEGIN TRANSACTION'); - FAllSitesAttached := FAttachedSites.Count > 0; + FConn.ExecuteDirect('BEGIN TRANSACTION'); + FAllSitesAttached := FAttachedSites.Count > 0; - if FQuery.Active <> queryactive then - begin - FQuery.Active := queryactive; + if FQuery.Active <> queryactive then + begin + FQuery.Active := queryactive; + end; + finally + Unlock; end; end; @@ -731,8 +786,14 @@ function TDBDataProcess.ExecuteDirect(SQL: String): Boolean; begin Result := False; - if FConn.Connected then + if not FConn.Connected then begin + Exit; + end; + + try + Lock; + try FConn.ExecuteDirect(SQL); Result := True; @@ -741,6 +802,8 @@ function TDBDataProcess.ExecuteDirect(SQL: String): Boolean; SendLogException(Self.ClassName + '[' + Website + '].ExecuteDirect.Error!'#13#10 + 'SQL: ' + SQL, E); end; + finally + Unlock; end; end; @@ -809,7 +872,7 @@ destructor TDBDataProcess.Destroy; end; except on E: Exception do - SendLogException(Self.ClassName+'['+Website+'].Destroy.Error!', E); + SendLogException(Self.ClassName + '[' + Website + '].Destroy.Error!', E); end; DoneLocateLink; @@ -837,32 +900,46 @@ function TDBDataProcess.Connect(const AWebsite: String): Boolean; var filepath: String = ''; begin - if CheckWebsiteAndFilePath(AWebsite, filepath) then - begin - Result := InternalOpen(filepath); - end - else - begin - Result := False; + Result := False; + + try + Lock; + + if CheckWebsiteAndFilePath(AWebsite, filepath) then + begin + Result := InternalOpen(filepath); + end; + finally + Unlock; end; end; function TDBDataProcess.ConnectFile(const AFile: String): Boolean; begin + Result := False; + try + Lock; + Result := InternalOpen(AFile); - except - Result := False; + finally + Unlock; end; end; function TDBDataProcess.Open(const AWebsite: String): Boolean; begin - Close; - Result := False; + try + Lock; + + Close; + Result := False; + + if not Connect(AWebsite) then + begin + Exit; + end; - if Connect(AWebsite) then - begin try if not TableExist(FTableName) then begin @@ -876,53 +953,57 @@ function TDBDataProcess.Open(const AWebsite: String): Boolean; on E: Exception do SendLogException(Self.ClassName + '.Open.Error!', E); end; + finally + Unlock; end; end; function TDBDataProcess.OpenTable(const ATableName: String; CheckRecordCount: Boolean): Boolean; begin - Result := False; + Result := FQuery.Active; - if FConn.Connected then + if not FConn.Connected then begin - try - if ATableName <> '' then - begin - FTableName := ATableName; - end; + Exit; + end; - if FTableName = '' then + try + if ATableName <> '' then + begin + FTableName := ATableName; + end; + + if FTableName = '' then + begin + Exit; + end; + + if TableExist(FTableName) then + begin + if FQuery.Active then begin - Exit; + FQuery.Close; end; - if TableExist(FTableName) then + if not FTrans.Active then begin - if FQuery.Active then - begin - FQuery.Close; - end; - - if FTrans.Active=False then - begin - FTrans.Active := True; - end; - - FSQLSelect := 'SELECT * FROM "' + FTableName + '"'; - FQuery.SQL.Text := FSQLSelect; + FTrans.Active := True; + end; - if CheckRecordCount then - begin - GetRecordCount; - end; + FSQLSelect := 'SELECT * FROM "' + FTableName + '"'; + FQuery.SQL.Text := FSQLSelect; - FQuery.Open; + if CheckRecordCount then + begin + GetRecordCount; end; - except - on E: Exception do - SendLogException(Self.ClassName+'['+Website+'].OpenTable.Error!', E); + + FQuery.Open; end; + except + on E: Exception do + SendLogException(Self.ClassName + '[' + Website + '].OpenTable.Error!', E); end; Result := FQuery.Active; @@ -935,16 +1016,18 @@ function TDBDataProcess.TableExist(const ATableName: String): Boolean; begin Result := False; - if FConn.Connected then + if not FConn.Connected then begin - ts := TStringList.Create; - try - FConn.GetTableNames(ts); - ts.Sorted := True; - Result := ts.Find(ATableName, i); - finally - ts.Free; - end; + Exit; + end; + + ts := TStringList.Create; + try + FConn.GetTableNames(ts); + ts.Sorted := True; + Result := ts.Find(ATableName, i); + finally + ts.Free; end; end; @@ -955,41 +1038,43 @@ procedure TDBDataProcess.CheckFieldsExist(const ATableName: String); FieldName, TableParams: String; FoundMissing: Boolean; begin - FoundMissing := False; - TableParams := ''; - if FConn.Connected then begin - ts := TStringList.Create; - try - FConn.GetFieldNames(ATableName, ts); - ts.Sorted := True; - for j := Low(DBDataProcessParams) to High(DBDataProcessParams) do - begin - FieldName := DBDataProcessParams[j]; + Exit; + end; - if ts.Find(FieldName, i) then - begin - if j > 0 then - begin - TableParams := TableParams + ','; - end; + FoundMissing := False; + TableParams := ''; + ts := TStringList.Create; - TableParams := TableParams + '"' + FieldName + '"'; - end - else + try + FConn.GetFieldNames(ATableName, ts); + ts.Sorted := True; + for j := Low(DBDataProcessParams) to High(DBDataProcessParams) do + begin + FieldName := DBDataProcessParams[j]; + + if ts.Find(FieldName, i) then + begin + if j > 0 then begin - FoundMissing := True; + TableParams := TableParams + ','; end; - end; - if FoundMissing then + TableParams := TableParams + '"' + FieldName + '"'; + end + else begin - ConvertNewTable(TableParams); + FoundMissing := True; end; - finally - ts.Free; end; + + if FoundMissing then + begin + ConvertNewTable(TableParams); + end; + finally + ts.Free; end; end; @@ -997,28 +1082,32 @@ procedure TDBDataProcess.Close; begin FRecordCount := 0; - if FConn.Connected then + if not FConn.Connected then begin - try - FQuery.Close; - RemoveFilter; - FConn.Close; - FConn.DatabaseName := ''; - except - on E: Exception do - SendLogException(Self.ClassName + '[' + Website + '].Close.Error!', E); - end; + Exit; + end; + + try + FQuery.Close; + RemoveFilter; + FConn.Close; + FConn.DatabaseName := ''; + except + on E: Exception do + SendLogException(Self.ClassName + '[' + Website + '].Close.Error!', E); end; end; procedure TDBDataProcess.CloseTable; begin - if FQuery.Active then + if not FQuery.Active then begin - FRecordCount := 0; - RemoveFilter; - FQuery.Close; + Exit; end; + + FRecordCount := 0; + RemoveFilter; + FQuery.Close; end; procedure TDBDataProcess.Save; @@ -1033,23 +1122,31 @@ procedure TDBDataProcess.Backup(const AWebsite: String); Exit; end; - if FConn.Connected then + if not FConn.Connected then begin - with TSQLite3Backup.Create do - begin - try - Backup(FConn, DATA_FOLDER + AWebsite + DBDATA_EXT); - finally - Free; - end; + Exit; + end; + + with TSQLite3Backup.Create do + begin + try + Backup(FConn, DATA_FOLDER + AWebsite + DBDATA_EXT); + finally + Free; end; end; end; procedure TDBDataProcess.Refresh(RecheckDataCount: Boolean); -begin - if FConn.Connected then +begin + if not FConn.Connected then begin + Exit; + end; + + try + + Lock; if FQuery.Active then begin if RecheckDataCount then @@ -1059,16 +1156,65 @@ procedure TDBDataProcess.Refresh(RecheckDataCount: Boolean); FQuery.Refresh; end - else - if Trim(FQuery.SQL.Text) <> '' then + else if Trim(FQuery.SQL.Text) <> '' then begin if RecheckDataCount then begin GetRecordCount; end; + if IsSelectStatement(FQuery.SQL.Text) then + begin + FQuery.Open; + end; + end; + finally + Unlock; + end; +end; + +function TDBDataProcess.IsSelectStatement(const SQL: string): Boolean; +var + CleanSQL: string; +begin + CleanSQL := UpperCase(Trim(SQL)); + + // Check for SELECT, WITH (CTE), or PRAGMA (some return results) + Result := (Pos('SELECT ', CleanSQL) = 1) or + (Pos('WITH ', CleanSQL) = 1) or + (Pos('PRAGMA ', CleanSQL) = 1); +end; + +function TDBDataProcess.FindData(const Link: String): Boolean; +begin + Result := False; + + if (Link = '') or (not FConn.Connected) then + begin + Exit; + end; + + try + Lock; + + try + if FQuery.Active then + begin + FQuery.Close; + end; + + FQuery.SQL.Text := 'SELECT * FROM "' + FTableName + '" WHERE ("link"=:link);'; + FQuery.Params.ParamByName('link').AsString := Link; + FQuery.Open; + Result := FQuery.Fields[0].AsString <> ''; + FQuery.Close; + except + on E: Exception do + SendLogException(ClassName + '[' + Website + '].FindData.Error!', E); end; + finally + Unlock; end; end; @@ -1079,49 +1225,60 @@ function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, i: Integer; begin Result := False; - if (Link = '') or - (not FConn.Connected) then + + if (Link = '') or (not FConn.Connected) then + begin + Exit; + end; + + if FindData(Link) then begin + Result := UpdateData(Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary, NumChapter, FWebsite); Exit; end; try - FQuery.SQL.Text := 'INSERT OR IGNORE INTO "' + FTableName + '" (' + DBDataProcessParam + ') VALUES (' + DBDataProcessParamInsert + ');'; - - // Set parameters - the parameter binding handles escaping - FQuery.Params.ParamByName('link').AsString := Link; - FQuery.Params.ParamByName('title').AsString := Title; - FQuery.Params.ParamByName('alttitles').AsString := AltTitles; - FQuery.Params.ParamByName('authors').AsString := Authors; - FQuery.Params.ParamByName('artists').AsString := Artists; - FQuery.Params.ParamByName('genres').AsString := Genres; - FQuery.Params.ParamByName('status').AsString := Status; - FQuery.Params.ParamByName('summary').AsString := Summary; - FQuery.Params.ParamByName('numchapter').AsInteger := NumChapter; - FQuery.Params.ParamByName('jdn').AsInteger := JDN; + Lock; - if FQuery.Active then - begin - FQuery.Close; - end; + try + FQuery.SQL.Text := 'INSERT OR IGNORE INTO "' + FTableName + '" (' + DBDataProcessParam + ') VALUES (' + DBDataProcessParamInsert + ');'; + + // Set parameters - the parameter binding handles escaping + FQuery.Params.ParamByName('link').AsString := Link; + FQuery.Params.ParamByName('title').AsString := Title; + FQuery.Params.ParamByName('alttitles').AsString := AltTitles; + FQuery.Params.ParamByName('authors').AsString := Authors; + FQuery.Params.ParamByName('artists').AsString := Artists; + FQuery.Params.ParamByName('genres').AsString := Genres; + FQuery.Params.ParamByName('status').AsString := Status; + FQuery.Params.ParamByName('summary').AsString := Summary; + FQuery.Params.ParamByName('numchapter').AsInteger := NumChapter; + FQuery.Params.ParamByName('jdn').AsInteger := JDN; - FQuery.ExecSQL; + if FQuery.Active then + begin + FQuery.Close; + end; - sql := FQuery.SQL.Text; - for i := 0 to FQuery.Params.Count - 1 do - begin - sql := StringReplace(sql, ':' + FQuery.Params[i].Name, QuotedStr(FQuery.Params[i].AsString), [rfReplaceAll, rfIgnoreCase]); - end; + FQuery.ExecSQL; - // Check changes - close previous operation first - FQuery.Close; - FQuery.SQL.Text := 'SELECT changes()'; - FQuery.Open; - Result := FQuery.Fields[0].AsInteger > 0; - FQuery.Close; - except - on E: Exception do - SendLogException(ClassName + '[' + Website + '].AddData.Error!' + LineEnding + sql, E); + sql := FQuery.SQL.Text; + for i := 0 to FQuery.Params.Count - 1 do + begin + sql := StringReplace(sql, ':' + FQuery.Params[i].Name, QuotedStr(FQuery.Params[i].AsString), [rfReplaceAll, rfIgnoreCase]); + end; + + Result := FQuery.RowsAffected > 0; + FQuery.Close; + + FQuery.SQL.Text := FSQLSelect; + FQuery.Open; + except + on E: Exception do + SendLogException(ClassName + '[' + Website + '].AddData.Error!' + LineEnding + sql, E); + end; + finally + Unlock; end; end; @@ -1138,6 +1295,7 @@ function TDBDataProcess.UpdateData(const Title, AltTitles, Link, Authors, Artist sql: String; begin Result := False; + if (Link = '') or (not FConn.Connected) then begin @@ -1145,36 +1303,46 @@ function TDBDataProcess.UpdateData(const Title, AltTitles, Link, Authors, Artist end; try - sql := 'UPDATE '; - if (AWebsite <> '') and (AWebsite <> FWebsite) and FAllSitesAttached then - begin - sql += '"' + AWebsite + '"."' + FTableName + '"'; - end - else - begin - sql += '"' + FTableName + '"'; - end; + Lock; - sql += ' SET "title"=' + QuotedStr(Title) + - ', "alttitles"=' + QuotedStr(AltTitles) + - ', "authors"=' + QuotedStr(Authors) + - ', "artists"=' + QuotedStr(Artists) + - ', "genres"=' + QuotedStr(Genres) + - ', "status"=' + QuotedStr(Status) + - ', "summary"=' + QuotedStr(Summary) + - ', "numchapter"=' + QuotedStr(IntToStr(NumChapter)) + - ' WHERE ("link"=' + QuotedStr(Link) + ');'; - FConn.ExecuteDirect(sql); - Result := True; - except - on E: Exception do - SendLogException(ClassName + '[' + Website + '].UpdateData.Error!' + LineEnding + sql, E); + try + sql := 'UPDATE '; + if (AWebsite <> '') and (AWebsite <> FWebsite) and FAllSitesAttached then + begin + sql += '"' + AWebsite + '"."' + FTableName + '"'; + end + else + begin + sql += '"' + FTableName + '"'; + end; + + sql += ' SET "title"=' + QuotedStr(Title) + + ', "alttitles"=' + QuotedStr(AltTitles) + + ', "authors"=' + QuotedStr(Authors) + + ', "artists"=' + QuotedStr(Artists) + + ', "genres"=' + QuotedStr(Genres) + + ', "status"=' + QuotedStr(Status) + + ', "summary"=' + QuotedStr(Summary) + + ', "numchapter"=' + QuotedStr(IntToStr(NumChapter)) + + ' WHERE ("link"=' + QuotedStr(Link) + ');'; + FConn.ExecuteDirect(sql); + Result := True; + + FQuery.SQL.Text := FSQLSelect; + FQuery.Open; + except + on E: Exception do + SendLogException(ClassName + '[' + Website + '].UpdateData.Error!' + LineEnding + sql, E); + end; + finally + Unlock; end; end; function TDBDataProcess.DeleteData(const RecIndex: Integer): Boolean; begin Result := False; + try if GoToRecNo(RecIndex) then begin @@ -1191,9 +1359,15 @@ function TDBDataProcess.DeleteData(const RecIndex: Integer): Boolean; procedure TDBDataProcess.Commit; var queryactive: Boolean; -begin - if FConn.Connected then +begin + if not FConn.Connected then begin + Exit; + end; + + try + Lock; + try queryactive := FQuery.Active; if FQuery.Active then @@ -1210,19 +1384,23 @@ procedure TDBDataProcess.Commit; on E: Exception do SendLogException(Self.ClassName + '[' + Website + '].Commit.Error!',E); end; + finally + Unlock; end; end; procedure TDBDataProcess.Rollback; begin - if FConn.Connected then + if not FConn.Connected then begin - try - FTrans.Rollback; - except - on E: Exception do - SendLogException(Self.ClassName + '[' + Website + '].Rollback.Error!',E); - end; + Exit; + end; + + try + FTrans.Rollback; + except + on E: Exception do + SendLogException(Self.ClassName + '[' + Website + '].Rollback.Error!',E); end; end; @@ -1233,6 +1411,7 @@ function TDBDataProcess.RegexEscapeInput(const Input: String): String; i: Integer; begin Result := ''; + for i := 1 to Length(Input) do begin if CharInSet(Input[i], RegexSpecialChars) then @@ -1260,73 +1439,86 @@ function TDBDataProcess.Search(ATitle: String): Boolean; if FQuery.Active then begin try - FQuery.Close; - with FQuery do - begin - SQL.Clear; - if FFilterApplied then - begin - SQL.AddText(FFilterSQL); - end - else - begin - SQL.Add(FSQLSelect); - end; + Lock; - if ATitle <> '' then + try + FQuery.Close; + + with FQuery do begin - if not FFilterApplied then + SQL.Clear; + if FFilterApplied then begin - SQL.Add('WHERE'); + SQL.AddText(FFilterSQL); + end + else + begin + SQL.Add(FSQLSelect); end; - if FAllSitesAttached then + if ATitle <> '' then begin - if SQL.Count > 0 then + if not FFilterApplied then + begin + SQL.Add('WHERE'); + end; + + if FAllSitesAttached then begin - i := 0; - while i < SQL.Count do + if SQL.Count > 0 then begin - if (SQL[i] = 'UNION ALL') or (SQL[i] = ')') then + i := 0; + while i < SQL.Count do begin - SQL.Insert(i, 'AND'); - SQL.Insert(i + 1, '("title" LIKE ' + QuotedLike(ATitle)); - SQL.Insert(i + 2, 'OR'); - SQL.Insert(i + 3, '"alttitles" LIKE ' + QuotedLike(ATitle) + ')'); - Inc(i, 5); - end - else - begin - Inc(i); + if (SQL[i] = 'UNION ALL') or (SQL[i] = ')') then + begin + SQL.Insert(i, 'AND'); + SQL.Insert(i + 1, '("title" LIKE ' + QuotedLike(ATitle)); + SQL.Insert(i + 2, 'OR'); + SQL.Insert(i + 3, '"alttitles" LIKE ' + QuotedLike(ATitle) + ')'); + Inc(i, 5); + end + else + begin + Inc(i); + end; end; end; + end + else + begin + Titles[0].Field := 'title'; + Titles[0].Value := ATitle; + Titles[1].Field := 'alttitles'; + Titles[1].Value := ATitle; + + AddSQLPairedFilter(Titles); end; + + FFiltered := True; end else begin - Titles[0].Field := 'title'; - Titles[0].Value := ATitle; - Titles[1].Field := 'alttitles'; - Titles[1].Value := ATitle; - - AddSQLPairedFilter(Titles); + FFiltered := FFilterApplied; end; + end; - FFiltered := True; - end - else + GetRecordCount; + + if IsSelectStatement(FQuery.SQL.Text) then begin - FFiltered := FFilterApplied; + FQuery.Open; end; + except + on E: Exception do + SendLogException(Self.ClassName + '[' + Website + '].Search.Error!'#13#10 + + 'SQL:'#13#10 + FQuery.SQL.Text, E); end; - GetRecordCount; - FQuery.Open; - except - on E: Exception do - SendLogException(Self.ClassName + '[' + Website + '].Search.Error!'#13#10 + - 'SQL:'#13#10 + FQuery.SQL.Text, E); + finally + Unlock; end; end; + Result := FQuery.Active; if not Result then @@ -1340,10 +1532,11 @@ function TDBDataProcess.CanFilter(const checkedGenres, uncheckedGenres: TStringL const stTitle, stAuthors, stArtists, stStatus, stSummary: String; const minusDay: Integer; const haveAllChecked, searchNewManga: Boolean): Boolean; begin - Result := False; + Result := True; + if not FQuery.Active then begin - Exit; + Exit(False); end; if ((stTitle = '') and @@ -1357,10 +1550,6 @@ function TDBDataProcess.CanFilter(const checkedGenres, uncheckedGenres: TStringL haveAllChecked then begin Result := False; - end - else - begin - Result := True; end; end; @@ -1447,76 +1636,83 @@ function TDBDataProcess.Filter(const checkedGenres, Exit; end; - with FQuery do - begin - FQuery.Close; - FRecordCount := 0; - tsql := SQL.Text; - SQL.Clear; - try - filtersingle := True; + try + Lock; - if FFilterAllSites and (FSitesList.Count > 0) then - begin - AttachAllSites; - if FAttachedSites.Count > 0 then - begin - SQL.Add('SELECT * FROM'); - SQL.Add('('); - SQL.Add('SELECT *, "-1" AS "website" FROM "' + FTableName + '"'); - SQL.Add('WHERE'); - GenerateSQLFilter; + with FQuery do + begin + FQuery.Close; + FRecordCount := 0; + tsql := SQL.Text; + SQL.Clear; + + try + filtersingle := True; - for i := 0 to FAttachedSites.Count - 1 do + if FFilterAllSites and (FSitesList.Count > 0) then + begin + AttachAllSites; + if FAttachedSites.Count > 0 then begin - SQL.Add('UNION ALL'); - SQL.Add('SELECT *, "' + IntToStr(i) + '" AS "website" FROM "' + FAttachedSites[i] + '"."' + FTableName + '"'); + SQL.Add('SELECT * FROM'); + SQL.Add('('); + SQL.Add('SELECT *, "-1" AS "website" FROM "' + FTableName + '"'); SQL.Add('WHERE'); GenerateSQLFilter; - end; - SQL.Add(')'); - SQL.Add('ORDER BY "title" COLLATE NATCMP'); - filtersingle := False; - end; - end; + for i := 0 to FAttachedSites.Count - 1 do + begin + SQL.Add('UNION ALL'); + SQL.Add('SELECT *, "' + IntToStr(i) + '" AS "website" FROM "' + FAttachedSites[i] + '"."' + FTableName + '"'); + SQL.Add('WHERE'); + GenerateSQLFilter; + end; - if filtersingle then - begin - SQL.Add(FSQLSelect); - SQL.Add('WHERE'); - GenerateSQLFilter; - end; + SQL.Add(')'); + SQL.Add('ORDER BY "title" COLLATE NATCMP'); + filtersingle := False; + end; + end; - Self.GetRecordCount; - FQuery.Open; - FFiltered := Active; - FFilterApplied := FFiltered; + if filtersingle then + begin + SQL.Add(FSQLSelect); + SQL.Add('WHERE'); + GenerateSQLFilter; + end; - if FFilterApplied then - begin - FFilterSQL := SQL.Text; - end - else - begin - FFilterSQL := ''; - end; - except - on E: Exception do - begin - SendLogException(Self.ClassName + '[' + Website + '].Filter.Error!'#13#10 + - 'SQL:'#13#10 + FQuery.SQL.Text, E); - FQuery.Close; - SQL.Text := tsql; Self.GetRecordCount; FQuery.Open; - FFilterAllSites := False; - FFiltered := False; - FFilterApplied := False; - FFilterSQL := ''; + FFiltered := Active; + FFilterApplied := FFiltered; + + if FFilterApplied then + begin + FFilterSQL := SQL.Text; + end + else + begin + FFilterSQL := ''; + end; + except + on E: Exception do + begin + SendLogException(Self.ClassName + '[' + Website + '].Filter.Error!'#13#10 + + 'SQL:'#13#10 + FQuery.SQL.Text, E); + FQuery.Close; + SQL.Text := tsql; + Self.GetRecordCount; + FQuery.Open; + FFilterAllSites := False; + FFiltered := False; + FFilterApplied := False; + FFilterSQL := ''; + end; end; + Result := FFiltered; end; - Result := FFiltered; + finally + Unlock; end; end; @@ -1525,6 +1721,7 @@ procedure TDBDataProcess.CreateDatabase(const AWebsite: String); filepath: String; begin Close; + if CheckWebsiteAndFilePath(AWebsite, filepath) then begin DeleteFile(filepath); @@ -1568,8 +1765,14 @@ procedure TDBDataProcess.Sort; var queryactive: Boolean; begin - if FConn.Connected then + if not FConn.Connected then begin + Exit; + end; + + try + Lock; + queryactive := FQuery.Active; FQuery.Close; with FConn do @@ -1592,6 +1795,8 @@ procedure TDBDataProcess.Sort; begin FQuery.Active := queryactive; end; + finally + Unlock; end; end; @@ -1599,23 +1804,19 @@ function TDBDataProcess.GetModule(const RecIndex: Integer): Pointer; var i: LongInt; begin - if FAllSitesAttached then + Result := FModule; + + if not FAllSitesAttached then begin - FQuery.RecNo := RecIndex + 1; - i := FQuery.Fields[DBTempFieldWebsiteIndex].AsInteger; + Exit; + end; - if i = -1 then - begin - Result := FModule; - end - else - begin - Result := Pointer(FAttachedSites.Objects[i]); - end; - end - else + FQuery.RecNo := RecIndex + 1; + i := FQuery.Fields[DBTempFieldWebsiteIndex].AsInteger; + + if i <> -1 then begin - Result := FModule; + Result := Pointer(FAttachedSites.Objects[i]); end; end; @@ -1629,15 +1830,17 @@ function TDBDataProcess.WebsiteLoaded(const AWebsite: String): Boolean; Exit(True); end; - if FAllSitesAttached then + if not FAllSitesAttached then + begin + Exit; + end; + + for i := 0 to FAttachedSites.Count - 1 do begin - for i := 0 to FAttachedSites.Count - 1 do + if FAttachedSites[i] = AWebsite then begin - if FAttachedSites[i] = AWebsite then - begin - Result := True; - Break; - end; + Result := True; + Break; end; end; end; @@ -1646,13 +1849,11 @@ function TDBDataProcess.LinkExist(const ALink: String): Boolean; var i: Integer; begin + Result := False; + if Assigned(FLinks) then begin Result := FLinks.Find(ALink, i); - end - else - begin - Result := False; end; end; @@ -1668,18 +1869,20 @@ procedure TDBDataProcess.InitLocateLink; end; FLinks.Sorted := False; - if FQuery.Active then + if not FQuery.Active then begin - FQuery.First; - repeat - FLinks.Add(FQuery.Fields[1].AsString); - FQuery.Next; - until FQuery.EOF; + Exit; + end; - if FLinks.Count > 0 then - begin - FLinks.Sorted := True; - end; + FQuery.First; + repeat + FLinks.Add(FQuery.Fields[1].AsString); + FQuery.Next; + until FQuery.EOF; + + if FLinks.Count > 0 then + begin + FLinks.Sorted := True; end; end; diff --git a/baseunits/uDownloadsManager.pas b/baseunits/uDownloadsManager.pas index 85cd288f2..a81960256 100644 --- a/baseunits/uDownloadsManager.pas +++ b/baseunits/uDownloadsManager.pas @@ -1736,19 +1736,30 @@ procedure TDownloadManager.DBUpdateOrder; var i: Integer; begin - if FUpdateOrderCount=0 then Exit; - for i := 0 to Items.Count-1 do - with Items[i] do begin - if i<>Order then + if FUpdateOrderCount = 0 then + begin + Exit; + end; + + for i := 0 to Items.Count - 1 do + begin + with Items[i] do begin - Order:=i; - FDownloadsDB.tempSQL+='UPDATE "downloads" SET "order"='+PrepSQLValue(Order)+' WHERE "id"='''+DlId+''';'; - Inc(FDownloadsDB.tempSQLcount); - if FDownloadsDB.tempSQLcount>=MAX_BIG_SQL_FLUSH_QUEUE then - FDownloadsDB.FlushSQL(False); + if i <> Order then + begin + Order := i; + FDownloadsDB.tempSQL += 'UPDATE "downloads" SET "order"=' + PrepSQLValue(Order) + ' WHERE "id"=''' + DlId + ''';'; + Inc(FDownloadsDB.tempSQLcount); + + if FDownloadsDB.tempSQLcount >= MAX_BIG_SQL_FLUSH_QUEUE then + begin + FDownloadsDB.FlushSQL(False); + end; + end; end; end; - FUpdateOrderCount:=0; + + FUpdateOrderCount := 0; end; procedure TDownloadManager.UpdateOrder; diff --git a/baseunits/uGetMangaInfosThread.pas b/baseunits/uGetMangaInfosThread.pas index d2437ab31..fcbdc6ae5 100644 --- a/baseunits/uGetMangaInfosThread.pas +++ b/baseunits/uGetMangaInfosThread.pas @@ -16,8 +16,9 @@ interface uses - SysUtils, LazFileUtils, StrUtils, Graphics, Dialogs, uBaseUnit, uData, - FMDOptions, BaseThread, ImgInfos, webp, MultiLog, MemBitmap, VirtualTrees; + SysUtils, LazFileUtils, StrUtils, Graphics, Dialogs, uBaseUnit, uData, Forms, + FMDOptions, BaseThread, ImgInfos, webp, MultiLog, MemBitmap, VirtualTrees, + DBDataProcess; type @@ -65,8 +66,11 @@ procedure TGetMangaInfosThread.Execute; function GetMangaInfo: Boolean; var infob: byte; + tempDataProcess: TDBDataProcess; data: PMangaInfoData; - oldModuleID, searchText: String; + oldModuleID, dataLink: String; + nodeIndex: Integer; + infoAlreadyExists: Boolean; begin Result := False; try @@ -153,34 +157,40 @@ procedure TGetMangaInfosThread.Execute; if (FInfo.MangaInfo.Title <> '') and (FInfo.MangaInfo.Link <> '') then begin + tempDataProcess := dataProcess; oldModuleID := dataProcess.Website; - if (oldModuleID <> m.ID) and dataProcess.Connected then + if oldModuleID <> m.ID then begin - dataProcess.Close; + tempDataProcess := TDBDataProcess.Create; end; - if dataProcess.Connect(m.ID) then + if not Assigned(FNode) then begin - FInfo.AddInfoToData(FInfo.MangaInfo.Title, FInfo.MangaInfo.Link, dataProcess); - dataProcess.Commit; - dataProcess.Sort; + FNode := MainForm.vtMangaList.FocusedNode; + end; + + data := MainForm.vtMangaList.GetNodeData(FNode); + dataLink := ''; + if Assigned(data) then + begin + dataLink := data^.Link; + end; + nodeIndex := MainForm.vtMangaList.AbsoluteIndex(FNode); + + if tempDataProcess.Connect(m.ID) then + begin + FInfo.AddInfoToData(FInfo.MangaInfo.Title, FInfo.MangaInfo.Link, tempDataProcess); + tempDataProcess.Sort; if oldModuleID = m.ID then - begin - dataProcess.Refresh(dataProcess.Filtered); - - searchText := MainForm.edMangaListSearch.Text; - if ContainsText(FInfo.MangaInfo.Title, searchText) or (searchText = '') then - begin - MainForm.OpenDataDB(m.ID); - MainForm.UpdateVtMangaListFilterStatus; - end; + begin + MainForm.vtMangaList.Clear; + tempDataProcess.Refresh(tempDataProcess.Filtered); + MainForm.vtMangaListResetList(nodeIndex, dataLink, m.ID); end else - begin - dataProcess.Close; - dataProcess.Connect(oldModuleID); - dataProcess.Refresh(dataProcess.Filtered); + begin + tempDataProcess.Free; end; end; end; @@ -210,6 +220,7 @@ procedure TGetMangaInfosThread.Execute; begin m := TModuleContainer(FInfo.Module); + try if not GetMangaInfo then begin @@ -239,6 +250,7 @@ procedure TGetMangaInfosThread.Execute; except end; end; + if not (Terminated or isExiting) then begin Synchronize(MainThreadShowCover); @@ -336,16 +348,18 @@ procedure TGetMangaInfosThread.MainThreadShowCover; MainForm.tmAnimateMangaInfo.Enabled := False; MainForm.pbWait.Visible := False; - if FIsHasMangaCover then + if not FIsHasMangaCover then begin - try - MainForm.imCover.Picture.Assign(FCover); - except - on E: Exception do ; - end; + Exit; + end; - FCover.Clear; + try + MainForm.imCover.Picture.Assign(FCover); + except + on E: Exception do ; end; + + FCover.Clear; end; constructor TGetMangaInfosThread.Create(const AModule: Pointer; diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 0dddaf5a0..e40fefa99 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -25,8 +25,8 @@ interface uSilentThread, uMisc, uGetMangaInfosThread, frmDropTarget, frmAccountManager, frmAccountSet, frmWebsiteOptionCustom, frmCustomColor, frmLogger, frmTransferFavorites, frmLuaModulesUpdater, CheckUpdate, DBDataProcess, uDarkStyleParams, uWin32WidgetSetDark, - SimpleTranslator, httpsendthread, DateUtils, SimpleException, uCustomControls, - uCustomControlsMultiLog, ImageMagickManager; + SimpleTranslator, httpsendthread, DateUtils, SimpleException, WebsiteModules, + uCustomControls, uCustomControlsMultiLog, ImageMagickManager; type @@ -708,6 +708,7 @@ TMainForm = class(TForm) Column: TColumnIndex; TextType: TVSTTextType; var CellText: String); procedure vtMangaListInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates); + procedure vtMangaListResetList(ANodeIndex: Integer; ALink, AModuleID: String); procedure vtOptionMangaSiteSelectionFreeNode(Sender : TBaseVirtualTree; Node : PVirtualNode); procedure vtOptionMangaSiteSelectionGetText(Sender: TBaseVirtualTree; @@ -845,6 +846,8 @@ TMainForm = class(TForm) // open db with thread procedure OpenDataDB(const AWebsite: String); + procedure CloseOpenDataDB; + procedure WaitForOpenDataDB; // search db with thread procedure SearchDataDB(const ATitle: String); @@ -1028,7 +1031,7 @@ implementation WinAPI, {$endif} frmImportFavorites, frmShutdownCounter, frmSelectDirectory, - frmWebsiteSettings, WebsiteModules, uUpdateThread, FMDVars, RegExpr, sqlite3dyn, Clipbrd, + frmWebsiteSettings, uUpdateThread, FMDVars, RegExpr, sqlite3dyn, Clipbrd, ssl_openssl3_lib, LazFileUtils, LazUTF8, webp, DBUpdater, pcre2, pcre2lib, dynlibs, LuaWebsiteModules, LuaBase, uBackupSettings, frmCustomMessageDlg; @@ -1203,24 +1206,30 @@ procedure TOpenDBThread.SyncOpenFinish; procedure TOpenDBThread.Execute; begin - if (FWebsite <> '') and (dataProcess <> nil) then + if (FWebsite = '') or (dataProcess = nil) then begin - Synchronize(@SyncOpenStart); + Exit; + end; + + Synchronize(@SyncOpenStart); - if dataProcess <> nil then + if dataProcess <> nil then + begin + if dataProcess.Website <> FWebsite then begin dataProcess.Open(FWebsite); - if FormMain.edMangaListSearch.Text <> '' then - begin - dataProcess.Search(MainForm.edMangaListSearch.Text); - end; end; - if not Terminated then + if FormMain.edMangaListSearch.Text <> '' then begin - Synchronize(@SyncOpenFinish); + dataProcess.Search(MainForm.edMangaListSearch.Text); end; end; + + if not Terminated then + begin + Synchronize(@SyncOpenFinish); + end; end; constructor TOpenDBThread.Create(const AWebsite: String); @@ -2086,6 +2095,26 @@ procedure TMainForm.OpenDataDB(const AWebsite: String); end; end; +procedure TMainForm.CloseOpenDataDB; +begin + if not Assigned(OpenDBThread) then + begin + Exit; + end; + + OpenDBThread.Destroy; +end; + +procedure TMainForm.WaitForOpenDataDB; +begin + if not Assigned(OpenDBThread) then + begin + Exit; + end; + + OpenDBThread.WaitFor; +end; + procedure TMainForm.SearchDataDB(const ATitle: String); begin if SearchDBThread = nil then @@ -7579,32 +7608,129 @@ procedure TMainForm.vtMangaListInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates); var data: PMangaInfoData; + nodeRecIndex: Integer; begin data := Sender.GetNodeData(Node); - if dataProcess.GoToRecNo(Node^.Index) then + nodeRecIndex := Node^.Index; + + if not dataProcess.GoToRecNo(nodeRecIndex) then + begin + Exit; + end; + with data^ do begin - Link := dataProcess.Value[Node^.Index, DATA_PARAM_LINK]; - Title := dataProcess.Value[Node^.Index, DATA_PARAM_TITLE]; - AltTitles := dataProcess.Value[Node^.Index, DATA_PARAM_ALTTITLES]; - Authors := dataProcess.Value[Node^.Index, DATA_PARAM_AUTHORS]; - Artists := dataProcess.Value[Node^.Index, DATA_PARAM_ARTISTS]; - Genres := dataProcess.Value[Node^.Index, DATA_PARAM_GENRES]; - Status := dataProcess.Value[Node^.Index, DATA_PARAM_STATUS]; - NumChapter := dataProcess.ValueInt[Node^.Index, DATA_PARAM_NUMCHAPTER]; - JDN := dataProcess.ValueInt[Node^.Index, DATA_PARAM_JDN]; - Summary := dataProcess.Value[Node^.Index, DATA_PARAM_SUMMARY]; + Link := dataProcess.Value[nodeRecIndex, DATA_PARAM_LINK]; + Title := dataProcess.Value[nodeRecIndex, DATA_PARAM_TITLE]; + AltTitles := dataProcess.Value[nodeRecIndex, DATA_PARAM_ALTTITLES]; + Authors := dataProcess.Value[nodeRecIndex, DATA_PARAM_AUTHORS]; + Artists := dataProcess.Value[nodeRecIndex, DATA_PARAM_ARTISTS]; + Genres := dataProcess.Value[nodeRecIndex, DATA_PARAM_GENRES]; + Status := dataProcess.Value[nodeRecIndex, DATA_PARAM_STATUS]; + NumChapter := dataProcess.ValueInt[nodeRecIndex, DATA_PARAM_NUMCHAPTER]; + JDN := dataProcess.ValueInt[nodeRecIndex, DATA_PARAM_JDN]; + Summary := dataProcess.Value[nodeRecIndex, DATA_PARAM_SUMMARY]; TitleFormat := Title + ' (' + IntToStr(NumChapter) + ')'; + if dataProcess.FilterAllSites then begin - Module := dataProcess.GetModule(Node^.Index); + Module := dataProcess.GetModule(nodeRecIndex); TitleFormat += ' [' + TModuleContainer(Module).Name + ']'; end else + begin Module := dataProcess.Module; + end; end; end; +procedure TMainForm.vtMangaListResetList(ANodeIndex: Integer; ALink, AModuleID: String); +var + i, totalNodes: Integer; + nextNode, newNode: PVirtualNode; + + procedure CheckNode(var AOldNode, ANewNode: PVirtualNode; ALink: String); + var + newData: PMangaInfoData; + begin + newData := vtMangaList.GetNodeData(AOldNode); + + if ALink = newData^.Link then + begin + ANewNode := AOldNode; + end; + end; + +begin + newNode := nil; + CloseOpenDataDB; + OpenDataDB(AModuleID); + + WaitForOpenDataDB; + UpdateVtMangaListFilterStatus; + + if (ANodeIndex < 0) or (ALink = '') then + begin + Exit; + end; + + vtMangaList.BeginUpdate; + totalNodes := vtMangaList.RootNodeCount; + + if (ANodeIndex < totalNodes) then + begin + // Smart traversal + if ANodeIndex < totalNodes div 2 then + begin + // Near beginning - go forward + nextNode := vtMangaList.GetFirst; + CheckNode(nextNode, newNode, ALink); + + for i := 0 to Min(totalNodes - 1, ANodeIndex) do + begin + if not Assigned(nextNode) then + begin + Break; + end; + + nextNode := vtMangaList.GetNext(nextNode); + CheckNode(nextNode, newNode, ALink); + end; + end + else + begin + // Near end - go backward + nextNode := vtMangaList.GetLast; + CheckNode(nextNode, newNode, ALink); + + for i := 0 to (totalNodes - ANodeIndex) do + begin + if not Assigned(nextNode) then + begin + Break; + end; + + nextNode := vtMangaList.GetPrevious(nextNode); + CheckNode(nextNode, newNode, ALink); + end; + end; + + end + else + begin + newNode := vtMangaList.GetLast + end; + + if Assigned(newNode) then + begin + vtMangaList.Selected[newNode] := True; + vtMangaList.FocusedNode := newNode; + vtMangaList.ScrollIntoView(newNode, True); + end; + + vtMangaList.EndUpdate; +end; + procedure TMainForm.vtOptionMangaSiteSelectionFreeNode( Sender : TBaseVirtualTree; Node : PVirtualNode); begin From 4f2c99fda86ec056a29003a8656f2a74c1844473 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Wed, 11 Feb 2026 20:43:32 +0800 Subject: [PATCH 25/35] Changed: Read and write to be separate queries Added: Better db interactions --- baseunits/DBDataProcess.pas | 661 ++++++++++++++++++++++-------------- 1 file changed, 410 insertions(+), 251 deletions(-) diff --git a/baseunits/DBDataProcess.pas b/baseunits/DBDataProcess.pas index 579292de6..f3f1feb2b 100644 --- a/baseunits/DBDataProcess.pas +++ b/baseunits/DBDataProcess.pas @@ -11,7 +11,7 @@ interface uses Classes, SysUtils, FileUtil, LazFileUtils, FMDOptions, MultiLog, sqlite3conn, - sqlite3backup, sqlite3dyn, sqldb, DB, RegExpr, SQLiteData; + sqlite3backup, sqlite3dyn, sqlite3ds, sqldb, DB, RegExpr, SQLiteData; type TFieldValuePair = record @@ -26,7 +26,8 @@ TDBDataProcess = class(TObject) FGuardian: TRTLCriticalSection; FConn: TSQLite3ConnectionH; FTrans: TSQLTransaction; - FQuery: TSQLQuery; + FReadQuery: TSQLQuery; + FWriteQuery: TSQLQuery; FRegxp: TRegExpr; FModule: Pointer; FWebsite: String; @@ -61,6 +62,7 @@ TDBDataProcess = class(TObject) function GetWebsiteName(const RecIndex: Integer): String; function GetValue(const RecIndex, FieldIndex: Integer): String; function GetValueInt(const RecIndex, FieldIndex: Integer): Integer; + function CheckAndRepairDatabase(const AModuleID: String): Boolean; procedure AttachAllSites; procedure DetachAllSites; function ExecuteDirect(SQL: String): Boolean; @@ -102,7 +104,8 @@ TDBDataProcess = class(TObject) procedure Backup(const AWebsite: String); procedure Refresh(RecheckDataCount: Boolean = False); function IsSelectStatement(const SQL: string): Boolean; - function FindData(const Link: String): Boolean; + function CheckData(const Link, AField: String): TField; + function ExistsData(const Link: String): Boolean; function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; NumChapter, JDN: Integer): Boolean; overload; function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; @@ -132,7 +135,7 @@ TDBDataProcess = class(TObject) property LinkCount: Integer read GetLinkCount; property Connection: TSQLite3ConnectionH read FConn; property Transaction: TSQLTransaction read FTrans; - property Table: TSQLQuery read FQuery; + property Table: TSQLQuery read FReadQuery; end; const @@ -308,7 +311,7 @@ procedure TDBDataProcess.ResetRecNo(Dataset: TDataSet); function TDBDataProcess.GoToRecNo(const ARecIndex: Integer): Boolean; begin - if FQuery.RecNo = ARecIndex + 1 then + if FReadQuery.RecNo = ARecIndex + 1 then begin Exit(True); end; @@ -320,16 +323,35 @@ function TDBDataProcess.GoToRecNo(const ARecIndex: Integer): Boolean; Exit; end; - if not FQuery.Active then + if not FReadQuery.Active then begin Exit; end; try - FRecNo := ARecIndex; - FQuery.RecNo := ARecIndex + 1; - Result := True; + // Save current position + FReadQuery.DisableControls; + try + FReadQuery.First; + + if ARecIndex > 0 then + begin + FReadQuery.MoveBy(ARecIndex); + end; + + if not FReadQuery.EOF then + begin + FRecNo := ARecIndex; + Result := True; + end; + finally + FReadQuery.EnableControls; + end; except + on E: Exception do + begin + SendLogException(Self.ClassName + '[' + Website + '].GoToRecNo.Error!', E); + end; end; end; @@ -339,10 +361,9 @@ procedure TDBDataProcess.CreateTable; begin Exit; end; - - try - Lock; + Lock; + try FConn.ExecuteDirect('DROP TABLE IF EXISTS "' + FTableName + '"'); FConn.ExecuteDirect('CREATE TABLE "' + FTableName + '" (' + DBDataProccesCreateParam + ');'); @@ -358,10 +379,9 @@ procedure TDBDataProcess.CreateField(const FieldName: String); begin Exit; end; - + + Lock; try - Lock; - FConn.ExecuteDirect('ALTER TABLE "' + FTableName + '" ADD COLUMN "' + FieldName + '" TEXT;'); FTrans.CommitRetaining; finally @@ -370,23 +390,15 @@ procedure TDBDataProcess.CreateField(const FieldName: String); end; procedure TDBDataProcess.ConvertNewTable(const TableParams: String); -var - qactive: Boolean; begin if not FConn.Connected then begin Exit; end; - + + Lock; try - Lock; try - qactive := FQuery.Active; - if FQuery.Active then - begin - FQuery.Close; - end; - with FConn do begin try @@ -394,18 +406,14 @@ procedure TDBDataProcess.ConvertNewTable(const TableParams: String); ExecuteDirect('CREATE TABLE "' + FTableName + '" (' + DBDataProccesCreateParam + ');'); ExecuteDirect('INSERT INTO "' + FTableName + '" (' + TableParams + ') SELECT ' + TableParams + ' FROM "' + FTableName + '_old"'); ExecuteDirect('DROP TABLE "' + FTableName + '_old"'); - VacuumTable; except on E: Exception do SendLogException(Self.ClassName + '[' + Website + '].Convert.Error!', E); end; end; - FTrans.Commit; - if qactive <> FQuery.Active then - begin - FQuery.Active := qactive; - end; + FTrans.Commit; + VacuumTable; except FTrans.Rollback; end; @@ -415,33 +423,27 @@ procedure TDBDataProcess.ConvertNewTable(const TableParams: String); end; procedure TDBDataProcess.VacuumTable; -var - queryactive: Boolean; -begin +begin if not FConn.Connected then begin Exit; end; + Lock; try - Lock; + try + FConn.ExecuteDirect('END TRANSACTION;'); - queryactive := FQuery.Active; - FQuery.Close; - - with FConn do - begin try - ExecuteDirect('END TRANSACTION'); - ExecuteDirect('VACUUM'); - except + FConn.ExecuteDirect('VACUUM;'); + finally + FConn.ExecuteDirect('BEGIN TRANSACTION;'); + end; + except + on E: Exception do + begin + SendLogException(Self.ClassName + '[' + Website + '].VacuumTable.Error!', E); end; - ExecuteDirect('BEGIN TRANSACTION'); - end; - - if FQuery.Active <> queryactive then - begin - FQuery.Active := queryactive; end; finally Unlock; @@ -453,7 +455,7 @@ procedure TDBDataProcess.GetRecordCount; bsql: String; begin FRecordCount := 0; - bsql := Trim(FQuery.SQL.Text); + bsql := Trim(FReadQuery.SQL.Text); if UpperCase(LeftStr(bsql, 8)) = 'SELECT *' then begin @@ -463,7 +465,7 @@ procedure TDBDataProcess.GetRecordCount; procedure TDBDataProcess.AddSQLCond(const sqltext: String; useOR: Boolean); begin - with FQuery.SQL do + with FReadQuery.SQL do begin if Count > 0 then begin @@ -612,8 +614,8 @@ function TDBDataProcess.GetWebsiteName(const RecIndex: Integer): String; end; try - FQuery.RecNo := RecIndex + 1; - Result := FQuery.Fields[DBTempFieldWebsiteIndex].AsString; + FReadQuery.RecNo := RecIndex + 1; + Result := FReadQuery.Fields[DBTempFieldWebsiteIndex].AsString; except on E: Exception do SendLogException(Self.ClassName + '[' + Website + '].GetWebsiteName Error!' + @@ -630,14 +632,14 @@ function TDBDataProcess.GetValue(const RecIndex, FieldIndex: Integer): String; Result := '0'; end; - if not FQuery.Active then + if not FReadQuery.Active then begin Exit; end; if GoToRecNo(RecIndex) then begin - Result := FQuery.Fields[FieldIndex].AsString; + Result := FReadQuery.Fields[FieldIndex].AsString; end; end; @@ -646,7 +648,7 @@ function TDBDataProcess.GetValueInt(const RecIndex, FieldIndex: Integer begin Result := 0; - if not FQuery.Active then + if not FReadQuery.Active then begin Exit; end; @@ -658,7 +660,57 @@ function TDBDataProcess.GetValueInt(const RecIndex, FieldIndex: Integer if GoToRecNo(RecIndex) then begin - Result := FQuery.Fields[FieldIndex].AsInteger; + Result := FReadQuery.Fields[FieldIndex].AsInteger; + end; +end; + +function TDBDataProcess.CheckAndRepairDatabase(const AModuleID: String): Boolean; +var + tempConn: TSQLite3Connection; + tempTrans: TSQLTransaction; + DBPath: String; +begin + Result := False; + DBPath := DBDataFilePath(AModuleID); + + if not FileExists(DBPath) then + begin + Exit; + end; + + // Create temporary connection + tempConn := TSQLite3Connection.Create(nil); + tempTrans := TSQLTransaction.Create(nil); + try + tempConn.DatabaseName := DBPath; + tempConn.Transaction := tempTrans; + tempConn.CharSet := 'UTF8'; + tempConn.Connected := True; + + tempTrans.StartTransaction; + try + // Check if table exists with correct structure + tempConn.ExecuteDirect( + 'CREATE TABLE IF NOT EXISTS "' + FTableName + '" (' + + DBDataProccesCreateParam + ')' + ); + + // Check for required columns and add if missing + tempConn.ExecuteDirect( + 'CREATE INDEX IF NOT EXISTS "idx_' + FTableName + '_link" ' + + 'ON "' + FTableName + '" ("link")' + ); + + tempTrans.Commit; + Result := True; + except + tempTrans.Rollback; + SendLogWarning(ClassName + '[' + Website + '].CheckAndRepairDatabase.Warning! Failed database: ' + DBPath); + end; + + finally + tempConn.Free; + tempTrans.Free; end; end; @@ -686,22 +738,22 @@ procedure TDBDataProcess.AttachAllSites; var i, attachedMax: Integer; m: TModuleContainer; - tempDataProcess: TDBDataProcess; begin RemoveCurrentSite; if (not FConn.Connected) or (SitesList.Count = 0) then begin Exit; end; - + + Lock; try - Lock; + if FTrans.Active then + begin + FTrans.Commit; + end; DetachAllSites; - FConn.ExecuteDirect('END TRANSACTION'); attachedMax := 125; - tempDataProcess := TDBDataProcess.Create; - try for i := 0 to SitesList.Count - 1 do begin @@ -717,22 +769,23 @@ procedure TDBDataProcess.AttachAllSites; m := TModuleContainer(FSitesList.Objects[i]); if (FAttachedSites.IndexOf(m.ID) = -1) and (FileExists(DBDataFilePath(m.ID))) then begin - tempDataProcess.Open(m.ID); // Check database structure so theres no errors if databases mismatch - attachedMax := attachedMax - 1; - FConn.ExecuteDirect('ATTACH ' + QuotedStr(DBDataFilePath(m.ID)) + ' AS "' + m.ID + '"'); - FAttachedSites.AddObject(m.ID, m); + if CheckAndRepairDatabase(m.ID) then + begin + FConn.ExecuteDirect('ATTACH ' + QuotedStr(DBDataFilePath(m.ID)) + ' AS "' + m.ID + '"'); + FAttachedSites.AddObject(m.ID, m); + DEC(attachedMax); + end; end; end; + + FAllSitesAttached := FAttachedSites.Count > 0; except on E: Exception do + begin SendLogException(ClassName + '[' + Website + '].AttachAllSites.Error!' + - ' try to attach ' + QuotedStr(SitesList[i]), E) + ' try to attach ' + QuotedStr(SitesList[i]), E); + end; end; - - tempDataProcess.Close; - tempDataProcess.Free; - FConn.ExecuteDirect('BEGIN TRANSACTION'); - FAllSitesAttached := FAttachedSites.Count > 0; finally Unlock; end; @@ -741,24 +794,19 @@ procedure TDBDataProcess.AttachAllSites; procedure TDBDataProcess.DetachAllSites; var i: Integer; - queryactive: Boolean; begin if (not FConn.Connected) or (FAttachedSites.Count = 0) then begin Exit; end; - + + Lock; try - Lock; - - queryactive := FQuery.Active; - if FQuery.Active then + if FTrans.Active then begin - FQuery.Close; + FTrans.Commit; end; - FTrans.CommitRetaining; - FConn.ExecuteDirect('END TRANSACTION'); for i := FAttachedSites.Count - 1 downto 0 do begin try @@ -770,13 +818,7 @@ procedure TDBDataProcess.DetachAllSites; end; end; - FConn.ExecuteDirect('BEGIN TRANSACTION'); FAllSitesAttached := FAttachedSites.Count > 0; - - if FQuery.Active <> queryactive then - begin - FQuery.Active := queryactive; - end; finally Unlock; end; @@ -790,10 +832,9 @@ function TDBDataProcess.ExecuteDirect(SQL: String): Boolean; begin Exit; end; - + + Lock; try - Lock; - try FConn.ExecuteDirect(SQL); Result := True; @@ -833,13 +874,12 @@ constructor TDBDataProcess.Create; begin inherited Create; InitCriticalSection(FGuardian); - FConn := TSQLite3ConnectionH.Create(nil); + FTrans := TSQLTransaction.Create(nil); - FQuery := TSQLQuery.Create(nil); + + FConn := TSQLite3ConnectionH.Create(nil); FConn.Transaction := FTrans; - FQuery.PacketRecords := 25; - FQuery.DataBase := FTrans.DataBase; - FQuery.Transaction := FTrans; + FRegxp := TRegExpr.Create; FRegxp.ModifierI := True; FSitesList := TStringList.Create; @@ -853,12 +893,33 @@ constructor TDBDataProcess.Create; FFilterSQL := ''; FAllSitesAttached := False; - ResetRecNo(nil); - FQuery.AfterOpen := @ResetRecNo; - FQuery.AfterInsert := @ResetRecNo; - FQuery.AfterDelete := @ResetRecNo; - FQuery.AfterEdit := @ResetRecNo; - FQuery.AfterRefresh := @ResetRecNo; + ResetRecNo(nil); + + FReadQuery := TSQLQuery.Create(nil); + FReadQuery.SQL.Text := FSQLSelect; + FReadQuery.PacketRecords := 25; + FReadQuery.DataBase := FTrans.DataBase; + FReadQuery.Transaction := FTrans; + FReadQuery.ReadOnly := True; + + FReadQuery.AfterOpen := @ResetRecNo; + FReadQuery.AfterInsert := @ResetRecNo; + FReadQuery.AfterDelete := @ResetRecNo; + FReadQuery.AfterEdit := @ResetRecNo; + FReadQuery.AfterRefresh := @ResetRecNo; + + + FWriteQuery := TSQLQuery.Create(nil); + FWriteQuery.PacketRecords := 25; + FWriteQuery.DataBase := FTrans.DataBase; + FWriteQuery.Transaction := FTrans; + FWriteQuery.ReadOnly := False; + + FWriteQuery.AfterOpen := @ResetRecNo; + FWriteQuery.AfterInsert := @ResetRecNo; + FWriteQuery.AfterDelete := @ResetRecNo; + FWriteQuery.AfterEdit := @ResetRecNo; + FWriteQuery.AfterRefresh := @ResetRecNo; end; destructor TDBDataProcess.Destroy; @@ -866,7 +927,8 @@ destructor TDBDataProcess.Destroy; try if FConn.Connected then begin - FQuery.Close; + FReadQuery.Close; + FWriteQuery.Close; Commit; Close; end; @@ -878,7 +940,8 @@ destructor TDBDataProcess.Destroy; DoneLocateLink; FAttachedSites.Free; FSitesList.Free; - FQuery.Free; + FReadQuery.Free; + FWriteQuery.Free; FTrans.Free; FConn.Free; FRegxp.Free; @@ -889,11 +952,23 @@ destructor TDBDataProcess.Destroy; procedure TDBDataProcess.Lock; begin EnterCriticalSection(FGuardian); + + if Assigned(FWriteQuery) then + begin + FWriteQuery.DisableControls; + end; end; procedure TDBDataProcess.Unlock; begin - LeaveCriticalSection(FGuardian); + try + if Assigned(FWriteQuery) then + begin + FWriteQuery.EnableControls; + end; + finally + LeaveCriticalSection(FGuardian); + end; end; function TDBDataProcess.Connect(const AWebsite: String): Boolean; @@ -901,10 +976,9 @@ function TDBDataProcess.Connect(const AWebsite: String): Boolean; filepath: String = ''; begin Result := False; - + + Lock; try - Lock; - if CheckWebsiteAndFilePath(AWebsite, filepath) then begin Result := InternalOpen(filepath); @@ -917,10 +991,9 @@ function TDBDataProcess.Connect(const AWebsite: String): Boolean; function TDBDataProcess.ConnectFile(const AFile: String): Boolean; begin Result := False; - + + Lock; try - Lock; - Result := InternalOpen(AFile); finally Unlock; @@ -929,9 +1002,8 @@ function TDBDataProcess.ConnectFile(const AFile: String): Boolean; function TDBDataProcess.Open(const AWebsite: String): Boolean; begin + Lock; try - Lock; - Close; Result := False; @@ -948,7 +1020,7 @@ function TDBDataProcess.Open(const AWebsite: String): Boolean; OpenTable(FTableName, True); CheckFieldsExist(FTableName); - Result := FQuery.Active; + Result := FReadQuery.Active; except on E: Exception do SendLogException(Self.ClassName + '.Open.Error!', E); @@ -961,7 +1033,7 @@ function TDBDataProcess.Open(const AWebsite: String): Boolean; function TDBDataProcess.OpenTable(const ATableName: String; CheckRecordCount: Boolean): Boolean; begin - Result := FQuery.Active; + Result := FReadQuery.Active; if not FConn.Connected then begin @@ -981,9 +1053,9 @@ function TDBDataProcess.OpenTable(const ATableName: String; if TableExist(FTableName) then begin - if FQuery.Active then + if FReadQuery.Active then begin - FQuery.Close; + FReadQuery.Close; end; if not FTrans.Active then @@ -992,21 +1064,21 @@ function TDBDataProcess.OpenTable(const ATableName: String; end; FSQLSelect := 'SELECT * FROM "' + FTableName + '"'; - FQuery.SQL.Text := FSQLSelect; + FReadQuery.SQL.Text := FSQLSelect; if CheckRecordCount then begin GetRecordCount; end; - FQuery.Open; + FReadQuery.Open; end; except on E: Exception do SendLogException(Self.ClassName + '[' + Website + '].OpenTable.Error!', E); end; - Result := FQuery.Active; + Result := FReadQuery.Active; end; function TDBDataProcess.TableExist(const ATableName: String): Boolean; @@ -1088,7 +1160,7 @@ procedure TDBDataProcess.Close; end; try - FQuery.Close; + FReadQuery.Close; RemoveFilter; FConn.Close; FConn.DatabaseName := ''; @@ -1100,14 +1172,14 @@ procedure TDBDataProcess.Close; procedure TDBDataProcess.CloseTable; begin - if not FQuery.Active then + if not FReadQuery.Active then begin Exit; end; FRecordCount := 0; RemoveFilter; - FQuery.Close; + FReadQuery.Close; end; procedure TDBDataProcess.Save; @@ -1143,30 +1215,26 @@ procedure TDBDataProcess.Refresh(RecheckDataCount: Boolean); begin Exit; end; - + + Lock; try - - Lock; - if FQuery.Active then + if FReadQuery.Active then begin if RecheckDataCount then begin GetRecordCount; end; - FQuery.Refresh; + FReadQuery.Refresh; end - else if Trim(FQuery.SQL.Text) <> '' then + else if Trim(FReadQuery.SQL.Text) <> '' then begin if RecheckDataCount then begin GetRecordCount; end; - if IsSelectStatement(FQuery.SQL.Text) then - begin - FQuery.Open; - end; + FReadQuery.Open; end; finally Unlock; @@ -1185,33 +1253,84 @@ function TDBDataProcess.IsSelectStatement(const SQL: string): Boolean; (Pos('PRAGMA ', CleanSQL) = 1); end; -function TDBDataProcess.FindData(const Link: String): Boolean; -begin - Result := False; +function TDBDataProcess.CheckData(const Link, AField: String): TField; +var + sqlText: String; + Field: TField; +begin + Result := TField.Create(nil); if (Link = '') or (not FConn.Connected) then begin Exit; end; - + + Lock; try - Lock; - try - if FQuery.Active then + if FReadQuery.Active then begin - FQuery.Close; + FReadQuery.Close; end; - FQuery.SQL.Text := 'SELECT * FROM "' + FTableName + '" WHERE ("link"=:link);'; - FQuery.Params.ParamByName('link').AsString := Link; + sqlText := FReadQuery.SQL.Text; + FReadQuery.SQL.Text := 'SELECT * FROM "' + FTableName + '" WHERE ("link"=:link);'; + FReadQuery.Params.ParamByName('link').AsString := Link; + + FReadQuery.Open; + Field := FReadQuery.FindField(AField); + if Assigned(Field) then + begin + Result := Field; + end; + + FReadQuery.SQL.Text := sqlText; + FReadQuery.Open; + except + on E: Exception do + SendLogException(ClassName + '[' + Website + '].CheckData.Error!', E); + end; + finally + Unlock; + end; +end; + +function TDBDataProcess.ExistsData(const Link: String): Boolean; +var + sqlText: String; + Field: TField; +begin + Result := False; - FQuery.Open; - Result := FQuery.Fields[0].AsString <> ''; - FQuery.Close; + if (Link = '') or (not FConn.Connected) then + begin + Exit; + end; + + Lock; + try + try + if FReadQuery.Active then + begin + FReadQuery.Close; + end; + + sqlText := FReadQuery.SQL.Text; + FReadQuery.SQL.Text := 'SELECT * FROM "' + FTableName + '" WHERE ("link"=:link);'; + FReadQuery.Params.ParamByName('link').AsString := Link; + + FReadQuery.Open; + Field := FReadQuery.FindField('link'); + if Assigned(Field) then + begin + Result := Field.AsString <> ''; + end; + + FReadQuery.SQL.Text := sqlText; + FReadQuery.Open; except on E: Exception do - SendLogException(ClassName + '[' + Website + '].FindData.Error!', E); + SendLogException(ClassName + '[' + Website + '].ExistsData.Error!', E); end; finally Unlock; @@ -1231,48 +1350,47 @@ function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, Exit; end; - if FindData(Link) then + if ExistsData(Link) then begin Result := UpdateData(Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary, NumChapter, FWebsite); Exit; end; - + + Lock; try - Lock; - try - FQuery.SQL.Text := 'INSERT OR IGNORE INTO "' + FTableName + '" (' + DBDataProcessParam + ') VALUES (' + DBDataProcessParamInsert + ');'; + FWriteQuery.SQL.Text := 'INSERT OR IGNORE INTO "' + FTableName + '" (' + DBDataProcessParam + ') VALUES (' + DBDataProcessParamInsert + ');'; // Set parameters - the parameter binding handles escaping - FQuery.Params.ParamByName('link').AsString := Link; - FQuery.Params.ParamByName('title').AsString := Title; - FQuery.Params.ParamByName('alttitles').AsString := AltTitles; - FQuery.Params.ParamByName('authors').AsString := Authors; - FQuery.Params.ParamByName('artists').AsString := Artists; - FQuery.Params.ParamByName('genres').AsString := Genres; - FQuery.Params.ParamByName('status').AsString := Status; - FQuery.Params.ParamByName('summary').AsString := Summary; - FQuery.Params.ParamByName('numchapter').AsInteger := NumChapter; - FQuery.Params.ParamByName('jdn').AsInteger := JDN; - - if FQuery.Active then + FWriteQuery.Params.ParamByName('link').AsString := Link; + FWriteQuery.Params.ParamByName('title').AsString := Title; + FWriteQuery.Params.ParamByName('alttitles').AsString := AltTitles; + FWriteQuery.Params.ParamByName('authors').AsString := Authors; + FWriteQuery.Params.ParamByName('artists').AsString := Artists; + FWriteQuery.Params.ParamByName('genres').AsString := Genres; + FWriteQuery.Params.ParamByName('status').AsString := Status; + FWriteQuery.Params.ParamByName('summary').AsString := Summary; + FWriteQuery.Params.ParamByName('numchapter').AsInteger := NumChapter; + FWriteQuery.Params.ParamByName('jdn').AsInteger := JDN; + + if FWriteQuery.Active then begin - FQuery.Close; + FWriteQuery.Close; end; - FQuery.ExecSQL; + FWriteQuery.ExecSQL; - sql := FQuery.SQL.Text; - for i := 0 to FQuery.Params.Count - 1 do + sql := FWriteQuery.SQL.Text; + for i := 0 to FWriteQuery.Params.Count - 1 do begin - sql := StringReplace(sql, ':' + FQuery.Params[i].Name, QuotedStr(FQuery.Params[i].AsString), [rfReplaceAll, rfIgnoreCase]); + sql := StringReplace(sql, ':' + FWriteQuery.Params[i].Name, QuotedStr(FWriteQuery.Params[i].AsString), [rfReplaceAll, rfIgnoreCase]); end; - Result := FQuery.RowsAffected > 0; - FQuery.Close; + Result := FWriteQuery.RowsAffected > 0; + FWriteQuery.Close; - FQuery.SQL.Text := FSQLSelect; - FQuery.Open; + //FReadQuery.SQL.Text := FSQLSelect; + FReadQuery.Open; except on E: Exception do SendLogException(ClassName + '[' + Website + '].AddData.Error!' + LineEnding + sql, E); @@ -1292,7 +1410,9 @@ function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, function TDBDataProcess.UpdateData(const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; NumChapter: Integer; AWebsite: String): Boolean; var - sql: String; + lastUpdated: Integer; + sql, tableWithSchema: String; + i: Integer; begin Result := False; @@ -1302,34 +1422,64 @@ function TDBDataProcess.UpdateData(const Title, AltTitles, Link, Authors, Artist Exit; end; + lastUpdated := CheckData(Link, 'jdn').AsInteger; + if (lastUpdated > (DateToJDN(Now - 1))) then + begin + Exit; + end; + + Lock; try - Lock; - try - sql := 'UPDATE '; if (AWebsite <> '') and (AWebsite <> FWebsite) and FAllSitesAttached then begin - sql += '"' + AWebsite + '"."' + FTableName + '"'; + tableWithSchema := '"' + AWebsite + '"."' + FTableName + '"'; end else begin - sql += '"' + FTableName + '"'; + tableWithSchema := '"' + FTableName + '"'; end; - sql += ' SET "title"=' + QuotedStr(Title) + - ', "alttitles"=' + QuotedStr(AltTitles) + - ', "authors"=' + QuotedStr(Authors) + - ', "artists"=' + QuotedStr(Artists) + - ', "genres"=' + QuotedStr(Genres) + - ', "status"=' + QuotedStr(Status) + - ', "summary"=' + QuotedStr(Summary) + - ', "numchapter"=' + QuotedStr(IntToStr(NumChapter)) + - ' WHERE ("link"=' + QuotedStr(Link) + ');'; - FConn.ExecuteDirect(sql); - Result := True; + FWriteQuery.SQL.Text := 'UPDATE ' + tableWithSchema + ' SET ' + + '"title" = :title, ' + + '"alttitles" = :alttitles, ' + + '"authors" = :authors, ' + + '"artists" = :artists, ' + + '"genres" = :genres, ' + + '"status" = :status, ' + + '"summary" = :summary, ' + + '"numchapter" = :numchapter ' + + 'WHERE "link" = :link'; + + // Set parameters + FWriteQuery.Params.ParamByName('title').AsString := Title; + FWriteQuery.Params.ParamByName('alttitles').AsString := AltTitles; + FWriteQuery.Params.ParamByName('authors').AsString := Authors; + FWriteQuery.Params.ParamByName('artists').AsString := Artists; + FWriteQuery.Params.ParamByName('genres').AsString := Genres; + FWriteQuery.Params.ParamByName('status').AsString := Status; + FWriteQuery.Params.ParamByName('summary').AsString := Summary; + FWriteQuery.Params.ParamByName('numchapter').AsInteger := NumChapter; + FWriteQuery.Params.ParamByName('link').AsString := Link; + + if FWriteQuery.Active then + begin + FWriteQuery.Close; + end; + + FWriteQuery.ExecSQL; + + sql := FWriteQuery.SQL.Text; + for i := 0 to FWriteQuery.Params.Count - 1 do + begin + sql := StringReplace(sql, ':' + FWriteQuery.Params[i].Name, QuotedStr(FWriteQuery.Params[i].AsString), [rfReplaceAll, rfIgnoreCase]); + end; + + Result := FWriteQuery.RowsAffected > 0; + FWriteQuery.Close; - FQuery.SQL.Text := FSQLSelect; - FQuery.Open; + //FReadQuery.SQL.Text := FSQLSelect; + FReadQuery.Open; except on E: Exception do SendLogException(ClassName + '[' + Website + '].UpdateData.Error!' + LineEnding + sql, E); @@ -1340,15 +1490,38 @@ function TDBDataProcess.UpdateData(const Title, AltTitles, Link, Authors, Artist end; function TDBDataProcess.DeleteData(const RecIndex: Integer): Boolean; +var + Link: String; begin Result := False; try - if GoToRecNo(RecIndex) then + if not GoToRecNo(RecIndex) then + begin + Exit; + end; + + Link := FReadQuery.FieldByName('link').AsString; + + // Now use write query to delete by link + FWriteQuery.SQL.Text := 'DELETE FROM "' + FTableName + '" WHERE "link" = :link'; + FWriteQuery.Params.ParamByName('link').AsString := Link; + + if FWriteQuery.Active then + begin + FWriteQuery.Close; + end; + + FWriteQuery.ExecSQL; + + Result := FWriteQuery.RowsAffected > 0; + + if Result then begin - FQuery.Delete; Dec(FRecordCount); - Result := True; + // Refresh the read query to reflect deletion + //FReadQuery.SQL.Text := FSQLSelect; + FReadQuery.Open; end; except on E: Exception do @@ -1364,21 +1537,20 @@ procedure TDBDataProcess.Commit; begin Exit; end; - + + Lock; try - Lock; - try - queryactive := FQuery.Active; - if FQuery.Active then + queryactive := FWriteQuery.Active; + if FWriteQuery.Active then begin - FQuery.Close; + FWriteQuery.Close; end; FTrans.CommitRetaining; - if FQuery.Active <> queryactive then + if FWriteQuery.Active <> queryactive then begin - FQuery.Active := queryactive; + FWriteQuery.Active := queryactive; end; except on E: Exception do @@ -1436,15 +1608,14 @@ function TDBDataProcess.Search(ATitle: String): Boolean; i: Integer; Titles: array[0..1] of TFieldValuePair; begin - if FQuery.Active then - begin + if FReadQuery.Active then + begin + Lock; try - Lock; - try - FQuery.Close; + FReadQuery.Close; - with FQuery do + with FReadQuery do begin SQL.Clear; if FFilterApplied then @@ -1504,22 +1675,18 @@ function TDBDataProcess.Search(ATitle: String): Boolean; end; GetRecordCount; - - if IsSelectStatement(FQuery.SQL.Text) then - begin - FQuery.Open; - end; + FReadQuery.Open; except on E: Exception do SendLogException(Self.ClassName + '[' + Website + '].Search.Error!'#13#10 + - 'SQL:'#13#10 + FQuery.SQL.Text, E); + 'SQL:'#13#10 + FReadQuery.SQL.Text, E); end; finally Unlock; end; end; - Result := FQuery.Active; + Result := FReadQuery.Active; if not Result then begin @@ -1534,7 +1701,7 @@ function TDBDataProcess.CanFilter(const checkedGenres, uncheckedGenres: TStringL begin Result := True; - if not FQuery.Active then + if not FReadQuery.Active then begin Exit(False); end; @@ -1606,7 +1773,7 @@ function TDBDataProcess.Filter(const checkedGenres, (not haveAllChecked), useRegExpr); end; - FQuery.SQL.Add(')'); + FReadQuery.SQL.Add(')'); end; //filter unchecked genres @@ -1619,13 +1786,13 @@ function TDBDataProcess.Filter(const checkedGenres, (not haveAllChecked), useRegExpr); end; - FQuery.SQL.Add(')'); + FReadQuery.SQL.Add(')'); end; end; begin Result := False; - if FQuery.Active = False then + if FReadQuery.Active = False then begin Exit; end; @@ -1635,13 +1802,12 @@ function TDBDataProcess.Filter(const checkedGenres, begin Exit; end; - + + Lock; try - Lock; - - with FQuery do + with FReadQuery do begin - FQuery.Close; + FReadQuery.Close; FRecordCount := 0; tsql := SQL.Text; SQL.Clear; @@ -1682,7 +1848,7 @@ function TDBDataProcess.Filter(const checkedGenres, end; Self.GetRecordCount; - FQuery.Open; + FReadQuery.Open; FFiltered := Active; FFilterApplied := FFiltered; @@ -1698,11 +1864,11 @@ function TDBDataProcess.Filter(const checkedGenres, on E: Exception do begin SendLogException(Self.ClassName + '[' + Website + '].Filter.Error!'#13#10 + - 'SQL:'#13#10 + FQuery.SQL.Text, E); - FQuery.Close; + 'SQL:'#13#10 + FReadQuery.SQL.Text, E); + FReadQuery.Close; SQL.Text := tsql; Self.GetRecordCount; - FQuery.Open; + FReadQuery.Open; FFilterAllSites := False; FFiltered := False; FFilterApplied := False; @@ -1736,9 +1902,9 @@ procedure TDBDataProcess.CreateDatabase(const AWebsite: String); procedure TDBDataProcess.GetFieldNames(const List: TStringList); begin - if (List <> nil) and (FQuery.Active) then + if (List <> nil) and (FReadQuery.Active) then begin - FQuery.GetFieldNames(List); + FReadQuery.GetFieldNames(List); end; end; @@ -1750,11 +1916,11 @@ procedure TDBDataProcess.RemoveFilter; FFiltered := False; FFilterApplied := False; FFilterSQL := ''; - FQuery.SQL.Text := FSQLSelect; + FReadQuery.SQL.Text := FSQLSelect; FRecordCount := 0; DetachAllSites; - if FQuery.Active then + if FReadQuery.Active then begin OpenTable(FTableName, True); end; @@ -1769,12 +1935,9 @@ procedure TDBDataProcess.Sort; begin Exit; end; - + + Lock; try - Lock; - - queryactive := FQuery.Active; - FQuery.Close; with FConn do begin try @@ -1783,18 +1946,14 @@ procedure TDBDataProcess.Sort; ExecuteDirect('INSERT INTO "' + FTableName + '_ordered" (' + DBDataProcessParam + ') SELECT ' + DBDataProcessParam + ' FROM "' + FTableName + '" ORDER BY "title" COLLATE NATCMP'); ExecuteDirect('DROP TABLE "' + FTableName + '"'); ExecuteDirect('ALTER TABLE "' + FTableName + '_ordered" RENAME TO "' + FTableName + '"'); - FTrans.Commit; - VacuumTable; except on E: Exception do SendLogException(Self.ClassName + '[' + Website + '].Sort.Error!', E); end; end; - if FQuery.Active <> queryactive then - begin - FQuery.Active := queryactive; - end; + FTrans.Commit; + VacuumTable; finally Unlock; end; @@ -1811,8 +1970,8 @@ function TDBDataProcess.GetModule(const RecIndex: Integer): Pointer; Exit; end; - FQuery.RecNo := RecIndex + 1; - i := FQuery.Fields[DBTempFieldWebsiteIndex].AsInteger; + FReadQuery.RecNo := RecIndex + 1; + i := FReadQuery.Fields[DBTempFieldWebsiteIndex].AsInteger; if i <> -1 then begin @@ -1869,16 +2028,16 @@ procedure TDBDataProcess.InitLocateLink; end; FLinks.Sorted := False; - if not FQuery.Active then + if not FReadQuery.Active then begin Exit; end; - FQuery.First; + FReadQuery.First; repeat - FLinks.Add(FQuery.Fields[1].AsString); - FQuery.Next; - until FQuery.EOF; + FLinks.Add(FReadQuery.Fields[1].AsString); + FReadQuery.Next; + until FReadQuery.EOF; if FLinks.Count > 0 then begin From 3ba4b1f76f488bceaf4152171f64cabe39c10d6b Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Fri, 6 Mar 2026 14:14:33 +0800 Subject: [PATCH 26/35] Added: Function to normalize decomposed korean text --- baseunits/uBaseUnit.pas | 172 +++++++++++++++++++++++++++++++++------- 1 file changed, 145 insertions(+), 27 deletions(-) diff --git a/baseunits/uBaseUnit.pas b/baseunits/uBaseUnit.pas index d5a89caa4..fe7323093 100644 --- a/baseunits/uBaseUnit.pas +++ b/baseunits/uBaseUnit.pas @@ -541,6 +541,7 @@ function CustomRename(const AString, AWebsite, AMangaName, AAuthor, AArtist, ACh const AReplaceUnicode: Boolean; const AReplaceUnicodeStr: String; const AFileName: String = ''): String; +function NormalizeKorean(const Input: String): String; // Get substring from source function GetString(const Source, sStart, sEnd: String): String; @@ -2109,18 +2110,79 @@ function HTMLEntitiesFilter(const Source: String): String; end; end; +function NormalizeKorean(const Input: string): string; +var + wsInput: WideString; + wsFinal: WideString; + i: Integer; +begin + wsInput := UTF8Decode(Input); + wsFinal := ''; + i := 1; + + while i <= Length(wsInput) do + begin + // Check for Korean Jamo sequences + if (i + 1 <= Length(wsInput)) and + (Ord(wsInput[i]) >= $1100) and (Ord(wsInput[i]) <= $1112) and // Initial + (Ord(wsInput[i + 1]) >= $1161) and (Ord(wsInput[i + 1]) <= $1175) then // Medial + begin + // Check for final consonant + if (i + 2 <= Length(wsInput)) and + (Ord(wsInput[i + 2]) >= $11A8) and (Ord(wsInput[i + 2]) <= $11C2) then + begin + // 3-Jamo: initial + medial + final + wsFinal := wsFinal + WideChar($AC00 + + ((Ord(wsInput[i]) - $1100) * 588) + + ((Ord(wsInput[i + 1]) - $1161) * 28) + + (Ord(wsInput[i + 2]) - $11A7)); + i := i + 3; + end + else + begin + // 2-Jamo: initial + medial (no final) + wsFinal := wsFinal + WideChar($AC00 + + ((Ord(wsInput[i]) - $1100) * 588) + + ((Ord(wsInput[i + 1]) - $1161) * 28)); + i := i + 2; + end; + end + else + begin + // Not Korean Jamo, keep as is + wsFinal := wsFinal + wsInput[i]; + i := i + 1; + end; + end; + + Result := UTF8Encode(wsFinal); +end; + function CommonStringFilter(const Source: String): String; +var + FilteredString: String; begin Result := Source; - if Source = '' then Exit; - Result := Trim(HTMLEntitiesFilter(StringFilter(Trim(Source)))); + if Length(Result) = 0 then + begin + Exit; + end; + + FilteredString := NormalizeKorean(Source); + FilteredString := StringFilter(Trim(FilteredString)); + FilteredString := Trim(HTMLEntitiesFilter(FilteredString)); + + Result := FilteredString; end; function StringBreaks(const Source: String): String; begin Result := Source; if Length(Result) = 0 then + begin Exit; + end; + Result := StringReplace(Result, '\n', #10, [rfReplaceAll]); Result := StringReplace(Result, '\r', #13, [rfReplaceAll]); end; @@ -2129,7 +2191,10 @@ function BreaksString(const Source: String): String; begin Result := Source; if Length(Result) = 0 then + begin Exit; + end; + Result := StringReplace(Result, #10, '\n', [rfReplaceAll]); Result := StringReplace(Result, #13, '\r', [rfReplaceAll]); end; @@ -2138,7 +2203,10 @@ function RemoveBreaks(const Source: String): String; begin Result := Source; if Length(Result) = 0 then + begin Exit; + end; + Result := StringReplace(Result, #10, '', [rfReplaceAll]); Result := StringReplace(Result, #13, '', [rfReplaceAll]); end; @@ -2147,7 +2215,10 @@ function RemoveStringBreaks(const Source: String): String; begin Result := Source; if Length(Result) = 0 then + begin Exit; + end; + Result := StringReplace(Result, #10, '', [rfReplaceAll]); Result := StringReplace(Result, #13, '', [rfReplaceAll]); Result := StringReplace(Result, '\n', '', [rfReplaceAll]); @@ -2158,7 +2229,9 @@ function RemoveDoubleSpace(const Source: String): String; begin Result := Source; while Pos(' ', Result) > 0 do + begin Result := StringReplace(Result, ' ', ' ', [rfReplaceAll, rfIgnoreCase]); + end; end; function TrimChar(const Source: String; const Chars: TSysCharSet): String; @@ -2172,14 +2245,20 @@ function TrimLeftChar(const Source: String; const Chars: TSysCharSet): String; i, j: Longint; begin Result := Source; + i := Length(Result); if i > 0 then begin j := 1; while (j <= i) and (Result[j] in Chars) do + begin Inc(j); + end; + if j > 1 then + begin Delete(Result, 1, j - 1); + end; end; end; @@ -2188,21 +2267,31 @@ function TrimRightChar(const Source: String; const Chars: TSysCharSet): String; i, j: Longint; begin Result := Source; + i := Length(Result); if i > 0 then begin j := i; while (j > 0) and (Result[j] in Chars) do + begin Dec(j); + end; + if j <> i then + begin SetLength(Result, j); + end; end; end; function GoogleResultURL(const AURL: String): String; begin Result := AURL; - if Pos('google.', LowerCase(AURL)) = 0 then Exit; + if Pos('google.', LowerCase(AURL)) = 0 then + begin + Exit; + end; + Result := DecodeURL(ReplaceRegExpr('(?i)^.*google\..*\&url=([^\&]+)\&?.*$', AURL, '$1', True)); end; @@ -2210,14 +2299,29 @@ procedure GoogleResultURLs(const AURLs: TStrings); var i: Integer; begin - if AURLs.Count = 0 then Exit; - if Pos('google.', LowerCase(AURLs.Text)) = 0 then Exit; - with TRegExpr.Create('(?i)^.*google\..*\&url=([^\&]+)\&?.*$') do try - for i := 0 to AURLs.Count - 1 do - if Pos('google.', LowerCase(AURLs[i])) <> 0 then - AURLs[i] := DecodeURL(Replace(AURLs[i], '$1', True)); - finally - Free; + if AURLs.Count = 0 then + begin + Exit; + end; + + if Pos('google.', LowerCase(AURLs.Text)) = 0 then + begin + Exit; + end; + + with TRegExpr.Create('(?i)^.*google\..*\&url=([^\&]+)\&?.*$') do + begin + try + for i := 0 to AURLs.Count - 1 do + begin + if Pos('google.', LowerCase(AURLs[i])) <> 0 then + begin + AURLs[i] := DecodeURL(Replace(AURLs[i], '$1', True)); + end; + end; + finally + Free; + end; end; end; @@ -2313,23 +2417,28 @@ function WebPToPNGStream(const AStream: TMemoryStream; writer: TFPWriterPNG; begin Result := False; + mem := nil; try mem := WebPToMemBitmap(AStream); if Assigned(mem) then - try - writer := TFPWriterPNG.create; - writer.Indexed := False; - writer.UseAlpha := mem.HasTransparentPixels; - writer.CompressionLevel := ALevel; - mem.SaveToStream(AStream, writer); - Result := True; - finally - writer.Free; + begin + try + writer := TFPWriterPNG.create; + writer.Indexed := False; + writer.UseAlpha := mem.HasTransparentPixels; + writer.CompressionLevel := ALevel; + mem.SaveToStream(AStream, writer); + Result := True; + finally + writer.Free; + end; end; finally if Assigned(mem) then + begin mem.Free; + end; end; end; @@ -2340,21 +2449,26 @@ function WebPToJPEGStream(const AStream: TMemoryStream; const AQuality: Integer writer: TFPWriterJPEG; begin Result := False; + mem := nil; try mem := WebPToMemBitmap(AStream); if Assigned(mem) then - try - writer := TFPWriterJPEG.create; - writer.CompressionQuality := AQuality; - mem.SaveToStream(AStream, writer); - Result := True; - finally - writer.Free; + begin + try + writer := TFPWriterJPEG.create; + writer.CompressionQuality := AQuality; + mem.SaveToStream(AStream, writer); + Result := True; + finally + writer.Free; + end; end; finally if Assigned(mem) then + begin mem.Free; + end; end; end; @@ -2366,6 +2480,7 @@ function PNGToJPEGStream(const AStream: TMemoryStream; const AQuality: Integer): begin Result := False; img := TFPMemoryImage.create(0,0); + reader := TFPReaderPNG.create; try writer := nil; @@ -2377,8 +2492,11 @@ function PNGToJPEGStream(const AStream: TMemoryStream; const AQuality: Integer): Result := True; except end; + if writer <> nil then + begin writer.Free; + end; finally reader.Free; img.Free; From 5bec00eb7b99cd6e68096576dfabf0a8cb7e06ea Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Wed, 25 Mar 2026 18:27:46 +0800 Subject: [PATCH 27/35] Removed: Image Magick combobox texts from translation files --- languages/fmd.de.po | 8 -------- languages/fmd.el_GR.po | 8 -------- languages/fmd.en.po | 8 -------- languages/fmd.es.po | 8 -------- languages/fmd.fr.po | 8 -------- languages/fmd.id_ID.po | 8 -------- languages/fmd.pl_PL.po | 8 -------- languages/fmd.pot | 8 -------- languages/fmd.pt_BR.po | 8 -------- languages/fmd.ru_RU.po | 8 -------- languages/fmd.tr_TR.po | 8 -------- languages/fmd.zh.po | 8 -------- mangadownloader/md.lpi | 4 ++++ 13 files changed, 4 insertions(+), 96 deletions(-) diff --git a/languages/fmd.de.po b/languages/fmd.de.po index 9cbe38932..7d5549bca 100644 --- a/languages/fmd.de.po +++ b/languages/fmd.de.po @@ -1021,14 +1021,6 @@ msgstr "Zur Downloadliste als angehaltene Aufgabe hinzufügen" msgid "" msgstr "" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Nur nach neuen Manga suchen" diff --git a/languages/fmd.el_GR.po b/languages/fmd.el_GR.po index 90e33c862..0cb0f05ca 100644 --- a/languages/fmd.el_GR.po +++ b/languages/fmd.el_GR.po @@ -1017,14 +1017,6 @@ msgstr "Προσθήκη στη λίστα λήψης ως διακοπείσα msgid "" msgstr "<καμία>" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Αναζήτηση μόνο νέου manga" diff --git a/languages/fmd.en.po b/languages/fmd.en.po index 4024e8697..9597e0138 100644 --- a/languages/fmd.en.po +++ b/languages/fmd.en.po @@ -1026,14 +1026,6 @@ msgstr "Add to download list as stopped task" msgid "" msgstr "" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Search only new manga" diff --git a/languages/fmd.es.po b/languages/fmd.es.po index 7ad5b4931..37f40ed09 100644 --- a/languages/fmd.es.po +++ b/languages/fmd.es.po @@ -1021,14 +1021,6 @@ msgstr "Agregar a Descargas como Tarea Detenida" msgid "" msgstr "" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Buscar Solo Manga Nuevo" diff --git a/languages/fmd.fr.po b/languages/fmd.fr.po index d5f7475da..e61e31b03 100644 --- a/languages/fmd.fr.po +++ b/languages/fmd.fr.po @@ -1023,14 +1023,6 @@ msgstr "Ne pas démarrer les tâches ajoutées à la liste des téléchargements msgid "" msgstr "" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Afficher les nouveaux mangas uniquement" diff --git a/languages/fmd.id_ID.po b/languages/fmd.id_ID.po index 2164ea871..d18e70f9f 100644 --- a/languages/fmd.id_ID.po +++ b/languages/fmd.id_ID.po @@ -1030,14 +1030,6 @@ msgstr "Tambahkan ke daftar unduhan tanpa dimulai" msgid "" msgstr "" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Hanya cari komik baru" diff --git a/languages/fmd.pl_PL.po b/languages/fmd.pl_PL.po index a4fb979e7..d90189927 100644 --- a/languages/fmd.pl_PL.po +++ b/languages/fmd.pl_PL.po @@ -1004,14 +1004,6 @@ msgstr "Dodaj do listy pobieranych jako zatrzymane zadanie" msgid "" msgstr "" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Szukaj tylko nowych mang" diff --git a/languages/fmd.pot b/languages/fmd.pot index 53dd7f3f6..63054ed6e 100644 --- a/languages/fmd.pot +++ b/languages/fmd.pot @@ -960,14 +960,6 @@ msgstr "" msgid "" msgstr "" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "" diff --git a/languages/fmd.pt_BR.po b/languages/fmd.pt_BR.po index 7332601d7..e9cdf0aee 100644 --- a/languages/fmd.pt_BR.po +++ b/languages/fmd.pt_BR.po @@ -1020,14 +1020,6 @@ msgstr "Adicionar download de lista como uma tarefa parada" msgid "" msgstr "" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Buscar somente novos mangás" diff --git a/languages/fmd.ru_RU.po b/languages/fmd.ru_RU.po index d8e1b3cf8..2d6fc63b9 100644 --- a/languages/fmd.ru_RU.po +++ b/languages/fmd.ru_RU.po @@ -1020,14 +1020,6 @@ msgstr "Добавить в список загрузки как останов msgid "" msgstr "<нет>" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Искать только новую мангу" diff --git a/languages/fmd.tr_TR.po b/languages/fmd.tr_TR.po index addc4ecf3..4927578c9 100644 --- a/languages/fmd.tr_TR.po +++ b/languages/fmd.tr_TR.po @@ -1022,14 +1022,6 @@ msgstr "İndirme listesine durdurulmuş görev olarak ekle" msgid "" msgstr "" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "Sadece yeni manga ara" diff --git a/languages/fmd.zh.po b/languages/fmd.zh.po index 364a12618..ec18afe4d 100644 --- a/languages/fmd.zh.po +++ b/languages/fmd.zh.po @@ -1020,14 +1020,6 @@ msgstr "作为已停止任务添加到下载列表" msgid "" msgstr "<无>" -#: tmainform.cbimagemagickcompression.text -msgid "None" -msgstr "" - -#: tmainform.cbimagemagicksaveas.text -msgid "JPEG" -msgstr "" - #: tmainform.cbonlynew.caption msgid "Search only new manga" msgstr "仅搜索新漫画" diff --git a/mangadownloader/md.lpi b/mangadownloader/md.lpi index 1cdb0c479..ecb3e9c40 100644 --- a/mangadownloader/md.lpi +++ b/mangadownloader/md.lpi @@ -20,6 +20,10 @@ + + + + From c1ab3572d6097f61b54eebbd3a3c32f0706dc80e Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Thu, 26 Mar 2026 22:42:11 +0800 Subject: [PATCH 28/35] Changed: Custom message dialog buttons to translatable texts Changed: Custom message dialog to be able to adjust according to button count and size --- languages/fmd.de.po | 52 ++++++++ languages/fmd.el_GR.po | 51 ++++++++ languages/fmd.en.po | 52 ++++++++ languages/fmd.es.po | 52 ++++++++ languages/fmd.fr.po | 52 ++++++++ languages/fmd.id_ID.po | 52 ++++++++ languages/fmd.pl_PL.po | 51 ++++++++ languages/fmd.pot | 48 +++++++ languages/fmd.pt_BR.po | 52 ++++++++ languages/fmd.ru_RU.po | 52 ++++++++ languages/fmd.tr_TR.po | 52 ++++++++ languages/fmd.zh.po | 52 ++++++++ mangadownloader/forms/frmMain.pas | 94 +++++++------- mangadownloader/forms/frmcustommessagedlg.lfm | 7 +- mangadownloader/forms/frmcustommessagedlg.pas | 120 ++++++++++-------- 15 files changed, 741 insertions(+), 98 deletions(-) diff --git a/languages/fmd.de.po b/languages/fmd.de.po index 7d5549bca..5b47189d2 100644 --- a/languages/fmd.de.po +++ b/languages/fmd.de.po @@ -108,6 +108,58 @@ msgstr "OK" msgid "Username or password can't be empty!" msgstr "Benutzername oder Passwort darf nicht leer sein!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "Abbrechen" + +#: frmcustommessagedlg.rs_dialogbuttonall +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "Alle" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "Abbrechen" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "OK" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.el_GR.po b/languages/fmd.el_GR.po index 0cb0f05ca..11f1680dd 100644 --- a/languages/fmd.el_GR.po +++ b/languages/fmd.el_GR.po @@ -108,6 +108,57 @@ msgstr "Εντάξει" msgid "Username or password can't be empty!" msgstr "Το όνομα χρήστη ή ο κωδικός πρόσβασης δεν μπορεί να είναι κενά!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "Άκυρο" + +#: frmcustommessagedlg.rs_dialogbuttonall +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "Άκυρο" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "Εντάξει" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.en.po b/languages/fmd.en.po index 9597e0138..231f3a049 100644 --- a/languages/fmd.en.po +++ b/languages/fmd.en.po @@ -107,6 +107,58 @@ msgstr "OK" msgid "Username or password can't be empty!" msgstr "Username or password can't be empty!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "Abort" + +#: frmcustommessagedlg.rs_dialogbuttonall +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "All" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "Cancel" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "OK" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.es.po b/languages/fmd.es.po index 37f40ed09..7ddd90edf 100644 --- a/languages/fmd.es.po +++ b/languages/fmd.es.po @@ -108,6 +108,58 @@ msgstr "OK" msgid "Username or password can't be empty!" msgstr "¡Nombre de usuario o contraseña no puede estar vacio!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "Abortar" + +#: frmcustommessagedlg.rs_dialogbuttonall +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "Todo" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "Cancelar" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "OK" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.fr.po b/languages/fmd.fr.po index e61e31b03..20199ffd8 100644 --- a/languages/fmd.fr.po +++ b/languages/fmd.fr.po @@ -108,6 +108,58 @@ msgstr "OK" msgid "Username or password can't be empty!" msgstr "Le nom d'utilisateur et le mot de passe ne peuvent pas être vides !" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "Annuler" + +#: frmcustommessagedlg.rs_dialogbuttonall +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "Tous" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "Annuler" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "OK" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.id_ID.po b/languages/fmd.id_ID.po index d18e70f9f..fdc1fb1d0 100644 --- a/languages/fmd.id_ID.po +++ b/languages/fmd.id_ID.po @@ -111,6 +111,58 @@ msgstr "Oke" msgid "Username or password can't be empty!" msgstr "Nama pengguna atau kata sandi tidak boleh kosong!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "Batalkan" + +#: frmcustommessagedlg.rs_dialogbuttonall +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "Semua" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "Batal" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "Oke" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.pl_PL.po b/languages/fmd.pl_PL.po index d90189927..6151624cb 100644 --- a/languages/fmd.pl_PL.po +++ b/languages/fmd.pl_PL.po @@ -105,6 +105,57 @@ msgstr "OK" msgid "Username or password can't be empty!" msgstr "Nazwa użytkownika lub hasło nie może być puste!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "Anuluj" + +#: frmcustommessagedlg.rs_dialogbuttonall +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "Anuluj" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "OK" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.pot b/languages/fmd.pot index 63054ed6e..aa45bf516 100644 --- a/languages/fmd.pot +++ b/languages/fmd.pot @@ -94,6 +94,54 @@ msgstr "" msgid "Username or password can't be empty!" msgstr "" +#: frmcustommessagedlg.rs_dialogbuttonabort +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonall +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.pt_BR.po b/languages/fmd.pt_BR.po index e9cdf0aee..ede99163c 100644 --- a/languages/fmd.pt_BR.po +++ b/languages/fmd.pt_BR.po @@ -107,6 +107,58 @@ msgstr "OK" msgid "Username or password can't be empty!" msgstr "Nome de usuário ou a senha não podem estar vazios!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "Abortar" + +#: frmcustommessagedlg.rs_dialogbuttonall +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "Todos" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "Cancelar" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "OK" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.ru_RU.po b/languages/fmd.ru_RU.po index 2d6fc63b9..ec36fef85 100644 --- a/languages/fmd.ru_RU.po +++ b/languages/fmd.ru_RU.po @@ -107,6 +107,58 @@ msgstr "OK" msgid "Username or password can't be empty!" msgstr "Имя пользователя и пароль не могут быть пустыми!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "Отмена" + +#: frmcustommessagedlg.rs_dialogbuttonall +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "Все" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "Отмена" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "OK" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.tr_TR.po b/languages/fmd.tr_TR.po index 4927578c9..278f7748c 100644 --- a/languages/fmd.tr_TR.po +++ b/languages/fmd.tr_TR.po @@ -109,6 +109,58 @@ msgstr "Tamam" msgid "Username or password can't be empty!" msgstr "Kullanıcı adı veya şifre boş olamaz!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "İptal" + +#: frmcustommessagedlg.rs_dialogbuttonall +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "Tümü" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "İptal" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "Tamam" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/languages/fmd.zh.po b/languages/fmd.zh.po index ec18afe4d..1a992edf7 100644 --- a/languages/fmd.zh.po +++ b/languages/fmd.zh.po @@ -107,6 +107,58 @@ msgstr "确定" msgid "Username or password can't be empty!" msgstr "用户名或密码不能为空!" +#: frmcustommessagedlg.rs_dialogbuttonabort +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonabort" +msgid "Abort" +msgstr "中止" + +#: frmcustommessagedlg.rs_dialogbuttonall +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonall" +msgid "All" +msgstr "所有" + +#: frmcustommessagedlg.rs_dialogbuttoncancel +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttoncancel" +msgid "Cancel" +msgstr "取消" + +#: frmcustommessagedlg.rs_dialogbuttonclose +msgid "Close" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonignore +msgid "Ignore" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonno +msgid "No" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonnoall +msgid "No to All" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonok +#, fuzzy +msgctxt "frmcustommessagedlg.rs_dialogbuttonok" +msgid "OK" +msgstr "确定" + +#: frmcustommessagedlg.rs_dialogbuttonretry +msgid "Retry" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyes +msgid "Yes" +msgstr "" + +#: frmcustommessagedlg.rs_dialogbuttonyesall +msgid "Yes to All" +msgstr "" + #: frmcustommessagedlg.rs_dialogconfirmation msgctxt "frmcustommessagedlg.rs_dialogconfirmation" msgid "Confirmation" diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index e40fefa99..56b07de1a 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -4325,13 +4325,11 @@ procedure TMainForm.miMangaListDownloadAllClick(Sender: TObject); try YesAll := False; NoAll := False; - if vtMangaList.SelectedCount = 1 then - begin - mBtns := [mbYes, mbNo]; - end - else + + mBtns := [mbYes, mbNo]; + if vtMangaList.SelectedCount > 1 then begin - mBtns := [mbYes, mbNo, mbYesToAll, mbNoToAll]; + mBtns := mBtns + [mbYesToAll, mbNoToAll]; end; xNode := vtMangaList.GetFirstSelected; @@ -4339,60 +4337,70 @@ procedure TMainForm.miMangaListDownloadAllClick(Sender: TObject); begin data := vtMangaList.GetNodeData(xNode); AllowedToCreate := True; - if DLManager.Count > 0 then + + if DLManager.Count <= 0 then begin - for i := 0 to DLManager.Count - 1 do + Break; + end; + + for i := 0 to DLManager.Count - 1 do + begin + if data^.Title <> DLManager.Items[i].DownloadInfo.title then + begin + Continue; + end; + + if YesAll then + begin + AllowedToCreate := True; + Break; + end; + + if NoAll then + begin + AllowedToCreate := False; + Break; + end; + + if OptionShowDownloadsTabOnNewTasks then begin - if data^.Title = DLManager.Items[i].DownloadInfo.title then + pcMain.ActivePage := tsDownload; + end; + + mResult := CenteredMessageDlg(Self, DLManager.Items[i].DownloadInfo.title + + LineEnding + LineEnding + RS_DlgTitleExistInDLlist, mtConfirmation, mBtns, 0); + case mResult of + mrYes: AllowedToCreate := True; + mrNo: AllowedToCreate := False; + mrYesToAll: begin - if YesAll then - begin - AllowedToCreate := True - end - else if NoAll then - begin - AllowedToCreate := False - end - else - begin - if OptionShowDownloadsTabOnNewTasks then - begin - pcMain.ActivePage := tsDownload; - end; - mResult := CenteredMessageDlg(Self, DLManager.Items[i].DownloadInfo.title + - LineEnding + LineEnding + RS_DlgTitleExistInDLlist, mtConfirmation, mBtns, 0); - case mResult of - mrYes : AllowedToCreate := True; - mrNo : AllowedToCreate := False; - mrYesToAll : - begin - YesAll := True; - NoAll := False; - AllowedToCreate := True; - end; - mrNoToAll : - begin - YesAll := False; - NoAll := True; - AllowedToCreate := False; - end; - end; - end; - Break; + YesAll := True; + NoAll := False; + AllowedToCreate := True; + end; + else + begin + YesAll := False; + NoAll := True; + AllowedToCreate := False; end; end; + + Break; end; if AllowedToCreate then begin SilentThreadManager.Add(MD_DownloadAll, TModuleContainer(data^.Module), data^.Title, data^.Link); end; + xNode := vtMangaList.GetNextSelected(xNode); end; except on E: Exception do ExceptionHandler(Self, E); end; + SilentThreadManager.EndAdd; end; diff --git a/mangadownloader/forms/frmcustommessagedlg.lfm b/mangadownloader/forms/frmcustommessagedlg.lfm index f636f387f..3fc4b45d5 100644 --- a/mangadownloader/forms/frmcustommessagedlg.lfm +++ b/mangadownloader/forms/frmcustommessagedlg.lfm @@ -23,17 +23,18 @@ object CustomMessageDlg: TCustomMessageDlg end object pnlButtons: TPanel AnchorSideLeft.Control = Owner + AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = imgIcon AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 0 + Left = 125 Height = 45 Top = 73 - Width = 300 - Anchors = [akLeft, akRight, akBottom] + Width = 50 + Anchors = [akLeft, akBottom] BorderSpacing.Top = 10 TabOrder = 0 end diff --git a/mangadownloader/forms/frmcustommessagedlg.pas b/mangadownloader/forms/frmcustommessagedlg.pas index a524e5202..7d5bc03e7 100644 --- a/mangadownloader/forms/frmcustommessagedlg.pas +++ b/mangadownloader/forms/frmcustommessagedlg.pas @@ -5,7 +5,8 @@ interface uses - Classes, SysUtils, Forms, Controls, Graphics, Dialogs, DialogRes, Buttons, ExtCtrls, StdCtrls, LCLType; + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, DialogRes, Buttons, + ExtCtrls, StdCtrls, LCLType, Windows; type @@ -41,6 +42,18 @@ function CenteredMessageDlg(const AForm: TForm; const AMsg: String; ADlgType: TM RS_DialogConfirmation = 'Confirmation'; RS_DialogCustom = 'Message'; + RS_DialogButtonYes = 'Yes'; + RS_DialogButtonNo = 'No'; + RS_DialogButtonOK = 'OK'; + RS_DialogButtonCancel = 'Cancel'; + RS_DialogButtonAbort = 'Abort'; + RS_DialogButtonRetry = 'Retry'; + RS_DialogButtonIgnore = 'Ignore'; + RS_DialogButtonAll = 'All'; + RS_DialogButtonNoAll = 'No to All'; + RS_DialogButtonYesAll = 'Yes to All'; + RS_DialogButtonClose = 'Close'; + implementation uses @@ -80,17 +93,17 @@ function CenteredMessageDlg(const AForm: TForm; const AMsg: String; ADlgType: TM function GetButtonCaption(Button: TMsgDlgBtn): String; begin case Button of - mbYes: Result := 'Yes'; - mbNo: Result := 'No'; - mbOK: Result := 'OK'; - mbCancel: Result := 'Cancel'; - mbAbort: Result := 'Abort'; - mbRetry: Result := 'Retry'; - mbIgnore: Result := 'Ignore'; - mbAll: Result := 'All'; - mbNoToAll: Result := 'No to All'; - mbYesToAll: Result := 'Yes to All'; - mbClose: Result := 'Close'; + mbYes: Result := RS_DialogButtonYes; + mbNo: Result := RS_DialogButtonNo; + mbOK: Result := RS_DialogButtonOK; + mbCancel: Result := RS_DialogButtonCancel; + mbAbort: Result := RS_DialogButtonAbort; + mbRetry: Result := RS_DialogButtonRetry; + mbIgnore: Result := RS_DialogButtonIgnore; + mbAll: Result := RS_DialogButtonAll; + mbYesToAll: Result := RS_DialogButtonYesAll; + mbNoToAll: Result := RS_DialogButtonNoAll; + mbClose: Result := RS_DialogButtonClose; else Result := ''; end; @@ -107,8 +120,8 @@ function GetButtonResult(Button: TMsgDlgBtn): TModalResult; mbRetry: Result := mrRetry; mbIgnore: Result := mrIgnore; mbAll: Result := mrAll; - mbNoToAll: Result := mrNoToAll; mbYesToAll: Result := mrYesToAll; + mbNoToAll: Result := mrNoToAll; mbClose: Result := mrClose; else Result := mrNone; @@ -132,57 +145,59 @@ procedure TCustomMessageDlg.FormCreate(Sender: TObject); procedure TCustomMessageDlg.CreateButtons(AButtons: TMsgDlgButtons); const - ButtonWidth = 75; - ButtonHeight = 25; - ButtonSpacing = 10; + ButtonWidthMin = 70; + ButtonWidthMax = 100; + ButtonHeightMin = 25; + ButtonHeightMax = 30; + ButtonPadding = 7; var BitBtn: TBitBtn; - LeftPos, ButtonCount, TotalWidth: Integer; + LeftPos, ButtonWidth, ButtonHeight: Integer; BtnKind: TMsgDlgBtn; begin - // Calculate the number of buttons and total width - ButtonCount := 0; - for BtnKind := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do - begin - if BtnKind in AButtons then - begin - Inc(ButtonCount); - end; - end; - - TotalWidth := (ButtonWidth * ButtonCount) + (ButtonSpacing * (ButtonCount - 1)); + ButtonWidth := 0; + ButtonHeight := 0; + pnlButtons.Height := ButtonHeightMax + (ButtonPadding * 2); - // Calculate the starting position for the buttons - LeftPos := (pnlButtons.Width - TotalWidth) div 2; + // Starting position for the buttons + LeftPos := ButtonPadding; // Create buttons dynamically based on AButtons for BtnKind := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do begin - if BtnKind in AButtons then + if not (BtnKind in AButtons) then begin - BitBtn := TBitBtn.Create(Self); - BitBtn.Parent := pnlButtons; - BitBtn.Caption := GetButtonCaption(BtnKind); - BitBtn.ModalResult := GetButtonResult(BtnKind); - BitBtn.Width := ButtonWidth; - BitBtn.Height := ButtonHeight; - BitBtn.Left := LeftPos; - BitBtn.Top := (pnlButtons.Height - ButtonHeight) div 2; - BitBtn.Images := MainForm.IconSmall; - - case BtnKind of - mbYes: BitBtn.ImageIndex := 2; - mbNo: BitBtn.ImageIndex := 1; - mbOK: BitBtn.ImageIndex := 2; - mbCancel: BitBtn.ImageIndex := 1; - mbAbort: BitBtn.ImageIndex := 1; - mbRetry: BitBtn.ImageIndex := 2; - mbIgnore: BitBtn.ImageIndex := 1; - end; - - LeftPos := LeftPos + ButtonWidth + ButtonSpacing; + Continue; + end; + + BitBtn := TBitBtn.Create(Self); + BitBtn.Parent := pnlButtons; + BitBtn.Caption := GetButtonCaption(BtnKind); + BitBtn.ModalResult := GetButtonResult(BtnKind); + BitBtn.Constraints.MinWidth := ButtonWidthMin; + BitBtn.Constraints.MaxWidth := ButtonWidthMax; + BitBtn.Constraints.MinHeight := ButtonHeightMin; + BitBtn.Constraints.MaxHeight := ButtonHeightMax; + BitBtn.Images := MainForm.IconSmall; + + case BtnKind of + mbYes: BitBtn.ImageIndex := 2; + mbNo: BitBtn.ImageIndex := 1; + mbOK: BitBtn.ImageIndex := 2; + mbCancel: BitBtn.ImageIndex := 1; + mbAbort: BitBtn.ImageIndex := 1; + mbRetry: BitBtn.ImageIndex := 2; + mbIgnore: BitBtn.ImageIndex := 1; end; + + BitBtn.GetPreferredSize(ButtonWidth, ButtonHeight); + BitBtn.Left := LeftPos; + BitBtn.Top := (pnlButtons.Height - ButtonHeight) div 2; + + LeftPos := LeftPos + ButtonWidth + ButtonPadding; end; + + pnlButtons.Width := LeftPos; end; procedure TCustomMessageDlg.SetIcon(ADlgType: TMsgDlgType); @@ -213,6 +228,7 @@ class function TCustomMessageDlg.ShowDlg(const AForm: TForm; const ACaption, AMs // Create buttons dynamically Dlg.CreateButtons(AButtons); + Dlg.Width := Max(Dlg.Width, Dlg.pnlButtons.Width); // Center the dialog on the provided form Dlg.Position := poDesigned; From e7aef6cb685123f90bddf2f8a482f738d8917e88 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Fri, 27 Mar 2026 00:17:09 +0800 Subject: [PATCH 29/35] Fixed: Update list not working with new database interactions Fixed: Code cleanup again --- baseunits/DBDataProcess.pas | 21 ++- baseunits/uGetMangaInfosThread.pas | 2 +- baseunits/uUpdateThread.pas | 5 +- mangadownloader/forms/frmMain.pas | 217 ++++++++++++++++++++--------- 4 files changed, 173 insertions(+), 72 deletions(-) diff --git a/baseunits/DBDataProcess.pas b/baseunits/DBDataProcess.pas index f3f1feb2b..e39915304 100644 --- a/baseunits/DBDataProcess.pas +++ b/baseunits/DBDataProcess.pas @@ -107,9 +107,11 @@ TDBDataProcess = class(TObject) function CheckData(const Link, AField: String): TField; function ExistsData(const Link: String): Boolean; function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; - NumChapter, JDN: Integer): Boolean; overload; + NumChapter, JDN: Integer; ExitExists: Boolean): Boolean; overload; function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; NumChapter: Integer; JDN: TDateTime): Boolean; overload; inline; + function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; + NumChapter: Integer; JDN: TDateTime; ExitExists: Boolean): Boolean; overload; inline; function UpdateData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; NumChapter: Integer; AWebsite: String = ''): Boolean; function DeleteData(const RecIndex: Integer): Boolean; @@ -1164,6 +1166,7 @@ procedure TDBDataProcess.Close; RemoveFilter; FConn.Close; FConn.DatabaseName := ''; + FWebsite := ''; except on E: Exception do SendLogException(Self.ClassName + '[' + Website + '].Close.Error!', E); @@ -1338,7 +1341,7 @@ function TDBDataProcess.ExistsData(const Link: String): Boolean; end; function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, Genres, - Status, Summary: String; NumChapter, JDN: Integer): Boolean; + Status, Summary: String; NumChapter, JDN: Integer; ExitExists: Boolean): Boolean; var sql: String; i: Integer; @@ -1352,6 +1355,11 @@ function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, if ExistsData(Link) then begin + if ExitExists then + begin + Exit; + end; + Result := UpdateData(Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary, NumChapter, FWebsite); Exit; end; @@ -1404,7 +1412,14 @@ function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, Status, Summary: String; NumChapter: Integer; JDN: TDateTime): Boolean; begin Result := AddData(Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary, - NumChapter, DateToJDN(JDN)); + NumChapter, DateToJDN(JDN), False); +end; + +function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, Genres, + Status, Summary: String; NumChapter: Integer; JDN: TDateTime; ExitExists: Boolean): Boolean; +begin + Result := AddData(Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary, + NumChapter, DateToJDN(JDN), ExitExists); end; function TDBDataProcess.UpdateData(const Title, AltTitles, Link, Authors, Artists, Genres, diff --git a/baseunits/uGetMangaInfosThread.pas b/baseunits/uGetMangaInfosThread.pas index fcbdc6ae5..81befee2e 100644 --- a/baseunits/uGetMangaInfosThread.pas +++ b/baseunits/uGetMangaInfosThread.pas @@ -338,7 +338,7 @@ procedure TGetMangaInfosThread.MainThreadShowInfos; ShowInformation; except on E: Exception do - Logger.SendException(Self.ClassName+'.MainThreadShowInfos error!', E); + Logger.SendException(Self.ClassName + '.MainThreadShowInfos error!', E); end; end; end; diff --git a/baseunits/uUpdateThread.pas b/baseunits/uUpdateThread.pas index 6edd1a79f..2dee84042 100644 --- a/baseunits/uUpdateThread.pas +++ b/baseunits/uUpdateThread.pas @@ -262,7 +262,7 @@ procedure TUpdateListThread.GetNamesAndLinks; begin for i := 0 to links.Count - 1 do begin - if FOwner.mainDataProcess.AddData(names[i], '', links[i], '', '', '', '', '', 0, 0) then + if not FOwner.mainDataProcess.existsData(links[i]) then begin FOwner.tempDataProcess.AddData(names[i], '', links[i], '', '', '', '', '', 0, 0); end @@ -841,7 +841,8 @@ procedure TUpdateListManagerThread.Execute; '', '', 0, - Now + Now, + True ); CheckCommit(5000); end; diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 56b07de1a..6a83569a9 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -7181,6 +7181,7 @@ procedure TMainForm.LoadFormInformation; begin SortColumn := ReadInteger(name, 'SortColumn', SortColumn); SortDirection := TSortDirection(ReadInteger(name, 'SortDirection', Integer(SortDirection))); + for i := 0 to Columns.Count - 1 do begin Columns[i].Width := ReadInteger(name, 'Column' + IntToStr(i) + 'Width', Columns[i].Width); @@ -7195,6 +7196,7 @@ procedure TMainForm.LoadFormInformation; MonitorRect: TRect; begin Result := False; + for i := 0 to Screen.MonitorCount - 1 do begin MonitorRect := Screen.Monitors[i].BoundsRect; @@ -7216,9 +7218,13 @@ procedure TMainForm.LoadFormInformation; psInfo.Position := ReadInteger('form', 'MangaInfoSplitter', psInfo.Position); if ReadBool('update', 'AutoCheckFavStartup', True) and ReadBool('update', 'AutoOpenFavStartup', False) then - pcMain.ActivePage := tsFavorites + begin + pcMain.ActivePage := tsFavorites; + end else + begin pcMain.PageIndex := ReadInteger('form', 'pcMainPageIndex', 0); + end; Left := ReadInteger('form', 'MainFormLeft', Left); Top := ReadInteger('form', 'MainFormTop', Top); @@ -7236,7 +7242,8 @@ procedure TMainForm.LoadFormInformation; CurrentFormWidth := Min(Width, Screen.DesktopWidth); CurrentFormHeight := Min(Height, Screen.DesktopHeight); - if Screen.PixelsPerInch > 96 then begin + if Screen.PixelsPerInch > 96 then + begin Width := ScaleScreenTo96(Width); Height := ScaleScreenTo96(Height); psDownloads.Position := ScaleScreenTo96(psDownloads.Position); @@ -7244,9 +7251,14 @@ procedure TMainForm.LoadFormInformation; end; if ReadBool('form', 'MainFormMaximized', False) then - PrevWindowState := wsMaximized + begin + PrevWindowState := wsMaximized; + end else + begin PrevWindowState := wsNormal; + end; + WindowState := PrevWindowState; ToolBarDownload.Visible := ReadBool('view', 'ShowDownloadsToolbar', True); @@ -7256,9 +7268,12 @@ procedure TMainForm.LoadFormInformation; // misc form components if tvDownloadFilter.Items.Count>0 then begin - index:=ReadInteger('general', 'DownloadFilterSelect', 0); - if index>=tvDownloadFilter.Items.Count then - index:=0; + index := ReadInteger('general', 'DownloadFilterSelect', 0); + if index >= tvDownloadFilter.Items.Count then + begin + index := 0; + end; + tvDownloadFilter.Items[index].Selected := True; end; @@ -7293,6 +7308,7 @@ procedure TMainForm.SaveFormInformation; begin WriteInteger(name, 'SortColumn', SortColumn); WriteInteger(name, 'SortDirection', Integer(SortDirection)); + for i := 0 to Columns.Count - 1 do begin WriteInteger(name, 'Column' + IntToStr(i) + 'Width', ScaleFontTo96(Columns[i].Width)); @@ -7346,10 +7362,14 @@ procedure TMainForm.ShowDropTarget(const AShow: Boolean); begin ckDropTarget.Checked := AShow; settingsfile.WriteBool('droptarget', 'Show', AShow); + if AShow then begin if FormDropTarget = nil then + begin Application.CreateForm(TFormDropTarget, FormDropTarget); + end; + frmDropTarget.OnDropChekout := @AddSilentThread; frmDropTarget.FAlphaBlendValue := tbDropTargetOpacity.Position; FormDropTarget.Show; @@ -7357,7 +7377,9 @@ procedure TMainForm.ShowDropTarget(const AShow: Boolean); else begin if Assigned(FormDropTarget) then + begin FormDropTarget.Close; + end; end; end; @@ -7413,14 +7435,17 @@ procedure TMainForm.ApplyLanguage; begin Exit; end; + if cbLanguages.ItemIndex < 0 then begin Exit; end; + if cbLanguages.ItemIndex >= AvailableLanguages.Count then begin Exit; end; + if winBuildNumber < 17763 then begin cbDarkmode.Enabled := False @@ -7445,6 +7470,7 @@ procedure TMainForm.ApplyLanguage; idxOptionCompress := rgOptionCompress.ItemIndex; idxOptionWebPConvertTo := cbWebPSaveAs.ItemIndex; idxOptionWebPPNGLevel := cbPNGCompressionLevel.ItemIndex; + if SimpleTranslator.SetLangByIndex(cbLanguages.ItemIndex) then begin // assign new value @@ -7480,7 +7506,9 @@ procedure TMainForm.ApplyLanguage; // refresh custom option if not isStartup then + begin WebsiteOptionCustomForm.CreateWebsiteOption; + end; end; end; end; @@ -7493,9 +7521,17 @@ procedure TMainForm.OpenWithExternalProgramChapters(const Dir: String; ADir, SDir, s: String; begin Result := ''; - if Filename = '' then Exit; + if Filename = '' then + begin + Exit; + end; + ADir := CorrectPathSys(Dir); - if not DirectoryExistsUTF8(ADir) then Exit; + if not DirectoryExistsUTF8(ADir) then + begin + Exit; + end; + for s in FMDSupportedPackedOutputExt do begin SDir := ChompPathDelim(CorrectPathSys(ADir + Filename)); @@ -7505,11 +7541,14 @@ procedure TMainForm.OpenWithExternalProgramChapters(const Dir: String; Break; end; end; + if Result = '' then begin ADir := CorrectPathSys(ADir + Filename); if DirectoryExistsUTF8(ADir) then - Result := GetLastDir(ADir); + begin + Result := GetLastDir(ADir); + end; end; end; @@ -7519,32 +7558,56 @@ procedure TMainForm.OpenWithExternalProgramChapters(const Dir: String; FindList: TStringList; SearchRec: TSearchRec; begin - if Dir = '' then Exit; + if Dir = '' then + begin + Exit; + end; + ADir := CorrectPathSys(Dir); + if Assigned(Chapters) then + begin if Chapters.Count > 0 then + begin for i := 0 to Chapters.Count - 1 do begin AFilename := FindSupportedOutputExt(ADir, Chapters[i]); + if AFilename <> '' then + begin Break; + end; end; + end; + end; if AFilename = '' then + begin try FindList := TStringList.Create; + if FindFirstUTF8(ADir + '*', faAnyFile and faDirectory, SearchRec) = 0 then + begin repeat FindList.Add(SearchRec.Name); until FindNextUTF8(SearchRec) <> 0; + end; + if FindList.Count >= 3 then - AFilename := FindList.Strings[2] + begin + AFilename := FindList.Strings[2]; + end else + begin AFilename := ''; + end; + FindCloseUTF8(SearchRec); finally FindList.Free; end; + end; + OpenWithExternalProgram(ADir, AFilename); end; @@ -7561,7 +7624,10 @@ procedure TMainForm.OpenWithExternalProgram(const Dir, Filename: String); if Exe <> '' then begin if (Pos(EXPARAM_PATH + EXPARAM_CHAPTER, Params) <> 0) then + begin AParam := PathDelim + AParam; + end; + Params := StringReplace(Params, EXPARAM_PATH, ADir, [rfIgnoreCase, rfReplaceAll]); Params := StringReplace(Params, EXPARAM_CHAPTER, AParam, [rfIgnoreCase, rfReplaceAll]); RunExternalProcess(Exe, Params, True, False); @@ -7569,7 +7635,10 @@ procedure TMainForm.OpenWithExternalProgram(const Dir, Filename: String); else begin if (ADir <> '') and (AParam <> '') then + begin AParam := ADir + PathDelim + AParam; + end; + OpenDocument(AParam); end; end; @@ -7580,8 +7649,11 @@ procedure TMainForm.TransferRateGraphInit(xCount: Integer); begin TransferRateGraphList.Clear; TransferRateGraphArea.Legend.Format := FormatByteSize(0, True); - for i:=1 to xCount do - TransferRateGraphList.DataPoints.Add(IntToStr(i)+'|0|?|'); + + for i := 1 to xCount do + begin + TransferRateGraphList.DataPoints.Add(IntToStr(i) + '|0|?|'); + end; end; procedure TMainForm.TransferRateGraphAddItem(TransferRate: Integer); @@ -7589,22 +7661,31 @@ procedure TMainForm.TransferRateGraphAddItem(TransferRate: Integer); i: Integer; begin TransferRateGraphArea.Legend.Format := FormatByteSize(TransferRate, True); + with TransferRateGraphList.DataPoints do begin for i := 0 to Count - 2 do - Strings[i] := IntToStr(i+1)+'|'+ValueFromIndex[i+1]; - Strings[Count-1] := IntToStr(Count)+'|'+IntToStr(TransferRate)+'|?|'; + begin + Strings[i] := IntToStr(i + 1) + '|' + ValueFromIndex[i + 1]; + end; + + Strings[Count - 1] := IntToStr(Count) + '|' + IntToStr(TransferRate) + '|?|'; end; end; procedure TMainForm.DoExitWaitCounter; begin - Logger.Send(Self.ClassName+', Execute exit counter'); - if isUpdating then begin - Logger.Send(Self.ClassName+', Update thread still exist, pending exit counter'); - isPendingExitCounter:=True + Logger.Send(Self.ClassName + ', Execute exit counter'); + + if isUpdating then + begin + Logger.Send(Self.ClassName + ', Update thread still exist, pending exit counter'); + isPendingExitCounter := True end - else tmExitCommand.Enabled:=True; + else + begin + tmExitCommand.Enabled := True; + end; end; procedure TMainForm.ExceptionHandler(Sender: TObject; E: Exception); @@ -7676,67 +7757,71 @@ procedure TMainForm.vtMangaListResetList(ANodeIndex: Integer; ALink, AModuleID: WaitForOpenDataDB; UpdateVtMangaListFilterStatus; - - if (ANodeIndex < 0) or (ALink = '') then - begin - Exit; - end; vtMangaList.BeginUpdate; - totalNodes := vtMangaList.RootNodeCount; - - if (ANodeIndex < totalNodes) then - begin - // Smart traversal - if ANodeIndex < totalNodes div 2 then + try + totalNodes := vtMangaList.RootNodeCount; + if totalNodes = 0 then begin - // Near beginning - go forward - nextNode := vtMangaList.GetFirst; - CheckNode(nextNode, newNode, ALink); + Exit; + end; - for i := 0 to Min(totalNodes - 1, ANodeIndex) do + if (ANodeIndex < 0) or (ALink = '') then + begin + newNode := vtMangaList.GetFirst; + end + else if (ANodeIndex < totalNodes) then + begin + // Smart traversal + if ANodeIndex < totalNodes div 2 then begin - if not Assigned(nextNode) then + // Near beginning - go forward + nextNode := vtMangaList.GetFirst; + CheckNode(nextNode, newNode, ALink); + + for i := 0 to Min(totalNodes - 1, ANodeIndex) do begin - Break; - end; + if not Assigned(nextNode) then + begin + Break; + end; - nextNode := vtMangaList.GetNext(nextNode); + nextNode := vtMangaList.GetNext(nextNode); + CheckNode(nextNode, newNode, ALink); + end; + end + else + begin + // Near end - go backward + nextNode := vtMangaList.GetLast; CheckNode(nextNode, newNode, ALink); - end; - end - else - begin - // Near end - go backward - nextNode := vtMangaList.GetLast; - CheckNode(nextNode, newNode, ALink); - for i := 0 to (totalNodes - ANodeIndex) do - begin - if not Assigned(nextNode) then + for i := 0 to (totalNodes - ANodeIndex) do begin - Break; - end; + if not Assigned(nextNode) then + begin + Break; + end; - nextNode := vtMangaList.GetPrevious(nextNode); - CheckNode(nextNode, newNode, ALink); + nextNode := vtMangaList.GetPrevious(nextNode); + CheckNode(nextNode, newNode, ALink); + end; end; + end + else + begin + newNode := vtMangaList.GetLast end; - end - else - begin - newNode := vtMangaList.GetLast - end; - - if Assigned(newNode) then - begin - vtMangaList.Selected[newNode] := True; - vtMangaList.FocusedNode := newNode; - vtMangaList.ScrollIntoView(newNode, True); + if Assigned(newNode) then + begin + vtMangaList.Selected[newNode] := True; + vtMangaList.FocusedNode := newNode; + vtMangaList.ScrollIntoView(newNode, True); + end; + finally + vtMangaList.EndUpdate; end; - - vtMangaList.EndUpdate; end; procedure TMainForm.vtOptionMangaSiteSelectionFreeNode( From a60ca7ea97b4637b61f849bbdccd6b7f9c89facb Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Fri, 27 Mar 2026 23:49:06 +0800 Subject: [PATCH 30/35] Fixed: Custom message dialog buttons not properly auto sizing Changed: Custom message dialog button panel to be hidden --- mangadownloader/forms/frmcustommessagedlg.lfm | 1 + mangadownloader/forms/frmcustommessagedlg.pas | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mangadownloader/forms/frmcustommessagedlg.lfm b/mangadownloader/forms/frmcustommessagedlg.lfm index 3fc4b45d5..b80545cec 100644 --- a/mangadownloader/forms/frmcustommessagedlg.lfm +++ b/mangadownloader/forms/frmcustommessagedlg.lfm @@ -36,6 +36,7 @@ object CustomMessageDlg: TCustomMessageDlg Width = 50 Anchors = [akLeft, akBottom] BorderSpacing.Top = 10 + BevelOuter = bvNone TabOrder = 0 end object lblMessage: TLabel diff --git a/mangadownloader/forms/frmcustommessagedlg.pas b/mangadownloader/forms/frmcustommessagedlg.pas index 7d5bc03e7..8ce3ce2b6 100644 --- a/mangadownloader/forms/frmcustommessagedlg.pas +++ b/mangadownloader/forms/frmcustommessagedlg.pas @@ -100,9 +100,9 @@ function GetButtonCaption(Button: TMsgDlgBtn): String; mbAbort: Result := RS_DialogButtonAbort; mbRetry: Result := RS_DialogButtonRetry; mbIgnore: Result := RS_DialogButtonIgnore; - mbAll: Result := RS_DialogButtonAll; - mbYesToAll: Result := RS_DialogButtonYesAll; + mbAll: Result := RS_DialogButtonAll; mbNoToAll: Result := RS_DialogButtonNoAll; + mbYesToAll: Result := RS_DialogButtonYesAll; mbClose: Result := RS_DialogButtonClose; else Result := ''; @@ -120,8 +120,8 @@ function GetButtonResult(Button: TMsgDlgBtn): TModalResult; mbRetry: Result := mrRetry; mbIgnore: Result := mrIgnore; mbAll: Result := mrAll; - mbYesToAll: Result := mrYesToAll; mbNoToAll: Result := mrNoToAll; + mbYesToAll: Result := mrYesToAll; mbClose: Result := mrClose; else Result := mrNone; @@ -146,7 +146,7 @@ procedure TCustomMessageDlg.FormCreate(Sender: TObject); procedure TCustomMessageDlg.CreateButtons(AButtons: TMsgDlgButtons); const ButtonWidthMin = 70; - ButtonWidthMax = 100; + ButtonWidthMax = 125; ButtonHeightMin = 25; ButtonHeightMax = 30; ButtonPadding = 7; @@ -171,6 +171,7 @@ procedure TCustomMessageDlg.CreateButtons(AButtons: TMsgDlgButtons); end; BitBtn := TBitBtn.Create(Self); + BitBtn.AutoSize := True; BitBtn.Parent := pnlButtons; BitBtn.Caption := GetButtonCaption(BtnKind); BitBtn.ModalResult := GetButtonResult(BtnKind); @@ -189,7 +190,8 @@ procedure TCustomMessageDlg.CreateButtons(AButtons: TMsgDlgButtons); mbRetry: BitBtn.ImageIndex := 2; mbIgnore: BitBtn.ImageIndex := 1; end; - + + BitBtn.HandleNeeded; BitBtn.GetPreferredSize(ButtonWidth, ButtonHeight); BitBtn.Left := LeftPos; BitBtn.Top := (pnlButtons.Height - ButtonHeight) div 2; From c18a24fc5efecae9a71df209f31c4628ae92179b Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Sat, 28 Mar 2026 09:39:58 +0800 Subject: [PATCH 31/35] Changed: Custom message dialog button minimum --- mangadownloader/forms/frmcustommessagedlg.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mangadownloader/forms/frmcustommessagedlg.pas b/mangadownloader/forms/frmcustommessagedlg.pas index 8ce3ce2b6..1ceff1cdf 100644 --- a/mangadownloader/forms/frmcustommessagedlg.pas +++ b/mangadownloader/forms/frmcustommessagedlg.pas @@ -147,7 +147,7 @@ procedure TCustomMessageDlg.CreateButtons(AButtons: TMsgDlgButtons); const ButtonWidthMin = 70; ButtonWidthMax = 125; - ButtonHeightMin = 25; + ButtonHeightMin = 26; ButtonHeightMax = 30; ButtonPadding = 7; var From 85bf93df12a744a8b89dacc350d81fc86cc08506 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Sat, 28 Mar 2026 10:21:35 +0800 Subject: [PATCH 32/35] Changed: Apply options button to show saved text for a second when apply --- languages/fmd.de.po | 4 ++++ languages/fmd.el_GR.po | 4 ++++ languages/fmd.en.po | 4 ++++ languages/fmd.es.po | 4 ++++ languages/fmd.fr.po | 4 ++++ languages/fmd.id_ID.po | 4 ++++ languages/fmd.pl_PL.po | 4 ++++ languages/fmd.pot | 4 ++++ languages/fmd.pt_BR.po | 4 ++++ languages/fmd.ru_RU.po | 4 ++++ languages/fmd.tr_TR.po | 4 ++++ languages/fmd.zh.po | 4 ++++ mangadownloader/forms/frmMain.pas | 33 +++++++++++++++++++++++++++++++ 13 files changed, 81 insertions(+) diff --git a/languages/fmd.de.po b/languages/fmd.de.po index 5b47189d2..b969dafbc 100644 --- a/languages/fmd.de.po +++ b/languages/fmd.de.po @@ -332,6 +332,10 @@ msgstr "%s Update*" msgid "All downloads" msgstr "Alle Downloads" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.el_GR.po b/languages/fmd.el_GR.po index 11f1680dd..e4cd91ef8 100644 --- a/languages/fmd.el_GR.po +++ b/languages/fmd.el_GR.po @@ -331,6 +331,10 @@ msgstr "" msgid "All downloads" msgstr "Όλες οι λήψεις" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.en.po b/languages/fmd.en.po index 231f3a049..f2d2feabd 100644 --- a/languages/fmd.en.po +++ b/languages/fmd.en.po @@ -337,6 +337,10 @@ msgstr "%s UPDATE*" msgid "All downloads" msgstr "All downloads" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.es.po b/languages/fmd.es.po index 7ddd90edf..d4eeaf1d6 100644 --- a/languages/fmd.es.po +++ b/languages/fmd.es.po @@ -332,6 +332,10 @@ msgstr "%s ACTUALIZAR*" msgid "All downloads" msgstr "Todas las descargas" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.fr.po b/languages/fmd.fr.po index 20199ffd8..62bc85065 100644 --- a/languages/fmd.fr.po +++ b/languages/fmd.fr.po @@ -334,6 +334,10 @@ msgstr "%s MISE À JOUR*" msgid "All downloads" msgstr "Tous les téléchargements" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.id_ID.po b/languages/fmd.id_ID.po index fdc1fb1d0..99c5e3b93 100644 --- a/languages/fmd.id_ID.po +++ b/languages/fmd.id_ID.po @@ -341,6 +341,10 @@ msgstr "%s PEMUTAKHIRAN*" msgid "All downloads" msgstr "Semua unduhan" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.pl_PL.po b/languages/fmd.pl_PL.po index 6151624cb..f07ee4f1c 100644 --- a/languages/fmd.pl_PL.po +++ b/languages/fmd.pl_PL.po @@ -328,6 +328,10 @@ msgstr "" msgid "All downloads" msgstr "Wszystkie pobrania" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.pot b/languages/fmd.pot index aa45bf516..e304859bf 100644 --- a/languages/fmd.pot +++ b/languages/fmd.pot @@ -309,6 +309,10 @@ msgstr "" msgid "All downloads" msgstr "" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.pt_BR.po b/languages/fmd.pt_BR.po index ede99163c..8fa92961b 100644 --- a/languages/fmd.pt_BR.po +++ b/languages/fmd.pt_BR.po @@ -331,6 +331,10 @@ msgstr "%s ATUALIZAR*" msgid "All downloads" msgstr "Todos os downloads" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.ru_RU.po b/languages/fmd.ru_RU.po index ec36fef85..6bb091299 100644 --- a/languages/fmd.ru_RU.po +++ b/languages/fmd.ru_RU.po @@ -331,6 +331,10 @@ msgstr "%s ОБНОВЛЕН*" msgid "All downloads" msgstr "Все загрузки" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.tr_TR.po b/languages/fmd.tr_TR.po index 278f7748c..36f8e1923 100644 --- a/languages/fmd.tr_TR.po +++ b/languages/fmd.tr_TR.po @@ -333,6 +333,10 @@ msgstr "%s GÜNCELLENDİ*" msgid "All downloads" msgstr "Tüm indirmeler" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/languages/fmd.zh.po b/languages/fmd.zh.po index 1a992edf7..01823d103 100644 --- a/languages/fmd.zh.po +++ b/languages/fmd.zh.po @@ -331,6 +331,10 @@ msgstr "%s 更新*" msgid "All downloads" msgstr "所有下载" +#: frmmain.rs_applybuttonsaved +msgid "Saved!" +msgstr "" + #: frmmain.rs_btnok msgctxt "frmmain.rs_btnok" msgid "&OK" diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 6a83569a9..17713205d 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -536,6 +536,8 @@ TMainForm = class(TForm) procedure btDownloadClick(Sender: TObject); procedure btFavoritesCheckNewChapterClick(Sender: TObject); procedure btOptionApplyClick(Sender: TObject); + procedure OptionButtonSavedText; + procedure OptionButtonRestoreText(Sender: TObject); procedure btFilterClick(Sender: TObject); procedure btFilterResetClick(Sender: TObject); @@ -716,6 +718,8 @@ TMainForm = class(TForm) var CellText: String); procedure DisableAddToFavorites(const AModule: Pointer); private + FApplyButtonText: String; + FApplyButtonTimer: TTimer; PrevWindowState: TWindowState; procedure vtDownloadMoveItems(NextIndex : Cardinal; Mode : TDropMode); protected @@ -986,6 +990,7 @@ TMangaInfoData = record RS_Checking = 'Checking...'; RS_AllDownloads = 'All downloads'; RS_InProgress = 'In progress'; + RS_ApplyButtonSaved = 'Saved!'; RS_History = 'History'; RS_Today = 'Today'; @@ -5539,6 +5544,32 @@ procedure TMainForm.vtMangaListColumnDblClick(Sender: TBaseVirtualTree; // options +procedure TMainForm.OptionButtonSavedText; +begin + if (FApplyButtonTimer <> nil) and FApplyButtonTimer.Enabled then + begin + OptionButtonRestoreText(FApplyButtonTimer); + end; + + FApplyButtonText := btOptionApply.Caption; + btOptionApply.Caption := RS_ApplyButtonSaved; + + if FApplyButtonTimer = nil then + begin + FApplyButtonTimer := TTimer.Create(nil); + FApplyButtonTimer.Interval := 1000; + FApplyButtonTimer.OnTimer := @OptionButtonRestoreText; + end; + + FApplyButtonTimer.Enabled := True; +end; + +procedure TMainForm.OptionButtonRestoreText(Sender: TObject); +begin + btOptionApply.Caption := FApplyButtonText; + FApplyButtonTimer.Enabled := False; +end; + procedure TMainForm.btOptionApplyClick(Sender: TObject); var oldOptionMaxParallel: Integer; @@ -5556,6 +5587,8 @@ procedure TMainForm.btOptionApplyClick(Sender: TObject); begin Self.SetFocus; end; + + OptionButtonSavedText; end; // vtMangaList From 3cbf2e49ff8bd61c1686eba9e9728922b5327378 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Mon, 6 Apr 2026 23:30:00 +0800 Subject: [PATCH 33/35] Fixed: Excessive database calls while searching Fixed: More code clean up and readability --- baseunits/DBDataProcess.pas | 336 +++++++++++++++++------------- mangadownloader/forms/frmMain.pas | 42 +--- 2 files changed, 192 insertions(+), 186 deletions(-) diff --git a/baseunits/DBDataProcess.pas b/baseunits/DBDataProcess.pas index e39915304..5d88ce590 100644 --- a/baseunits/DBDataProcess.pas +++ b/baseunits/DBDataProcess.pas @@ -19,6 +19,25 @@ TFieldValuePair = record Value: String; end; + { TMangaInfoData } + + PMangaInfoData = ^TMangaInfoData; + + TMangaInfoData = record + Module: Pointer; + Link, + Title, + AltTitles, + TitleFormat, + Authors, + Artists, + Genres, + Status, + Summary: String; + NumChapter, + JDN: Integer; + end; + { TDBDataProcess } TDBDataProcess = class(TObject) @@ -82,6 +101,7 @@ TDBDataProcess = class(TObject) function TableExist(const ATableName: String): Boolean; function RegexEscapeInput(const Input: String): String; function RegexEscapeAltTitles(const ATitle: String): String; + procedure SearchUnionSQL(ATitle: String); function Search(ATitle: String): Boolean; function CanFilter(const checkedGenres, uncheckedGenres: TStringList; const stTitle, stAuthors, stArtists, stStatus, stSummary: String; @@ -118,7 +138,9 @@ TDBDataProcess = class(TObject) procedure Commit; procedure Rollback; procedure RemoveFilter; - procedure Sort; + procedure Sort; + + procedure GetCurrentRecordValues(out Data: TMangaInfoData); function GetModule(const RecIndex: Integer): Pointer; function GoToRecNo(const ARecIndex: Integer): Boolean; @@ -312,43 +334,33 @@ procedure TDBDataProcess.ResetRecNo(Dataset: TDataSet); end; function TDBDataProcess.GoToRecNo(const ARecIndex: Integer): Boolean; -begin +begin + Result := False; + + if not FReadQuery.Active then + begin + Exit; + end; + if FReadQuery.RecNo = ARecIndex + 1 then begin Exit(True); end; - Result := False; - GetRecordCount; - if ARecIndex > RecordCount then + if (FRecordCount = 0) or ((FRecordCount > 0) and (ARecIndex >= FRecordCount)) then begin - Exit; + GetRecordCount; end; - if not FReadQuery.Active then + if (ARecIndex < 0) or (ARecIndex >= FRecordCount) then begin Exit; end; try - // Save current position - FReadQuery.DisableControls; - try - FReadQuery.First; - - if ARecIndex > 0 then - begin - FReadQuery.MoveBy(ARecIndex); - end; - - if not FReadQuery.EOF then - begin - FRecNo := ARecIndex; - Result := True; - end; - finally - FReadQuery.EnableControls; - end; + FReadQuery.RecNo := ARecIndex + 1; + FRecNo := ARecIndex; + Result := True; except on E: Exception do begin @@ -357,6 +369,32 @@ function TDBDataProcess.GoToRecNo(const ARecIndex: Integer): Boolean; end; end; +procedure TDBDataProcess.GetCurrentRecordValues(out Data: TMangaInfoData); +begin + Data.Link := FReadQuery.Fields[DATA_PARAM_LINK].AsString; + Data.Title := FReadQuery.Fields[DATA_PARAM_TITLE].AsString; + Data.AltTitles := FReadQuery.Fields[DATA_PARAM_ALTTITLES].AsString; + Data.Authors := FReadQuery.Fields[DATA_PARAM_AUTHORS].AsString; + Data.Artists := FReadQuery.Fields[DATA_PARAM_ARTISTS].AsString; + Data.Genres := FReadQuery.Fields[DATA_PARAM_GENRES].AsString; + Data.Status := FReadQuery.Fields[DATA_PARAM_STATUS].AsString; + Data.NumChapter := FReadQuery.Fields[DATA_PARAM_NUMCHAPTER].AsInteger; + Data.JDN := FReadQuery.Fields[DATA_PARAM_JDN].AsInteger; + Data.Summary := FReadQuery.Fields[DATA_PARAM_SUMMARY].AsString; + + Data.TitleFormat := Data.Title + ' (' + IntToStr(Data.NumChapter) + ')'; + + if FFilterAllSites then + begin + Data.Module := GetModule(FRecNo); + Data.TitleFormat += ' [' + TModuleContainer(Data.Module).Name + ']'; + end + else + begin + Data.Module := FModule; + end; +end; + procedure TDBDataProcess.CreateTable; begin if not FConn.Connected then @@ -466,23 +504,27 @@ procedure TDBDataProcess.GetRecordCount; end; procedure TDBDataProcess.AddSQLCond(const sqltext: String; useOR: Boolean); +var + sqlAndOr: String; begin with FReadQuery.SQL do begin - if Count > 0 then + if Count <= 0 then + begin + Add(sqltext); + Exit; + end; + + if (Strings[Count - 1] <> '(') and + (UpCase(Trim(Strings[Count - 1])) <> 'WHERE') then begin - if (Strings[Count - 1] <> '(') and - (UpCase(Trim(Strings[Count - 1])) <> 'WHERE') then + sqlAndOr := 'AND'; + if useOR then begin - if useOR then - begin - Add('OR'); - end - else - begin - Add('AND'); - end; + sqlAndOr := 'OR'; end; + + Add(sqlAndOr); end; Add(sqltext); @@ -492,43 +534,50 @@ procedure TDBDataProcess.AddSQLCond(const sqltext: String; useOR: Boolean); procedure TDBDataProcess.AddSQLSimpleFilter(const fieldname, Value: String; useNOT: Boolean; useOR: Boolean; useRegexp: Boolean); var - svalue: String; - scond: String; + srchCondNot, srchCondRegLike, srchValue: String; begin - svalue := LowerCase(Trim(Value)); + srchValue := LowerCase(Trim(Value)); - if (fieldname = '') or (svalue = '') then + if (fieldname = '') or (srchValue = '') then begin Exit; end; - + + srchCondNot := ''; if useNOT then begin - scond := ' NOT'; - end - else - begin - scond := ''; + srchCondNot := ' NOT'; end; + srchCondRegLike := 'LIKE'; if useRegexp then begin - AddSQLCond('LOWER("' + fieldname + '")' + scond + ' REGEXP ' + QuotedStr(svalue), useOR); - end - else - begin - AddSQLCond('LOWER("' + fieldname + '")' + scond + ' LIKE ' + QuotedLike(svalue), useOR); + srchCondRegLike := 'REGEXP'; end; + + AddSQLCond(Format('LOWER("%s")%s %s LOWER(%s)', [fieldname, srchCondNot, srchCondRegLike, QuotedLike(srchValue)]), useOR); end; procedure TDBDataProcess.AddSQLPairedFilter(const Pairs: array of TFieldValuePair; useNOT, useOR, useRegexp: Boolean); var i: Integer; - scond, svalue, sqlCondition: String; + srchCondNot, srchCondRegLike, srchValue, sqlCondition: String; begin sqlCondition := ''; + srchCondNot := ''; + if useNOT then + begin + srchCondNot := ' NOT'; + end; + + srchCondRegLike := ' LIKE '; + if useRegexp then + begin + srchCondRegLike := ' REGEXP '; + end; + for i := 0 to High(Pairs) do begin if (Pairs[i].Field = '') or (Pairs[i].Value = '') then @@ -536,29 +585,12 @@ procedure TDBDataProcess.AddSQLPairedFilter(const Pairs: array of TFieldValuePai Continue; end; - svalue := LowerCase(Trim(Pairs[i].Value)); - - if useNOT then - begin - scond := ' NOT'; - end - else - begin - scond := ''; - end; - - if useRegexp then - begin - sqlCondition := sqlCondition + 'LOWER("' + Pairs[i].Field + '")' + scond + ' REGEXP ' + QuotedStr(svalue); - end - else - begin - sqlCondition := sqlCondition + 'LOWER("' + Pairs[i].Field + '")' + scond + ' LIKE ' + QuotedLike(svalue); - end; + srchValue := LowerCase(Trim(Pairs[i].Value)); + sqlCondition += Format('LOWER("%s")%s %s LOWER(%s)', [Pairs[i].Field, srchCondNot, srchCondRegLike, QuotedLike(srchValue)]); if i < High(Pairs) then begin - sqlCondition := sqlCondition + ' OR '; // Add OR between pair conditions + sqlCondition += ' OR '; // Add OR between pair conditions end; end; @@ -1618,87 +1650,94 @@ function TDBDataProcess.RegexEscapeAltTitles(const ATitle: String): String; Result := HeadRegex + RegexEscapeInput(ATitle) + TailRegex; end; -function TDBDataProcess.Search(ATitle: String): Boolean; +procedure TDBDataProcess.SearchUnionSQL(ATitle: String); var + NewSQL: TStringList; + sqlTitleSearch: String; i: Integer; - Titles: array[0..1] of TFieldValuePair; begin - if FReadQuery.Active then - begin - Lock; - try - try - FReadQuery.Close; + if FReadQuery.SQL.Count <= 0 then + begin + Exit; + end; - with FReadQuery do - begin - SQL.Clear; - if FFilterApplied then - begin - SQL.AddText(FFilterSQL); - end - else - begin - SQL.Add(FSQLSelect); - end; + sqlTitleSearch := QuotedLike(ATitle); + NewSQL := TStringList.Create(); + for i := 0 to FReadQuery.SQL.Count - 1 do + begin + if (FReadQuery.SQL[i] = 'UNION ALL') or (FReadQuery.SQL[i] = ')') then + begin + NewSQL.Add('AND (LOWER("title") LIKE LOWER(' + sqlTitleSearch + ') OR LOWER("alttitles") LIKE LOWER(' + sqlTitleSearch + '))'); + end; - if ATitle <> '' then - begin - if not FFilterApplied then - begin - SQL.Add('WHERE'); - end; + NewSQL.Add(FReadQuery.SQL[i]); + end; - if FAllSitesAttached then - begin - if SQL.Count > 0 then - begin - i := 0; - while i < SQL.Count do - begin - if (SQL[i] = 'UNION ALL') or (SQL[i] = ')') then - begin - SQL.Insert(i, 'AND'); - SQL.Insert(i + 1, '("title" LIKE ' + QuotedLike(ATitle)); - SQL.Insert(i + 2, 'OR'); - SQL.Insert(i + 3, '"alttitles" LIKE ' + QuotedLike(ATitle) + ')'); - Inc(i, 5); - end - else - begin - Inc(i); - end; - end; - end; - end - else - begin - Titles[0].Field := 'title'; - Titles[0].Value := ATitle; - Titles[1].Field := 'alttitles'; - Titles[1].Value := ATitle; + FReadQuery.SQL.Assign(NewSQL); +end; - AddSQLPairedFilter(Titles); - end; +function TDBDataProcess.Search(ATitle: String): Boolean; +var + Titles: array[0..1] of TFieldValuePair; +begin + Result := True; + FFiltered := FFilterApplied; + FRecordCount := 0; - FFiltered := True; - end - else - begin - FFiltered := FFilterApplied; - end; + if not FReadQuery.Active then + begin + FFiltered := False; + Exit(False); + end; + + Titles[0].Field := 'title'; + Titles[0].Value := ATitle; + Titles[1].Field := 'alttitles'; + Titles[1].Value := ATitle; + + Lock; + try + try + FReadQuery.Close; + FReadQuery.SQL.Clear; + + if FFilterApplied then + begin + FReadQuery.SQL.AddText(FFilterSQL); + end + else + begin + FReadQuery.SQL.Add(FSQLSelect); + end; + + if ATitle <> '' then + begin + if not FFilterApplied then + begin + FReadQuery.SQL.Add('WHERE'); end; - GetRecordCount; - FReadQuery.Open; - except - on E: Exception do - SendLogException(Self.ClassName + '[' + Website + '].Search.Error!'#13#10 + - 'SQL:'#13#10 + FReadQuery.SQL.Text, E); + if FAllSitesAttached then + begin + SearchUnionSQL(ATitle); + end + else + begin + AddSQLPairedFilter(Titles); + end; + + FFiltered := True; end; - finally - Unlock; + + GetRecordCount; + FReadQuery.Open; + except + on E: Exception do + SendLogException(Self.ClassName + '[' + Website + '].Search.Error!'#13#10 + + 'SQL:'#13#10 + FReadQuery.SQL.Text, E); end; + finally + Unlock; end; Result := FReadQuery.Active; @@ -1901,6 +1940,7 @@ procedure TDBDataProcess.CreateDatabase(const AWebsite: String); var filepath: String; begin + filepath := ''; Close; if CheckWebsiteAndFilePath(AWebsite, filepath) then @@ -1943,8 +1983,6 @@ procedure TDBDataProcess.RemoveFilter; end; procedure TDBDataProcess.Sort; -var - queryactive: Boolean; begin if not FConn.Connected then begin @@ -1985,9 +2023,17 @@ function TDBDataProcess.GetModule(const RecIndex: Integer): Pointer; Exit; end; - FReadQuery.RecNo := RecIndex + 1; - i := FReadQuery.Fields[DBTempFieldWebsiteIndex].AsInteger; + try + FReadQuery.RecNo := RecIndex + 1; + FRecNo := RecIndex; + except + on E: Exception do + begin + SendLogException(Self.ClassName + '[' + Website + '].GetModule.Error!', E); + end; + end; + i := FReadQuery.Fields[DBTempFieldWebsiteIndex].AsInteger; if i <> -1 then begin Result := Pointer(FAttachedSites.Objects[i]); diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 17713205d..11d52d9ad 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -898,23 +898,6 @@ TSearchDBThread = class(TThread) procedure NewSearch(const ASearchStr: String); end; - PMangaInfoData = ^TMangaInfoData; - - TMangaInfoData = record - Module: Pointer; - Link, - Title, - AltTitles, - TitleFormat, - Authors, - Artists, - Genres, - Status, - Summary: String; - NumChapter, - JDN: Integer; - end; - var MainForm: TMainForm; TimerBackupInterval: Integer = 10; @@ -7740,30 +7723,7 @@ procedure TMainForm.vtMangaListInitNode(Sender: TBaseVirtualTree; ParentNode, Exit; end; - with data^ do - begin - Link := dataProcess.Value[nodeRecIndex, DATA_PARAM_LINK]; - Title := dataProcess.Value[nodeRecIndex, DATA_PARAM_TITLE]; - AltTitles := dataProcess.Value[nodeRecIndex, DATA_PARAM_ALTTITLES]; - Authors := dataProcess.Value[nodeRecIndex, DATA_PARAM_AUTHORS]; - Artists := dataProcess.Value[nodeRecIndex, DATA_PARAM_ARTISTS]; - Genres := dataProcess.Value[nodeRecIndex, DATA_PARAM_GENRES]; - Status := dataProcess.Value[nodeRecIndex, DATA_PARAM_STATUS]; - NumChapter := dataProcess.ValueInt[nodeRecIndex, DATA_PARAM_NUMCHAPTER]; - JDN := dataProcess.ValueInt[nodeRecIndex, DATA_PARAM_JDN]; - Summary := dataProcess.Value[nodeRecIndex, DATA_PARAM_SUMMARY]; - TitleFormat := Title + ' (' + IntToStr(NumChapter) + ')'; - - if dataProcess.FilterAllSites then - begin - Module := dataProcess.GetModule(nodeRecIndex); - TitleFormat += ' [' + TModuleContainer(Module).Name + ']'; - end - else - begin - Module := dataProcess.Module; - end; - end; + dataprocess.GetCurrentRecordValues(data^); end; procedure TMainForm.vtMangaListResetList(ANodeIndex: Integer; ALink, AModuleID: String); From d3fe1d005c91ce6cb38acbd8b02179a855188504 Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Wed, 8 Apr 2026 12:17:18 +0800 Subject: [PATCH 34/35] Fixed: Forgotten custom colour change between themes --- mangadownloader/forms/frmCustomColor.pas | 63 +++++++++++++----------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/mangadownloader/forms/frmCustomColor.pas b/mangadownloader/forms/frmCustomColor.pas index 3db5bec1d..7130a1925 100644 --- a/mangadownloader/forms/frmCustomColor.pas +++ b/mangadownloader/forms/frmCustomColor.pas @@ -19,7 +19,7 @@ TColorMapping = record TThemeCustomColorManager = class private - FThemeColorMappings: array[0..14] of TColorMapping; + FThemeColorMappings: array[0..15] of TColorMapping; procedure SetColorMapping(Index: Integer; const AName: String; ALight, ADark: TColor); public constructor Create; @@ -432,20 +432,21 @@ constructor TThemeCustomColorManager.Create; begin // Initialize theme color mappings SetColorMapping(0, 'BSDisabled', clBtnShadow, clGrayText); - SetColorMapping(1, 'BSTreeLine', clBtnShadow, clGrayText); - SetColorMapping(2, 'BSUnfocusedSelection', clMedGray, clGray); - SetColorMapping(3, 'BSUnfocusedSelectionBorder', clGray, clMedGray); - SetColorMapping(4, 'BSSortedColumn', CL_BSSortedColumn, CL_BSSortedColumnDark); - SetColorMapping(5, 'BSEnabledWebsiteSettings', CL_BSEnabledWebsiteSettings, CL_BSEnabledWebsiteSettingsDark); - SetColorMapping(6, 'MNNewManga', CL_MNNewManga, CL_MNNewMangaDark); - SetColorMapping(7, 'MNCompletedManga', CL_MNCompletedManga, CL_MNCompletedMangaDark); - SetColorMapping(8, 'FVBrokenFavorite', CL_FVBrokenFavorite, CL_FVBrokenFavoriteDark); - SetColorMapping(9, 'FVChecking', CL_FVChecking, CL_FVCheckingDark); - SetColorMapping(10, 'FVNewChapterFound', CL_FVNewChapterFound, CL_FVNewChapterFoundDark); - SetColorMapping(11, 'FVCompletedManga', CL_FVCompletedManga, CL_FVCompletedMangaDark); - SetColorMapping(12, 'FVEmptyChapters', CL_FVEmptyChapters, CL_FVEmptyChaptersDark); - SetColorMapping(13, 'CHDownloaded', CL_CHDownloaded, CL_CHDownloadedDark); - SetColorMapping(14, 'MDNewUpdate', CL_MDNewUpdate, CL_MDNewUpdateDark); + SetColorMapping(1, 'BSGridLine', clBtnShadow, clGrayText); + SetColorMapping(2, 'BSTreeLine', clBtnShadow, clGrayText); + SetColorMapping(3, 'BSUnfocusedSelection', clMedGray, clGray); + SetColorMapping(4, 'BSUnfocusedSelectionBorder', clGray, clMedGray); + SetColorMapping(5, 'BSSortedColumn', CL_BSSortedColumn, CL_BSSortedColumnDark); + SetColorMapping(6, 'BSEnabledWebsiteSettings', CL_BSEnabledWebsiteSettings, CL_BSEnabledWebsiteSettingsDark); + SetColorMapping(7, 'MNNewManga', CL_MNNewManga, CL_MNNewMangaDark); + SetColorMapping(8, 'MNCompletedManga', CL_MNCompletedManga, CL_MNCompletedMangaDark); + SetColorMapping(9, 'FVBrokenFavorite', CL_FVBrokenFavorite, CL_FVBrokenFavoriteDark); + SetColorMapping(10, 'FVChecking', CL_FVChecking, CL_FVCheckingDark); + SetColorMapping(11, 'FVNewChapterFound', CL_FVNewChapterFound, CL_FVNewChapterFoundDark); + SetColorMapping(12, 'FVCompletedManga', CL_FVCompletedManga, CL_FVCompletedMangaDark); + SetColorMapping(13, 'FVEmptyChapters', CL_FVEmptyChapters, CL_FVEmptyChaptersDark); + SetColorMapping(14, 'CHDownloaded', CL_CHDownloaded, CL_CHDownloadedDark); + SetColorMapping(15, 'MDNewUpdate', CL_MDNewUpdate, CL_MDNewUpdateDark); end; procedure TThemeCustomColorManager.SetColorMapping(Index: Integer; const AName: String; ALight, ADark: TColor); @@ -459,34 +460,38 @@ function TThemeCustomColorManager.CheckDefaultCustomColors(const AName: String; var i: Integer; begin - Result := AColor; // Default to custom color + Result := AColor; for i := Low(FThemeColorMappings) to High(FThemeColorMappings) do begin - if (AName = FThemeColorMappings[i].Name) then + if (AName <> FThemeColorMappings[i].Name) then begin - if IsDarkModeEnabled then + Continue; + end; + + if IsDarkModeEnabled then + begin + if AColor = FThemeColorMappings[i].Light then begin - if AColor = FThemeColorMappings[i].Light then - begin - Result := FThemeColorMappings[i].Dark; - end; - end - else + Result := FThemeColorMappings[i].Dark; + end; + end + else + begin + if AColor = FThemeColorMappings[i].Dark then begin - if AColor = FThemeColorMappings[i].Dark then - begin - Result := FThemeColorMappings[i].Light; - end; + Result := FThemeColorMappings[i].Light; end; - Exit; // Exit early once found end; + + Exit; end; end; procedure TThemeCustomColorManager.CheckListColors; begin BasicListColors[2] := CheckDefaultCustomColors('BSDisabled', BasicListColors[2]); + BasicListColors[8] := CheckDefaultCustomColors('BSGridLine', BasicListColors[8]); BasicListColors[13] := CheckDefaultCustomColors('BSTreeLine', BasicListColors[13]); BasicListColors[14] := CheckDefaultCustomColors('BSUnfocusedSelection', BasicListColors[14]); BasicListColors[15] := CheckDefaultCustomColors('BSUnfocusedSelectionBorder', BasicListColors[15]); From ecdc63dd8a8d87d7634df03b140748881c85684b Mon Sep 17 00:00:00 2001 From: NhKPaNdA Date: Mon, 13 Apr 2026 04:23:48 +0800 Subject: [PATCH 35/35] Fixed: Sorting and Vacuuming manga list db when updating on view info --- baseunits/DBDataProcess.pas | 89 +++++++++++++++++--- baseunits/uData.pas | 15 +++- baseunits/uGetMangaInfosThread.pas | 131 +++++++++++++++-------------- baseunits/uUpdateThread.pas | 2 +- mangadownloader/forms/frmMain.pas | 4 +- 5 files changed, 166 insertions(+), 75 deletions(-) diff --git a/baseunits/DBDataProcess.pas b/baseunits/DBDataProcess.pas index 5d88ce590..b6d4aa1ee 100644 --- a/baseunits/DBDataProcess.pas +++ b/baseunits/DBDataProcess.pas @@ -37,6 +37,18 @@ TMangaInfoData = record NumChapter, JDN: Integer; end; + + { TVacuumThread } + + TDBVacuumThread = class(TThread) + private + FDatabaseFile, + FWebsite: string; + protected + procedure Execute; override; + public + constructor Create(const ADatabaseFile, AWebsite: string); + end; { TDBDataProcess } @@ -52,6 +64,7 @@ TDBDataProcess = class(TObject) FWebsite: String; FTableName: String; FRecordCount: Integer; + FSorted: Boolean; FFiltered: Boolean; FFilterAllSites: Boolean; FFilterApplied: Boolean; @@ -127,11 +140,11 @@ TDBDataProcess = class(TObject) function CheckData(const Link, AField: String): TField; function ExistsData(const Link: String): Boolean; function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; - NumChapter, JDN: Integer; ExitExists: Boolean): Boolean; overload; + NumChapter, JDN: Integer; ExitExistsCheck: Boolean): Boolean; overload; function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; NumChapter: Integer; JDN: TDateTime): Boolean; overload; inline; function AddData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; - NumChapter: Integer; JDN: TDateTime; ExitExists: Boolean): Boolean; overload; inline; + NumChapter: Integer; JDN: TDateTime; ExitExistsCheck: Boolean): Boolean; overload; inline; function UpdateData(Const Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary: String; NumChapter: Integer; AWebsite: String = ''): Boolean; function DeleteData(const RecIndex: Integer): Boolean; @@ -190,7 +203,7 @@ procedure OverwriteDBDataProcess(const AWebsite, NWebsite: String); implementation uses - uBaseUnit, WebsiteModules; + uBaseUnit, WebsiteModules, frmMain; function NaturalCompareCallback({%H-}user: pointer; len1: longint; data1: pointer; len2: longint; data2: pointer): longint; cdecl; @@ -316,6 +329,48 @@ procedure OverwriteDBDataProcess(const AWebsite, NWebsite: String); RenameFile(DATA_FOLDER + NWebsite + DBDATA_EXT, DATA_FOLDER + AWebsite + DBDATA_EXT); end; +{ TDBVacuumThread } + +constructor TDBVacuumThread.Create(const ADatabaseFile, AWebsite: string); +begin + inherited Create(False); + FDatabaseFile := ADatabaseFile; + FWebsite := AWebsite; + FreeOnTerminate := True; +end; + +procedure TDBVacuumThread.Execute; +var + VacuumConn: TSQLite3ConnectionH; + VacuumTrans: TSQLTransaction; +begin + VacuumTrans := TSQLTransaction.Create(nil); + VacuumConn := TSQLite3ConnectionH.Create(nil); + + try + VacuumConn.DatabaseName := FDatabaseFile; + VacuumConn.Transaction := VacuumTrans; + + try + VacuumConn.ExecuteDirect('END TRANSACTION;'); + + try + VacuumConn.ExecuteDirect('VACUUM;'); + finally + VacuumConn.ExecuteDirect('BEGIN TRANSACTION;'); + end; + except + on E: Exception do + begin + SendLogException(Self.ClassName + '[' + FWebsite + '].VacuumTable.Error!', E); + end; + end; + finally + VacuumTrans.Free; + VacuumConn.Free; + end; +end; + { TDBDataProcess } function TDBDataProcess.GetLinkCount: Integer; @@ -920,7 +975,8 @@ constructor TDBDataProcess.Create; FAttachedSites := TStringList.Create; FTableName := 'masterlist'; FSQLSelect := 'SELECT * FROM "' + FTableName + '"'; - FRecordCount := 0; + FRecordCount := 0; + FSorted := False; FFiltered := False; FFilterAllSites := False; FFilterApplied := False; @@ -957,6 +1013,8 @@ constructor TDBDataProcess.Create; end; destructor TDBDataProcess.Destroy; +var + i: Integer; begin try if FConn.Connected then @@ -1185,6 +1243,8 @@ procedure TDBDataProcess.CheckFieldsExist(const ATableName: String); end; procedure TDBDataProcess.Close; +var + databaseName: String; begin FRecordCount := 0; @@ -1193,11 +1253,19 @@ procedure TDBDataProcess.Close; Exit; end; + databaseName := FConn.DatabaseName; try FReadQuery.Close; RemoveFilter; FConn.Close; FConn.DatabaseName := ''; + + if FSorted and MainForm.cbOptionVacuumDatabasesOnExit.Checked then + begin + TDBVacuumThread.Create(databaseName, FWebsite); + end; + + FSorted := False; FWebsite := ''; except on E: Exception do @@ -1373,7 +1441,7 @@ function TDBDataProcess.ExistsData(const Link: String): Boolean; end; function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, Genres, - Status, Summary: String; NumChapter, JDN: Integer; ExitExists: Boolean): Boolean; + Status, Summary: String; NumChapter, JDN: Integer; ExitExistsCheck: Boolean): Boolean; var sql: String; i: Integer; @@ -1387,7 +1455,7 @@ function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, if ExistsData(Link) then begin - if ExitExists then + if ExitExistsCheck then begin Exit; end; @@ -1448,10 +1516,10 @@ function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, end; function TDBDataProcess.AddData(const Title, AltTitles, Link, Authors, Artists, Genres, - Status, Summary: String; NumChapter: Integer; JDN: TDateTime; ExitExists: Boolean): Boolean; + Status, Summary: String; NumChapter: Integer; JDN: TDateTime; ExitExistsCheck: Boolean): Boolean; begin Result := AddData(Title, AltTitles, Link, Authors, Artists, Genres, Status, Summary, - NumChapter, DateToJDN(JDN), ExitExists); + NumChapter, DateToJDN(JDN), ExitExistsCheck); end; function TDBDataProcess.UpdateData(const Title, AltTitles, Link, Authors, Artists, Genres, @@ -1988,7 +2056,9 @@ procedure TDBDataProcess.Sort; begin Exit; end; - + + FSorted := True; + Lock; try with FConn do @@ -2006,7 +2076,6 @@ procedure TDBDataProcess.Sort; end; FTrans.Commit; - VacuumTable; finally Unlock; end; diff --git a/baseunits/uData.pas b/baseunits/uData.pas index 7c579dd69..e3df56de1 100644 --- a/baseunits/uData.pas +++ b/baseunits/uData.pas @@ -36,6 +36,7 @@ TMangaInformation = class(TObject) constructor Create(const AOwnerThread: TBaseThread = nil); destructor Destroy; override; function GetInfoFromURL(const AURL: String): Byte; + function DataExists(const ADataProcess: TDBDataProcess): Boolean; procedure SyncInfoToData(const ADataProcess: TDBDataProcess); overload; procedure AddInfoToData(const ATitle, ALink: String; const ADataProcess: TDBDataProcess); overload; property Thread: TBaseThread read FOwner; @@ -262,6 +263,18 @@ function TMangaInformation.GetInfoFromURL(const AURL: String): Byte; end; end; +function TMangaInformation.DataExists(const ADataProcess: TDBDataProcess): Boolean; +begin + Result := False; + + if not Assigned(ADataProcess) then + begin + Exit; + end; + + Result := ADataProcess.ExistsData(MangaInfo.Link); +end; + procedure TMangaInformation.SyncInfoToData(const ADataProcess: TDBDataProcess); begin if not Assigned(ADataProcess) then @@ -296,7 +309,7 @@ procedure TMangaInformation.AddInfoToData(const ATitle, ALink: String; const ADa with MangaInfo do begin ADataProcess.AddData(Title, AltTitles, Link, Authors, Artists, Genres, Status, - StringBreaks(Summary), NumChapter, Now); + StringBreaks(Summary), NumChapter, Now, True); end; end; diff --git a/baseunits/uGetMangaInfosThread.pas b/baseunits/uGetMangaInfosThread.pas index 81befee2e..d431ab6bf 100644 --- a/baseunits/uGetMangaInfosThread.pas +++ b/baseunits/uGetMangaInfosThread.pas @@ -18,7 +18,7 @@ interface uses SysUtils, LazFileUtils, StrUtils, Graphics, Dialogs, uBaseUnit, uData, Forms, FMDOptions, BaseThread, ImgInfos, webp, MultiLog, MemBitmap, VirtualTrees, - DBDataProcess; + DBDataProcess, WebsiteModules; type @@ -31,12 +31,13 @@ TGetMangaInfosThread = class(TBaseThread) FTitle, FLink: String; FInfo: TMangaInformation; + FModule: TModuleContainer; FNumChapter: Cardinal; FIsHasMangaCover: Boolean; FFillSaveTo: Boolean; protected procedure Execute; override; - procedure MainThreadSyncInfos; + procedure MainThreadSyncAddInfos; procedure MainThreadShowInfos; procedure MainThreadShowCover; procedure MainThreadShowCannotGetInfo; @@ -51,26 +52,76 @@ TGetMangaInfosThread = class(TBaseThread) implementation uses - frmMain, frmCustomMessageDlg, WebsiteModules, FMDVars; + frmMain, frmCustomMessageDlg, FMDVars; -procedure TGetMangaInfosThread.MainThreadSyncInfos; +procedure TGetMangaInfosThread.MainThreadSyncAddInfos; +var + tempDataProcess: TDBDataProcess; + data: PMangaInfoData; + oldModuleID, dataLink: String; + nodeIndex: Integer; begin - FInfo.SyncInfoToData(dataProcess); - dataProcess.Commit; + if (FInfo.MangaInfo.Title = '') or (FInfo.MangaInfo.Link = '') then + begin + Exit; + end; + + tempDataProcess := dataProcess; + oldModuleID := dataProcess.Website; + if oldModuleID <> FModule.ID then + begin + tempDataProcess := TDBDataProcess.Create; + end; + + try + if not tempDataProcess.Connect(FModule.ID) then + begin + Exit; + end; + + if not Assigned(FNode) then + begin + FNode := MainForm.vtMangaList.FocusedNode; + end; + + data := MainForm.vtMangaList.GetNodeData(FNode); + dataLink := ''; + if Assigned(data) then + begin + dataLink := data^.Link; + end; + nodeIndex := MainForm.vtMangaList.AbsoluteIndex(FNode); + + if FInfo.DataExists(tempDataProcess) then + begin + FInfo.SyncInfoToData(tempDataProcess); + tempDataProcess.Commit; + end + else + begin + FInfo.AddInfoToData(FInfo.MangaInfo.Title, FInfo.MangaInfo.Link, tempDataProcess); + tempDataProcess.Sort; + end; + finally + if oldModuleID = FModule.ID then + begin + MainForm.vtMangaList.Clear; + tempDataProcess.Refresh(tempDataProcess.Filtered); + MainForm.vtMangaListResetList(nodeIndex, dataLink, FModule.ID); + end + else + begin + tempDataProcess.Free; + end; + end; end; procedure TGetMangaInfosThread.Execute; -var - m: TModuleContainer; function GetMangaInfo: Boolean; var infob: byte; - tempDataProcess: TDBDataProcess; data: PMangaInfoData; - oldModuleID, dataLink: String; - nodeIndex: Integer; - infoAlreadyExists: Boolean; begin Result := False; try @@ -78,7 +129,7 @@ procedure TGetMangaInfosThread.Execute; FInfo.MangaInfo.Title := FTitle; data := MainForm.vtMangaList.GetNodeData(FNode); if Assigned(data) and (MainForm.cbSelectManga.ItemIndex <> -1) and - (m = TModuleContainer(MainForm.cbSelectManga.Items.Objects[MainForm.cbSelectManga.ItemIndex])) then + (FModule = TModuleContainer(MainForm.cbSelectManga.Items.Objects[MainForm.cbSelectManga.ItemIndex])) then begin if FInfo.MangaInfo.Title = '' then begin @@ -119,9 +170,9 @@ procedure TGetMangaInfosThread.Execute; end; data := MainForm.vtMangaList.GetNodeData(FNode); - if Assigned(data) and dataProcess.WebsiteLoaded(m.ID) then //todo: use tmodulecontainer + if Assigned(data) and dataProcess.WebsiteLoaded(FModule.ID) then //todo: use tmodulecontainer begin - if not(m.InformationAvailable) then + if not(FModule.InformationAvailable) then begin if FInfo.MangaInfo.AltTitles = '' then begin @@ -149,50 +200,6 @@ procedure TGetMangaInfosThread.Execute; end; end; - if not (Terminated or isExiting) then - begin - Synchronize(MainThreadSyncInfos); - end; - end; - - if (FInfo.MangaInfo.Title <> '') and (FInfo.MangaInfo.Link <> '') then - begin - tempDataProcess := dataProcess; - oldModuleID := dataProcess.Website; - if oldModuleID <> m.ID then - begin - tempDataProcess := TDBDataProcess.Create; - end; - - if not Assigned(FNode) then - begin - FNode := MainForm.vtMangaList.FocusedNode; - end; - - data := MainForm.vtMangaList.GetNodeData(FNode); - dataLink := ''; - if Assigned(data) then - begin - dataLink := data^.Link; - end; - nodeIndex := MainForm.vtMangaList.AbsoluteIndex(FNode); - - if tempDataProcess.Connect(m.ID) then - begin - FInfo.AddInfoToData(FInfo.MangaInfo.Title, FInfo.MangaInfo.Link, tempDataProcess); - tempDataProcess.Sort; - - if oldModuleID = m.ID then - begin - MainForm.vtMangaList.Clear; - tempDataProcess.Refresh(tempDataProcess.Filtered); - MainForm.vtMangaListResetList(nodeIndex, dataLink, m.ID); - end - else - begin - tempDataProcess.Free; - end; - end; end; if FFillSaveTo and OptionGenerateMangaFolder then @@ -219,8 +226,6 @@ procedure TGetMangaInfosThread.Execute; end; begin - m := TModuleContainer(FInfo.Module); - try if not GetMangaInfo then begin @@ -255,6 +260,8 @@ procedure TGetMangaInfosThread.Execute; begin Synchronize(MainThreadShowCover); end; + + MainThreadSyncAddInfos; end; except on E: Exception do @@ -370,6 +377,7 @@ constructor TGetMangaInfosThread.Create(const AModule: Pointer; FIsHasMangaCover := False; FFillSaveTo := False; FInfo := TMangaInformation.Create(Self); + FModule := TModuleContainer(AModule); FInfo.Module := AModule; FLink := ALink; FNode := ANode; @@ -380,6 +388,7 @@ destructor TGetMangaInfosThread.Destroy; GetInfosThread := nil; FCover := nil; FInfo.Free; + //FModule.Free; inherited Destroy; end; diff --git a/baseunits/uUpdateThread.pas b/baseunits/uUpdateThread.pas index 2dee84042..4ba3638c0 100644 --- a/baseunits/uUpdateThread.pas +++ b/baseunits/uUpdateThread.pas @@ -262,7 +262,7 @@ procedure TUpdateListThread.GetNamesAndLinks; begin for i := 0 to links.Count - 1 do begin - if not FOwner.mainDataProcess.existsData(links[i]) then + if not FOwner.mainDataProcess.ExistsData(links[i]) then begin FOwner.tempDataProcess.AddData(names[i], '', links[i], '', '', '', '', '', 0, 0); end diff --git a/mangadownloader/forms/frmMain.pas b/mangadownloader/forms/frmMain.pas index 11d52d9ad..434d875d7 100644 --- a/mangadownloader/forms/frmMain.pas +++ b/mangadownloader/forms/frmMain.pas @@ -6749,8 +6749,8 @@ procedure TMainForm.ApplyOptions; OptionDeleteCompletedTasksOnClose := cbOptionDeleteCompletedTasksOnClose.Checked; OptionSortDownloadsOnNewTasks := cbOptionSortDownloadsOnNewTasks.Checked; OptionLongNamePaths := cbOptionEnableLongNamePaths.Checked; - DLManager.DB.AutoVacuum:=cbOptionVacuumDatabasesOnExit.Checked; - FavoriteManager.DB.AutoVacuum:=cbOptionVacuumDatabasesOnExit.Checked; + DLManager.DB.AutoVacuum := cbOptionVacuumDatabasesOnExit.Checked; + FavoriteManager.DB.AutoVacuum := cbOptionVacuumDatabasesOnExit.Checked; // view ToolBarDownload.Visible := cbOptionShowDownloadToolbar.Checked;