From 273b10c5ce28a955e6b7a6b384cba736f1762d77 Mon Sep 17 00:00:00 2001 From: Mikhail Grigoryev Date: Wed, 22 May 2013 09:48:12 +0000 Subject: Added plugin MirandaNGHistoryToDB (www.im-history.ru) git-svn-id: http://svn.miranda-ng.org/main/trunk@4793 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/MirandaNGHistoryToDB/About.dfm | 208 + plugins/MirandaNGHistoryToDB/About.pas | 146 + plugins/MirandaNGHistoryToDB/Contacts.pas | 211 + plugins/MirandaNGHistoryToDB/Database.pas | 421 ++ plugins/MirandaNGHistoryToDB/FSMonitor.pas | 222 + plugins/MirandaNGHistoryToDB/Global.inc | 2 + plugins/MirandaNGHistoryToDB/Global.pas | 1250 ++++++ .../HistoryToDBUpdater/Global.pas | 1583 +++++++ .../HistoryToDBUpdater/HistoryToDBUpdater.dpr | 32 + .../HistoryToDBUpdater/HistoryToDBUpdater.dproj | 197 + .../HistoryToDBUpdater/HistoryToDBUpdater.manifest | 21 + .../HistoryToDBUpdater/HistoryToDBUpdater.mes | 163 + .../HistoryToDBUpdater/HistoryToDBUpdater.otares | Bin 0 -> 96 bytes .../HistoryToDBUpdater/HistoryToDBUpdater.res | Bin 0 -> 146856 bytes .../HistoryToDBUpdater/HistoryToDBUpdater_Icon.ico | Bin 0 -> 144763 bytes .../HistoryToDBUpdater/Main.dfm | 530 +++ .../HistoryToDBUpdater/Main.pas | 1497 +++++++ .../HistoryToDBUpdater/NTNative.pas | 210 + .../HistoryToDBUpdater/jedi.inc | 1430 +++++++ .../HistoryToDBUpdater/readme-dev.txt | 38 + .../IMDownloaderComponent/Demo/DownLoaderTest.dpr | 15 + .../Demo/DownLoaderTest.dproj | 109 + .../IMDownloaderComponent/Demo/DownLoaderTest.res | Bin 0 -> 5280 bytes .../Demo/DownLoaderTestUnit.dfm | 125 + .../Demo/DownLoaderTestUnit.pas | 176 + .../IMDownloaderComponent/IMDownloader.dcr | Bin 0 -> 1728 bytes .../IMDownloaderComponent/IMDownloader.dpk | 38 + .../IMDownloaderComponent/IMDownloader.dproj | 168 + .../IMDownloaderComponent/IMDownloader.res | Bin 0 -> 5560 bytes .../IMDownloaderComponent/IMDownloader_Icon.ico | Bin 0 -> 4286 bytes .../IMDownloaderComponent/uIMDownloader.pas | 612 +++ .../IMDownloaderComponent/uMD5.pas | 456 ++ plugins/MirandaNGHistoryToDB/MapStream.pas | 185 + plugins/MirandaNGHistoryToDB/Menu.pas | 326 ++ .../MirandaNGHistoryToDB/MirandaNGHistoryToDB.dpr | 935 ++++ .../MirandaNGHistoryToDB.dproj | 226 + .../MirandaNGHistoryToDB/MirandaNGHistoryToDB.mes | 163 + .../MirandaNGHistoryToDB/MirandaNGHistoryToDB.res | Bin 0 -> 1100 bytes plugins/MirandaNGHistoryToDB/MsgExport.dfm | 4447 ++++++++++++++++++++ plugins/MirandaNGHistoryToDB/MsgExport.pas | 452 ++ plugins/MirandaNGHistoryToDB/copy_langs.bat | 14 + plugins/MirandaNGHistoryToDB/icons.res | Bin 0 -> 321592 bytes plugins/MirandaNGHistoryToDB/jedi.inc | 1430 +++++++ plugins/MirandaNGHistoryToDB/langs/English.xml | 505 +++ plugins/MirandaNGHistoryToDB/langs/Russian.xml | 506 +++ plugins/MirandaNGHistoryToDB/m_historytodb.inc | 40 + 46 files changed, 19089 insertions(+) create mode 100644 plugins/MirandaNGHistoryToDB/About.dfm create mode 100644 plugins/MirandaNGHistoryToDB/About.pas create mode 100644 plugins/MirandaNGHistoryToDB/Contacts.pas create mode 100644 plugins/MirandaNGHistoryToDB/Database.pas create mode 100644 plugins/MirandaNGHistoryToDB/FSMonitor.pas create mode 100644 plugins/MirandaNGHistoryToDB/Global.inc create mode 100644 plugins/MirandaNGHistoryToDB/Global.pas create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Global.pas create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dpr create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dproj create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.manifest create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.mes create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.otares create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.res create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater_Icon.ico create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.dfm create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.pas create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/NTNative.pas create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/jedi.inc create mode 100644 plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/readme-dev.txt create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dpr create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dproj create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.res create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.dfm create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.pas create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dcr create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dpk create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dproj create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.res create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader_Icon.ico create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uIMDownloader.pas create mode 100644 plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uMD5.pas create mode 100644 plugins/MirandaNGHistoryToDB/MapStream.pas create mode 100644 plugins/MirandaNGHistoryToDB/Menu.pas create mode 100644 plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dpr create mode 100644 plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dproj create mode 100644 plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.mes create mode 100644 plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.res create mode 100644 plugins/MirandaNGHistoryToDB/MsgExport.dfm create mode 100644 plugins/MirandaNGHistoryToDB/MsgExport.pas create mode 100644 plugins/MirandaNGHistoryToDB/copy_langs.bat create mode 100644 plugins/MirandaNGHistoryToDB/icons.res create mode 100644 plugins/MirandaNGHistoryToDB/jedi.inc create mode 100644 plugins/MirandaNGHistoryToDB/langs/English.xml create mode 100644 plugins/MirandaNGHistoryToDB/langs/Russian.xml create mode 100644 plugins/MirandaNGHistoryToDB/m_historytodb.inc (limited to 'plugins/MirandaNGHistoryToDB') diff --git a/plugins/MirandaNGHistoryToDB/About.dfm b/plugins/MirandaNGHistoryToDB/About.dfm new file mode 100644 index 0000000000..9aeea290e8 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/About.dfm @@ -0,0 +1,208 @@ +object AboutForm: TAboutForm + Left = 200 + Top = 108 + BorderIcons = [biMinimize, biMaximize] + BorderStyle = bsSingle + Caption = 'About' + ClientHeight = 263 + ClientWidth = 346 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + Icon.Data = { + 0000010001001010000001000000680400001600000028000000100000002000 + 0000010020000000000000040000000000000000000000000000000000000000 + 0000000000000000000000000000FF1F2A000000000000000000000000000000 + 00000000000000000000FF1F2A00000000000000000000000000000000000000 + 00000000000000000000FF1F2A00FEEFA900FF1F2A00CDCDCD00CDCDCD00CDCD + CD00CDCDCD00FF1F2A00FEEFA900FF1F2A000000000000000000000000000000 + 000000000000FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F + 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A0000000000000000000000 + 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FECF4D00FFCC + 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A0000000000FF1F + 2A00FEEFA900FFE55F00FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC + 4A00FFD35000FFE55F00FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A000000 + 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC + 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A00000000000000 + 000000000000FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F + 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A0000000000000000000000 + 000000000000C1BDB600FF1F2A00FEEFA900FF1F2A00C1B7AF00D2BEB900D2BE + B900D2BEB900FF1F2A00FEEFA900FF1F2A00C1BDB60000000000000000000000 + 000000000000BAB7AF00A39A8F00FF1F2A00CAC1B800DFD5CC00FAE2DF00F7DB + D900DFD5CC00CAC1B800FF1F2A00A39A8F00BAB7AF0000000000000000000000 + 000000000000B1AB9F00C9C2B900CFC7BF00D5CCC400DCD3CA00E8DDD500E4D6 + CF00E4D6CF00D5CCC400CFC7BF00C9C2B900B1AB9F0000000000000000000000 + 000000000000B0AB9E00C7C0B600CCC4BB00D3C9C100DAD0C700EBE1DA00E4D9 + D100DDD2CA00DBCDC500DDCAC400DBC4BF00C1ADA40000000000000000000000 + 000000000000AFAA9D00C8C1B700E8E3DB00F5F0E800FDF8F200FBF7F000FCF7 + F100FDF8F200F7F0EA00ECE3DC00CDC3BB00B2AA9E0000000000000000000000 + 000000000000AEA89C00FBF5EF00EEE7DE00E0D8CE00DDD5CC00DDD4CB00DDD4 + CB00DDD5CC00E0D7CE00EDE6DE00FBF6EF00AEA89C0000000000000000000000 + 000000000000AFA99D00E1D8CE00E1D7CE00DFD6CC00DFD5CB00DFD5CB00DFD5 + CB00DFD5CB00DFD6CC00E1D7CE00E1D8CE00AFA99D0000000000000000000000 + 000000000000D9D9D900B6B0A400D6CFC400E6DED500EFE7DD00EEE6DC00EEE6 + DC00EFE7DD00E6DED500D6CFC400B6B0A400D9D9D90000000000000000000000 + 00000000000000000000D9D9D900C4C0B700AEA99C00AEA89C00AEA89C00AEA8 + 9C00AEA89C00AEA99C00C4C0B700D9D9D900000000000000000000000000F7EF + FFFFE007FFFFC003FFFF8001FFFF0000FFFF8001FFFFC003FFFFC003FFFFC003 + FFFFC003FFFFC003FFFFC003FFFFC003FFFFC003FFFFC003FFFFE007FFFF} + OldCreateOrder = False + Position = poScreenCenter + OnClose = FormClose + OnCreate = FormCreate + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object AboutImage: TImage + Left = 8 + Top = 2 + Width = 328 + Height = 55 + Transparent = True + end + object CloseButton: TButton + Left = 270 + Top = 233 + Width = 70 + Height = 25 + Caption = 'Close' + TabOrder = 0 + OnClick = CloseButtonClick + end + object AboutPageControl: TPageControl + Left = 8 + Top = 63 + Width = 332 + Height = 168 + ActivePage = VersionTabSheet + TabOrder = 1 + object VersionTabSheet: TTabSheet + Caption = #1054' '#1087#1088#1086#1075#1088#1072#1084#1084#1077 + DesignSize = ( + 324 + 140) + object BAbout: TBevel + Left = 3 + Top = 7 + Width = 318 + Height = 130 + Anchors = [akLeft, akTop, akRight, akBottom] + ExplicitWidth = 363 + ExplicitHeight = 187 + end + object LProgramName: TLabel + Left = 16 + Top = 16 + Width = 72 + Height = 13 + Caption = 'HistoryToDB' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [fsBold] + ParentFont = False + end + object LCopyright: TLabel + Left = 16 + Top = 32 + Width = 124 + Height = 13 + Caption = 'Copyright '#169' 2011-2013 by' + end + object LabelAuthor: TLabel + Left = 143 + Top = 32 + Width = 80 + Height = 13 + Cursor = crHandPoint + Caption = 'Michael Grigorev' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ParentFont = False + OnClick = LabelAuthorClick + end + object LVersionNum: TLabel + Left = 56 + Top = 48 + Width = 33 + Height = 13 + Caption = '1.0.0.0' + end + object LVersion: TLabel + Left = 16 + Top = 48 + Width = 41 + Height = 13 + Caption = 'Version: ' + end + object LLicense: TLabel + Left = 16 + Top = 64 + Width = 43 + Height = 13 + Caption = 'License: ' + end + object LLicenseType: TLabel + Left = 59 + Top = 64 + Width = 33 + Height = 13 + Caption = 'GPLv3' + end + object LWeb: TLabel + Left = 16 + Top = 80 + Width = 29 + Height = 13 + Caption = 'Web: ' + end + object LabelWebSite: TLabel + Left = 46 + Top = 80 + Width = 82 + Height = 13 + Cursor = crHandPoint + Caption = 'www.im-history.ru' + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlue + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ParentFont = False + OnClick = LabelWebSiteClick + end + end + object ThankYouTabSheet: TTabSheet + Caption = #1041#1083#1072#1075#1086#1076#1072#1088#1085#1086#1089#1090#1080 + ImageIndex = 1 + DesignSize = ( + 324 + 140) + object BThankYou: TBevel + Left = 3 + Top = 3 + Width = 318 + Height = 134 + Anchors = [akLeft, akTop, akRight, akBottom] + ExplicitWidth = 311 + ExplicitHeight = 115 + end + object ThankYou: TLabel + Left = 11 + Top = 11 + Width = 305 + Height = 118 + AutoSize = False + Caption = #1057#1087#1072#1089#1080#1073#1086' '#1074#1089#1077#1084'!' + WordWrap = True + end + end + end +end diff --git a/plugins/MirandaNGHistoryToDB/About.pas b/plugins/MirandaNGHistoryToDB/About.pas new file mode 100644 index 0000000000..7d175adb84 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/About.pas @@ -0,0 +1,146 @@ +{ ############################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.5 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ############################################################################ } + +unit About; + +interface + +uses Windows, Messages, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls, + Buttons, ExtCtrls, ShellAPI, Global, ComCtrls; + +type + TAboutForm = class(TForm) + AboutImage: TImage; + CloseButton: TButton; + AboutPageControl: TPageControl; + VersionTabSheet: TTabSheet; + ThankYouTabSheet: TTabSheet; + BAbout: TBevel; + LProgramName: TLabel; + LCopyright: TLabel; + LabelAuthor: TLabel; + LVersionNum: TLabel; + LVersion: TLabel; + LLicense: TLabel; + LLicenseType: TLabel; + LWeb: TLabel; + LabelWebSite: TLabel; + BThankYou: TBevel; + ThankYou: TLabel; + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure CloseButtonClick(Sender: TObject); + procedure LabelAuthorClick(Sender: TObject); + procedure LabelWebSiteClick(Sender: TObject); + procedure MemoThankYouEnter(Sender: TObject); + private + { Private declarations } + // + procedure OnLanguageChanged(var Msg: TMessage); message WM_LANGUAGECHANGED; + procedure LoadLanguageStrings; + public + { Public declarations } + end; + +var + AboutForm: TAboutForm; + +implementation + +{$R *.dfm} +{$R icons.res} + +procedure TAboutForm.CloseButtonClick(Sender: TObject); +begin + Close; +end; + +procedure TAboutForm.FormClose(Sender: TObject; var Action: TCloseAction); +begin + // - + Global_AboutForm_Showing := False; +end; + +procedure TAboutForm.FormCreate(Sender: TObject); +var + AboutBitmap: TBitmap; +begin + // + AboutFormHandle := Handle; + SetWindowLong(Handle, GWL_HWNDPARENT, 0); + SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW); + // + AboutBitmap := TBitmap.Create; + try + AboutBitmap.LoadFromResourceName(HInstance, 'About'); + AboutImage.Picture.Assign(AboutBitmap); + finally + AboutBitmap.Free; + end; + LabelAuthor.Cursor := crHandPoint; + LabelWebSite.Cursor := crHandPoint; + // + LoadLanguageStrings; +end; + +procedure TAboutForm.FormShow(Sender: TObject); +begin + // - + Global_AboutForm_Showing := True; + // " " + LVersionNum.Caption := IntToStr(htdVerMajor) + '.' + IntToStr(htdVerMinor) + '.' + IntToStr(htdVerRelease) + '.' + IntToStr(htdVerBuild) + ' ' + htdPlatform; +end; + +procedure TAboutForm.LabelAuthorClick(Sender: TObject); +begin + ShellExecute(0, 'open', 'mailto:sleuthhound@gmail.com', nil, nil, SW_RESTORE); +end; + +procedure TAboutForm.LabelWebSiteClick(Sender: TObject); +begin + ShellExecute(0, 'open', 'http://www.im-history.ru', nil, nil, SW_RESTORE); +end; + +// - Memo :-D +procedure TAboutForm.MemoThankYouEnter(Sender: TObject); +begin + CloseButton.SetFocus; +end; + +// +procedure TAboutForm.OnLanguageChanged(var Msg: TMessage); +begin + LoadLanguageStrings; +end; + +// +procedure TAboutForm.LoadLanguageStrings; +begin + Caption := GetLangStr('AboutFormCaption'); + LProgramName.Caption := htdPluginShortName; + CloseButton.Caption := GetLangStr('CloseButton'); + LVersion.Caption := GetLangStr('Version'); + LLicense.Caption := GetLangStr('License'); + VersionTabSheet.Caption := GetLangStr('AboutFormCaption'); + ThankYouTabSheet.Caption := GetLangStr('LThankYou'); + // + LVersionNum.Left := LVersion.Left + 1 + LVersion.Width; + LLicenseType.Left := LLicense.Left + 1 + LLicense.Width; + // + if CoreLanguage = 'Russian' then + ThankYou.Caption := ThankYouText_Rus + else + ThankYou.Caption := ThankYouText_Eng; + // End +end; + +end. + diff --git a/plugins/MirandaNGHistoryToDB/Contacts.pas b/plugins/MirandaNGHistoryToDB/Contacts.pas new file mode 100644 index 0000000000..8d95b5f3bc --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/Contacts.pas @@ -0,0 +1,211 @@ +{ ################################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.5 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ################################################################################ } + +{ ################################################################################ } +{ # # } +{ # History++ plugin for Miranda IM: the free IM client for Microsoft* Windows* # } +{ # # } +{ # Copyright (C) 2006-2009 theMIROn, 2003-2006 Art Fedorov. # } +{ # History+ parts (C) 2001 Christian Kastner # } +{ # # } +{ # This program is free software; you can redistribute it and/or modify # } +{ # it under the terms of the GNU General Public License as published by # } +{ # the Free Software Foundation; either version 2 of the License, or # } +{ # (at your option) any later version. # } +{ # # } +{ # This program is distributed in the hope that it will be useful, # } +{ # but WITHOUT ANY WARRANTY; without even the implied warranty of # } +{ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # } +{ # GNU General Public License for more details. # } +{ # # } +{ # You should have received a copy of the GNU General Public License # } +{ # along with this program; if not, write to the Free Software # } +{ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # } +{ # # } +{ ################################################################################ } + +unit Contacts; + +interface + +uses + Windows, SysUtils, Forms, Classes, Global; + +function GetContactDisplayName(hContact: THandle; Proto: AnsiString = ''; Contact: Boolean = False): String; +function GetContactProto(hContact: THandle): AnsiString; overload; +function GetContactProto(hContact: THandle; var SubContact: THandle; var SubProtocol: AnsiString): AnsiString; overload; +function GetContactID(hContact: THandle; Proto: AnsiString = ''; Contact: boolean = false): AnsiString; +function TranslateAnsiW(const S: AnsiString): WideString; +function GetMyContactDisplayName(Proto: AnsiString): String; +function GetMyContactID(Proto: AnsiString): String; + +implementation + +uses m_api; + +function GetContactProto(hContact: THandle): AnsiString; +begin + Result := PAnsiChar(CallService(MS_PROTO_GETCONTACTBASEPROTO, hContact, 0)); +end; + +function GetContactProto(hContact: THandle; var SubContact: THandle; var SubProtocol: AnsiString): AnsiString; +begin + Result := PAnsiChar(CallService(MS_PROTO_GETCONTACTBASEPROTO, hContact, 0)); + if MetaContactsEnabled and (Result = MetaContactsProto) then + begin + SubContact := CallService(MS_MC_GETMOSTONLINECONTACT, hContact, 0); + SubProtocol := PAnsiChar(CallService(MS_PROTO_GETCONTACTBASEPROTO, SubContact, 0)); + end + else + begin + SubContact := hContact; + SubProtocol := Result; + end; +end; + +function GetContactDisplayName(hContact: THandle; Proto: AnsiString = ''; Contact: Boolean = False): String; +var + ci: TContactInfo; + RetPWideChar, UW: PChar; +begin + if (hContact = 0) and Contact then + Result := TranslateW('Server') + else + begin + if Proto = '' then + Proto := GetContactProto(hContact); + if Proto = '' then + Result := TranslateW('Unknown Contact') + else + begin + ci.cbSize := SizeOf(ci); + ci.hContact := hContact; + ci.szProto := PAnsiChar(Proto); + ci.dwFlag := CNF_DISPLAY + CNF_UNICODE; + if CallService(MS_CONTACT_GETCONTACTINFO, 0, LPARAM(@ci)) = 0 then + begin + RetPWideChar := ci.retval.szVal.w; + UW := TranslateW('Unknown Contact'); + if WideCompareText(RetPWideChar, UW) = 0 then + Result := AnsiToWideString(GetContactID(hContact, Proto), CP_ACP) + else + Result := RetPWideChar; + end + else + Result := String(GetContactID(hContact, Proto)); + if Result = '' then + Result := TranslateAnsiW(Proto); + end; + end; +end; + +function GetContactID(hContact: THandle; Proto: AnsiString = ''; Contact: Boolean = False): AnsiString; +var + uid: PAnsiChar; + dbv: TDBVARIANT; + cgs: TDBCONTACTGETSETTING; + tmp: String; +begin + Result := ''; + if not((hContact = 0) and Contact) then + begin + if Proto = '' then + Proto := GetContactProto(hContact); + uid := PAnsiChar(CallProtoService(PAnsiChar(Proto), PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0)); + if (Cardinal(uid) <> CALLSERVICE_NOTFOUND) and (uid <> nil) then + begin + cgs.szModule := PAnsiChar(Proto); + cgs.szSetting := uid; + cgs.pValue := @dbv; + try + if CallService(MS_DB_CONTACT_GETSETTING, hContact, LPARAM(@cgs)) = 0 then + begin + case dbv._type of + DBVT_BYTE: + Result := AnsiString(intToStr(dbv.bVal)); + DBVT_WORD: + Result := AnsiString(intToStr(dbv.wVal)); + DBVT_DWORD: + Result := AnsiString(intToStr(dbv.dVal)); + DBVT_ASCIIZ: + Result := AnsiString(dbv.szVal.a); + DBVT_UTF8: + begin + tmp := AnsiToWideString(dbv.szVal.a, CP_UTF8); + Result := WideToAnsiString(tmp, hppCodepage); + end; + DBVT_WCHAR: + Result := WideToAnsiString(dbv.szVal.w, hppCodepage); + end; + DBFreeVariant(@dbv); + end; + except + end; + end; + end; +end; + +function TranslateAnsiW(const S: AnsiString): WideString; +begin + Result := AnsiToWideString(Translate(PAnsiChar(S)),hppCodepage); +end; + +function GetMyContactDisplayName(Proto: AnsiString): String; +var + ci: TContactInfo; + RetPWideChar, UW: PChar; +begin + ci.cbSize := SizeOf(ci); + ci.hContact := 0; + ci.szProto := PAnsiChar(Proto); + ci.dwFlag := CNF_DISPLAY + CNF_UNICODE; + if CallService(MS_CONTACT_GETCONTACTINFO, 0, LPARAM(@ci)) = 0 then + begin + RetPWideChar := ci.retval.szVal.w; + UW := TranslateW('Unknown Contact'); + if WideCompareText(RetPWideChar, UW) = 0 then + Result := TranslateW('Unknown Contact') + else + Result := RetPWideChar; + end + else + Result := TranslateW('Unknown Contact'); +end; + +function GetMyContactID(Proto: AnsiString): String; +var + ci: TContactInfo; + RetPWideChar, UW: PChar; + TmpContactID: AnsiString; +begin + ci.cbSize := SizeOf(ci); + ci.hContact := 0; + ci.szProto := PAnsiChar(Proto); + ci.dwFlag := CNF_DISPLAY + CNF_UNICODE; + if CallService(MS_CONTACT_GETCONTACTINFO, 0, LPARAM(@ci)) = 0 then + begin + RetPWideChar := ci.retval.szVal.w; + UW := TranslateW('Unknown Contact'); + if WideCompareText(RetPWideChar, UW) = 0 then + Result := TranslateW('Unknown Contact') + else + begin + TmpContactID := GetContactID(ci.hContact, Proto); + if TmpContactID <> '' then + Result := TmpContactID + else + Result := TranslateW('Unknown Contact'); + end; + end + else + Result := TranslateW('Unknown Contact'); +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/Database.pas b/plugins/MirandaNGHistoryToDB/Database.pas new file mode 100644 index 0000000000..ba58a7295a --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/Database.pas @@ -0,0 +1,421 @@ +{ ################################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.5 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ################################################################################ } + +{ ################################################################################ } +{ # # } +{ # History++ plugin for Miranda IM: the free IM client for Microsoft* Windows* # } +{ # # } +{ # Copyright (C) 2006-2009 theMIROn, 2003-2006 Art Fedorov. # } +{ # History+ parts (C) 2001 Christian Kastner # } +{ # # } +{ # This program is free software; you can redistribute it and/or modify # } +{ # it under the terms of the GNU General Public License as published by # } +{ # the Free Software Foundation; either version 2 of the License, or # } +{ # (at your option) any later version. # } +{ # # } +{ # This program is distributed in the hope that it will be useful, # } +{ # but WITHOUT ANY WARRANTY; without even the implied warranty of # } +{ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # } +{ # GNU General Public License for more details. # } +{ # # } +{ # You should have received a copy of the GNU General Public License # } +{ # along with this program; if not, write to the Free Software # } +{ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # } +{ # # } +{ ################################################################################ } + +unit Database; + +interface + +uses m_api, windows, global; + +procedure SetSafetyMode(Safe: Boolean); + +function DBGetContactSettingString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; ErrorValue: PAnsiChar): AnsiString; +function DBGetContactSettingWideString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; ErrorValue: PWideChar): WideString; +function DBWriteContactSettingWideString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; const val: PWideChar): Integer; + +function DBDelete(const Module, Param: AnsiString): Boolean; overload; +function DBDelete(const hContact: THandle; const Module, Param: AnsiString): Boolean; overload; +function DBExists(const Module, Param: AnsiString): Boolean; overload; +function DBExists(const hContact: THandle; const Module, Param: AnsiString): Boolean; overload; + +function GetDBBlob(const Module,Param: AnsiString; var Value: Pointer; var Size: Integer): Boolean; overload; +function GetDBBlob(const hContact: THandle; const Module,Param: AnsiString; var Value: Pointer; var Size: Integer): Boolean; overload; +function GetDBStr(const Module,Param: AnsiString; Default: AnsiString): AnsiString; overload; +function GetDBStr(const hContact: THandle; const Module,Param: AnsiString; Default: AnsiString): AnsiString; overload; +function GetDBWideStr(const Module,Param: AnsiString; Default: WideString): WideString; overload; +function GetDBWideStr(const hContact: THandle; const Module,Param: AnsiString; Default: WideString): WideString; overload; +function GetDBInt(const Module,Param: AnsiString; Default: Integer): Integer; overload; +function GetDBInt(const hContact: THandle; const Module,Param: AnsiString; Default: Integer): Integer; overload; +function GetDBWord(const Module,Param: AnsiString; Default: Word): Word; overload; +function GetDBWord(const hContact: THandle; const Module,Param: AnsiString; Default: Word): Word; overload; +function GetDBDWord(const Module,Param: AnsiString; Default: DWord): DWord; overload; +function GetDBDWord(const hContact: THandle; const Module,Param: AnsiString; Default: DWord): DWord; overload; +function GetDBByte(const Module,Param: AnsiString; Default: Byte): Byte; overload; +function GetDBByte(const hContact: THandle; const Module,Param: AnsiString; Default: Byte): Byte; overload; +function GetDBBool(const Module,Param: AnsiString; Default: Boolean): Boolean; overload; +function GetDBBool(const hContact: THandle; const Module,Param: AnsiString; Default: Boolean): Boolean; overload; +function GetDBDateTime(const hContact: THandle; const Module,Param: AnsiString; Default: TDateTime): TDateTime; overload; +function GetDBDateTime(const Module,Param: AnsiString; Default: TDateTime): TDateTime; overload; + +function WriteDBBlob(const Module,Param: AnsiString; Value: Pointer; Size: Integer): Integer; overload; +function WriteDBBlob(const hContact: THandle; const Module,Param: AnsiString; Value: Pointer; Size: Integer): Integer; overload; +function WriteDBByte(const Module,Param: AnsiString; Value: Byte): Integer; overload; +function WriteDBByte(const hContact: THandle; const Module,Param: AnsiString; Value: Byte): Integer; overload; +function WriteDBWord(const Module,Param: AnsiString; Value: Word): Integer; overload; +function WriteDBWord(const hContact: THandle; const Module,Param: AnsiString; Value: Word): Integer; overload; +function WriteDBDWord(const Module,Param: AnsiString; Value: DWord): Integer; overload; +function WriteDBDWord(const hContact: THandle; const Module,Param: AnsiString; Value: DWord): Integer; overload; +function WriteDBInt(const Module,Param: AnsiString; Value: Integer): Integer; overload; +function WriteDBInt(const hContact: THandle; const Module,Param: AnsiString; Value: Integer): Integer; overload; +function WriteDBStr(const Module,Param: AnsiString; Value: AnsiString): Integer; overload; +function WriteDBStr(const hContact: THandle; const Module,Param: AnsiString; Value: AnsiString): Integer; overload; +function WriteDBWideStr(const Module,Param: AnsiString; Value: WideString): Integer; overload; +function WriteDBWideStr(const hContact: THandle; const Module,Param: AnsiString; Value: WideString): Integer; overload; +function WriteDBBool(const Module,Param: AnsiString; Value: Boolean): Integer; overload; +function WriteDBBool(const hContact: THandle; const Module,Param: AnsiString; Value: Boolean): Integer; overload; +function WriteDBDateTime(const hContact: THandle; const Module,Param: AnsiString; Value: TDateTime): Integer; overload; +function WriteDBDateTime(const Module,Param: AnsiString; Value: TDateTime): Integer; overload; + +implementation + +procedure SetSafetyMode(Safe: Boolean); +begin + CallService(MS_DB_SETSAFETYMODE,WPARAM(Safe),0); +end; + +function DBExists(const Module, Param: AnsiString): Boolean; +begin + Result := DBExists(0,Module,Param); +end; + +function DBExists(const hContact: THandle; const Module, Param: AnsiString): Boolean; +var + dbv: TDBVARIANT; + cgs: TDBCONTACTGETSETTING; +begin + cgs.szModule := PAnsiChar(Module); + cgs.szSetting := PAnsiChar(Param); + cgs.pValue := @dbv; + Result := (CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) = 0); + if Result then + DBFreeVariant(@dbv); +end; + +function GetDBBlob(const Module,Param: AnsiString; var Value: Pointer; var Size: Integer): Boolean; +begin + Result := GetDBBlob(0,Module,Param,Value,Size); +end; + +function GetDBBlob(const hContact: THandle; const Module,Param: AnsiString; var Value: Pointer; var Size: Integer): Boolean; +var + cgs: TDBContactGetSetting; + dbv: TDBVARIANT; +begin + Result := False; + ZeroMemory(@cgs,SizeOf(cgs)); + cgs.szModule := PAnsiChar(Module); + cgs.szSetting := PAnsiChar(Param); + cgs.pValue := @dbv; + if CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) <> 0 then exit; + Size := dbv.cpbVal; + Value := nil; + if dbv.cpbVal = 0 then exit; + GetMem(Value,dbv.cpbVal); + Move(dbv.pbVal^,PByte(Value)^,dbv.cpbVal); + DBFreeVariant(@dbv); + Result := True; +end; + +function GetDBBool(const Module,Param: AnsiString; Default: Boolean): Boolean; +begin + Result := GetDBBool(0,Module,Param,Default); +end; + +function GetDBBool(const hContact: THandle; const Module,Param: AnsiString; Default: Boolean): Boolean; +begin + Result := Boolean(GetDBByte(hContact,Module,Param,Byte(Default))); +end; + +function GetDBByte(const Module,Param: AnsiString; Default: Byte): Byte; +begin + Result := GetDBByte(0,Module,Param,Default); +end; + +function GetDBByte(const hContact: THandle; const Module,Param: AnsiString; Default: Byte): Byte; +begin + Result := DBGetContactSettingByte(hContact,PAnsiChar(Module),PAnsiChar(Param),Default); +end; + +function GetDBWord(const Module,Param: AnsiString; Default: Word): Word; +begin + Result := GetDBWord(0,Module,Param,Default); +end; + +function GetDBWord(const hContact: THandle; const Module,Param: AnsiString; Default: Word): Word; +begin + Result := DBGetContactSettingWord(hContact,PAnsiChar(Module),PAnsiChar(Param),Default); +end; + +function GetDBDWord(const Module,Param: AnsiString; Default: DWord): DWord; +begin + Result := GetDBDWord(0,Module,Param,Default); +end; + +function GetDBDWord(const hContact: THandle; const Module,Param: AnsiString; Default: DWord): DWord; +begin + Result := DBGetContactSettingDWord(hContact,PAnsiChar(Module),PAnsiChar(Param),Default); +end; + +function GetDBInt(const Module,Param: AnsiString; Default: Integer): Integer; +begin + Result := GetDBInt(0,Module,Param,Default); +end; + +function GetDBInt(const hContact: THandle; const Module,Param: AnsiString; Default: Integer): Integer; +var + cws:TDBCONTACTGETSETTING; + dbv:TDBVariant; +begin + dbv._type := DBVT_DWORD; + dbv.dVal:=Default; + cws.szModule:=PAnsiChar(Module); + cws.szSetting:=PAnsiChar(Param); + cws.pValue:=@dbv; + if CallService(MS_DB_CONTACT_GETSETTING,hContact,LPARAM(@cws))<>0 then + Result:=default + else + Result:=dbv.dval; +end; + +function GetDBStr(const Module,Param: AnsiString; Default: AnsiString): AnsiString; +begin + Result := GetDBStr(0,Module,Param,Default); +end; + +function GetDBStr(const hContact: THandle; const Module,Param: AnsiString; Default: AnsiString): AnsiString; +begin + Result := DBGetContactSettingString(hContact,PAnsiChar(Module),PAnsiChar(Param),PAnsiChar(Default)); +end; + +function DBGetContactSettingString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; ErrorValue: PAnsiChar): AnsiString; +var + dbv: TDBVARIANT; + cgs: TDBCONTACTGETSETTING; + tmp: WideString; +begin + cgs.szModule := szModule; + cgs.szSetting := szSetting; + cgs.pValue := @dbv; + if CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) <> 0 then + Result := ErrorValue + else begin + case dbv._type of + DBVT_ASCIIZ: + Result := AnsiString(dbv.szVal.a); + DBVT_UTF8: begin + tmp := AnsiToWideString(dbv.szVal.a,CP_UTF8); + Result := WideToAnsiString(tmp,hppCodepage); + end; + DBVT_WCHAR: + Result := WideToAnsiString(dbv.szVal.w,hppCodepage); + end; + // free variant + DBFreeVariant(@dbv); + end; +end; + +function GetDBWideStr(const Module,Param: AnsiString; Default: WideString): WideString; +begin + Result := GetDBWideStr(0,Module,Param,Default); +end; + +function GetDBWideStr(const hContact: THandle; const Module,Param: AnsiString; Default: WideString): WideString; +begin + Result := DBGetContactSettingWideString(hContact,PAnsiChar(Module),PAnsiChar(Param),PWideChar(Default)); +end; + +function DBGetContactSettingWideString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; ErrorValue: PWideChar): WideString; +var + dbv: TDBVARIANT; + cgs: TDBCONTACTGETSETTING; +begin + cgs.szModule := szModule; + cgs.szSetting := szSetting; + cgs.pValue := @dbv; + if CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) <> 0 then + Result := ErrorValue + else begin + case dbv._type of + DBVT_ASCIIZ: + Result := AnsiToWideString(dbv.szVal.a,hppCodepage); + DBVT_UTF8: + Result := AnsiToWideString(dbv.szVal.a,CP_UTF8); + DBVT_WCHAR: + Result := WideString(dbv.szVal.w); + end; + // free variant + DBFreeVariant(@dbv); + end; +end; + +function GetDBDateTime(const hContact: THandle; const Module,Param: AnsiString; Default: TDateTime): TDateTime; overload; +var + p: Pointer; + s: Integer; +begin + Result := Default; + if not GetDBBlob(hContact,Module,Param,p,s) then exit; + if s <> SizeOf(TDateTime) then begin + FreeMem(p,s); + exit; + end; + Result := PDateTime(p)^; + FreeMem(p,s); +end; + +function GetDBDateTime(const Module,Param: AnsiString; Default: TDateTime): TDateTime; overload; +begin + Result := GetDBDateTime(0,Module,Param,Default); +end; + +function DBDelete(const Module, Param: AnsiString): Boolean; +begin + Result := DBDelete(0,Module,Param); +end; + +function DBDelete(const hContact: THandle; const Module, Param: AnsiString): Boolean; +begin + Result := (DBDeleteContactSetting(hContact,PAnsiChar(Module),PAnsiChar(Param)) = 0); +end; + +function WriteDBBool(const Module,Param: AnsiString; Value: Boolean): Integer; +begin + Result := WriteDBBool(0,Module,Param,Value); +end; + +function WriteDBBool(const hContact: THandle; const Module,Param: AnsiString; Value: Boolean): Integer; +begin + Result := WriteDBByte(hContact,Module,Param,Byte(Value)); +end; + +function WriteDBByte(const Module,Param: AnsiString; Value: Byte): Integer; +begin + Result := WriteDBByte(0,Module,Param,Value); +end; + +function WriteDBByte(const hContact: THandle; const Module,Param: AnsiString; Value: Byte): Integer; +begin + Result := DBWriteContactSettingByte(hContact,PAnsiChar(Module), PAnsiChar(Param), Value); +end; + +function WriteDBWord(const Module,Param: AnsiString; Value: Word): Integer; +begin + Result := WriteDBWord(0,Module,Param,Value); +end; + +function WriteDBWord(const hContact: THandle; const Module,Param: AnsiString; Value: Word): Integer; +begin + Result := DBWriteContactSettingWord(hContact,PAnsiChar(Module),PAnsiChar(Param),Value); +end; + +function WriteDBDWord(const Module,Param: AnsiString; Value: DWord): Integer; +begin + Result := WriteDBWord(0,Module,Param,Value); +end; + +function WriteDBDWord(const hContact: THandle; const Module,Param: AnsiString; Value: DWord): Integer; +begin + Result := DBWriteContactSettingDWord(hContact,PAnsiChar(Module),PAnsiChar(Param),Value); +end; + +function WriteDBInt(const Module,Param: AnsiString; Value: Integer): Integer; +begin + Result := WriteDBInt(0,Module,Param,Value); +end; + +function WriteDBInt(const hContact: THandle; const Module,Param: AnsiString; Value: Integer): Integer; +var + cws: TDBCONTACTWRITESETTING; +begin + cws.szModule := PAnsiChar(Module); + cws.szSetting := PAnsiChar(Param); + cws.value._type := DBVT_DWORD; + cws.value.dVal := Value; + Result := CallService(MS_DB_CONTACT_WRITESETTING, hContact, lParam(@cws)); +end; + +function WriteDBStr(const Module,Param: AnsiString; Value: AnsiString): Integer; +begin + Result := WriteDBStr(0,Module,Param,Value); +end; + +function WriteDBStr(const hContact: THandle; const Module,Param: AnsiString; Value: AnsiString): Integer; +begin + Result := DBWriteContactSettingString(hContact,PAnsiChar(Module),PAnsiChar(Param),PAnsiChar(Value)); +end; + +function WriteDBWideStr(const Module,Param: AnsiString; Value: WideString): Integer; +begin + Result := WriteDBWideStr(0,Module,Param,Value); +end; + +function WriteDBWideStr(const hContact: THandle; const Module,Param: AnsiString; Value: WideString): Integer; +begin + Result := DBWriteContactSettingWideString(hContact,PAnsiChar(Module),PAnsiChar(Param),PWideChar(Value)); +end; + +function DBWriteContactSettingWideString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; const val: PWideChar): Integer; +var + cws: TDBCONTACTWRITESETTING; +begin + cws.szModule := szModule; + cws.szSetting := szSetting; + cws.value._type := DBVT_WCHAR; + cws.value.szVal.w := val; + Result := CallService(MS_DB_CONTACT_WRITESETTING, hContact, lParam(@cws)); +end; + +function WriteDBBlob(const Module,Param: AnsiString; Value: Pointer; Size: Integer): Integer; +begin + Result := WriteDBBlob(0,Module,Param,Value,Size); +end; + +function WriteDBBlob(const hContact: THandle; const Module,Param: AnsiString; Value: Pointer; Size: Integer): Integer; +var + cws: TDBContactWriteSetting; +begin + ZeroMemory(@cws,SizeOf(cws)); + cws.szModule := PAnsiChar(Module); + cws.szSetting := PAnsiChar(Param); + cws.value._type := DBVT_BLOB; + cws.value.pbVal := Value; + cws.value.cpbVal := Word(Size); + Result := CallService(MS_DB_CONTACT_WRITESETTING,hContact,lParam(@cws)); +end; + +function WriteDBDateTime(const hContact: THandle; const Module,Param: AnsiString; Value: TDateTime): Integer; overload; +var + p: PDateTime; +begin + GetMem(p,SizeOf(TDateTime)); + p^ := Value; + Result := WriteDBBlob(hContact,Module,Param,p,SizeOf(TDateTime)); + FreeMem(p,SizeOf(TDateTime)); +end; + +function WriteDBDateTime(const Module,Param: AnsiString; Value: TDateTime): Integer; overload; +begin + Result := WriteDBDateTime(0,Module,Param,Value); +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/FSMonitor.pas b/plugins/MirandaNGHistoryToDB/FSMonitor.pas new file mode 100644 index 0000000000..b19cde322f --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/FSMonitor.pas @@ -0,0 +1,222 @@ +{ ############################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.5 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ############################################################################ } + +unit FSMonitor; + +{$I jedi.inc} + +interface + +type + // ( callback ) + PInfoCallBack = ^TInfoCallBack; + TInfoCallBack = record + FAction : Integer; // ( FILE_ACTION_XXX) + FDrive : String; // , + FOldFileName : String; // + FNewFileName : String; // + end; + + // callback , + TWatchFileSystemCallBack = procedure (pInfo: TInfoCallBack); + + { + : + pName - + pFilter - FILE_NOTIFY_XXX + pSubTree - + pInfoCallBack - callback , } + procedure StartWatch(pName: String; pFilter: Cardinal; pSubTree: Boolean; pInfoCallBack: TWatchFileSystemCallBack); + // + procedure StopWatch; + +implementation + +uses + Classes, Windows, SysUtils, IniFiles; + +const + FILE_LIST_DIRECTORY = $0001; + +type + PFileNotifyInformation = ^TFileNotifyInformation; + TFileNotifyInformation = record + NextEntryOffset : DWORD; + Action : DWORD; + FileNameLength : DWORD; + FileName : Array[0..0] of WideChar; + end; + + WFSError = class(Exception); + + TWFS = class(TThread) + private + FName : String; + FFilter : Cardinal; + FSubTree : Boolean; + FInfoCallBack : TWatchFileSystemCallBack; + FWatchHandle : THandle; + FWatchBuf : Array[0..4096] of Byte; + FOverLapp : TOverlapped; + FPOverLapp : POverlapped; + FBytesWritte : DWORD; + FCompletionPort : THandle; + FNumBytes : Cardinal; + FOldFileName : String; + function CreateDirHandle(aDir: string): THandle; + procedure WatchEvent; + //procedure HandleEvent; + protected + procedure Execute; override; + public + constructor Create(pName: String; pFilter: Cardinal; pSubTree: Boolean; pInfoCallBack: TWatchFileSystemCallBack); + destructor Destroy; override; + end; + + +var + WFS : TWFS; + +procedure StartWatch(pName: String; pFilter: Cardinal; pSubTree: Boolean; pInfoCallBack: TWatchFileSystemCallBack); +begin + WFS := TWFS.Create(pName, pFilter, pSubTree, pInfoCallBack); +end; + +procedure StopWatch; +begin + if Assigned(WFS) then + begin + PostQueuedCompletionStatus(WFS.FCompletionPort, 0, 0, nil); + WFS.Terminate; + WFS.WaitFor; + WFS.Free; + WFS := nil; + end; +end; + +constructor TWFS.Create(pName: String; pFilter: Cardinal; pSubTree: Boolean; pInfoCallBack: TWatchFileSystemCallBack); +begin + inherited Create(True); + FreeOnTerminate := False; + FName := IncludeTrailingBackslash(pName); + FFilter := pFilter; + FSubTree := pSubTree; + FOldFileName := EmptyStr; + ZeroMemory(@FOverLapp, SizeOf(TOverLapped)); + FPOverLapp := @FOverLapp; + ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf)); + FInfoCallBack := pInfoCallBack; + Resume; +end; + + +destructor TWFS.Destroy; +begin + PostQueuedCompletionStatus(FCompletionPort, 0, 0, nil); + CloseHandle(FWatchHandle); + FWatchHandle := 0; + CloseHandle(FCompletionPort); + FCompletionPort := 0; + inherited Destroy; +end; + +function TWFS.CreateDirHandle(aDir: String): THandle; +begin + Result := CreateFile(PChar(aDir), FILE_LIST_DIRECTORY, FILE_SHARE_READ+FILE_SHARE_DELETE+FILE_SHARE_WRITE, + nil,OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0); +end; + +procedure TWFS.Execute; +begin + FWatchHandle := CreateDirHandle(FName); + WatchEvent; +end; + +{procedure TWFS.HandleEvent; +var + FileNotifyInfo : PFileNotifyInformation; + InfoCallBack : TInfoCallBack; + Offset : Longint; +begin + Pointer(FileNotifyInfo) := @FWatchBuf[0]; + repeat + Offset := FileNotifyInfo^.NextEntryOffset; + InfoCallBack.FAction := FileNotifyInfo^.Action; + InfoCallBack.FDrive := FName; + SetString(InfoCallBack.FNewFileName,FileNotifyInfo^.FileName,FileNotifyInfo^.FileNameLength ); + InfoCallBack.FNewFileName := Trim(InfoCallBack.FNewFileName); + case FileNotifyInfo^.Action of + FILE_ACTION_RENAMED_OLD_NAME: FOldFileName := Trim(WideCharToString(@(FileNotifyInfo^.FileName[0]))); + FILE_ACTION_RENAMED_NEW_NAME: InfoCallBack.FOldFileName := FOldFileName; + end; + FInfoCallBack(InfoCallBack); + PChar(FileNotifyInfo) := PChar(FileNotifyInfo)+Offset; + until (Offset=0) or Terminated; +end;} + +procedure TWFS.WatchEvent; +var + {$ifdef DELPHIXE_UP} + CompletionKey: DWORD_PTR; + {$ELSE} + CompletionKey: Cardinal; + {$endif} + // HandleEvent + FileNotifyInfo : PFileNotifyInformation; + InfoCallBack : TInfoCallBack; + Offset : Longint; + // End +begin + FCompletionPort := CreateIoCompletionPort(FWatchHandle, 0, Longint(pointer(self)), 0); + ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf)); + if not ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree, + FFilter, @FBytesWritte, @FOverLapp, 0) then + begin + raise WFSError.Create(SysErrorMessage(GetLastError)); + Terminate; + end + else + begin + while not Terminated do + begin + GetQueuedCompletionStatus(FCompletionPort, FNumBytes, CompletionKey, FPOverLapp, INFINITE); + if CompletionKey <> 0 then + begin + //Synchronize(HandleEvent); + { .. Synchronize(HandleEvent) + , + -> http://forum.qip.ru/showthread.php?t=25200 } + Pointer(FileNotifyInfo) := @FWatchBuf[0]; + repeat + Offset := FileNotifyInfo^.NextEntryOffset; + InfoCallBack.FAction := FileNotifyInfo^.Action; + InfoCallBack.FDrive := FName; + SetString(InfoCallBack.FNewFileName,FileNotifyInfo^.FileName,FileNotifyInfo^.FileNameLength ); + InfoCallBack.FNewFileName := Trim(InfoCallBack.FNewFileName); + case FileNotifyInfo^.Action of + FILE_ACTION_RENAMED_OLD_NAME: FOldFileName := Trim(WideCharToString(@(FileNotifyInfo^.FileName[0]))); + FILE_ACTION_RENAMED_NEW_NAME: InfoCallBack.FOldFileName := FOldFileName; + end; + FInfoCallBack(InfoCallBack); + PChar(FileNotifyInfo) := PChar(FileNotifyInfo)+Offset; + until (Offset=0) or Terminated; + // End synchronize + ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf)); + FBytesWritte := 0; + ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree, FFilter, + @FBytesWritte, @FOverLapp, 0); + end + else + Terminate; + end + end +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/Global.inc b/plugins/MirandaNGHistoryToDB/Global.inc new file mode 100644 index 0000000000..cdbc123caa --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/Global.inc @@ -0,0 +1,2 @@ +// Replace Default Miranda History Module +{$DEFINE REPLDEFHISTMOD} diff --git a/plugins/MirandaNGHistoryToDB/Global.pas b/plugins/MirandaNGHistoryToDB/Global.pas new file mode 100644 index 0000000000..fc4cc4c4bb --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/Global.pas @@ -0,0 +1,1250 @@ +{ ############################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.5 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ############################################################################ } + +unit Global; + +interface + +uses + Windows, SysUtils, IniFiles, Messages, XMLIntf, XMLDoc, + FSMonitor, DCPcrypt2, DCPblockciphers, DCPsha1, DCPdes, DCPmd5, ActiveX, MapStream; + +type + TCopyDataType = (cdtString = 0, cdtImage = 1, cdtRecord = 2); + TCopyDataStruct = packed record + dwData: DWORD; + cbData: DWORD; + lpData: Pointer; + end; + //TByteArr = Array of Byte; + TArrayOfString = Array of String; + +const + htdPluginShortName = 'MirandaNGHistoryToDB'; + htdDescription_RU = ' .'; + htdDescription_EN = 'Storing the history in the database.'; + htdAuthor_EN = 'Michael Grigorev'; + htdAuthor_RU = 'Michael Grigorev'; + htdAuthorEmail = 'sleuthhound@gmail.com'; + htdCopyright_EN = '(c) 2011-2013 Michael Grigorev'; + htdCopyright_RU = '(c) 2011-2013 Michael Grigorev'; + htdHomePageURL = 'http://www.im-history.ru/'; + htdVerMajor = {MAJOR_VER}2{/MAJOR_VER}; + htdVerMinor = {MINOR_VER}5{/MINOR_VER}; + htdVerRelease = {SUB_VER}0{/SUB_VER}; + htdVerBuild = {BUILD}0{/BUILD}; + htdVersion = htdVerMajor shl 24 + htdVerMinor shl 16 + htdVerRelease shl 8 + htdVerBuild; + {$IFDEF WIN32} + htdPlatform = 'x86'; + {$ELSE} + htdPlatform = 'x64'; + {$ENDIF} + htdDBName = 'MirandaNGHistoryToDB'; + htdIMClientName = 'MirandaNG'; + {htdFLUpdateURL = 'http://addons.miranda-im.org/feed.php?dlfile=0'; + htdFLVersionURL = 'http://addons.miranda-im.org/details.php?action=viewfile&id=0'; + htdFLVersionPrefix= ''+htdPluginShortName+' '; + htdUpdateURL = 'http://www.im-history.ru/get.php?file=MirandaNGHistoryToDB'; + htdVersionURL = 'http://www.im-history.ru/get.php?file=MirandaNGHistoryToDB-Version'; + htdVersionPrefix = htdPluginShortName+' version '; + htdChangelogURL = 'http://www.im-history.ru/changelog/miranda.html';} + + // Generate your own unique id for your plugin. + // Do not use this UUID! + // Use Shift+Ctrl+G or uuidgen.exe to generate the uuuid + MIID_HISTORYTODBDLL:TGUID = '{1F83C057-C59F-483B-B82E-1AE5CA6138EB}'; + + MS_MHTD_SHOWHISTORY: PAnsiChar = 'MirandaNGHistoryToDB/ShowHistory'; + MS_MHTD_GETVERSION: PAnsiChar = 'MirandaNGHistoryToDB/GetVersion'; + MS_MHTD_SHOWCONTACTHISTORY: PAnsiChar = 'MirandaNGHistoryToDB/ShowContactHistory'; + + DefaultDBAddres = 'db01.im-history.ru'; + DefaultDBName = 'imhistory'; + ININame = 'HistoryToDB.ini'; + DefININame = 'DefaultUser.ini'; + MesLogName = 'HistoryToDBMes.sql'; + ErrLogName = 'HistoryToDBErr.log'; + ImportLogName = 'HistoryToDBImport.sql'; + ContactListName = 'ContactList.csv'; + ProtoListName = 'ProtoList.csv'; + DebugLogName = 'HistoryToDBDebug.log'; + MSG_LOG : WideString = 'insert into uin_%s values (null, %s, ''%s'', ''%s'', ''%s'', ''%s'', %s, ''%s'', ''%s'', ''%s'', null);'; + MSG_LOG_ORACLE : WideString = 'insert into uin_%s values (null, %s, ''%s'', ''%s'', ''%s'', ''%s'', %s, %s, ''%s'', ''%s'', null)'; + CHAT_MSG_LOG : WideString = 'insert into uin_chat_%s values (null, %s, ''%s'', ''%s'', ''%s'', ''%s'', %s, %s, %s, ''%s'', ''%s'', null);'; + CHAT_MSG_LOG_ORACLE : WideString = 'insert into uin_chat_%s values (null, %s, %s, ''%s'', ''%s'', ''%s'', %s, %s, %s, ''%s'', ''%s'', null)'; + // (01/01/1970) Unix Timestamp + UnixStartDate: TDateTime = 25569.0; + // HistoryToDBSync HistoryToDBViewer + EncryptKey = 'jsU6s2msoxghsKsn7'; + // + WM_LANGUAGECHANGED = WM_USER + 1; + dirLangs = 'langs\'; + defaultLangFile = 'English.xml'; + ThankYouText_Rus = ' .' + #13#10 + + ' (UksusoFF) .' + #13#10 + + ' .' + #13#10 + + ' . (HDHMETRO) .' + #13#10 + + 'Providence .' + #13#10 + + 'Cy6 RnQ.'; + ThankYouText_Eng = 'Anna Nikiforova for active testing of plug-in.' + #13#10 + + 'Kirill Uksusov (UksusoFF) for active testing of plug-in and new ideas.' + #13#10 + + 'Igor Guryanov for active testing of plug-in.' + #13#10 + + 'Vyacheslav S. (HDHMETRO) for active testing of plug-in.' + #13#10 + + 'Providence for active testing of plug-in and new ideas.' + #13#10 + + 'Cy6 for help in implementing the import history RnQ.'; + +var + hppCodepage: Cardinal; + hppVersionStr: AnsiString; + MetaContactsEnabled: Boolean; + MetaContactsProto: AnsiString; + WriteErrLog, AniEvents, EnableHistoryEncryption, ShowPluginButton, AddSpecialContact, BlockSpamMsg: Boolean; + EnableDebug, EnableCallBackDebug, ExPrivateChatName, GetContactList: Boolean; + SyncMethod, SyncInterval, SyncMessageCount, MaxErrLogSize: Integer; + DBType, DBName, DBUserName, DefaultLanguage: String; + //Global_AccountUIN: WideString; + //Global_AccountName: WideString; + //Global_CurrentAccountUIN: WideString; + //Global_CurrentAccountName: WideString; + Global_CurrentAccountProtoID: Integer; + Global_CurrentAccountProtoName, Global_CurrentAccountProtoAccount: WideString; + Glogal_History_Type: Integer; + //Global_ChatName: WideString; + Global_AboutForm_Showing: Boolean; + DllPath, DllName, ProfilePath, MyAccount: String; + MessageCount: Integer; + // + CoreLanguage: String; + AboutFormHandle: HWND; + ExportFormHandle: HWND; + LangDoc: IXMLDocument; + PluginPath: String = ''; + // + Cipher: TDCP_3des; + Digest: Array[0..19] of Byte; + Hash: TDCP_sha1; + // - + TFMsgLog: TextFile; + MsgLogOpened: Boolean; + TFErrLog: TextFile; + ErrLogOpened: Boolean; + TFDebugLog: TextFile; + DebugLogOpened: Boolean; + TFContactListLog: TextFile; + ContactListLogOpened: Boolean; + TFProtoListLog: TextFile; + ProtoListLogOpened: Boolean; + TFImportLog: TextFile; + ImportLogOpened: Boolean; + ExportFormDestroy: Boolean; + // MMF + FMap: TMapStream; + +function BoolToIntStr(Bool: Boolean): String; +function UnixToDateTime(USec: Longint): TDateTime; +function PrepareString(const Source : PWideChar) : WideString; +function MatchStrings(Source, Pattern: String): Boolean; +function ReadCustomINI(INIPath, CustomParams, DefaultParamsStr: String): String; +function EncryptMD5(Str: String): String; +function EncryptStr(const Str: String): String; +function SearchMainWindow(MainWindowName: pWideChar): Boolean; +function OpenLogFile(LogPath: String; LogType: Integer): Boolean; +function GetMyFileSize(const Path: String): Integer; +function ExtractFileNameEx(FileName: String; ShowExtension: Boolean): String; +function WideStringToString(const ws: WideString; codePage: Word): AnsiString; +function AnsiToWideString(const S: AnsiString; CodePage: Cardinal; InLength: Integer = -1): WideString; +function WideToAnsiString(const WS: WideString; CodePage: Cardinal; InLength: Integer = -1): AnsiString; +function Utf8ToWideChar(Dest: PWideChar; MaxDestChars: Integer; Source: PAnsiChar; SourceBytes: Integer; CodePage: Cardinal = CP_ACP): Integer; +function StrContactProtoToInt(Proto: AnsiString): Integer; +function UnixToLocalTime(tUnix :Longint): TDateTime; +function GetUserTempPath: WideString; +procedure IMDelay(Value: Cardinal); +procedure EncryptInit; +procedure EncryptFree; +procedure WriteInLog(LogPath: String; TextString: String; LogType: Integer); +procedure CloseLogFile(LogType: Integer); +procedure LoadINI(INIPath: String); +procedure OnSendMessageToAllComponent(Msg: String); +procedure OnSendMessageToOneComponent(WinName, Msg: String); +procedure WriteCustomINI(INIPath, CustomParams, ParamsStr: String); +procedure ProfileDirChangeCallBack(pInfo: TInfoCallBack); +// +procedure CoreLanguageChanged; +procedure MsgDie(Caption, Msg: WideString); +procedure MsgInf(Caption, Msg: WideString); +function GetLangStr(StrID: String): WideString; + +implementation + +uses Menu; + +function BoolToIntStr(Bool: Boolean): String; +begin + if Bool then + Result := '1' + else + Result := '0' +end; + +// Unix Timestamp DateTime +function UnixToDateTime(USec: Longint): TDateTime; +begin + Result := (Usec / 86400) + UnixStartDate; +end; + +// +function PrepareString(const Source : PWideChar) : WideString; +var + SLen,i : Cardinal; + WSTmp : WideString; + WChar : WideChar; +begin + Result := ''; + SLen := Length(WideString(Source)); + if (SLen>0) then + begin + for i:=1 to SLen do + begin + WChar:=WideString(Source)[i]; + case WChar of + #$09 :{tab} WSTmp:=WSTmp+'\t'; + #$0A :{line feed} WSTmp:=WSTmp+'\n'; + #$0D :{carriage return} WSTmp:=WSTmp+'\r'; + #$27 :{single quote mark aka apostrophe?} WSTmp:=WSTmp+WChar+WChar; + #$22, {double quote mark aka inch sign?} + #$5C, {backslash itself} + #$60 :{another single quote mark} WSTmp:=WSTmp+'\'+WChar; + else WSTmp := WSTmp + WChar; + end; + end; + Result := WSTmp; + end; +end; + +// LogType = 0 - MesLogName +// LogType = 1 - ErrLogName +// LogType = 2 - DebugLogName +// LogType = 3 - ContactListName +// LogType = 4 - ProtoListName +// LogType = 5 - ImportLogName +function OpenLogFile(LogPath: String; LogType: Integer): Boolean; +var + Path: WideString; +begin + if LogType = 0 then + Path := LogPath + MesLogName + else if LogType = 1 then + begin + Path := LogPath + ErrLogName; + if (LogType > 0) and (GetMyFileSize(Path) > MaxErrLogSize*1024) then + DeleteFile(Path); + end + else if LogType = 2 then + Path := LogPath + DebugLogName + else if LogType = 3 then + begin + Path := LogPath + ContactListName; + if FileExists(Path) then + begin + try + DeleteFile(Path); + except + end; + end; + end + else if LogType = 4 then + begin + Path := LogPath + ProtoListName; + if FileExists(Path) then + begin + try + DeleteFile(Path); + except + end; + end; + end + else + Path := LogPath + ImportLogName; + {$I-} + try + if LogType = 0 then + Assign(TFMsgLog, Path) + else if LogType = 1 then + Assign(TFErrLog, Path) + else if LogType = 2 then + Assign(TFDebugLog, Path) + else if LogType = 3 then + Assign(TFContactListLog, Path) + else if LogType = 4 then + Assign(TFProtoListLog, Path) + else + Assign(TFImportLog, Path); + if FileExists(Path) then + begin + if LogType = 0 then + Append(TFMsgLog) + else if LogType = 1 then + Append(TFErrLog) + else if LogType = 2 then + Append(TFDebugLog) + else if LogType = 3 then + Append(TFContactListLog) + else if LogType = 4 then + Append(TFProtoListLog) + else + Append(TFImportLog); + end + else + begin + if LogType = 0 then + Rewrite(TFMsgLog) + else if LogType = 1 then + Rewrite(TFErrLog) + else if LogType = 2 then + Rewrite(TFDebugLog) + else if LogType = 3 then + Rewrite(TFContactListLog) + else if LogType = 4 then + Rewrite(TFProtoListLog) + else + Rewrite(TFImportLog); + end; + Result := True; + except + on e : + Exception do + begin + CloseLogFile(LogType); + Result := False; + Exit; + end; + end; + {$I+} +end; + +// LogType = 0 - MesLogName +// LogType = 1 - ErrLogName +// LogType = 2 - DebugLogName +// LogType = 3 - ContactListName +// LogType = 4 - ProtoListName +procedure WriteInLog(LogPath: String; TextString: String; LogType: Integer); +var + Path: WideString; +begin + if LogType = 0 then + begin + if not MsgLogOpened then + MsgLogOpened := OpenLogFile(LogPath, 0); + Path := LogPath + MesLogName + end + else if LogType = 1 then + begin + if not ErrLogOpened then + ErrLogOpened := OpenLogFile(LogPath, 1); + Path := LogPath + ErrLogName; + if (LogType > 0) and (GetMyFileSize(Path) > MaxErrLogSize*1024) then + begin + CloseLogFile(LogType); + DeleteFile(Path); + if not OpenLogFile(LogPath, LogType) then + Exit; + end; + end + else if LogType = 2 then + begin + if not DebugLogOpened then + DebugLogOpened := OpenLogFile(LogPath, 2); + Path := LogPath + DebugLogName; + end + else if LogType = 3 then + begin + if not ContactListLogOpened then + ContactListLogOpened := OpenLogFile(LogPath, 3); + Path := LogPath + ContactListName; + end + else if LogType = 4 then + begin + if not ProtoListLogOpened then + ProtoListLogOpened := OpenLogFile(LogPath, 4); + Path := LogPath + ProtoListName; + end + else + begin + if not ImportLogOpened then + ImportLogOpened := OpenLogFile(LogPath, 5); + Path := LogPath + ImportLogName; + end; + {$I-} + try + if LogType = 0 then + WriteLn(TFMsgLog, TextString) + else if LogType = 1 then + WriteLn(TFErrLog, TextString) + else if LogType = 2 then + WriteLn(TFDebugLog, TextString) + else if LogType = 3 then + WriteLn(TFContactListLog, TextString) + else if LogType = 4 then + WriteLn(TFProtoListLog, TextString) + else + WriteLn(TFImportLog, TextString); + except + on e : + Exception do + begin + CloseLogFile(LogType); + Exit; + end; + end; + if MsgLogOpened then + CloseLogFile(0); + {$I+} +end; + +procedure CloseLogFile(LogType: Integer); +begin + {$I-} + if LogType = 0 then + begin + CloseFile(TFMsgLog); + MsgLogOpened := False; + end + else if LogType = 1 then + begin + CloseFile(TFErrLog); + ErrLogOpened := False; + end + else if LogType = 2 then + begin + CloseFile(TFDebugLog); + DebugLogOpened := False; + end + else if LogType = 3 then + begin + CloseFile(TFContactListLog); + ContactListLogOpened := False; + end + else if LogType = 4 then + begin + CloseFile(TFProtoListLog); + ProtoListLogOpened := False; + end + else + begin + CloseFile(TFImportLog); + ImportLogOpened := False; + end; + {$I+} +end; + +// , -1 +function GetMyFileSize(const Path: String): Integer; +var + FD: TWin32FindData; + FH: THandle; +begin + FH := FindFirstFile(PChar(Path), FD); + Result := 0; + if FH = INVALID_HANDLE_VALUE then + Exit; + Result := FD.nFileSizeLow; + if ((FD.nFileSizeLow and $80000000) <> 0) or + (FD.nFileSizeHigh <> 0) then + Result := -1; + //FindClose(FH); +end; + +// +procedure LoadINI(INIPath: String); +var + Path: WideString; + Temp: String; + INI: TIniFile; +begin + // + if not DirectoryExists(INIPath) then + CreateDir(INIPath); + Path := INIPath + ININame; + if FileExists(Path) then + begin + Ini := TIniFile.Create(Path); + DBType := INI.ReadString('Main', 'DBType', 'mysql'); // mysql postgresql + DBUserName := INI.ReadString('Main', 'DBUserName', 'username'); + SyncMethod := INI.ReadInteger('Main', 'SyncMethod', 1); + SyncInterval := INI.ReadInteger('Main', 'SyncInterval', 0); + + Temp := INI.ReadString('Main', 'WriteErrLog', '1'); + if Temp = '1' then WriteErrLog := True + else WriteErrLog := False; + + Temp := INI.ReadString('Main', 'ShowAnimation', '1'); + if Temp = '1' then AniEvents := True + else AniEvents := False; + + Temp := INI.ReadString('Main', 'EnableHistoryEncryption', '0'); + if Temp = '1' then EnableHistoryEncryption := True + else EnableHistoryEncryption := False; + + Temp := INI.ReadString('Main', 'AddSpecialContact', '1'); + if Temp = '1' then AddSpecialContact := True + else AddSpecialContact := False; + + DefaultLanguage := INI.ReadString('Main', 'DefaultLanguage', 'Russian'); + SyncMessageCount := INI.ReadInteger('Main', 'SyncMessageCount', 50); + + Temp := INI.ReadString('Main', 'ShowPluginButton', '1'); + if Temp = '1' then ShowPluginButton := True + else ShowPluginButton := False; + + Temp := INI.ReadString('Main', 'BlockSpamMsg', '0'); + if Temp = '1' then BlockSpamMsg := True + else BlockSpamMsg := False; + + Temp := INI.ReadString('Main', 'EnableExPrivateChatName', '0'); + if Temp = '1' then ExPrivateChatName := True + else ExPrivateChatName := False; + + Temp := INI.ReadString('Main', 'EnableDebug', '0'); + if Temp = '1' then EnableDebug := True + else EnableDebug := False; + + Temp := INI.ReadString('Main', 'EnableCallBackDebug', '0'); + if Temp = '1' then EnableCallBackDebug := True + else EnableCallBackDebug := False; + + MaxErrLogSize := INI.ReadInteger('Main', 'MaxErrLogSize', 20); + end + else + begin + INI := TIniFile.Create(path); + // - + DBType := 'mysql'; + DBName := DefaultDBName; + DBUserName := 'username'; + SyncMethod := 1; + SyncInterval := 0; + SyncMessageCount := 50; + WriteErrLog := True; + AniEvents := True; + ShowPluginButton := True; + EnableHistoryEncryption := False; + AddSpecialContact := True; + BlockSpamMsg := False; + EnableDebug := False; + EnableCallBackDebug := False; + MaxErrLogSize := 20; + // + INI.WriteString('Main', 'DBType', DBType); + INI.WriteString('Main', 'DBAddress', DefaultDBAddres); + INI.WriteString('Main', 'DBSchema', 'username'); + INI.WriteString('Main', 'DBPort', '3306'); + INI.WriteString('Main', 'DBName', DefaultDBName); + INI.WriteString('Main', 'DBUserName', DBUserName); + INI.WriteString('Main', 'DBPasswd', 'skGvQNyWUHcHohJS2+2r4A=='); + INI.WriteInteger('Main', 'SyncMethod', SyncMethod); + INI.WriteInteger('Main', 'SyncInterval', SyncInterval); + INI.WriteInteger('Main', 'SyncTimeCount', 40); + INI.WriteInteger('Main', 'SyncMessageCount', SyncMessageCount); + INI.WriteInteger('Main', 'NumLastHistoryMsg', 6); + INI.WriteString('Main', 'WriteErrLog', BoolToIntStr(WriteErrLog)); + INI.WriteString('Main', 'ShowAnimation', BoolToIntStr(AniEvents)); + INI.WriteString('Main', 'EnableHistoryEncryption', BoolToIntStr(EnableHistoryEncryption)); + INI.WriteString('Main', 'DefaultLanguage', CoreLanguage); + INI.WriteString('Main', 'HideHistorySyncIcon', '0'); + INI.WriteString('Main', 'ShowPluginButton', BoolToIntStr(ShowPluginButton)); + INI.WriteString('Main', 'AddSpecialContact', BoolToIntStr(AddSpecialContact)); + INI.WriteString('Main', 'BlockSpamMsg', BoolToIntStr(BlockSpamMsg)); + INI.WriteInteger('Main', 'MaxErrLogSize', MaxErrLogSize); + INI.WriteString('Main', 'AlphaBlend', '0'); + INI.WriteString('Main', 'AlphaBlendValue', '255'); + INI.WriteString('Main', 'EnableDebug', '0'); + INI.WriteString('Main', 'EnableCallBackDebug', '0'); + INI.WriteString('Fonts', 'FontInTitle', '183|-11|Verdana|0|96|8|Y|N|N|N|'); + INI.WriteString('Fonts', 'FontOutTitle', '8404992|-11|Verdana|0|96|8|Y|N|N|N|'); + INI.WriteString('Fonts', 'FontInBody', '-16777208|-11|Verdana|0|96|8|N|N|N|N|'); + INI.WriteString('Fonts', 'FontOutBody', '-16777208|-11|Verdana|0|96|8|N|N|N|N|'); + INI.WriteString('Fonts', 'FontService', '16711680|-11|Verdana|0|96|8|Y|N|N|N|'); + INI.WriteString('Fonts', 'TitleParagraph', '4|4|'); + INI.WriteString('Fonts', 'MessagesParagraph', '2|2|'); + INI.WriteString('HotKey', 'GlobalHotKey', '0'); + INI.WriteString('HotKey', 'SyncHotKey', 'Ctrl+Alt+F12'); + INI.WriteString('HotKey', 'ExSearchHotKey', 'Ctrl+F3'); + INI.WriteString('HotKey', 'ExSearchNextHotKey', 'F3'); + end; + INI.Free; +end; + +{ } +procedure WriteCustomINI(INIPath, CustomParams, ParamsStr: String); +var + Path: String; + INI: TIniFile; +begin + Path := INIPath + ININame; + if FileExists(Path) then + begin + INI := TIniFile.Create(Path); + try + INI.WriteString('Main', CustomParams, ParamsStr); + finally + INI.Free; + end; + end + else + begin + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - WriteCustomINI: ' + GetLangStr('SettingsErrSave'), 2); + MsgDie(htdPluginShortName, GetLangStr('SettingsErrSave')); + end; +end; + +{ } +function ReadCustomINI(INIPath, CustomParams, DefaultParamsStr: String): String; +var + Path: String; + INI: TIniFile; +begin + Path := INIPath + ININame; + if FileExists(Path) then + begin + INI := TIniFile.Create(Path); + try + Result := INI.ReadString('Main', CustomParams, DefaultParamsStr); + finally + INI.Free; + end; + end + else + begin + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ReadCustomINI: ' + GetLangStr('SettingsErrRead'), 2); + MsgDie(htdPluginShortName, GetLangStr('SettingsErrRead')); + end; +end; + +{ } +{ : + 001 - HistoryToDB.ini + 002 - + 003 - + 0040 - ( AntiBoss) + 0041 - ( AntiBoss) + 005 - + 0050 - MD5- + 0051 - MD5- + 0060 - + 0061 - + 007 - - + 008 - / + : + : + 008|0|UserID|UserName|ProtocolType + : + 008|2|ChatName + 009 - . + 010 - SQL-insert +} +procedure OnSendMessageToAllComponent(Msg: String); +var + HToDB: HWND; + copyDataStruct : TCopyDataStruct; + EncryptMsg, WinName: String; +begin + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" .', 2); + EncryptMsg := EncryptStr(Msg); + // HistoryToDBViewer + WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')'; + HToDB := FindWindow(nil, pWideChar(WinName)); + if HToDB <> 0 then + begin + copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString);; + copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char);; + copyDataStruct.lpData := PChar(EncryptMsg); + SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct)); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" ' + WinName, 2); + end; + // HistoryToDBSync + WinName := 'HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')'; + HToDB := FindWindow(nil, pWideChar(WinName)); + if HToDB <> 0 then + begin + copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString);; + copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char);; + copyDataStruct.lpData := PChar(EncryptMsg); + SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct)); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" ' + WinName, 2); + end; + // HistoryToDBImport + WinName := 'HistoryToDBImport for ' + htdIMClientName + ' ('+MyAccount+')'; + HToDB := FindWindow(nil, pWideChar(WinName)); + if HToDB <> 0 then + begin + copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString);; + copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char);; + copyDataStruct.lpData := PChar(EncryptMsg); + SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct)); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" ' + WinName, 2); + end; + // HistoryToDBUpdater + WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')'; + HToDB := FindWindow(nil, pWideChar(WinName)); + if HToDB <> 0 then + begin + copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString);; + copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char);; + copyDataStruct.lpData := PChar(EncryptMsg); + SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct)); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" ' + WinName, 2); + end; +end; + +procedure OnSendMessageToOneComponent(WinName, Msg: String); +var + HToDB: HWND; + copyDataStruct : TCopyDataStruct; + AppNameStr, EncryptMsg: String; +begin + // WinName + HToDB := FindWindow(nil, pWideChar(WinName)); + if HToDB <> 0 then + begin + EncryptMsg := EncryptStr(Msg); + copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString); + copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char); + copyDataStruct.lpData := PChar(EncryptMsg); + SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct)); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToOneComponent: "' + Msg + '" ' + WinName, 2); + end; +end; + +{ } +function SearchMainWindow(MainWindowName: pWideChar): Boolean; +var + HToDB: HWND; +begin + // + HToDB := FindWindow(nil, MainWindowName); + if HToDB <> 0 then + Result := True + else + Result := False +end; + +{ . + , (* ?). + ( ) . + : MatchStrings('David Stidolph','*St*') True. + C- Sean Stanley + Delphi David Stidolph} +function MatchStrings(Source, Pattern: String): Boolean; +var + pSource: array[0..255] of Char; + pPattern: array[0..255] of Char; + + function MatchPattern(element, pattern: PChar): Boolean; + + function IsPatternWild(pattern: PChar): Boolean; + begin + Result := StrScan(pattern, '*') <> nil; + if not Result then + Result := StrScan(pattern, '?') <> nil; + end; + + begin + if 0 = StrComp(pattern, '*') then + Result := True + else if (element^ = Chr(0)) and (pattern^ <> Chr(0)) then + Result := False + else if element^ = Chr(0) then + Result := True + else + begin + case pattern^ of + '*': if MatchPattern(element, @pattern[1]) then + Result := True + else + Result := MatchPattern(@element[1], pattern); + '?': Result := MatchPattern(@element[1], @pattern[1]); + else + if element^ = pattern^ then + Result := MatchPattern(@element[1], @pattern[1]) + else + Result := False; + end; + end; + end; +begin + StrPCopy(pSource, source); + StrPCopy(pPattern, pattern); + Result := MatchPattern(pSource, pPattern); +end; + +// +procedure MsgDie(Caption, Msg: WideString); +begin + //{$IFDEF UNICODE} + //MessageBoxW(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONERROR); + //{$ELSE} + //MessageBoxA(GetForegroundWindow, PAnsiChar(Msg), PAnsiChar(Caption), MB_ICONERROR); + //{$ENDIF} + MessageBox(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONERROR); +end; + +// +procedure MsgInf(Caption, Msg: WideString); +begin + //{$IFDEF UNICODE} + //MessageBoxW(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONINFORMATION); + //{$ELSE} + //MessageBoxA(GetForegroundWindow, PAnsiChar(Msg), PAnsiChar(Caption), MB_ICONINFORMATION); + //{$ENDIF} + MessageBox(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONINFORMATION); +end; + +// +function GetLangStr(StrID: String): WideString; +begin + if (not Assigned(LangDoc)) or (not LangDoc.Active) then + begin + Result := ''; + Exit; + end; + if LangDoc.ChildNodes['strings'].ChildNodes.FindNode(StrID) <> nil then + Result := LangDoc.ChildNodes['strings'].ChildNodes[StrID].Text + else + Result := 'String not found.'; +end; + +{ } +procedure ProfileDirChangeCallBack(pInfo: TInfoCallBack); +var + SettingsFormRequest: String; +begin + SettingsFormRequest := ReadCustomINI(ProfilePath, 'SettingsFormRequestSend', '0'); + if EnableCallBackDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ProfileDirChangeCallBack: SettingsFormRequestSend = ' + SettingsFormRequest + ' | FAction = ' + IntToStr(pInfo.FAction) + ' | FOldFileName = ' + pInfo.FOldFileName + ' | FNewFileName = ' + Trim(pInfo.FNewFileName), 2); + if (pInfo.FAction = 3) and (Trim(pInfo.FNewFileName) = 'HistoryToDB.ini') and (SettingsFormRequest = '0') then + begin + IMDelay(500); + LoadINI(ProfilePath); + CoreLanguage := DefaultLanguage; + if EnableCallBackDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ProfileDirChangeCallBack: HistoryToDB.ini . | = ' + CoreLanguage, 2); + // COM + // , , CoreLanguageChanged + // " CoInitialize" + // CoInitialize ActiveX + CoInitializeEx(nil, COINIT_MULTITHREADED); + // + CoreLanguageChanged; + // COM () + CoUninitialize(); + CoUninitialize(); + // + RebuildMainMenu; + // MMF + if SyncMethod = 0 then + begin + if not Assigned(FMap) then + begin + if EnableCallBackDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ProfileDirChangeCallBack: TMapStream', 2); + FMap := TMapStream.CreateEx('HistoryToDB for QIP ('+MyAccount+')',MAXDWORD,2000); + end; + end + else + begin + if Assigned(FMap) then + begin + FMap.Free; + FMap := nil; + end; + end; + end; +end; + +// MD5 +function EncryptMD5(Str: String): String; +var + Hash: TDCP_md5; + Digest: Array[0..15] of Byte; + I: Integer; + P: String; +begin + if Str <> '' then + begin + Hash:= TDCP_md5.Create(nil); + try + Hash.HashSize := 128; + Hash.Init; + Hash.UpdateStr(Str); + Hash.Final(Digest); + P := ''; + for I:= 0 to 15 do + P:= P + IntToHex(Digest[I], 2); + finally + Hash.Free; + end; + Result := P; + end + else + Result := 'MD5'; +end; + +// +procedure EncryptInit; +begin + Hash:= TDCP_sha1.Create(nil); + try + Hash.Init; + Hash.UpdateStr(EncryptKey); + Hash.Final(Digest); + finally + Hash.Free; + end; + Cipher := TDCP_3des.Create(nil); + try + Cipher.Init(Digest,Sizeof(Digest)*8,nil); + except + on E: Exception do + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - EncryptInit: ' + E.Message, 2); + end; +end; + +// +procedure EncryptFree; +begin + if Assigned(Cipher) then + begin + Cipher.Burn; + Cipher.Free; + end; +end; + +// +function EncryptStr(const Str: String): String; +begin + Result := ''; + if Str <> '' then + begin + Cipher.Reset; + Result := Cipher.EncryptString(Str); + end; +end; + +{ . + , . + : + FileName - , + ShowExtension - TRUE, + ( ), , , + , . } +function ExtractFileNameEx(FileName: String; ShowExtension: Boolean): String; +var + I: Integer; + S, S1: string; +begin + I := Length(FileName); + if I <> 0 then + begin + while (FileName[i] <> '\') and (i > 0) do + i := i - 1; + S := Copy(FileName, i + 1, Length(FileName) - i); + i := Length(S); + if i = 0 then + begin + Result := ''; + Exit; + end; + while (S[i] <> '.') and (i > 0) do + i := i - 1; + S1 := Copy(S, 1, i - 1); + if s1 = '' then + s1 := s; + if ShowExtension = True then + Result := s + else + Result := s1; + end + else + Result := ''; +end; + +function WideStringToString(const ws: WideString; codePage: Word): AnsiString; +var + l: integer; +begin + if ws = '' then + Result := '' + else + begin + l := WideCharToMultiByte(codePage, + WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR, + @ws[1], -1, nil, 0, nil, nil); + SetLength(Result, l - 1); + if l > 1 then + WideCharToMultiByte(codePage, + WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR, + @ws[1], -1, @Result[1], l - 1, nil, nil); + end; +end; + +function AnsiToWideString(const S: AnsiString; CodePage: Cardinal; InLength: Integer = -1): WideString; +var + InputLength, + OutputLength: Integer; +begin + Result := ''; + if S = '' then + exit; + if Codepage = CP_UTF8 then + begin + Result := UTF8ToWideString(S); // CP_UTF8 not supported on Windows 95 + end + else + begin + if InLength < 0 then + InputLength := Length(S) + else + InputLength := InLength; + OutputLength := MultiByteToWideChar(Codepage, 0, PAnsiChar(S), InputLength, nil, 0); + SetLength(Result, OutputLength); + MultiByteToWideChar(Codepage, MB_PRECOMPOSED, PAnsiChar(S), InputLength, PWideChar(Result), + OutputLength); + end; +end; + +function WideToAnsiString(const WS: WideString; CodePage: Cardinal; InLength: Integer = -1): AnsiString; +var + InputLength, + OutputLength: Integer; +begin + Result := ''; + if WS = '' then + exit; + if Codepage = CP_UTF8 then + Result := UTF8Encode(WS) // CP_UTF8 not supported on Windows 95 + else + begin + if InLength < 0 then + InputLength := Length(WS) + else + InputLength := InLength; + OutputLength := WideCharToMultiByte(Codepage, 0, PWideChar(WS), InputLength, nil, 0, + nil, nil); + SetLength(Result, OutputLength); + WideCharToMultiByte(Codepage, 0, PWideChar(WS), InputLength, PAnsiChar(Result), + OutputLength, nil, nil); + end; +end; + +function StrContactProtoToInt(Proto: AnsiString): Integer; +var + ProtoType: Integer; +begin + { + 0 - ICQ + 1 - Google Talk + 2 - MRA + 3 - Jabber + 4 - QIP.Ru + 5 - Facebook + 6 - VKontacte + 7 - Twitter + 8 - Social (LiveJournal) + 9 - AIM + 10 - IRC + 11 - MSN + 12 - YAHOO + 13 - GADU + 14 - SKYPE + 15 - MetaContacts + 16 - Unknown + } + if MatchStrings(LowerCase(Proto), 'icq*') then + ProtoType := 0 + else if MatchStrings(LowerCase(Proto), 'google talk*') then + ProtoType := 1 + else if MatchStrings(LowerCase(Proto), 'mrad*') then + ProtoType := 15 + else if MatchStrings(LowerCase(Proto), 'mra*') then + ProtoType := 2 + else if MatchStrings(LowerCase(Proto), 'jabber*') then + ProtoType := 3 + else if (LowerCase(Proto) = 'qip.ru') then + ProtoType := 4 + else if MatchStrings(LowerCase(Proto), 'facebook*') then + ProtoType := 5 + else if MatchStrings(LowerCase(Proto), 'vkontakte*') then + ProtoType := 6 + else if MatchStrings(LowerCase(Proto), '*') then + ProtoType := 6 + else if MatchStrings(LowerCase(Proto), 'twitter*') then + ProtoType := 7 + else if MatchStrings(LowerCase(Proto), 'livejournal*') then + ProtoType := 8 + else if MatchStrings(LowerCase(Proto), 'aim*') then + ProtoType := 9 + else if MatchStrings(LowerCase(Proto), 'irc*') then + ProtoType := 10 + else if MatchStrings(LowerCase(Proto), 'msn*') then + ProtoType := 11 + else if MatchStrings(LowerCase(Proto), 'yahoo*') then + ProtoType := 12 + else if MatchStrings(LowerCase(Proto), 'gadu*') then + ProtoType := 13 + else if MatchStrings(LowerCase(Proto), 'skype*') then + ProtoType := 14 + else if MatchStrings(LowerCase(Proto), 'metacontacts*') then + ProtoType := 15 + else + ProtoType := 16; + Result := ProtoType; +end; + +{ } +procedure IMDelay(Value: Cardinal); +var + F, N: Cardinal; +begin + N := 0; + while N <= (Value div 10) do + begin + SleepEx(1, True); + //Application.ProcessMessages; + Inc(N); + end; + F := GetTickCount; + repeat + //Application.ProcessMessages; + N := GetTickCount; + until (N - F >= (Value mod 10)) or (N < F); +end; + +function Utf8ToWideChar(Dest: PWideChar; MaxDestChars: Integer; Source: PAnsiChar; SourceBytes: Integer; CodePage: Cardinal = CP_ACP): Integer; +const + MB_ERR_INVALID_CHARS = 8; +var + Src,SrcEnd: PAnsiChar; + Dst,DstEnd: PWideChar; +begin + if (Source = nil) or (SourceBytes <= 0) then + begin + Result := 0; + end + else if (Dest = nil) or (MaxDestChars <= 0) then + begin + Result := -1; + end + else + begin + Src := Source; + SrcEnd := Source + SourceBytes; + Dst := Dest; + DstEnd := Dst + MaxDestChars; + while (PAnsiChar(Src) < PAnsiChar(SrcEnd)) and (Dst < DstEnd) do + begin + if (Byte(Src[0]) and $80) = 0 then + begin + Dst[0] := WideChar(Src[0]); + Inc(Src); + end + else if (Byte(Src[0]) and $E0) = $E0 then + begin + if Src + 2 >= SrcEnd then + break; + if (Src[1] = #0) or ((Byte(Src[1]) and $C0) <> $80) then + break; + if (Src[2] = #0) or ((Byte(Src[2]) and $C0) <> $80) then + break; + Dst[0] := WideChar(((Byte(Src[0]) and $0F) shl 12) + ((Byte(Src[1]) and $3F) shl 6) + + ((Byte(Src[2]) and $3F))); + Inc(Src, 3); + end + else if (Byte(Src[0]) and $E0) = $C0 then + begin + if Src + 1 >= SrcEnd then + break; + if (Src[1] = #0) or ((Byte(Src[1]) and $C0) <> $80) then + break; + Dst[0] := WideChar(((Byte(Src[0]) and $1F) shl 6) + ((Byte(Src[1]) and $3F))); + Inc(Src, 2); + end + else + begin + if MultiByteToWideChar(CodePage, MB_ERR_INVALID_CHARS, Src, 1, Dst, 1) = 0 then + Dst[0] := '?'; + Inc(Src); + end; + Inc(Dst); + end; + Dst[0] := #0; + Inc(Dst); + Result := Dst - Dest; + end; +end; + +// Unix Timestamp +function UnixToLocalTime(tUnix :Longint): TDateTime; +var + TimeZone :TTimeZoneInformation; + Bias :Integer; +begin + if (GetTimeZoneInformation(TimeZone) = TIME_ZONE_ID_DAYLIGHT) then + Bias := TimeZone.Bias + TimeZone.DaylightBias + else + Bias := TimeZone.Bias + TimeZone.StandardBias; + Result := EncodeDate(1970,1,1) - Bias / 1440 + tUnix / 86400; +end; + +{ } +procedure CoreLanguageChanged; +var + LangFile: String; +begin + if CoreLanguage = '' then + Exit; + try + LangFile := PluginPath + dirLangs + CoreLanguage + '.xml'; + if FileExists(LangFile) then + LangDoc.LoadFromFile(LangFile) + else + begin + if FileExists(PluginPath + dirLangs + defaultLangFile) then + LangDoc.LoadFromFile(PluginPath + dirLangs + defaultLangFile) + else + begin + MsgDie(htdPluginShortName, 'Not found any language file!'); + Exit; + end; + end; + SendMessage(AboutFormHandle, WM_LANGUAGECHANGED, 0, 0); + SendMessage(ExportFormHandle, WM_LANGUAGECHANGED, 0, 0); + except + on E: Exception do + begin + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - Error on CoreLanguageChanged: ' + Trim(E.Message) + ' | CoreLanguage: ' + CoreLanguage, 2); + MsgDie(htdPluginShortName, 'Error on CoreLanguageChanged: ' + E.Message + sLineBreak + + 'CoreLanguage: ' + CoreLanguage); + end; + end; +end; + +{ } +function GetUserTempPath: WideString; +var + UserPath: WideString; +begin + Result := ''; + SetLength(UserPath, MAX_PATH); + GetTempPath(MAX_PATH, PChar(UserPath)); + GetLongPathName(PChar(UserPath), PChar(UserPath), MAX_PATH); + SetLength(UserPath, StrLen(PChar(UserPath))); + Result := UserPath; +end; + +begin + hppVersionStr := AnsiString(Format('%d.%d.%d.%d',[htdVerMajor,htdVerMinor,htdVerRelease,htdVerBuild])); +end. diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Global.pas b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Global.pas new file mode 100644 index 0000000000..6747ee346d --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Global.pas @@ -0,0 +1,1583 @@ +{ ################################################################################ } +{ # # } +{ # IM-History - HistoryToDBUpdater v1.0 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ################################################################################ } + +unit Global; + +{$I jedi.inc} + +interface + +uses + Windows, Forms, Classes, SysUtils, IniFiles, DCPcrypt2, DCPblockciphers, DCPsha1, + DCPdes, DCPmd5, TypInfo, Messages, XMLIntf, XMLDoc, StrUtils, Types, TLHELP32, PsAPI, NTNative; + +type + TWinVersion = (wvUnknown,wv95,wv98,wvME,wvNT3,wvNT4,wvW2K,wvXP,wv2003,wvVista,wv7,wv2008,wv8); + TCopyDataType = (cdtString = 0, cdtImage = 1, cdtRecord = 2); + TDelim = set of Char; + TArrayOfString = Array of String; + TArrayOfCardinal = Array of Cardinal; + TProcessInfo = packed record + ProcessName: String; + PID: DWord; + ProcessFullCmd: String; + ProcessPath: String; + ProcessParamCmd: String; + end; + TProcessInfoArray = Array of TProcessInfo; + +const + ProgramsName = 'HistoryToDBUpdater'; + ProgramsVer : WideString = '2.5.0.0'; + DefaultDBAddres = 'db01.im-history.ru'; + DefaultDBName = 'imhistory'; + ININame = 'HistoryToDB.ini'; + ErrLogName = 'HistoryToDBUpdaterErr.log'; + DebugLogName = 'HistoryToDBUpdaterDebug.log'; + // (01/01/1970) Unix Timestamp + UnixStartDate: TDateTime = 25569.0; + // DBPasswd + EncryptKey = 'jsU6s2msoxghsKsn7'; + // + WM_LANGUAGECHANGED = WM_USER + 1; + dirLangs = 'langs\'; + dirSQLUpdate = 'update\'; + defaultLangFile = 'English.xml'; + // End + WM_MSGBOX = WM_USER + 2; + uURL = 'http://im-history.ru/update/get.php?file=HistoryToDB-Update'; + {$IFDEF WIN32} + PlatformType = 'x86'; + {$ELSE} + PlatformType = 'x64'; + {$ENDIF} +var + WriteErrLog: Boolean; + EnableDebug, AlphaBlendEnable: Boolean; + MaxErrLogSize, AlphaBlendEnableValue: Integer; + DBType, DefaultLanguage, IMClientType: String; + PluginPath, ProfilePath: WideString; + Global_MainForm_Showing, Global_AboutForm_Showing: Boolean; + Global_IMProcessPID: DWORD; + // + IMUseProxy, IMProxyAuth: Boolean; + IMProxyAddress, IMProxyPort, IMProxyUser, IMProxyUserPagsswd: String; + DBUserName, MyAccount: String; + IMClientPlatformType: String; + UpdateServer: String; + // + Cipher: TDCP_3des; + Digest: Array[0..19] of Byte; + Hash: TDCP_sha1; + // + CoreLanguage: String; + MainFormHandle: HWND; + AboutFormHandle: HWND; + LangDoc: IXMLDocument; + +function BoolToIntStr(Bool: Boolean): String; +function IsNumber(const S: String): Boolean; +function DateTimeToUnix(ConvDate: TDateTime): Longint; +function UnixToDateTime(USec: Longint): TDateTime; +function PrepareString(const Source : PWideChar) : AnsiString; +function EncryptStr(const Str: String): String; +function DecryptStr(const Str: String): String; +function EncryptMD5(Str: String): String; +function MatchStrings(source, pattern: String): Boolean; +function ExtractFileNameEx(FileName: String; ShowExtension: Boolean): String; +function ReadCustomINI(INIPath, CustomSection, CustomParams, DefaultParamsStr: String): String; +function GetSystemDefaultUILanguage: UINT; stdcall; external kernel32 name 'GetSystemDefaultUILanguage'; +function GetSysLang: AnsiString; +function Tok(Sep: String; var S: String): String; +function GetMyFileSize(const Path: String): Integer; +function SearchMainWindow(MainWindowName: pWideChar): Boolean; +function StrContactProtoToInt(Proto: AnsiString): Integer; +function IsProcessRun(ProcessName: String): Boolean; overload; +function IsProcessRun(ProcessName, WinCaption: String): Boolean; overload; +function GetProcessID(ExeFileName: String): Cardinal; +//function GetProcessIDMulti(ExeFileName: String): TArrayOfString; +function GetProcessIDMulti2(ExeFileName: String): TArrayOfCardinal; +function GetThreadsOfProcess(APID: Cardinal): TIntegerDynArray; +function KillTask(ExeFileName: String): Integer; overload; +function KillTask(ExeFileName, WinCaption: String): Integer; overload; +function ProcessTerminate(dwPID: Cardinal): Boolean; +function ProcCloseEnum(hwnd: THandle; data: Pointer):BOOL;stdcall; +function ProcQuitEnum(hwnd: THandle; data: Pointer):BOOL;stdcall; +function GetProcessFileName(PID: DWord; FullPath: Boolean=True): String; +function GetProcessCmdLine(dwProcessId : DWORD): String; +function SetProcessDebugPrivelege: Boolean; +function EndProcess(IMClientExeName: String; EndType: Integer; EndProcess: Boolean): TProcessInfoArray; +function GetUserTempPath: WideString; +//function ProcGetCaptionForHandleEnum(hwnd: THandle; data: Pointer):BOOL;stdcall; +function EnumThreadWndProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall; +function StringToParts(sString:String; tdDelim:TDelim): TArrayOfString; +function ExtractWord(const AString: string; const ADelimiter: Char; const ANumber: integer): string; +procedure EncryptInit; +procedure EncryptFree; +procedure WriteInLog(LogPath: String; TextString: String; LogType: Integer); +procedure LoadINI(INIPath: String; NotSettingsForm: Boolean); +procedure WriteCustomINI(INIPath, CustomSection, CustomParams, ParamsStr: String); +procedure MakeTransp(winHWND: HWND); +procedure OnSendMessageToAllComponent(Msg: String); +procedure IMDelay(Value: Cardinal); +procedure OnSendMessageToOneComponent(WinName, Msg: String); +function DetectWinVersion: TWinVersion; +function DetectWinVersionStr: String; +// +procedure MsgDie(Caption, Msg: WideString); +procedure MsgInf(Caption, Msg: WideString); +function GetLangStr(StrID: String): WideString; + +implementation + +function BoolToIntStr(Bool: Boolean): String; +begin + if Bool then + Result := '1' + else + Result := '0' +end; + +function IsNumber(const S: string): Boolean; +begin + Result := True; + try + StrToInt(S); + except + Result := False; + end; +end; + +// DateTime Unix Timestamp +function DateTimeToUnix(ConvDate: TDateTime): Longint; +begin + Result := Round((ConvDate - UnixStartDate) * 86400); +end; + +// Unix Timestamp DateTime +function UnixToDateTime(USec: Longint): TDateTime; +begin + Result := (Usec / 86400) + UnixStartDate; +end; + +// +function PrepareString(const Source : PWideChar) : AnsiString; +var + SLen,i : Cardinal; + WSTmp : WideString; + WChar : WideChar; +begin + Result := ''; + SLen := Length(WideString(Source)); + if (SLen>0) then + begin + for i:=1 to SLen do + begin + WChar:=WideString(Source)[i]; + case WChar of + #$09 :{tab} WSTmp:=WSTmp+'\t'; + #$0A :{line feed} WSTmp:=WSTmp+'\n'; + #$0D :{carriage return} WSTmp:=WSTmp+'\r'; + #$27 :{single quote mark aka apostrophe?} WSTmp:=WSTmp+WChar+WChar; + #$22, {double quote mark aka inch sign?} + #$5C, {backslash itself} + #$60 :{another single quote mark} WSTmp:=WSTmp+'\'+WChar; + else WSTmp := WSTmp + WChar; + end; + end; + Result := AnsiString(WSTmp); + end; +end; + +// +procedure EncryptInit; +begin + Hash:= TDCP_sha1.Create(nil); + try + Hash.Init; + Hash.UpdateStr(EncryptKey); + Hash.Final(Digest); + finally + Hash.Free; + end; + Cipher := TDCP_3des.Create(nil); + Cipher.Init(Digest,Sizeof(Digest)*8,nil); +end; + +// +procedure EncryptFree; +begin + if Assigned(Cipher) then + begin + Cipher.Burn; + Cipher.Free; + end; +end; + +// +function EncryptStr(const Str: String): String; +begin + Result := ''; + if Str <> '' then + begin + Cipher.Reset; + Result := Cipher.EncryptString(Str); + end; +end; + +// +function DecryptStr(const Str: String): String; +begin + Result := ''; + if Str <> '' then + begin + Cipher.Reset; + Result := Cipher.DecryptString(Str);; + end; +end; + +// MD5 +function EncryptMD5(Str: String): String; +var + Hash: TDCP_md5; + Digest: Array[0..15] of Byte; + I: Integer; + P: String; +begin + if Str <> '' then + begin + Hash:= TDCP_md5.Create(nil); + try + Hash.HashSize := 128; + Hash.Init; + Hash.UpdateStr(Str); + Hash.Final(Digest); + P := ''; + for I:= 0 to 15 do + P:= P + IntToHex(Digest[I], 2); + finally + Hash.Free; + end; + Result := P; + end + else + Result := 'MD5'; +end; + +// LogType = 0 - ErrLogName +// LogType = 1 - DebugLogName +procedure WriteInLog(LogPath: String; TextString: String; LogType: Integer); +var + Path: WideString; + TF: TextFile; +begin + if LogType = 0 then + begin + Path := LogPath + ErrLogName; + if (GetMyFileSize(Path) > MaxErrLogSize*1024) then + DeleteFile(Path); + end + else + Path := LogPath + DebugLogName; + {$I-} + try + Assign(TF,Path); + if FileExists(Path) then + Append(TF) + else + Rewrite(TF); + Writeln(TF,TextString); + CloseFile(TF); + except + on e : + Exception do + begin + CloseFile(TF); + Exit; + end; + end; + {$I+} +end; + +// +procedure LoadINI(INIPath: String; NotSettingsForm: Boolean); +var + Path: WideString; + Temp: String; + INI: TIniFile; +begin + // + if not DirectoryExists(INIPath) then + CreateDir(INIPath); + Path := INIPath + ININame; + if FileExists(Path) then + begin + INI := TIniFile.Create(Path); + try + DBType := INI.ReadString('Main', 'DBType', 'Unknown'); + DBUserName := INI.ReadString('Main', 'DBUserName', 'username'); + DefaultLanguage := INI.ReadString('Main', 'DefaultLanguage', 'English'); + IMClientType := INI.ReadString('Main', 'IMClientType', 'Unknown'); + MyAccount := INI.ReadString('Main', 'MyAccount', DBUserName); + + Temp := INI.ReadString('Main', 'WriteErrLog', '0'); + if Temp = '1' then WriteErrLog := True + else WriteErrLog := False; + + MaxErrLogSize := INI.ReadInteger('Main', 'MaxErrLogSize', 20); + + Temp := INI.ReadString('Main', 'EnableDebug', '0'); + if Temp = '1' then EnableDebug := True + else EnableDebug := False; + + Temp := INI.ReadString('Main', 'AlphaBlend', '0'); + if Temp = '1' then AlphaBlendEnable := True + else AlphaBlendEnable := False; + AlphaBlendEnableValue := INI.ReadInteger('Main', 'AlphaBlendValue', 255); + + Temp := INI.ReadString('Proxy', 'UseProxy', '0'); + if Temp = '1' then IMUseProxy := True + else IMUseProxy := False; + + IMProxyAddress := INI.ReadString('Proxy', 'ProxyAddress', '127.0.0.1'); + IMProxyPort := INI.ReadString('Proxy', 'ProxyPort', '3128'); + + Temp := INI.ReadString('Proxy', 'ProxyAuth', '0'); + if Temp = '1' then IMProxyAuth := True + else IMProxyAuth := False; + + IMProxyUser := INI.ReadString('Proxy', 'ProxyUser', ''); + IMProxyUserPagsswd := INI.ReadString('Proxy', 'ProxyUserPasswd', ''); + if IMProxyUserPagsswd <> '' then + IMProxyUserPagsswd := DecryptStr(IMProxyUserPagsswd); + + IMClientPlatformType := INI.ReadString('Main', 'IMClientPlatformType', PlatformType); + UpdateServer := INI.ReadString('Updater', 'UpdateServer', uURL); + finally + INI.Free; + end; + end + else + begin + INI := TIniFile.Create(path); + try + // - + DBType := 'Unknown'; + DefaultLanguage := 'English'; + IMClientType := 'Unknown'; + WriteErrLog := True; + MaxErrLogSize := 20; + EnableDebug := False; + AlphaBlendEnable := False; + AlphaBlendEnableValue := 255; + IMUseProxy := False; + IMProxyAddress := '127.0.0.1'; + IMProxyPort := '3128'; + IMProxyAuth := False; + IMProxyUser := ''; + IMProxyUserPagsswd := ''; + // + INI.WriteString('Main', 'DBType', DBType); + INI.WriteString('Main', 'DefaultLanguage', DefaultLanguage); + INI.WriteString('Main', 'IMClientType', IMClientType); + INI.WriteString('Main', 'WriteErrLog', BoolToIntStr(WriteErrLog)); + INI.WriteInteger('Main', 'MaxErrLogSize', MaxErrLogSize); + INI.WriteString('Main', 'EnableDebug', BoolToIntStr(EnableDebug)); + INI.WriteString('Main', 'AlphaBlend', BoolToIntStr(AlphaBlendEnable)); + INI.WriteInteger('Main', 'AlphaBlendValue', AlphaBlendEnableValue); + INI.WriteString('Proxy', 'UseProxy', BoolToIntStr(IMUseProxy)); + INI.WriteString('Proxy', 'ProxyAddress', IMProxyAddress); + INI.WriteString('Proxy', 'ProxyPort', IMProxyPort); + INI.WriteString('Proxy', 'ProxyAuth', BoolToIntStr(IMProxyAuth)); + INI.WriteString('Proxy', 'ProxyUser', IMProxyUser); + INI.WriteString('Proxy', 'ProxyUserPasswd', IMProxyUserPagsswd); + INI.WriteString('Updater', 'UpdateServer', uURL); + finally + INI.Free; + end; + end; +end; + +{ . + , (* ?). + ( ) . + : MatchStrings('David Stidolph','*St*') True. + C- Sean Stanley + Delphi David Stidolph} +function MatchStrings(source, pattern: String): Boolean; +var + pSource: array[0..255] of Char; + pPattern: array[0..255] of Char; + + function MatchPattern(element, pattern: PChar): Boolean; + + function IsPatternWild(pattern: PChar): Boolean; + begin + Result := StrScan(pattern, '*') <> nil; + if not Result then + Result := StrScan(pattern, '?') <> nil; + end; + + begin + if 0 = StrComp(pattern, '*') then + Result := True + else if (element^ = Chr(0)) and (pattern^ <> Chr(0)) then + Result := False + else if element^ = Chr(0) then + Result := True + else + begin + case pattern^ of + '*': if MatchPattern(element, @pattern[1]) then + Result := True + else + Result := MatchPattern(@element[1], pattern); + '?': Result := MatchPattern(@element[1], @pattern[1]); + else + if element^ = pattern^ then + Result := MatchPattern(@element[1], @pattern[1]) + else + Result := False; + end; + end; + end; +begin + StrPCopy(pSource, source); + StrPCopy(pPattern, pattern); + Result := MatchPattern(pSource, pPattern); +end; + +{ . + , . + : + FileName - , + ShowExtension - TRUE, + ( ), , , + , . } +function ExtractFileNameEx(FileName: String; ShowExtension: Boolean): String; +var + I: Integer; + S, S1: string; +begin + I := Length(FileName); + if I <> 0 then + begin + while (FileName[i] <> '\') and (i > 0) do + i := i - 1; + S := Copy(FileName, i + 1, Length(FileName) - i); + i := Length(S); + if i = 0 then + begin + Result := ''; + Exit; + end; + while (S[i] <> '.') and (i > 0) do + i := i - 1; + S1 := Copy(S, 1, i - 1); + if s1 = '' then + s1 := s; + if ShowExtension = True then + Result := s + else + Result := s1; + end + else + Result := ''; +end; + +{ MessageBox } +procedure MakeTransp(winHWND: HWND); +var + exStyle: Longint; +begin + exStyle := GetWindowLong(winHWND, GWL_EXSTYLE); + if (exStyle and WS_EX_LAYERED = 0) then + begin + exStyle := exStyle or WS_EX_LAYERED; + SetwindowLong(winHWND, GWL_EXSTYLE, exStyle); + end; + SetLayeredWindowAttributes(winHWND, 0, AlphaBlendEnableValue, LWA_ALPHA); +end; + +// +procedure MsgDie(Caption, Msg: WideString); +begin + if AlphaBlendEnable then + PostMessage(GetForegroundWindow, WM_USER + 2, 0, 0); + MessageBoxW(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONERROR); +end; + +// +procedure MsgInf(Caption, Msg: WideString); +begin + if AlphaBlendEnable then + PostMessage(GetForegroundWindow, WM_USER + 2, 0, 0); + MessageBoxW(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONINFORMATION); +end; + +// +function GetLangStr(StrID: String): WideString; +begin + if (not Assigned(LangDoc)) or (not LangDoc.Active) then + begin + Result := ''; + Exit; + end; + if LangDoc.ChildNodes['strings'].ChildNodes.FindNode(StrID) <> nil then + Result := LangDoc.ChildNodes['strings'].ChildNodes[StrID].Text + else + Result := 'String not found.'; +end; + +function GetSysLang: AnsiString; +var + WinLanguage: Array [0..50] of Char; +begin + //Result := Lo(GetSystemDefaultUILanguage); + VerLanguageName(GetSystemDefaultLangID, WinLanguage, 50); + Result := StrPas(WinLanguage); +end; + +{ S , -, + Sep. , + S } +function Tok(Sep: String; var S: String): String; + + function isoneof(c, s: string): Boolean; + var + iTmp: integer; + begin + Result := False; + for iTmp := 1 to Length(s) do + begin + if c = Copy(s, iTmp, 1) then + begin + Result := True; + Exit; + end; + end; + end; + +var + c, t: String; +begin + if s = '' then + begin + Result := s; + Exit; + end; + c := Copy(s, 1, 1); + while isoneof(c, sep) do + begin + s := Copy(s, 2, Length(s) - 1); + c := Copy(s, 1, 1); + end; + t := ''; + while (not isoneof(c, sep)) and (s <> '') do + begin + t := t + c; + s := Copy(s, 2, length(s) - 1); + c := Copy(s, 1, 1); + end; + Result := t; +end; + +{ } +procedure WriteCustomINI(INIPath, CustomSection, CustomParams, ParamsStr: String); +var + Path: String; + IsFileClosed: Boolean; + sFile: DWORD; + INI: TIniFile; +begin + Path := INIPath + ININame; + if FileExists(Path) then + begin + // - + IsFileClosed := False; + repeat + sFile := CreateFile(PChar(Path),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + if (sFile <> INVALID_HANDLE_VALUE) then + begin + CloseHandle(sFile); + IsFileClosed := True; + end; + until IsFileClosed; + // End + INI := TIniFile.Create(Path); + try + INI.WriteString(CustomSection, CustomParams, ParamsStr); + finally + INI.Free; + end; + end + else + MsgDie(ProgramsName, GetLangStr('SettingsErrSave')); +end; + +{ } +function ReadCustomINI(INIPath, CustomSection, CustomParams, DefaultParamsStr: String): String; +var + Path: String; + INI: TIniFile; +begin + Path := INIPath + ININame; + INI := TIniFile.Create(Path); + if FileExists(Path) then + begin + try + Result := INI.ReadString(CustomSection, CustomParams, DefaultParamsStr); + finally + INI.Free; + end; + end + else + MsgDie(ProgramsName, GetLangStr('SettingsErrRead')); +end; + +// , -1 +function GetMyFileSize(const Path: String): Integer; +var + FD: TWin32FindData; + FH: THandle; +begin + FH := FindFirstFile(PChar(Path), FD); + Result := 0; + if FH = INVALID_HANDLE_VALUE then + Exit; + Result := FD.nFileSizeLow; + if ((FD.nFileSizeLow and $80000000) <> 0) or + (FD.nFileSizeHigh <> 0) then + Result := -1; + //FindClose(FH); +end; + +{ } +function SearchMainWindow(MainWindowName: pWideChar): Boolean; +var + HToDB: HWND; +begin + // + HToDB := FindWindow(nil, MainWindowName); + if HToDB <> 0 then + Result := True + else + Result := False +end; + +{ } +{ : + 001 - HistoryToDB.ini + 002 - + 003 - + 0040 - ( AntiBoss) + 0041 - ( AntiBoss) + 0050 - MD5- + 0051 - MD5- + 0060 - + 0061 - + 007 - - + 008 - / + : + : + 008|0|UserID|UserName|ProtocolType + : + 008|2|ChatName + 009 - . +} +procedure OnSendMessageToAllComponent(Msg: String); +var + HToDB: HWND; + copyDataStruct : TCopyDataStruct; + EncryptMsg, WinName: String; +begin + EncryptMsg := EncryptStr(Msg); + WinName := 'HistoryToDBViewer for ' + IMClientType; + // HistoryToDBViewer + HToDB := FindWindow(nil, pChar(WinName)); + if HToDB <> 0 then + begin + copyDataStruct.dwData := Integer(cdtString); + copyDataStruct.cbData := 2*Length(EncryptMsg); + copyDataStruct.lpData := PChar(EncryptMsg); + SendMessage(HToDB, WM_COPYDATA, 0, Integer(@copyDataStruct)); + end; + WinName := 'HistoryToDBSync for ' + IMClientType; + // HistoryToDBSync + HToDB := FindWindow(nil, pChar(WinName)); + if HToDB <> 0 then + begin + copyDataStruct.dwData := Integer(cdtString); + copyDataStruct.cbData := 2*Length(EncryptMsg); + copyDataStruct.lpData := PChar(EncryptMsg); + SendMessage(HToDB, WM_COPYDATA, 0, Integer(@copyDataStruct)); + end; + WinName := 'HistoryToDBImport for ' + IMClientType; + // HistoryToDBImport + HToDB := FindWindow(nil, pChar(WinName)); + if HToDB <> 0 then + begin + copyDataStruct.dwData := Integer(cdtString); + copyDataStruct.cbData := 2*Length(EncryptMsg); + copyDataStruct.lpData := PChar(EncryptMsg); + SendMessage(HToDB, WM_COPYDATA, 0, Integer(@copyDataStruct)); + end; +end; + +procedure OnSendMessageToOneComponent(WinName, Msg: String); +var + HToDB: HWND; + copyDataStruct : TCopyDataStruct; + EncryptMsg: String; +begin + EncryptMsg := EncryptStr(Msg); + // HistoryToDBViewer + HToDB := FindWindow(nil, pChar(WinName)); + if HToDB <> 0 then + begin + copyDataStruct.dwData := Integer(cdtString); + copyDataStruct.cbData := 2*Length(EncryptMsg); + copyDataStruct.lpData := PChar(EncryptMsg); + SendMessage(HToDB, WM_COPYDATA, 0, Integer(@copyDataStruct)); + end; +end; + +function StrContactProtoToInt(Proto: AnsiString): Integer; +var + ProtoType: Integer; +begin + { + 0 - ICQ + 1 - Google Talk + 2 - MRA + 3 - Jabber + 4 - QIP.Ru + 5 - Facebook + 6 - VKontacte + 7 - Twitter + 8 - Social (LiveJournal) + 9 - AIM + 10 - IRC + 11 - MSN + 12 - YAHOO + 13 - GADU + 14 - SKYPE + 15 - Unknown + } + if MatchStrings(LowerCase(Proto), 'icq*') then + ProtoType := 0 + else if MatchStrings(LowerCase(Proto), 'google talk*') then + ProtoType := 1 + else if MatchStrings(LowerCase(Proto), 'mra*') then + ProtoType := 2 + else if MatchStrings(LowerCase(Proto), 'jabber*') then + ProtoType := 3 + else if (LowerCase(Proto) = 'qip.ru') then + ProtoType := 4 + else if MatchStrings(LowerCase(Proto), 'facebook*') then + ProtoType := 5 + else if MatchStrings(LowerCase(Proto), 'vkontakte*') then + ProtoType := 6 + else if MatchStrings(Proto, '*') then + ProtoType := 6 + else if MatchStrings(Proto, '*') then + ProtoType := 6 + else if MatchStrings(LowerCase(Proto), 'twitter*') then + ProtoType := 7 + else if MatchStrings(LowerCase(Proto), 'livejournal*') then + ProtoType := 8 + else if MatchStrings(LowerCase(Proto), 'aim*') then + ProtoType := 9 + else if MatchStrings(LowerCase(Proto), 'irc*') then + ProtoType := 10 + else if MatchStrings(LowerCase(Proto), 'msn*') then + ProtoType := 11 + else if MatchStrings(LowerCase(Proto), 'yahoo*') then + ProtoType := 12 + else if MatchStrings(LowerCase(Proto), 'gadu*') then + ProtoType := 13 + else if MatchStrings(LowerCase(Proto), 'skype*') then + ProtoType := 14 + else + ProtoType := 15; + Result := ProtoType; +end; + +{ } +procedure IMDelay(Value: Cardinal); +var + F, N: Cardinal; +begin + N := 0; + while N <= (Value div 10) do + begin + SleepEx(1, True); + Application.ProcessMessages; + Inc(N); + end; + F := GetTickCount; + repeat + Application.ProcessMessages; + N := GetTickCount; + until (N - F >= (Value mod 10)) or (N < F); +end; + +{ WM_CLOSE PID } +function ProcCloseEnum(hwnd: THandle; data: Pointer):BOOL;stdcall; +var + Pid: DWORD; +begin + Result := True; + GetWindowThreadProcessId(hwnd, pid); + if Pid = DWORD(data) then + begin + PostMessage(hwnd, WM_CLOSE, 0, 0); + end; +end; + +{ WM_QUIT PID } +function ProcQuitEnum(hwnd: THandle; data: Pointer):BOOL;stdcall; +var + Pid: DWORD; +begin + Result := True; + GetWindowThreadProcessId(hwnd, pid); + if Pid = DWORD(data) then + begin + PostMessage(hwnd, WM_QUIT, 0, 0); + end; +end; + +{function ProcGetCaptionForHandleEnum(hwnd: THandle; data: Pointer):BOOL;stdcall; +var + Pid: DWORD; + WinCaption: Array [0 .. 255] of Char; +begin + Result := True; + GetWindowThreadProcessId(hwnd, pid); + if Pid = DWORD(data) then + begin + //PostMessage(hwnd, WM_QUIT, 0, 0); + GetWindowText(hwnd, WinCaption, SizeOf(WinCaption)); + if WinCaption <> '' then + MsgInf('ProcGetCaptionForHandleEnum', WinCaption); + end; +end;} + +{ WM_QUIT + TArrayOfString + + + EndType = 0 - WM_CLOSE + EndType = 1 - WM_QUIT + } +function EndProcess(IMClientExeName: String; EndType: Integer; EndProcess: Boolean): TProcessInfoArray; +var + I: Integer; + ProcessPIDListArray: TArrayOfCardinal; + MyFullCMD, MyCMD, ProcessCmdLine: String; +begin + SetLength(Result, 0); + SetLength(ProcessPIDListArray, 0); + ProcessPIDListArray := GetProcessIDMulti2(IMClientExeName); + for I := 0 to High(ProcessPIDListArray) do + begin + SetLength(Result, Length(Result)+1); + Result[Length(Result)-1].ProcessName := IMClientExeName; + Result[Length(Result)-1].PID := ProcessPIDListArray[I]; + ProcessCmdLine := GetProcessCmdLine(ProcessPIDListArray[I]); + if ProcessCmdLine = '' then + begin + + if (IMClientExeName = 'qip.exe') and (DetectWinVersionStr = 'Windows 7') then + ProcessCmdLine := '"C:\Program Files\QIP 2012\qip.exe"' + else if (IMClientExeName = 'qip.exe') and (DetectWinVersionStr <> 'Windows 7') then + ProcessCmdLine := '"C:\Program Files (x86)\QIP 2012\qip.exe"' + + else if (IMClientExeName = 'miranda32.exe') and (IMClientType = 'Miranda') and (DetectWinVersionStr = 'Windows 7') then + ProcessCmdLine := '"C:\Program Files\Miranda IM\miranda32.exe"' + else if (IMClientExeName = 'miranda32.exe') and (IMClientType = 'Miranda') and (DetectWinVersionStr <> 'Windows 7') then + ProcessCmdLine := '"C:\Program Files (x86)\Miranda IM\miranda32.exe"' + else if (IMClientExeName = 'miranda64.exe') and (IMClientType = 'Miranda') and (DetectWinVersionStr = 'Windows 7') then + ProcessCmdLine := '"C:\Program Files\Miranda IM\miranda32.exe"' + else if (IMClientExeName = 'miranda64.exe') and (IMClientType = 'Miranda') and (DetectWinVersionStr <> 'Windows 7') then + ProcessCmdLine := '"C:\Program Files\Miranda IM\miranda32.exe"' + + else if (IMClientExeName = 'miranda32.exe') and (IMClientType = 'MirandaNG') and (DetectWinVersionStr = 'Windows 7') then + ProcessCmdLine := '"C:\Program Files\Miranda NG\miranda32.exe"' + else if (IMClientExeName = 'miranda32.exe') and (IMClientType = 'MirandaNG') and (DetectWinVersionStr <> 'Windows 7') then + ProcessCmdLine := '"C:\Program Files (x86)\Miranda NG\miranda32.exe"' + else if (IMClientExeName = 'miranda64.exe') and (IMClientType = 'MirandaNG') and (DetectWinVersionStr = 'Windows 7') then + ProcessCmdLine := '"C:\Program Files\Miranda NG\miranda32.exe"' + else if (IMClientExeName = 'miranda64.exe') and (IMClientType = 'MirandaNG') and (DetectWinVersionStr <> 'Windows 7') then + ProcessCmdLine := '"C:\Program Files\Miranda NG\miranda32.exe"' + + else if (IMClientExeName = 'skype.exe') and (DetectWinVersionStr = 'Windows 7') then + ProcessCmdLine := '"C:\Program Files (x86)\Skype\Phone\skype.exe"' + else if (IMClientExeName = 'skype.exe') and (DetectWinVersionStr <> 'Windows 7') then + ProcessCmdLine := '"C:\Program Files\Skype\Phone\skype.exe"' + else + ProcessCmdLine := IMClientExeName; + end; + Result[Length(Result)-1].ProcessFullCmd := ProcessCmdLine; + //MsgInf('EndProcess', 'ProcessName: ' + Result[Length(Result)-1].ProcessName + #13 + 'PID: ' + IntToStr(Result[Length(Result)-1].PID) + #13 + 'ProcessFullCmd: ' + Result[Length(Result)-1].ProcessFullCmd); + //Result[Length(Result)-1] := GetProcessFileName(StrToInt(ProcessListArray[I]), True); + // CMD + // "C:/Program Files/PostgreSQL/9.1/bin/postgres.exe" "--forklog" "244" "248" + // + // "C:\Program Files\Microsoft Firewall Client 2004\FwcAgent.exe" + if Result[Length(Result)-1].ProcessFullCmd[1] = '"' then + begin + MyFullCMD := Result[Length(Result)-1].ProcessFullCmd; + Delete(MyFullCMD, 1, 1); + MyCMD := Copy(MyFullCMD, 1, Pos('"', MyFullCMD)-1); + Delete(MyFullCMD, 1, Pos('"', MyFullCMD)+1); + Result[Length(Result)-1].ProcessPath := MyCMD; + Result[Length(Result)-1].ProcessParamCmd := MyFullCMD; + end + else + begin + MyFullCMD := Result[Length(Result)-1].ProcessFullCmd; + // CMD + // C:\WINDOWS\system32\svchost -k DcomLaunch + if Pos(' ', MyFullCMD) > 0 then + begin + MyCMD := Copy(MyFullCMD, 1, Pos(' ', MyFullCMD)-1); + Delete(MyFullCMD, 1, Pos(' ', MyFullCMD)); + Result[Length(Result)-1].ProcessPath := MyCMD; + Result[Length(Result)-1].ProcessParamCmd := MyFullCMD; + end + // CMD + // C:\WINDOWS\system32\lsass.exe + else + begin + Result[Length(Result)-1].ProcessPath := MyFullCMD; + Result[Length(Result)-1].ProcessParamCmd := ''; + end; + end; + // + if EndProcess then + begin + if EndType = 0 then //WM_CLOSE + EnumWindows(@ProcCloseEnum, ProcessPIDListArray[I]) + else //WM_QUIT + EnumWindows(@ProcQuitEnum, ProcessPIDListArray[I]); + end; + end; +end; + +function EnumThreadWndProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall; +var + WindowClassName: String; + WindowClassNameLength: Integer; + WinCaption: Array [0 .. 255] of Char; + ThreadProcessWinCaption: String; + PID: DWORD; +begin + Result := True; + ThreadProcessWinCaption := String(LPARAM); + GetWindowThreadProcessId(hwnd, pid); + SetLength(WindowClassName, MAX_PATH); + WindowClassNameLength := GetClassName(hwnd, PChar(WindowClassName), MAX_PATH); + GetWindowText(hwnd, WinCaption, SizeOf(WinCaption)); + if MatchStrings(LeftStr(WindowClassName, WindowClassNameLength), 'TMain*') and (WinCaption = ThreadProcessWinCaption) then + begin + Global_IMProcessPID := PID; + //MsgInf('EnumThreadWndProc', 'PID : ' + IntToStr(PID) + #10#13 + ': ' + LeftStr(WindowClassName, WindowClassNameLength) + #10#13 + ' : ' + WinCaption); + end; + // . + //EnumChildWindows(hwnd, @EnumThreadWndProc, lParam); +end; + +{ ID } +function GetThreadsOfProcess(APID: Cardinal): TIntegerDynArray; +var + lSnap: DWord; + lThread: TThreadEntry32; +begin + Result := nil; + if APID <> INVALID_HANDLE_VALUE then + begin + lSnap := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (lSnap <> INVALID_HANDLE_VALUE) then + begin + lThread.dwSize := SizeOf(TThreadEntry32); + if Thread32First(lSnap, lThread) then + repeat + if lThread.th32OwnerProcessID = APID then + begin + SetLength(Result, Length(Result) + 1); + Result[High(Result)] := lThread.th32ThreadID; + end; + until not Thread32Next(lSnap, lThread); + CloseHandle(lSnap); + end; + end; +end; + +{ } +function IsProcessRun(ProcessName: String): Boolean; overload; +var + Snapshot: THandle; + Proc: TProcessEntry32; +begin + Result := False; + Snapshot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if Snapshot = INVALID_HANDLE_VALUE then + Exit; + Proc.dwSize := SizeOf(TProcessEntry32); + if Process32First(Snapshot, Proc) then + repeat + if Proc.szExeFile = ProcessName then + begin + Result := True; + Break; + end; + until not Process32Next(Snapshot, Proc); + CloseHandle(Snapshot); +end; + +function IsProcessRun(ProcessName, WinCaption: String): Boolean; overload; +var + Snapshot: THandle; + Proc: TProcessEntry32; + lThreads: TIntegerDynArray; + J: Integer; +begin + Result := False; + Snapshot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if Snapshot = INVALID_HANDLE_VALUE then + Exit; + Proc.dwSize := SizeOf(TProcessEntry32); + if Process32First(Snapshot, Proc) then + repeat + if ((UpperCase(ExtractFileName(Proc.szExeFile)) = UpperCase(ProcessName)) + or (UpperCase(Proc.szExeFile) = UpperCase(ProcessName))) then + begin + // + //EnumWindows(@ProcGetCaptionForHandleEnum, FProcessEntry32.th32ProcessID); + // ClassName + Global_IMProcessPID := 0; + lThreads := GetThreadsOfProcess(Proc.th32ProcessID); + for J := Low(lThreads) to High(lThreads) do + EnumThreadWindows(lThreads[J], @EnumThreadWndProc, LPARAM(WinCaption)); + if Global_IMProcessPID = Proc.th32ProcessID then + //MsgInf('IsProcessRun', ' '); + Result := True; + // Ends + end; + until not Process32Next(Snapshot, Proc); + CloseHandle(Snapshot); +end; + +{ } +function KillTask(ExeFileName: String): Integer; +const + PROCESS_TERMINATE=$0001; +var + ContinueLoop: BOOL; + FSnapshotHandle: THandle; + FProcessEntry32: TProcessEntry32; +begin + Result := 0; + FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); + FProcessEntry32.dwSize := Sizeof(FProcessEntry32); + ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); + while Integer(ContinueLoop) <> 0 do + begin + if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) + or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then + Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0), + FProcessEntry32.th32ProcessID), 0)); + ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); + end; + CloseHandle(FSnapshotHandle); +end; + +{ } +function KillTask(ExeFileName, WinCaption: String): Integer; overload; +const + PROCESS_TERMINATE=$0001; +var + ContinueLoop: BOOL; + FSnapshotHandle: THandle; + FProcessEntry32: TProcessEntry32; + lThreads: TIntegerDynArray; + J: Integer; +begin + Result := 0; + FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); + FProcessEntry32.dwSize := Sizeof(FProcessEntry32); + ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); + while Integer(ContinueLoop) <> 0 do + begin + if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) + or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then + begin + // + //EnumWindows(@ProcGetCaptionForHandleEnum, FProcessEntry32.th32ProcessID); + // ClassName + Global_IMProcessPID := 0; + lThreads := GetThreadsOfProcess(FProcessEntry32.th32ProcessID); + for J := Low(lThreads) to High(lThreads) do + EnumThreadWindows(lThreads[J], @EnumThreadWndProc, LPARAM(WinCaption)); + if Global_IMProcessPID = FProcessEntry32.th32ProcessID then + //MsgInf('KillTask', ' '); + Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0), FProcessEntry32.th32ProcessID), 0)); + // Ends + end; + ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); + end; + CloseHandle(FSnapshotHandle); +end; + +{ PID } +function GetProcessID(ExeFileName: String): Cardinal; +var + ContinueLoop: BOOL; + FSnapshotHandle: THandle; + FProcessEntry32: TProcessEntry32; +begin + Result := 0; + FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); + FProcessEntry32.dwSize := Sizeof(FProcessEntry32); + ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); + repeat + if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) + or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then + begin + Result := FProcessEntry32.th32ProcessID; + Break; + end; + ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); + until not ContinueLoop; + CloseHandle(FSnapshotHandle); +end; + +{ PID } +{function GetProcessIDMulti(ExeFileName: String): TArrayOfString; +var + ContinueLoop: BOOL; + FSnapshotHandle: THandle; + FProcessEntry32: TProcessEntry32; +begin + SetLength(Result, 0); + //Result := 0; + FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); + FProcessEntry32.dwSize := Sizeof(FProcessEntry32); + ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); + repeat + if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) + or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then + begin + SetLength(Result, Length(Result)+1); + Result[Length(Result)-1] := IntToStr(FProcessEntry32.th32ProcessID); + end; + ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); + until not ContinueLoop; + CloseHandle(FSnapshotHandle); +end;} + +{ PID } +function GetProcessIDMulti2(ExeFileName: String): TArrayOfCardinal; +var + ContinueLoop: BOOL; + FSnapshotHandle: THandle; + FProcessEntry32: TProcessEntry32; +begin + SetLength(Result, 0); + //Result := 0; + FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); + FProcessEntry32.dwSize := Sizeof(FProcessEntry32); + ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); + repeat + if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) + or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then + begin + SetLength(Result, Length(Result)+1); + Result[Length(Result)-1] := FProcessEntry32.th32ProcessID; + end; + ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); + until not ContinueLoop; + CloseHandle(FSnapshotHandle); +end; + +{ PID } +function GetProcessFileName(PID: DWord; FullPath: Boolean=True): String; +var + Handle: THandle; +begin + Result := ''; + Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID); + try + if Handle <> 0 then + begin + SetLength(Result, MAX_PATH); + if FullPath then + begin + if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then + SetLength(Result, StrLen(PChar(Result))) + else + Result := ''; + end + else + begin + if GetModuleBaseNameA(Handle, 0, PAnsiChar(Result), MAX_PATH) > 0 then + SetLength(Result, StrLen(PChar(Result))) + else + Result := ''; + end; + end; + finally + CloseHandle(Handle); + end; +end; + +{ PID } +function GetProcessCmdLine(dwProcessId : DWORD): String; +const + STATUS_SUCCESS = $00000000; + SE_DEBUG_NAME = 'SeDebugPrivilege'; + ProcessWow64Information = 26; +var + ProcessHandle : THandle; + ProcessBasicInfo : PROCESS_BASIC_INFORMATION; + ReturnLength : DWORD; + lpNumberOfBytesRead : ULONG_PTR; + TokenHandle : THandle; + lpLuid : TOKEN_PRIVILEGES; + OldlpLuid : TOKEN_PRIVILEGES; + Rtl : RTL_USER_PROCESS_PARAMETERS; + Peb : _PEB; + IsProcessx64 : Boolean; + {$IFDEF CPUX64} + PEBBaseAddress32 : Pointer; + Peb32 : _PEB32; + Rtl32 : RTL_USER_PROCESS_PARAMETERS32; + {$ENDIF} + Ws: WideString; +begin + Result:=''; + if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TokenHandle) then + begin + try + if not LookupPrivilegeValue(nil, SE_DEBUG_NAME, lpLuid.Privileges[0].Luid) then + RaiseLastOSError + else + begin + lpLuid.PrivilegeCount := 1; + lpLuid.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; + ReturnLength := 0; + OldlpLuid := lpLuid; + // SeDebugPrivilege + if not AdjustTokenPrivileges(TokenHandle, False, lpLuid, SizeOf(OldlpLuid), OldlpLuid, ReturnLength) then RaiseLastOSError; + end; + + ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, dwProcessId); + if ProcessHandle = 0 then RaiseLastOSError + else + try + IsProcessx64 := ProcessIsX64(ProcessHandle); + + {$IFNDEF CPUX64} + if IsProcessx64 then + raise Exception.Create('Only 32 bits processes are supported'); + {$ENDIF} + + {$IFDEF CPUX64} + if IsProcessx64 then + begin + {$ENDIF} + // PROCESS_BASIC_INFORMATION PEB + if (NtQueryInformationProcess(ProcessHandle,0{=>ProcessBasicInformation},@ProcessBasicInfo, SizeOf(ProcessBasicInfo), @ReturnLength)=STATUS_SUCCESS) and (ReturnLength=SizeOf(ProcessBasicInfo)) then + begin + // PEB + if not ReadProcessMemory(ProcessHandle, ProcessBasicInfo.PEBBaseAddress, @Peb, sizeof(Peb), lpNumberOfBytesRead) then + RaiseLastOSError + else + begin + // RTL_USER_PROCESS_PARAMETERS + if not ReadProcessMemory(ProcessHandle, Peb.ProcessParameters, @Rtl, SizeOf(Rtl), lpNumberOfBytesRead) then + RaiseLastOSError + else + begin + SetLength(ws,(Rtl.CommandLine.Length div 2)); + if not ReadProcessMemory(ProcessHandle,Rtl.CommandLine.Buffer,PWideChar(ws),Rtl.CommandLine.Length,lpNumberOfBytesRead) then + RaiseLastOSError + else + Result := String(ws); + end; + end; + end + else + RaiseLastOSError; + {$IFDEF CPUX64} + end + else + begin + // PEB + if NtQueryInformationProcess(ProcessHandle, ProcessWow64Information, @PEBBaseAddress32, SizeOf(PEBBaseAddress32), nil)=STATUS_SUCCESS then + begin + // PEB + if not ReadProcessMemory(ProcessHandle, PEBBaseAddress32, @Peb32, sizeof(Peb32), lpNumberOfBytesRead) then + RaiseLastOSError + else + begin + // RTL_USER_PROCESS_PARAMETERS + if not ReadProcessMemory(ProcessHandle, Pointer(Peb32.ProcessParameters), @Rtl32, SizeOf(Rtl32), lpNumberOfBytesRead) then + RaiseLastOSError + else + begin + SetLength(ws,(Rtl32.CommandLine.Length div 2)); + if not ReadProcessMemory(ProcessHandle, Pointer(Rtl32.CommandLine.Buffer), PWideChar(ws), Rtl32.CommandLine.Length, lpNumberOfBytesRead) then + RaiseLastOSError + else + Result := String(Ws); + end; + end; + end + else + RaiseLastOSError; + end; + {$ENDIF} + finally + CloseHandle(ProcessHandle); + end; + finally + CloseHandle(TokenHandle); + end; + end + else + RaiseLastOSError; +end; + +{ SeDebugPrivilege } +function SetProcessDebugPrivelege: Boolean; +var + hToken: THandle; + tp: TTokenPrivileges; + rl: Cardinal; +begin + Result := False; + if not OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES,hToken) then + Exit; + try + if not LookupPrivilegeValue(nil,'SeDebugPrivilege', tp.Privileges[0].Luid) then + Exit; + tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; + tp.PrivilegeCount := 1; + Result := AdjustTokenPrivileges(hToken,false,tp,0,nil,rl) and (GetLastError=0); + finally + CloseHandle(hToken); + end +end; + +// . +// , . +// 'SeDebugPrivilege' +// ( +// . +// / . +// . , +// - . +// , . +function ProcessTerminate(dwPID: Cardinal): Boolean; +var + hToken:THandle; + SeDebugNameValue:Int64; + tkp:TOKEN_PRIVILEGES; + ReturnLength:Cardinal; + hProcess:THandle; +begin + Result := False; + // SeDebugPrivilege + // + if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken ) then + Exit; + // LUID + if not LookupPrivilegeValue(nil, 'SeDebugPrivilege', SeDebugNameValue) then + begin + CloseHandle(hToken); + Exit; + end; + tkp.PrivilegeCount := 1; + tkp.Privileges[0].Luid := SeDebugNameValue; + tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; + // + AdjustTokenPrivileges(hToken, False, tkp, SizeOf(tkp), tkp, ReturnLength); + if GetLastError() <> ERROR_SUCCESS then + Exit; + // . SeDebugPrivilege, + // + // + hProcess := OpenProcess(PROCESS_TERMINATE, FALSE, dwPID); + if hProcess = 0 then + Exit; + // + if not TerminateProcess(hProcess, DWORD(-1)) then + Exit; + CloseHandle( hProcess ); + // + tkp.Privileges[0].Attributes := 0; + AdjustTokenPrivileges(hToken, FALSE, tkp, SizeOf(tkp), tkp, ReturnLength); + if GetLastError() <> ERROR_SUCCESS then + Exit; + Result := True; +end; + +function StringToParts(sString: String; tdDelim: TDelim): TArrayOfString; +var + iCounter,iBegin:Integer; +begin + if length(sString)>0 then + begin + include(tdDelim, #0); + iBegin:=1; + SetLength(Result, 0); + for iCounter:=1 to Length(sString)+1 do + begin + if(sString[iCounter] in tdDelim) then + begin + SetLength(Result, Length(Result)+1); + Result[Length(Result)-1] := Copy(sString, iBegin, iCounter-iBegin); + iBegin := iCounter+1; + end; + end; + end; +end; + +{ Edit1.Text := ExtractWord(ExtractWord('admin:login:password', ':', 3)); //'password' } +function ExtractWord(const AString: string; const ADelimiter: Char; const ANumber: integer): string; +var + i, j, k: integer; +begin + i := 1; + k := 1; + while k <> ANumber do + begin + if AString[i] = ADelimiter then + begin + Inc(k); + end; + Inc(i); + end; + j := i + 1; + while (j <= Length(AString)) and (AString[j] <> ADelimiter) do + Inc(j); + Result := Copy(AString, i, j - i); +end; + +{ } +function GetUserTempPath: WideString; +var + UserPath: WideString; +begin + Result := ''; + SetLength(UserPath, MAX_PATH); + GetTempPath(MAX_PATH, PChar(UserPath)); + GetLongPathName(PChar(UserPath), PChar(UserPath), MAX_PATH); + SetLength(UserPath, StrLen(PChar(UserPath))); + Result := UserPath; +end; + +{ +DwMajorVersion:DWORD - Windows + + Windows 95 - 4 + Windows 98 - 4 + Windows Me - 4 + Windows NT 3.51 - 3 + Windows NT 4.0 - 4 + Windows 2000 - 5 + Windows XP - 5 + +DwMinorVersion: DWORD - + + Windows 95 - 0 + Windows 98 - 10 + Windows Me - 90 + Windows NT 3.51 - 51 + Windows NT 4.0 - 0 + Windows 2000 - 0 + Windows XP - 1 + + +DwBuildNumber: DWORD + Win NT 4 - + Win 9x - - / - + + +dwPlatformId: DWORD + + VER_PLATFORM_WIN32s Win32s on Windows 3.1. + VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 9x + VER_PLATFORM_WIN32_NT Win32 on Windows NT, 2000 + + +SzCSDVersion:DWORD + NT - Phar ServicePack + 9x - . , +} +function DetectWinVersion: TWinVersion; +var + OSVersionInfo : TOSVersionInfo; +begin + Result := wvUnknown; // + OSVersionInfo.dwOSVersionInfoSize := sizeof(TOSVersionInfo); + if GetVersionEx(OSVersionInfo) + then + begin + case OSVersionInfo.DwMajorVersion of + 3: Result := wvNT3; // Windows NT 3 + 4: case OSVersionInfo.DwMinorVersion of + 0: if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT + then Result := wvNT4 // Windows NT 4 + else Result := wv95; // Windows 95 + 10: Result := wv98; // Windows 98 + 90: Result := wvME; // Windows ME + end; + 5: case OSVersionInfo.DwMinorVersion of + 0: Result := wvW2K; // Windows 2000 + 1: Result := wvXP; // Windows XP + 2: Result := wv2003; // Windows 2003 + 3: Result := wvVista; // Windows Vista + end; + 6: case OSVersionInfo.DwMinorVersion of + 0: Result := wv2008; // Windows 2008 + 1: Result := wv7; // Windows 7 + end; + 7: case OSVersionInfo.DwMinorVersion of + 1: Result := wv8; // Windows 8 + end; + end; + end; +end; + +function DetectWinVersionStr: String; +const + VersStr : Array[TWinVersion] of String = ( + 'Unknown OS', + 'Windows 95', + 'Windows 98', + 'Windows ME', + 'Windows NT 3', + 'Windows NT 4', + 'Windows 2000', + 'Windows XP', + 'Windows Server 2003', + 'Windows Vista', + 'Windows 7', + 'Windows Server 2008', + 'Windows 8'); +begin + Result := VersStr[DetectWinVersion]; +end; + +begin +end. diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dpr b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dpr new file mode 100644 index 0000000000..62b3039fd9 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dpr @@ -0,0 +1,32 @@ +{ ################################################################################ } +{ # # } +{ # IM-History - HistoryToDBUpdater v1.0 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ################################################################################ } + +program HistoryToDBUpdater; + +uses + madExcept, + madLinkDisAsm, + madListHardware, + madListProcesses, + madListModules, + Forms, + Main in 'Main.pas' {MainForm}, + Global in 'Global.pas'; + +{$R *.res} + +begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.Title := 'HistoryToDBUpdater'; + Application.CreateForm(TMainForm, MainForm); + if MainForm.RunAppDone then + Application.Run; +end. diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dproj b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dproj new file mode 100644 index 0000000000..72aa3a5ce1 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dproj @@ -0,0 +1,197 @@ + + + {939BF92A-9B69-4A14-B992-518631C54279} + HistoryToDBUpdater.dpr + True + Release + 3 + Application + VCL + 14.4 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + false + false + 1049 + false + 00400000 + false + false + Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;CFBundleExecutable= + + + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + true + HistoryToDBUpdater_Icon1.ico + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + $(BDS)\bin\default_app.manifest + + + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + 1033 + true + HistoryToDBUpdater_Icon1.ico + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + $(BDS)\bin\default_app.manifest + + + false + RELEASE;$(DCC_Define) + false + 0 + + + true + true + madExcept;$(DCC_Define) + true + 3 + HistoryToDBUpdater_Icon.ico + ..\..\..\bin10\Release\Plugins\ + ..\..\..\bin10\Release\Plugins\ + ..\..\..\bin10\Release\Obj\hpp\ + ..\..\..\bin10\Release\Obj\hpp\ + true + 1033 + 5 + CompanyName=http://www.im-history.ru;FileDescription=HistoryToDBUpdater;FileVersion=2.5.0.0;InternalName=HistoryToDBUpdater;LegalCopyright=Michael Grigorev;LegalTrademarks=http://www.im-history.ru;OriginalFilename=HistoryToDBUpdater.exe;ProductName=HistoryToDBUpdater;ProductVersion=1.0.0.0;Comments=http://www.im-history.ru + 2 + + + true + 2 + madExcept;$(DCC_Define) + true + 5 + true + HistoryToDBUpdater_Icon.ico + 3 + ..\..\..\bin10\Release64\Plugins\ + ..\..\..\bin10\Release64\Plugins\ + 1033 + true + ..\..\..\bin10\Release64\Obj\hpp\ + CompanyName=http://www.im-history.ru;FileDescription=HistoryToDBUpdater;FileVersion=2.5.0.0;InternalName=HistoryToDBUpdater;LegalCopyright=Michael Grigorev;LegalTrademarks=http://www.im-history.ru;OriginalFilename=HistoryToDBUpdater.exe;ProductName=HistoryToDBUpdater;ProductVersion=1.0.0.0;Comments=http://www.im-history.ru + ..\..\..\bin10\Release64\Obj\hpp\ + + + DEBUG;$(DCC_Define) + true + false + + + + MainSource + + +
MainForm
+
+ + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + +
+ + Delphi.Personality.12 + + + + + HistoryToDBUpdater.dpr + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1049 + 1251 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + + + + + + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + True + True + + + 12 + + + +
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.manifest b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.manifest new file mode 100644 index 0000000000..812068c2ab --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.manifest @@ -0,0 +1,21 @@ + + + +HistoryToDBUpdater + + + + + + diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.mes b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.mes new file mode 100644 index 0000000000..1fcb334c1d --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.mes @@ -0,0 +1,163 @@ +[GeneralSettings] +MesVersion=4 +HandleExceptions=1 +LinkInCode=1 +AppendMapFileToBinary=1 +NoOwnMadExceptSettings=0 +CheckFileCrc=1 +CheckForFrozenMainThread=0 +FreezeTimeout=60000 +ReportLeaks=0 +WindowsLogo=0 +CrashOnBuffer=0 +CrashOnUnderrun=0 +AutomaticallySaveBugReport=1 +AutoSaveBugReportIfNotSent=1 +AutomaticallyMailBugReport=0 +AutoMailProgressBox=0 +CopyBugReportToClipboard=0 +SuspendAllRunningThreads=0 +ShowPleaseWaitBox=1 +PleaseWaitIcon=plwait1 +AutomaticallyContinueApplication=0 +AutomaticallyRestartApplication=0 +AutomaticallyCloseApplication=0 +SendInBackground=1 +SendHelper=196608 +Send32Icon=send321 +UploadViaHttp=0 +HttpServer= +HttpSsl=0 +HttpPort=0 +HttpAccount= +HttpPassword= +UploadToFogBugz=0 +UploadToBugZilla=0 +UploadToMantis=0 +BugTrackerAccount= +BugTrackerPassword= +BugTrackerProject= +BugTrackerArea= +BugTrackerAssignTo= +MailAsSmtpServer=0 +MailAsSmtpClient=0 +SmtpServer= +SmtpSsl=0 +SmtpTls=0 +SmtpPort=0 +SmtpAccount= +SmtpPassword= +MailViaMapi=1 +MailViaMailto=1 +MailAddress=sleuthhound@gmail.com +BugReportFile=bugreport.txt +AttachBugReport=1 +AttachBugReportFile=1 +DeleteBugReportFile=1 +BugReportSendAs=bugreport.txt +BugReportZip= +ScreenShotDepth=8 +ScreenShotAppOnly=0 +ScreenShotSendAs=screenshot.png +ScreenShotZip= +AdditionalAttachments= +AppendBugReports=1 +BugReportFileSize=100000 +DontSaveDuplicateExceptions=1 +DontSaveDuplicateFreezings=1 +DuplicateExceptionDefinition=1 +DuplicateFreezeDefinition=2 +ShowExceptionBox=1 +OkBtnText=&OK +DetailsBtnText=&Details +PleaseWaitTitle=Information +PleaseWaitText=Please wait a moment... +BugTrackerTitle=%25appname%25, %25exceptMsg%25 +BugTrackerDescr=error details: %0d%0a%25errorDetails%25 +MailSubject=bug report +MailBody=please find the bug report attached +SendBoxTitle=Sending bug report... +PrepareAttachMsg=Preparing attachments... +MxLookupMsg=Searching for mail server... +ConnectMsg=Connecting to server... +SendMailMsg=Sending mail... +FieldsMsg=Setting fields... +SendAttachMsg=Sending attachments... +SendFinalizeMsg=Finalizing... +MailFailureMsg=Sorry, sending the bug report didn't work. +VersionVariable= +[ExceptionBox] +ShowButtonMailBugReport=1 +ShowButtonSaveBugReport=0 +ShowButtonPrintBugReport=0 +ShowButtonShowBugReport=1 +ShowButtonContinueApplication=1 +ShowButtonRestartApplication=1 +ShowButtonCloseApplication=1 +IconButtonSendBugReport=send1 +IconButtonSaveBugReport=save1 +IconButtonPrintBugReport=print1 +IconButtonShowBugReport=show1 +IconButtonContinueApplication=continue1 +IconButtonCantContinueApplication=cantContinue1 +IconButtonRestartApplication=restart1 +IconButtonCloseApplication=close1 +FocusedButton=0 +SendAssistant=SendAssistant +SaveAssistant=SaveAssistant +PrintAssistant=PrintAssistant +AutomaticallyShowBugReport=0 +NoOwnerDrawButtons=0 +BigExceptionIcon=big1 +TitleBar=%25appname%25 +ExceptionMessage=An error occurred in the application. +FrozenMessage=The application seems to be frozen. +BitFaultMsg=The file "%25modname%25" seems to be corrupt! +MailBugReportText=send bug report +SaveBugReportText=save bug report +PrintBugReportText=print bug report +ShowBugReportText=show bug report +ContinueApplicationText=continue application +RestartApplicationText=restart application +CloseApplicationText=close application +[BugReport] +ListThreads=1 +ListModules=1 +ListHardware=1 +ShowCpuRegisters=1 +ShowStackDump=1 +Disassembly=1 +HideUglyItems=0 +ShowRelativeAddrs=1 +ShowRelativeLines=1 +FormatDisassembly=0 +LimitDisassembly=5 +EnabledPlugins=modules|processes|hardware +[Filters] +Filter1ExceptionClasses=EDBEditError +Filter1DontCreateBugReport=1 +Filter1DontCreateScreenshot=1 +Filter1DontSuspendThreads=1 +Filter1DontCallHandlers=1 +Filter1ShowBox=3 +Filter1Assis= +Filter2ExceptionClasses= +Filter2DontCreateBugReport=0 +Filter2DontCreateScreenshot=0 +Filter2DontSuspendThreads=0 +Filter2DontCallHandlers=0 +Filter2ShowBox=0 +Filter2Assis= +GeneralDontCreateBugReport=0 +GeneralDontCreateScreenshot=0 +GeneralDontSuspendThreads=0 +GeneralDontCallHandlers=0 +GeneralShowBox=0 +GeneralAssis= +[Assistants] +Assistant1=SendAssistant|Send Assistant|ContactForm|DetailsForm|ScrShotForm +Assistant2=SaveAssistant|Save Assistant|ContactForm|DetailsForm +Assistant3=PrintAssistant|Print Assistant|ContactForm|DetailsForm +Forms1=TPF0%0eTMEContactForm%0bContactForm%07Message%0c%13%00%00%00Contact Information%08MinWidth%04%00%00%00%00%08OnAction%0c%1b%00%00%00madExcept.HandleContactForm%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c%0a%00%00%00your name:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%08NameEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%09%0aOutputName%0c%0c%00%00%00contact name%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%08INVLabel%06Label2%07Caption%0c%0b%00%00%00your email:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%09EmailEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00contact email%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%0bINVCheckBox%08MemCheck%07Caption%0c%0b%00%00%00remember me%07Checked%08%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%00 +Forms2=TPF0%0eTMEDetailsForm%0bDetailsForm%07Message%0c%0d%00%00%00Error Details%08MinWidth%04%00%00%00%00%08OnAction%0c%00%00%00%00%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c'%00%00%00in which situation did the error occur?%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%0bDetailsMemo%07Colored%09%07Enabled%09%05Lines%04%09%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00error details%0aOutputType%07%0dnvoOwnSection%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%00 +Forms3=TPF0%0eTMEScrShotForm%0bScrShotForm%0dActiveControl%07%0bContinueBtn%07Message%0c%18%00%00%00Screenshot Configuration%08MinWidth%04%00%00%00%00%08OnAction%0c%1e%00%00%00madExcept.HandleScreenshotForm%05Timer%04%fa%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%0bINVCheckBox%0bAttachCheck%07Caption%0c%25%00%00%00attach a screenshot to the bug report%07Checked%09%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%08INVImage%0aScrShotImg%06Border%09%09Clickable%09%07Enabled%09%04File%0c%00%00%00%00%06Height%04%00%00%00%00%07Spacing%04%00%00%00%00%05Width%04%00%00%00%00%00%00%08INVLabel%06Label1%07Caption%0c%15%00%00%00(click to edit image)%07Enabled%09%07Spacing%04%00%00%00%00%00%00%00 diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.otares b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.otares new file mode 100644 index 0000000000..93e7e944f2 Binary files /dev/null and b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.otares differ diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.res b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.res new file mode 100644 index 0000000000..f283649744 Binary files /dev/null and b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.res differ diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater_Icon.ico b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater_Icon.ico new file mode 100644 index 0000000000..244fcd4ddd Binary files /dev/null and b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater_Icon.ico differ diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.dfm b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.dfm new file mode 100644 index 0000000000..623f7ef672 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.dfm @@ -0,0 +1,530 @@ +object MainForm: TMainForm + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu, biMinimize] + Caption = 'HistoryToDBUpdater' + ClientHeight = 357 + ClientWidth = 486 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + Icon.Data = { + 0000010001001010000001000000680400001600000028000000100000002000 + 0000010020000000000000040000000000000000000000000000000000000000 + 0000000000000000000000000000FF1F2A000000000000000000000000000000 + 00000000000000000000FF1F2A00000000000000000000000000000000000000 + 000000000000D0CDC500FF1F2A00FEEFA900FF1F2A00CDCDCD00CDCDCD00CDCD + CD00CDCDCD00FF1F2A00FEEFA900FF1F2A000000000000000000000000000000 + 0000D0CDC500FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F + 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A00D0CDC500000000000000 + 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FECF4D00FFCC + 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A0000000000FF1F + 2A00FEEFA900FFE55F00FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC + 4A00FFD35000FFE55F00FFE55F00FFE55F00FFE55F00FF1F2A00FF1F2A000000 + 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC + 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A00000000000000 + 0000C1BDB600FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F + 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A00CFC7BF00000000000000 + 0000C1BDB600F9F3ED00FF1F2A00FEEFA900FF1F2A00D2D2D200D2D2D200D2D2 + D200D2D2D200FF1F2A00FEEFA900FF1F2A00BAB7AF00CFC7BF00000000000000 + 0000BAB7AF00A39A8F00BAB2A700FF1F2A00D2D2D200D2D2D200D2D2D200D2D2 + D200D2D2D200D2D2D200FF1F2A00CFC7BF00A39A8F00BAB7AF00000000000000 + 0000B1AB9F00C9C2B900CFC7BF00D5CCC400DCD3CA00E4D9D200E8DDD500E4D6 + CF00E4D6CF00E4D6CF00D5CCC400CFC7BF00C9C2B900B1AB9F00000000000000 + 0000B0AB9E00C7C0B600CCC4BB00D3C9C100DAD0C700E1D7CF00EBE1DA00E4D9 + D100E4D9D100DDD2CA00DBCDC500DDCAC400DBC4BF00C1ADA400000000000000 + 0000AFAA9D00C8C1B700E8E3DB00F5F0E800FDF8F200FCF8F100FBF7F000FCF7 + F100FCF7F100FDF8F200F7F0EA00ECE3DC00CDC3BB00B2AA9E00000000000000 + 0000AEA89C00FBF5EF00EEE7DE00E0D8CE00DDD5CC00DDD4CB00DDD4CB00DDD4 + CB00DDD4CB00DDD5CC00E0D7CE00EDE6DE00FBF6EF00AEA89C00000000000000 + 0000AFA99D00E1D8CE00E1D7CE00DFD6CC00DFD5CB00DFD5CB00DFD5CB00DFD5 + CB00DFD5CB00DFD5CB00DFD6CC00E1D7CE00E1D8CE00AFA99D00000000000000 + 000000000000B6B0A400D6CFC400E6DED500EFE7DD00EEE6DC00EEE6DC00EEE6 + DC00EEE6DC00EFE7DD00E6DED500D6CFC400B6B0A40000000000000000000000 + 00000000000000000000C4C0B700AEA99C00AEA89C00AEA89C00AEA89C00AEA8 + 9C00AEA89C00AEA89C00AEA99C00C4C0B700000000000000000000000000F7EF + FFFFC007FFFF8001FFFF8001FFFF0000FFFF8001FFFF8001FFFF8001FFFF8001 + FFFF8001FFFF8001FFFF8001FFFF8001FFFF8001FFFFC003FFFFE007FFFF} + OldCreateOrder = False + Position = poScreenCenter + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShow = FormShow + DesignSize = ( + 486 + 357) + PixelsPerInch = 96 + TextHeight = 13 + object GBUpdater: TGroupBox + Left = 8 + Top = 8 + Width = 472 + Height = 145 + Anchors = [akLeft, akTop, akRight] + Caption = ' '#1054#1073#1085#1086#1074#1083#1077#1085#1080#1077' ' + TabOrder = 0 + DesignSize = ( + 472 + 145) + object LAmountDesc: TLabel + Left = 16 + Top = 56 + Width = 37 + Height = 13 + Caption = #1054#1073#1098#1077#1084':' + end + object LAmount: TLabel + Left = 59 + Top = 56 + Width = 30 + Height = 13 + Caption = '10000' + end + object LSpeedDesc: TLabel + Left = 16 + Top = 75 + Width = 52 + Height = 13 + Caption = #1057#1082#1086#1088#1086#1089#1090#1100':' + end + object LSpeed: TLabel + Left = 74 + Top = 75 + Width = 49 + Height = 13 + Caption = '1000 '#1050#1073'/c' + end + object LFileDesc: TLabel + Left = 210 + Top = 75 + Width = 53 + Height = 13 + Caption = #1054#1087#1080#1089#1072#1085#1080#1077':' + end + object LFileDescription: TLabel + Left = 269 + Top = 75 + Width = 62 + Height = 13 + Caption = #1053#1077' '#1080#1079#1074#1077#1089#1090#1085#1086 + end + object LFileMD5Desc: TLabel + Left = 210 + Top = 94 + Width = 25 + Height = 13 + Caption = 'MD5:' + end + object LFileMD5: TLabel + Left = 241 + Top = 94 + Width = 62 + Height = 13 + Caption = #1053#1077' '#1080#1079#1074#1077#1089#1090#1085#1086 + end + object LFileNameDesc: TLabel + Left = 210 + Top = 56 + Width = 58 + Height = 13 + Caption = #1048#1084#1103' '#1092#1072#1081#1083#1072':' + end + object LFileName: TLabel + Left = 274 + Top = 56 + Width = 62 + Height = 13 + Caption = #1053#1077' '#1080#1079#1074#1077#1089#1090#1085#1086 + end + object LStatus: TLabel + Left = 17 + Top = 21 + Width = 322 + Height = 13 + Hint = 'UpdateStatus' + Caption = #1053#1072#1078#1084#1080#1090#1077' '#1082#1085#1086#1087#1082#1091' "'#1054#1073#1085#1086#1074#1080#1090#1100'" '#1076#1083#1103' '#1085#1072#1095#1072#1083#1072' '#1087#1088#1086#1094#1077#1089#1089#1072' '#1086#1073#1085#1086#1074#1083#1077#1085#1080#1103'.' + end + object ProgressBarDownloads: TProgressBar + Left = 16 + Top = 40 + Width = 444 + Height = 10 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + end + object ButtonSettings: TButton + Left = 114 + Top = 109 + Width = 90 + Height = 25 + Caption = #1053#1072#1089#1090#1088#1086#1081#1082#1080 + ImageIndex = 1 + Images = ImageList_Main + TabOrder = 2 + OnClick = ButtonSettingsClick + end + object ButtonUpdate: TButton + Left = 16 + Top = 109 + Width = 95 + Height = 25 + Hint = 'UpdateButton' + Caption = #1054#1073#1085#1086#1074#1080#1090#1100 + ImageIndex = 0 + Images = ImageList_Main + TabOrder = 1 + OnClick = ButtonUpdateStartClick + end + end + object SettingsPageControl: TPageControl + Left = 8 + Top = 159 + Width = 472 + Height = 193 + ActivePage = TabSheetSettings + Anchors = [akLeft, akTop, akRight] + TabOrder = 1 + object TabSheetSettings: TTabSheet + Caption = #1054#1073#1097#1080#1077' '#1085#1072#1089#1090#1088#1086#1081#1082#1080 + ImageIndex = 2 + DesignSize = ( + 464 + 165) + object GBSettings: TGroupBox + Left = 3 + Top = 0 + Width = 458 + Height = 161 + Anchors = [akLeft, akTop, akRight] + Caption = ' '#1054#1073#1097#1080#1077' '#1085#1072#1089#1090#1088#1086#1081#1082#1080 + TabOrder = 0 + object LLanguage: TLabel + Left = 16 + Top = 81 + Width = 88 + Height = 13 + Caption = #1071#1079#1099#1082' '#1087#1088#1086#1075#1088#1072#1084#1084#1099':' + end + object LIMClientType: TLabel + Left = 16 + Top = 27 + Width = 56 + Height = 13 + Caption = 'IM-'#1082#1083#1080#1077#1085#1090':' + end + object LDBType: TLabel + Left = 16 + Top = 54 + Width = 39 + Height = 13 + Caption = #1058#1080#1087' '#1041#1044':' + end + object LPlatformType: TLabel + Left = 261 + Top = 27 + Width = 18 + Height = 13 + Caption = 'x86' + end + object CBLang: TComboBox + Left = 110 + Top = 78 + Width = 145 + Height = 21 + Style = csDropDownList + TabOrder = 2 + OnChange = CBLangChange + end + object CBIMClientType: TComboBox + Left = 110 + Top = 24 + Width = 145 + Height = 21 + Style = csDropDownList + TabOrder = 0 + OnChange = CBIMClientTypeChange + end + object CBDBType: TComboBox + Left = 110 + Top = 51 + Width = 145 + Height = 21 + Style = csDropDownList + TabOrder = 1 + OnChange = CBDBTypeChange + end + end + end + object TabSheetConnectSettings: TTabSheet + Caption = #1053#1072#1089#1090#1088#1086#1081#1082#1080' '#1089#1086#1077#1076#1080#1085#1077#1085#1080#1103 + DesignSize = ( + 464 + 165) + object GBConnectSettings: TGroupBox + Left = 3 + Top = 0 + Width = 458 + Height = 161 + Anchors = [akLeft, akTop, akRight] + Caption = ' '#1053#1072#1089#1090#1088#1086#1081#1082#1080' '#1089#1086#1077#1076#1080#1085#1077#1085#1080#1103' ' + TabOrder = 0 + object LProxyAddress: TLabel + Left = 16 + Top = 47 + Width = 118 + Height = 13 + Caption = #1040#1076#1088#1077#1089' '#1087#1088#1086#1082#1089#1080'-'#1089#1077#1088#1074#1077#1088#1072':' + end + object LProxyPort: TLabel + Left = 267 + Top = 48 + Width = 29 + Height = 13 + Caption = #1055#1086#1088#1090':' + end + object LProxyUser: TLabel + Left = 16 + Top = 98 + Width = 76 + Height = 13 + Caption = #1055#1086#1083#1100#1079#1086#1074#1072#1090#1077#1083#1100':' + end + object LProxyUserPasswd: TLabel + Left = 16 + Top = 125 + Width = 41 + Height = 13 + Caption = #1055#1072#1088#1086#1083#1100':' + end + object CBUseProxy: TCheckBox + Left = 16 + Top = 24 + Width = 193 + Height = 17 + Caption = #1048#1089#1087#1086#1083#1100#1079#1086#1074#1072#1090#1100' '#1089#1074#1086#1081' '#1087#1088#1086#1082#1089#1080'-'#1089#1077#1088#1074#1077#1088 + TabOrder = 0 + OnClick = CBUseProxyClick + end + object EProxyAddress: TEdit + Left = 140 + Top = 44 + Width = 121 + Height = 21 + TabOrder = 1 + Text = '127.0.0.1' + end + object EProxyPort: TEdit + Left = 302 + Top = 44 + Width = 73 + Height = 21 + MaxLength = 5 + NumbersOnly = True + TabOrder = 2 + Text = '3128' + end + object EProxyUser: TEdit + Left = 98 + Top = 95 + Width = 163 + Height = 21 + TabOrder = 4 + end + object CBProxyAuth: TCheckBox + Left = 16 + Top = 71 + Width = 233 + Height = 17 + Caption = #1055#1088#1086#1082#1089#1080'-'#1089#1077#1088#1074#1077#1088' '#1090#1088#1077#1073#1091#1077#1090' '#1072#1074#1090#1086#1088#1080#1079#1072#1094#1080#1102 + TabOrder = 3 + OnClick = CBProxyAuthClick + end + object EProxyUserPasswd: TEdit + Left = 98 + Top = 122 + Width = 163 + Height = 21 + PasswordChar = '*' + TabOrder = 5 + end + end + end + object TabSheetLog: TTabSheet + Caption = #1051#1086#1075#1080 + ImageIndex = 1 + DesignSize = ( + 464 + 165) + object LogMemo: TMemo + Left = 3 + Top = 3 + Width = 458 + Height = 159 + Anchors = [akLeft, akTop, akRight, akBottom] + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 0 + end + end + end + object IMDownloader1: TIMDownloader + OnError = IMDownloader1Error + OnAccepted = IMDownloader1Accepted + OnHeaders = IMDownloader1Headers + OnMD5Checked = IMDownloader1MD5Checked + OnDownloading = IMDownloader1Downloading + OnStartDownload = IMDownloader1StartDownload + OnBreak = IMDownloader1Break + Left = 384 + Top = 112 + end + object ImageList_Main: TImageList + ColorDepth = cd32Bit + DrawingStyle = dsTransparent + Left = 384 + Top = 64 + Bitmap = { + 494C010102000400300210001000FFFFFFFF2110FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000001000000001002000000000000010 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000112A1251235A26B72A6E2DE42C732EF52C732EF5286C2CE6027920FA0279 + 1CFF000200040000000000000000000000000000000000000000000000000000 + 0000000000000000000029292963414141BF3C3C3CBF1F1F1F63000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000207030D2A65 + 2EB637873CFB9AC49CFFB2C19CFFBCC09BFFBDC29CFFAFD2B0FF0A8732FF41A0 + 5DFF06731FF2030C051C00000000000000000000000000000000000000001111 + 11290505050E01010102767676EABDBDBDFFB2B2B2FF545454EA010101020404 + 040E0C0C0C290000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000308030D397E3ED16EB6 + 85FFADE8C7FFBFD29FFF20964FFF1A9047FF148E41FF0F8A39FF389E5CFF7EC0 + 95FF44A260FF06781FF8030D051E0000000000000000000000004E4E4E9B6D6D + 6DFD5A5A5AE70B0B0B19777777E7CBCBCBFFC7C7C7FF585858E7080808194F4F + 4FE74D4D4DFD2B2B2B9B00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000034743BB174BF8CFF98D7 + B2FF77BF7EFFBBC17CFF279A59FF8FCAA8FF8CC8A4FF89C5A0FF87C49DFF68B5 + 84FF81C196FF46A464FF057620F500030009000000004F4F4F7BBCBCBCFFDEDE + DEFFA6A6A6FF7D7D7DF4848484FEC4C4C4FFC2C2C2FF6C6C6CFE686868F4A6A6 + A6FFD2D2D2FF808080FF2727277B000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001631194650AB5AFBB4EAD3FF67BB + 72FF6CBC6FFFBDB56BFF2F9E61FF93CDACFF6DB98DFF69B788FF64B584FF5FB2 + 7EFF65B481FF82C197FF3A9F5AFF007B23FB000000005353537DA5A5A5FED5D5 + D5FFC5C5C5FFCBCBCBFFD1D1D1FFC9C9C9FFC7C7C7FFCCCCCCFFC5C5C5FFBDBD + BDFFCBCBCBFF6D6D6DFE3131317D000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000003D8146B291D7AEFF9FDEB3FF83C5 + 6EFFA7D07EFFC4A45AFF35A269FF95CEAFFF93CDACFF90CBA9FF8FCBA7FF72BB + 8FFF89C7A0FF44A466FF088735FF215A24BF00000000000000005A5A5A85C5C5 + C5FFC1C1C1FFC5C5C5FFC7C7C7FFAAAAAAFFA7A7A7FFC1C1C1FFBEBEBEFFB5B5 + B5FFAAAAAAFF3636368500000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000052AA5DE4AFE9CFFF82D48FFFBEDC + 89FFC2CB81FFCCA154FF3BA46DFF38A26BFF33A065FF2F9C5FFF53AE7AFF90CB + A9FF4DAA72FF168E44FFA0D8BBFF296D2CE8838383CD7F7F7FE3959595EECFCF + CFFFC6C6C6FFCCCCCCFF7A7A7AC629292944272727446F6F6FC6C1C1C1FFBCBC + BCFFB9B9B9FF5C5C5CEE4E4E4EE3424242CD0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000005BBB67F6BDEFDDFF71D17BFF8FD1 + 6AFFBBE09DFFC7A65CFFD3AF5CFFC59851FFC5BB6CFFAED178FF39A162FF58B2 + 80FF269755FF58A265FFB0E3CEFF2D7832F7BEBEBEFDE2E2E2FFD2D2D2FFC6C6 + C6FFCDCDCDFFB1B1B1FF27272744000000000000000028282844A8A8A8FFC2C2 + C2FFB7B7B7FFC0C0C0FFD2D2D2FF5F5F5FFD0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000005BBB68F5BDF0DCFF80D882FF75DB + 6BFFBEE599FFCCDFA6FFCAA75BFFC1BC6AFFB7DA8AFFA5D85EFF3AA666FF2F9E + 63FF57BB4EFF61AA6AFFB1E4CEFF317C35F6C2C2C2FDE9E9E9FFD6D6D6FFC9C9 + C9FFCECECEFFA5A5A5FF23232344000000000000000029292944ACACACFFC4C4 + C4FFBABABAFFC6C6C6FFDDDDDDFF696969FD0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000054AD60E2B2ECD2FF9AE2A1FF9CEA + 8CFFD4EDB6FFD0EAC7FFCFB86CFFCCB064FFCBC973FF74DB65FF64D94BFF63D7 + 4BFF6AD35BFF71BA7CFFA4DBC1FF337A36E6A0A0A0CDADADADE3B3B3B3EED8D8 + D8FFCDCDCDFFBCBCBCFF656565C61F1F1F44222222446F6F6FC6C3C3C3FFC2C2 + C2FFCDCDCDFF838383EE787878E3696969CD0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000408449AD97DEB4FFB4EBCCFFB0EF + A6FFC9EEA8FFD1EAC9FFD5CF8CFFD9CB8AFFCDB364FFBBBB65FF99D66FFF81DE + 71FF78DC6FFF90D0A2FF87C8A3FF2C672FB9000000000000000066666685D4D4 + D4FFCCCCCCFFC9C9C9FFBABABAFF9C9C9CFFA1A1A1FFC2C2C2FFC6C6C6FFC1C1 + C1FFB7B7B7FF4747478500000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000162E1A3C5DBF6AFABFF3E2FFB4EF + B3FFB4F0ABFFC0EDB6FFD4E3B6FFD9D89BFFDAD394FFCDB46BFFC7B26BFFB4CB + 83FF93DF99FFAEE7CDFF43984AFC142D154F000000006363637DC3C3C3FEDCDC + DCFFD4D4D4FFD9D9D9FFDBDBDBFFD6D6D6FFD4D4D4FFD9D9D9FFD2D2D2FFCBCB + CBFFC8C8C8FF787878FE3636367D000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000003D7E46A586D79FFFBFF2 + DEFFC7F2D6FFD5EFD5FFD0E9CFFFD5DBA5FFDCDEAAFFDBCD8FFFD7C88AFFC9C0 + 8DFFBCD5AEFF78C790FF33743BB600000000000000006363637BDCDCDCFFEDED + EDFFDBDBDBFFB9B9B9F4BDBDBDFED6D6D6FFD4D4D4FFAFAFAFFEA4A4A4F4CBCB + CBFFE7E7E7FFB7B7B7FF4343437B000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000001040105499653C48BD8 + A1FFCDF5E8FFD4EDDAFFCEEDD3FFCFDFAEFFD6DEB4FFD4D4A1FFCED0A0FFC3D0 + A9FF86C990FF428E4BD1040A040F0000000000000000000000007F7F7F9BCCCC + CCFDB7B7B7E713131319AFAFAFE7DEDEDEFFDDDDDDFFA1A1A1E7101010199C9C + 9CE7A6A6A6FD6363639B00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000020302043D7C + 45A45DBD69F8A4E1BAFFB9EACCFFC4E0BDFFC4DAB3FFBCD7AFFFA5D7ABFF5ABA + 65FB3F8447B60309040C00000000000000000000000000000000000000002121 + 21290A0A0A0E02020202B6B6B6EAE5E5E5FFE4E4E4FF9E9E9EEA010101020A0A + 0A0E1C1C1C290000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000162E193D3F8249AA53AB5EDF5BBA67F45DBD69F857B263E942884BB21B36 + 1D48000000000000000000000000000000000000000000000000000000000000 + 000000000000000000004E4E4E63959595BF929292BF4A4A4A63000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000100000000100010000000000800000000000000000000000 + 000000000000000000000000FFFFFF0000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000} + end +end diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.pas b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.pas new file mode 100644 index 0000000000..7579d1834a --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.pas @@ -0,0 +1,1497 @@ +{ ################################################################################ } +{ # # } +{ # IM-History - HistoryToDBUpdater v1.0 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ################################################################################ } + +unit Main; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, ComCtrls, XMLIntf, XMLDoc, Global, IniFiles, uIMDownloader, ShellApi, + ImgList; + +type + TMainForm = class(TForm) + GBUpdater: TGroupBox; + ProgressBarDownloads: TProgressBar; + LAmountDesc: TLabel; + LAmount: TLabel; + LSpeedDesc: TLabel; + LSpeed: TLabel; + ButtonSettings: TButton; + ButtonUpdate: TButton; + SettingsPageControl: TPageControl; + TabSheetConnectSettings: TTabSheet; + TabSheetLog: TTabSheet; + GBConnectSettings: TGroupBox; + LProxyAddress: TLabel; + LProxyPort: TLabel; + LProxyUser: TLabel; + LProxyUserPasswd: TLabel; + CBUseProxy: TCheckBox; + EProxyAddress: TEdit; + EProxyPort: TEdit; + EProxyUser: TEdit; + CBProxyAuth: TCheckBox; + EProxyUserPasswd: TEdit; + LogMemo: TMemo; + LFileDesc: TLabel; + LFileDescription: TLabel; + LFileMD5Desc: TLabel; + LFileMD5: TLabel; + LFileNameDesc: TLabel; + LFileName: TLabel; + IMDownloader1: TIMDownloader; + LStatus: TLabel; + TabSheetSettings: TTabSheet; + GBSettings: TGroupBox; + LLanguage: TLabel; + CBLang: TComboBox; + LIMClientType: TLabel; + CBIMClientType: TComboBox; + LDBType: TLabel; + CBDBType: TComboBox; + ImageList_Main: TImageList; + LPlatformType: TLabel; + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure FormDestroy(Sender: TObject); + procedure ButtonSettingsClick(Sender: TObject); + procedure ButtonUpdateStartClick(Sender: TObject); + procedure ButtonUpdateStopClick(Sender: TObject); + procedure CBUseProxyClick(Sender: TObject); + procedure CBProxyAuthClick(Sender: TObject); + procedure IMDownloader1StartDownload(Sender: TObject); + procedure IMDownloader1Break(Sender: TObject); + procedure IMDownloader1Downloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal); + procedure IMDownloader1Error(Sender: TObject; E: TIMDownloadError); + procedure IMDownloader1Accepted(Sender: TObject); + procedure IMDownloader1Headers(Sender: TObject; Headers: String); + procedure IMDownloader1MD5Checked(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: string); + procedure CBLangChange(Sender: TObject); + procedure CBIMClientTypeChange(Sender: TObject); + procedure CBDBTypeChange(Sender: TObject); + procedure ButtonUpdateEnableStart; + procedure ButtonUpdateEnableStop; + procedure FindLangFile; + procedure CoreLanguageChanged; + procedure InstallUpdate; + procedure SetProxySettings; + procedure AntiBoss(HideAllForms: Boolean); + procedure RunIMClient(IMClientName: String; IMProcessArray: TProcessInfoArray); + procedure RunAllIMClients; + function StartStepByStepUpdate(CurrStep: Integer; INIFileName: String): Integer; + private + { Private declarations } + FLanguage : WideString; + procedure OnControlReq(var Msg : TWMCopyData); message WM_COPYDATA; + // + procedure OnLanguageChanged(var Msg: TMessage); message WM_LANGUAGECHANGED; + procedure LoadLanguageStrings; + function EndTask(TaskName, FormName: String): Boolean; + public + { Public declarations } + RunAppDone: Boolean; + C1, C2: TLargeInteger; + iCounterPerSec: TLargeInteger; + TrueHeader: Boolean; + CurrentUpdateStep: Integer; + HeaderMD5: String; + HeaderFileSize: Integer; + HeaderFileName: String; + MD5InMemory: String; + IMMD5Correct: Boolean; + IMSizeCorrect: Boolean; + INISavePath: String; + SavePath: String; + SystemLang: String; + IMCancelCopy: Boolean; + DropboxProcessInfo: TProcessInfoArray; + QIPProcessInfo: TProcessInfoArray; + RnQProcessInfo: TProcessInfoArray; + SkypeProcessInfo: TProcessInfoArray; + MirandaProcessInfo: TProcessInfoArray; + property CoreLanguage: WideString read FLanguage; + end; + +function CopyProgressFunc(TotalFileSize: Int64; TotalBytesTransferred: Int64; + StreamSize: Int64; StreamBytesTransferred: Int64; dwStreamNumber: DWORD; + dwCallbackReason: DWORD; hSourceFile: THandle; hDestinationFile: THandle; + lpData: Pointer): DWORD; stdcall; + +var + MainForm: TMainForm; + + +implementation + +{$R *.dfm} + +procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); +var + INI: TIniFile; + Path: WideString; + IsFileClosed: Boolean; + sFile: DWORD; +begin + // - + Global_MainForm_Showing := False; + // + DBType := CBDBType.Items[CBDBType.ItemIndex]; + IMClientType := CBIMClientType.Items[CBIMClientType.ItemIndex]; + DefaultLanguage := CoreLanguage; + Path := ProfilePath + ININame; + if FileExists(Path) then + begin + try + // - + IsFileClosed := False; + repeat + sFile := CreateFile(PChar(Path),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + if (sFile <> INVALID_HANDLE_VALUE) then + begin + CloseHandle(sFile); + IsFileClosed := True; + end; + until IsFileClosed; + // End + INI := TIniFile.Create(Path); + if ParamCount = 0 then + begin + INI.WriteString('Main', 'DBType', DBType); + INI.WriteString('Main', 'IMClientType', IMClientType); + INI.WriteString('Main', 'DefaultLanguage', DefaultLanguage); + end; + INI.WriteString('Proxy', 'UseProxy', BoolToIntStr(CBUseProxy.Checked)); + INI.WriteString('Proxy', 'ProxyAddress', EProxyAddress.Text); + INI.WriteString('Proxy', 'ProxyPort', EProxyPort.Text); + INI.WriteString('Proxy', 'ProxyAuth', BoolToIntStr(CBProxyAuth.Checked)); + INI.WriteString('Proxy', 'ProxyUser', EProxyUser.Text); + INI.WriteString('Proxy', 'ProxyUserPasswd', EncryptStr(EProxyUserPasswd.Text)); + INI.WriteString('Updater', 'UpdateServer', UpdateServer); + finally + INI.Free; + end; + end; + if FileExists(INISavePath) then + DeleteFile(INISavePath); + // + if EnableDebug then + LogMemo.Lines.SaveToFile(ProfilePath + DebugLogName); +end; + +procedure TMainForm.FormCreate(Sender: TObject); +var + CmdHelpStr: WideString; +begin + RunAppDone := False; + TrueHeader := False; + IMMD5Correct := False; + IMSizeCorrect := False; + CurrentUpdateStep := 0; + // + if MatchStrings(GetSysLang, '*') or MatchStrings(GetSysLang, 'Russian*') then + SystemLang := 'Russian' + else + SystemLang := 'English'; + // + if SystemLang = 'Russian' then + begin + CmdHelpStr := ' ' + ProgramsName + ' v' + ProgramsVer + ' ' + PlatformType + ':' + #13 + + '--------------------------------------------------------------' + #13#13 + + 'HistoryToDBUpdater.exe <1>' + #13#13 + + '<1> - ( ) - HistoryToDB.ini (: "C:\Program Files\QIP Infium\Profiles\username@qip.ru\Plugins\QIPHistoryToDB\")'; + end + else + begin + CmdHelpStr := 'Startup options ' + ProgramsName + ' v' + ProgramsVer + ' ' + PlatformType + ':' + #13 + + '------------------------------------------------' + #13#13 + + 'HistoryToDBUpdater.exe <1>' + #13#13 + + '<1> - (Optional) - The path to the configuration file HistoryToDB.ini (Example: "C:\Program Files\QIP Infium\Profiles\username@qip.ru\Plugins\QIPHistoryToDB\")'; + end; + // + if (ParamStr(1) = '/?') or (ParamStr(1) = '-?') then + begin + MsgInf(ProgramsName, CmdHelpStr); + Exit; + end + else + begin + if ParamCount >= 1 then + begin + ProfilePath := IncludeTrailingPathDelimiter(ParamStr(1)); + end + else + begin + ProfilePath := ExtractFilePath(Application.ExeName); + end; + PluginPath := ExtractFilePath(Application.ExeName); + // + SavePath := GetUserTempPath + 'IMHistory\'; + INISavePath := SavePath + 'HistoryToDBUpdate.ini'; + IMDownloader1.DirPath := PluginPath; + // + EncryptInit; + // + LoadINI(ProfilePath, false); + // + if ParamCount >= 1 then + FLanguage := DefaultLanguage + else + FLanguage := SystemLang; + LangDoc := NewXMLDocument(); + if not DirectoryExists(PluginPath + dirLangs) then + CreateDir(PluginPath + dirLangs); + if not FileExists(PluginPath + dirLangs + defaultLangFile) then + begin + if SystemLang = 'Russian' then + CmdHelpStr := ' ' + PluginPath + dirLangs + defaultLangFile + ' .' + else + CmdHelpStr := 'The localization file ' + PluginPath + dirLangs + defaultLangFile + ' is not found.'; + MsgInf(ProgramsName, CmdHelpStr); + // + EncryptFree; + Exit; + end; + CoreLanguageChanged; + // + FindLangFile; + // + MainFormHandle := Handle; + SetWindowLong(Handle, GWL_HWNDPARENT, 0); + SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW); + // + LoadLanguageStrings; + // + RunAppDone := True; + end; +end; + +procedure TMainForm.FormDestroy(Sender: TObject); +begin + if RunAppDone then + begin + // + EncryptFree; + end; +end; + +procedure TMainForm.FormShow(Sender: TObject); +var + I: Integer; +begin + // - + Global_MainForm_Showing := True; + // + AlphaBlend := AlphaBlendEnable; + AlphaBlendValue := AlphaBlendEnableValue; + // . + LAmount.Caption := '0 '+GetLangStr('Kb'); + LFileName.Caption := GetLangStr('Unknown'); + LFileDescription.Caption := GetLangStr('Unknown'); + LFileMD5.Caption := GetLangStr('Unknown'); + LSpeed.Caption := '0 '+GetLangStr('KbSec'); + CBUseProxy.Checked := False; + EProxyAddress.Enabled := False; + EProxyPort.Enabled := False; + CBProxyAuth.Enabled := False; + SettingsPageControl.ActivePage := TabSheetSettings; + SettingsPageControl.Visible := False; + MainForm.Height := SettingsPageControl.Height + 5; + if (DBType = 'Unknown') or (ParamCount = 0) then + begin + CBDBType.Enabled := True; + CBDBType.Items.Add('Unknown'); + CBDBType.Items.Add('mysql'); + CBDBType.Items.Add('postgresql'); + CBDBType.Items.Add('oracle'); + CBDBType.Items.Add('sqlite-3'); + CBDBType.Items.Add('firebird-2.0'); + CBDBType.Items.Add('firebird-2.5'); + if ParamCount = 0 then + begin + for I := 0 to CBDBType.Items.Count-1 do + if CBDBType.Items[I] = DBType then + CBDBType.ItemIndex := I + end + else + CBDBType.ItemIndex := 0; + // + ButtonSettingsClick(Self); + end + else + begin + CBDBType.Enabled := False; + CBDBType.Items.Add(DBType); + CBDBType.ItemIndex := 0; + end; + if (IMClientType = 'Unknown') or (ParamCount = 0) then + begin + CBIMClientType.Enabled := True; + CBIMClientType.Items.Add('Unknown'); + CBIMClientType.Items.Add('QIP'); + CBIMClientType.Items.Add('RnQ'); + CBIMClientType.Items.Add('Skype'); + CBIMClientType.Items.Add('Miranda'); + CBIMClientType.Items.Add('MirandaNG'); + if ParamCount = 0 then + begin + for I := 0 to CBIMClientType.Items.Count-1 do + if CBIMClientType.Items[I] = IMClientType then + CBIMClientType.ItemIndex := I + end + else + CBIMClientType.ItemIndex := 0; + // + if not SettingsPageControl.Visible then + ButtonSettingsClick(Self); + end + else + begin + CBIMClientType.Enabled := False; + CBIMClientType.Items.Add(IMClientType); + CBIMClientType.ItemIndex := 0; + end; + // + LPlatformType.Caption := IMClientPlatformType; + // + CBUseProxy.Checked := IMUseProxy; + EProxyAddress.Text := IMProxyAddress; + EProxyPort.Text := IMProxyPort; + CBProxyAuth.Checked := IMProxyAuth; + EProxyUser.Text := IMProxyUser; + EProxyUserPasswd.Text := IMProxyUserPagsswd; + // + LogMemo.Lines.Add(ProgramsName + ' v' + ProgramsVer + ' ' + PlatformType); +end; + +procedure TMainForm.ButtonSettingsClick(Sender: TObject); +begin + if not SettingsPageControl.Visible then + begin + MainForm.Height := GBUpdater.Height + SettingsPageControl.Height + 55; + SettingsPageControl.Visible := True; + end + else + begin + SettingsPageControl.Visible := False; + MainForm.Height := SettingsPageControl.Height + 5; + end; +end; + +procedure TMainForm.ButtonUpdateStartClick(Sender: TObject); +var + AllProcessEndErr: Integer; +begin + IMCancelCopy := False; + AllProcessEndErr := 0; + if (DBType = 'Unknown') or (IMClientType = 'Unknown') then + MsgInf(Caption, GetLangStr('SelectDBTypeAndIMClient')) + else + begin + LogMemo.Clear; + // Dropbox + {if IsProcessRun('Dropbox.exe') then + begin + if SystemLang = 'Russian' then + MsgString := ' Dropbox.' + #13 + + ' IM-, ' + #13 + + ' .' + #13 + + ' Dropbox?' + else + MsgString := 'Find the program in the memory of Dropbox.' + #13 + + 'If you use it to synchronize the IM-client, to properly' + #13 + + 'update all the components necessary to close the plug.' + #13 + + 'Close Dropbox?'; + case MessageBox(MainForm.Handle, PWideChar(MsgString), PWideChar(Caption),36) of + 6: DropboxProcessInfo := EndProcess('Dropbox.exe', True); + end; + end;} + // + if not EndTask('HistoryToDBSync.exe', 'HistoryToDBSync for ' + IMClientType + ' (' + MyAccount + ')') then + Inc(AllProcessEndErr); + if not EndTask('HistoryToDBViewer.exe', 'HistoryToDBViewer for ' + IMClientType + ' (' + MyAccount + ')') then + Inc(AllProcessEndErr); + if not EndTask('HistoryToDBImport.exe', 'HistoryToDBImport for ' + IMClientType + ' (' + MyAccount + ')') then + Inc(AllProcessEndErr); + // , + if AllProcessEndErr = 0 then + begin + // IM- + if IMClientType = 'QIP' then + begin + LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['qip.exe'])); + QIPProcessInfo := EndProcess('qip.exe', 0, True); + end; + if IMClientType = 'Miranda' then + begin + if IMClientPlatformType = 'x86' then + begin + LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['miranda32.exe'])); + MirandaProcessInfo := EndProcess('miranda32.exe', 1, True); + end + else + begin + LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['miranda64.exe'])); + MirandaProcessInfo := EndProcess('miranda64.exe', 1, True); + end; + end; + if IMClientType = 'MirandaNG' then + begin + if IMClientPlatformType = 'x86' then + begin + LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['miranda32.exe'])); + MirandaProcessInfo := EndProcess('miranda32.exe', 0, True); + end + else + begin + LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['miranda64.exe'])); + MirandaProcessInfo := EndProcess('miranda64.exe', 0, True); + end; + end; + if IMClientType = 'RnQ' then + begin + if IsProcessRun('rnq.exe') then + begin + RnQProcessInfo := EndProcess('rnq.exe', 0, True); + LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['rnq.exe'])); + end; + if IsProcessRun('R&Q.exe') then + begin + RnQProcessInfo := EndProcess('R&Q.exe', 0, True); + LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['R&Q.exe'])); + end; + end; + if IMClientType = 'Skype' then + begin + SkypeProcessInfo := EndProcess('skype.exe', 0, True); + LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['skype.exe'])); + end; + // + TrueHeader := False; + CurrentUpdateStep := 0; + SetProxySettings; + if IMClientPlatformType = 'x86' then + IMDownloader1.URL := UpdateServer + '&platform=windows-x86' + else + IMDownloader1.URL := UpdateServer + '&platform=windows-x64'; + IMDownloader1.DownLoad; + end + else + MsgInf(Caption, GetLangStr('ManualUpdate')); + end; +end; + +{ } +procedure TMainForm.SetProxySettings; +begin + if CBUseProxy.Checked then + begin + IMDownloader1.Proxy := EProxyAddress.Text + ':' + EProxyPort.Text; + if CBProxyAuth.Checked then + begin + IMDownloader1.ProxyAuthUserName := EProxyUser.Text; + IMDownloader1.ProxyAuthPassword := EProxyUserPasswd.Text; + end + else + begin + IMDownloader1.ProxyAuthUserName := ''; + IMDownloader1.ProxyAuthPassword := ''; + end; + end + else + begin + IMDownloader1.Proxy := ''; + IMDownloader1.AuthUserName := ''; + IMDownloader1.AuthPassword := ''; + end; +end; + +procedure TMainForm.IMDownloader1Accepted(Sender: TObject); +var + MaxSteps: Integer; +begin + LStatus.Caption := GetLangStr('DownloadSuccessful'); + LStatus.Hint := 'DownloadSuccessful'; + LStatus.Repaint; + LAmount.Caption := CurrToStr(IMDownloader1.AcceptedSize/1024)+' '+GetLangStr('Kb'); + LAmount.Repaint; + if not TrueHeader then + begin + LFileName.Caption := GetLangStr('Unknown'); + LFileDescription.Caption := GetLangStr('Unknown'); + LFileMD5.Caption := GetLangStr('Unknown'); + LStatus.Caption := GetLangStr('InvalidResponseHeader'); + LStatus.Hint := 'InvalidResponseHeader'; + LStatus.Repaint; + ButtonUpdateEnableStart; + end + else + begin + LStatus.Caption := GetLangStr('IsChecksum'); + LStatus.Hint := 'IsChecksum'; + LStatus.Repaint; + if MD5InMemory <> 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' then + begin + LogMemo.Lines.Add(GetLangStr('MD5FileInMemory') + ' ' + MD5InMemory); + LogMemo.Lines.Add(GetLangStr('FileSizeInMemory') + ' ' + IntToStr(IMDownloader1.OutStream.Size)); + end; + if IMMD5Correct and IMSizeCorrect then + begin + if MD5InMemory <> 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' then + begin + LStatus.Caption := GetLangStr('ChecksumConfirmed'); + LStatus.Hint := 'ChecksumConfirmed'; + LStatus.Repaint; + LogMemo.Lines.Add(GetLangStr('ChecksumConfirmed')); + end + else + begin + LStatus.Caption := GetLangStr('ChecksumFileEqServer'); + LStatus.Hint := 'ChecksumFileEqServer'; + LStatus.Repaint; + LogMemo.Lines.Add(GetLangStr('ChecksumFileEqServer')); + end; + // - INI + if CurrentUpdateStep = 0 then + INISavePath := SavePath + HeaderFileName; + // + if not DirectoryExists(SavePath) then + CreateDir(SavePath); + // + if CurrentUpdateStep = 0 then + begin + if FileExists(INISavePath) then + DeleteFile(INISavePath); + end; + if FileExists(SavePath + HeaderFileName) then + DeleteFile(SavePath + HeaderFileName); + // + try + if MD5InMemory <> 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' then + begin + IMDownloader1.OutStream.SaveToFile(SavePath + HeaderFileName); + LStatus.Caption := GetLangStr('FileSavedAs') + ' ' + HeaderFileName; + LStatus.Hint := 'FileSavedAs'; + LStatus.Repaint; + LogMemo.Lines.Add(GetLangStr('FileSavedAs') + ' ' + HeaderFileName); + end; + Inc(CurrentUpdateStep); + if CurrentUpdateStep > 0 then + MaxSteps := StartStepByStepUpdate(CurrentUpdateStep, INISavePath); + except + on E: Exception do + begin + LStatus.Caption := GetLangStr('ErrFileSavedAs') + ' ' + HeaderFileName; + LStatus.Hint := 'ErrFileSavedAs'; + LStatus.Repaint; + LogMemo.Lines.Add(GetLangStr('ErrFileSavedAs') + ' ' + HeaderFileName); + end; + end; + end + else + begin + if not IMMD5Correct then + begin + LStatus.Caption := GetLangStr('ChecksumNotConfirmed'); + LStatus.Hint := 'ChecksumNotConfirmed'; + LStatus.Repaint; + LogMemo.Lines.Add(GetLangStr('ChecksumNotConfirmed')); + end; + if not IMSizeCorrect then + begin + LStatus.Caption := GetLangStr('SizeNotConfirmed'); + LStatus.Hint := 'SizeNotConfirmed'; + LStatus.Repaint; + LogMemo.Lines.Add(GetLangStr('SizeNotConfirmed')); + end; + ButtonUpdateEnableStart; + end; + end; +end; + +function TMainForm.StartStepByStepUpdate(CurrStep: Integer; INIFileName: String): Integer; +var + UpdateINI: TIniFile; + MaxStep, IMClientCount, IMClientDownloadFileCount: Integer; + DatabaseCount, DatabaseDownloadFileCount, I, UpdateServerInServiceMode: Integer; + IMClientName, IMClientNum, UpdateURL: String; + DatabaseName, DatabaseNum, TmpUpdateServer: String; + FileListArray: TArrayOfString; + DownloadListArray: TArrayOfString; +begin + Result := 0; + if FileExists(INIFileName) then + begin + UpdateINI := TIniFile.Create(INIFileName); + UpdateServerInServiceMode := UpdateINI.ReadInteger('HistoryToDBUpdate', 'UpdateServerInServiceMode', 0); + LogMemo.Lines.Add('UpdateServerInServiceMode = ' + IntToStr(UpdateServerInServiceMode)); + // + if UpdateServerInServiceMode = 1 then + begin + LogMemo.Lines.Add(Format(GetLangStr('UpdateServerInServiceMode'), [' '])); + IMDownloader1.BreakDownload; + MsgInf(Caption, Format(GetLangStr('UpdateServerInServiceMode'), [#13])); + Result := -1; + // . + ButtonUpdateEnableStart; + // IM- + RunAllIMClients; + // + Close; + Exit; + end; + // + TmpUpdateServer := UpdateINI.ReadString('HistoryToDBUpdate', 'UpdateServer', UpdateServer); + if TmpUpdateServer <> UpdateServer then + UpdateServer := TmpUpdateServer; + // End + MaxStep := UpdateINI.ReadInteger('HistoryToDBUpdate', 'FileCount', 0); + IMClientCount := UpdateINI.ReadInteger('HistoryToDBUpdate', 'IMClientCount', 0); + if EnableDebug then + LogMemo.Lines.Add(' IM- INI- = ' + IntToStr(IMClientCount)); + IMClientDownloadFileCount := 0; + SetLength(DownloadListArray, 0); + if IMClientCount > 0 then + begin + IMClientName := ''; + while (IMClientCount > 0) and (IMClientName <> CBIMClientType.Items[CBIMClientType.ItemIndex]) do + begin + IMClientName := UpdateINI.ReadString('HistoryToDBUpdate', 'IMClient'+IntToStr(IMClientCount)+'Name', ''); + IMClientNum := UpdateINI.ReadString('HistoryToDBUpdate', 'IMClient'+IntToStr(IMClientCount)+'File', ''); + if EnableDebug then + begin + LogMemo.Lines.Add('IM- = ' + IMClientName); + LogMemo.Lines.Add(' = ' + IMClientNum); + end; + Dec(IMClientCount); + end; + FileListArray := StringToParts(IMClientNum, [',']); + SetLength(DownloadListArray, Length(FileListArray)); + DownloadListArray := FileListArray; + IMClientDownloadFileCount := Length(FileListArray); + if EnableDebug then + begin + for I := 0 to High(FileListArray) do + LogMemo.Lines.Add(' '+IMClientName+' = ' + FileListArray[I]); + end; + end; + DatabaseCount := UpdateINI.ReadInteger('HistoryToDBUpdate', 'DatabaseCount', 0); + DatabaseDownloadFileCount := 0; + if EnableDebug then + LogMemo.Lines.Add(' Database INI- = ' + IntToStr(DatabaseCount)); + if DatabaseCount > 0 then + begin + DatabaseName := ''; + while (DatabaseCount > 0) and (DatabaseName <> CBDBType.Items[CBDBType.ItemIndex]) do + begin + DatabaseName := UpdateINI.ReadString('HistoryToDBUpdate', 'Database'+IntToStr(DatabaseCount)+'Name', ''); + DatabaseNum := UpdateINI.ReadString('HistoryToDBUpdate', 'Database'+IntToStr(DatabaseCount)+'File', ''); + if EnableDebug then + begin + LogMemo.Lines.Add('Database = ' + DatabaseName); + LogMemo.Lines.Add(' = ' + DatabaseNum); + end; + Dec(DatabaseCount); + end; + FileListArray := StringToParts(DatabaseNum, [',']); + SetLength(DownloadListArray, Length(DownloadListArray) + Length(FileListArray)); + DatabaseDownloadFileCount := Length(FileListArray); + for I := 0 to High(FileListArray) do + begin + DownloadListArray[IMClientDownloadFileCount+I] := FileListArray[I]; + if EnableDebug then + LogMemo.Lines.Add(' '+DatabaseName+' = ' + FileListArray[I]); + end; + end; + if EnableDebug then + begin + LogMemo.Lines.Add(' = ' + IntToStr(Length(DownloadListArray))); + for I := 0 to High(DownloadListArray) do + LogMemo.Lines.Add('DownloadListArray['+IntToStr(I)+'] = ' + DownloadListArray[I]); + end; + MaxStep := IMClientDownloadFileCount + DatabaseDownloadFileCount; + Result := MaxStep; + if EnableDebug then + LogMemo.Lines.Add(' = ' + IntToStr(MaxStep)); + if CurrentUpdateStep > MaxStep then + begin + LStatus.Caption := GetLangStr('AllUpdatesDownloaded'); + LStatus.Hint := 'AllUpdatesDownloaded'; + LStatus.Repaint; + LogMemo.Lines.Add('========================================='); + LogMemo.Lines.Add(GetLangStr('AllUpdatesDownloaded')); + InstallUpdate; + LStatus.Caption := GetLangStr('AllUpdatesInstalled'); + LStatus.Hint := 'AllUpdatesInstalled'; + LStatus.Repaint; + LogMemo.Lines.Add('========================================='); + LogMemo.Lines.Add(GetLangStr('AllUpdatesInstalled')); + // . + ButtonUpdateEnableStart; + // IM- + RunAllIMClients; + Close; + Exit; + end; + LogMemo.Lines.Add('================= ' + GetLangStr('Step') + ' '+IntToStr(CurrStep)+' ================='); + LogMemo.Lines.Add(GetLangStr('NumberFilesUpdate') + ' = ' + IntToStr(MaxStep)); + if MaxStep > 0 then + begin + UpdateURL := UpdateINI.ReadString('HistoryToDBUpdate', 'File'+DownloadListArray[CurrStep-1], ''); + if (UpdateURL <> '') and (CurrStep <= MaxStep) then + begin + LogMemo.Lines.Add(GetLangStr('FileToUpdate') + ' = ' + UpdateURL); + if MatchStrings(UpdateURL, '*file=*Lang') then + IMDownloader1.DirPath := PluginPath + dirLangs + else if MatchStrings(UpdateURL, '*file=*-update-*-to-*') then + IMDownloader1.DirPath := PluginPath + dirSQLUpdate + else + IMDownloader1.DirPath := PluginPath; + IMDownloader1.URL := UpdateURL; + IMDownloader1.DownLoad; + end + else + CurrentUpdateStep := 0; + end; + end + else + LogMemo.Lines.Add(GetLangStr('UpdateSettingsFileNotFound') + ' ' + INIFileName); +end; + +procedure TMainForm.InstallUpdate; +var + SR: TSearchRec; +begin + LAmount.Caption := '0 '+GetLangStr('Kb'); + LFileName.Caption := GetLangStr('Unknown'); + LFileDescription.Caption := GetLangStr('Unknown'); + LFileMD5.Caption := GetLangStr('Unknown'); + LSpeed.Caption := '0 '+GetLangStr('KbSec'); + // + if FindFirst(SavePath + '*.*', faAnyFile or faDirectory, SR) = 0 then + begin + repeat + if (SR.Attr = faDirectory) and ((SR.Name = '.') or (SR.Name = '..')) then // . .. + begin + Continue; // + end; + if MatchStrings(SR.Name, 'HistoryToDBUpdater.exe') then + begin + LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]); + LStatus.Hint := 'UpdateFile'; + LStatus.Repaint; + LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name])); + if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + 'HistoryToDBUpdater.upd'), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then + begin + DeleteFile(SavePath + SR.Name); + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name])); + end + else + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name])); + end; + if MatchStrings(SR.Name, '*.xml') then + begin + LStatus.Caption := Format(GetLangStr('UpdateLangFile'), [SR.Name]); + LStatus.Hint := 'UpdateLangFile'; + LStatus.Repaint; + LogMemo.Lines.Add(Format(GetLangStr('UpdateLangFile'), [SR.Name])); + if FileExists(PluginPath + dirLangs + SR.Name) then + DeleteFile(PluginPath + dirLangs + SR.Name); + if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + dirLangs + SR.Name), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then + begin + DeleteFile(SavePath + SR.Name); + LogMemo.Lines.Add(Format(GetLangStr('UpdateLangFileDone'), [SR.Name])); + end + else + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name])); + end; + if MatchStrings(SR.Name, '*.sql') then + begin + LStatus.Caption := Format(GetLangStr('UpdateSQLFile'), [SR.Name]); + LStatus.Hint := 'UpdateSQLFile'; + LStatus.Repaint; + LogMemo.Lines.Add(Format(GetLangStr('UpdateSQLFile'), [SR.Name])); + if not DirectoryExists(PluginPath + dirSQLUpdate) then + CreateDir(PluginPath + dirSQLUpdate); + if FileExists(PluginPath + dirSQLUpdate + SR.Name) then + DeleteFile(PluginPath + dirSQLUpdate + SR.Name); + if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + dirSQLUpdate + SR.Name), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then + begin + DeleteFile(SavePath + SR.Name); + LogMemo.Lines.Add(Format(GetLangStr('UpdateSQLFileDone'), [SR.Name])); + end + else + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name])); + end; + if MatchStrings(SR.Name, '*.exe') then + begin + LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]); + LStatus.Hint := 'UpdateFile'; + LStatus.Repaint; + LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name])); + if FileExists(PluginPath + SR.Name) then + DeleteFile(PluginPath + SR.Name); + if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + SR.Name), nil, nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then + begin + DeleteFile(SavePath + SR.Name); + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name])); + end + else + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name])); + end; + if MatchStrings(SR.Name, '*.dll') then + begin + LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]); + LStatus.Hint := 'UpdateFile'; + LStatus.Repaint; + LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name])); + if FileExists(PluginPath + SR.Name) then + DeleteFile(PluginPath + SR.Name); + if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + SR.Name), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then + begin + DeleteFile(SavePath + SR.Name); + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name])); + end + else + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name])); + end; + if MatchStrings(SR.Name, '*.msg') then + begin + LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]); + LStatus.Hint := 'UpdateFile'; + LStatus.Repaint; + LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name])); + if FileExists(PluginPath + SR.Name) then + DeleteFile(PluginPath + SR.Name); + if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + SR.Name), nil, nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then + begin + DeleteFile(SavePath + SR.Name); + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name])); + end + else + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name])); + end; + if MatchStrings(SR.Name, '*.txt') then + begin + LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]); + LStatus.Hint := 'UpdateFile'; + LStatus.Repaint; + LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name])); + if FileExists(PluginPath + SR.Name) then + DeleteFile(PluginPath + SR.Name); + if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + SR.Name), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then + begin + DeleteFile(SavePath + SR.Name); + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name])); + end + else + LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name])); + end; + until FindNext(SR) <> 0; + FindClose(SR); + end; +end; + +procedure TMainForm.IMDownloader1Break(Sender: TObject); +begin + LStatus.Caption := GetLangStr('DownloadStopped'); + LStatus.Hint := 'DownloadStopped'; + LAmount.Caption := CurrToStr(IMDownloader1.AcceptedSize/1024)+' '+GetLangStr('Kb'); + LAmount.Repaint; + ButtonUpdateEnableStart; +end; + +procedure TMainForm.IMDownloader1Downloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal); +begin + QueryPerformanceCounter(C2); + ProgressBarDownloads.Max := MaxSize; + ProgressBarDownloads.Position := AcceptedSize; + LStatus.Caption := GetLangStr('Loading'); + LStatus.Hint := 'Loading'; + LAmount.Caption := CurrToStr(AcceptedSize/1024)+' '+GetLangStr('Kb'); + LAmount.Repaint; + LSpeed.Caption := CurrToStr((AcceptedSize/1024)/((C2 - C1) / iCounterPerSec))+' '+GetLangStr('KbSec'); + LSpeed.Repaint; +end; + +procedure TMainForm.IMDownloader1Error(Sender: TObject; E: TIMDownloadError); +var + S, HS: String; +begin + case E of + deInternetOpen: + begin + S := GetLangStr('ErrInternetOpen'); + HS := 'ErrInternetOpen'; + end; + deInternetOpenUrl: + begin + S := GetLangStr('ErrInternetOpenURL'); + HS := 'ErrInternetOpenURL'; + end; + deDownloadingFile: + begin + S := GetLangStr('ErrDownloadingFile'); + HS := 'ErrDownloadingFile'; + end; + deRequest: + begin + S := GetLangStr('ErrRequest'); + HS := 'ErrRequest'; + end; + end; + LStatus.Caption := S; + LStatus.Hint := HS; + LogMemo.Lines.Add(S); + LAmount.Caption := CurrToStr(IMDownloader1.AcceptedSize/1024)+' '+GetLangStr('Kb'); + LAmount.Repaint; + if not TrueHeader then + begin + LFileName.Caption := GetLangStr('Unknown'); + LFileDescription.Caption := GetLangStr('Unknown'); + LFileMD5.Caption := GetLangStr('Unknown'); + end; + ButtonUpdateEnableStart; +end; + +{ + : + _|_|MD5Sum_|_ +} +procedure TMainForm.IMDownloader1Headers(Sender: TObject; Headers: string); +var + HeadersStrList: TStringList; + I: Integer; + Size: String; + Ch: Char; + ResultFilename, ResultFileDesc, ResultMD5Sum, ResultHeaders: String; + ResultFileSize: Integer; +begin + //LogMemo.Lines.Add(Headers); + HeadersStrList := TStringList.Create; + HeadersStrList.Clear; + HeadersStrList.Text := Headers; + HeadersStrList.Delete(HeadersStrList.Count-1); // CRLF + if HeadersStrList.Count > 0 then + begin + ResultFilename := 'Test'; + ResultFileDesc := 'Test'; + ResultMD5Sum := '00000000000000000000000000000000'; + ResultFileSize := 0; + LogMemo.Lines.Add(GetLangStr('ParseHeader')); + for I := 0 to HeadersStrList.Count - 1 do + begin + //LogMemo.Lines.Add(HeadersStrList[I]); + // + // Content-Disposition: attachment; filename="-" + // HTTP- + // get.php + if pos('content-disposition', lowercase(HeadersStrList[I])) > 0 then + begin + ResultFilename := HeadersStrList[I]; + Delete(ResultFilename, 1, Pos('"', HeadersStrList[I])); + Delete(ResultFilename, Length(ResultFilename),1); + //LogMemo.Lines.Add('Filename: '+ResultFilename); + end; + // + // Content-Description: Desc + if pos('content-description', lowercase(HeadersStrList[I])) > 0 then + begin + ResultFileDesc := HeadersStrList[I]; + Delete(ResultFileDesc, 1, Pos(':', HeadersStrList[I])); + Delete(ResultFileDesc, 1,1); + //LogMemo.Lines.Add('Description: '+ResultFileDesc); + end; + // + // Content-MD5Sum: MD5 + if pos('content-md5sum', lowercase(HeadersStrList[I])) > 0 then + begin + ResultMD5Sum := HeadersStrList[I]; + Delete(ResultMD5Sum, 1, Pos(':', HeadersStrList[I])); + Delete(ResultMD5Sum, 1,1); + //LogMemo.Lines.Add('MD5: '+ResultMD5Sum); + end; + // + // Content-Length: + if pos('content-length', lowercase(HeadersStrList[i])) > 0 then + begin + Size := ''; + for Ch in HeadersStrList[I]do + if Ch in ['0'..'9'] then + Size := Size + Ch; + ResultFileSize := StrToIntDef(Size,-1);// + Length(HeadersStrList.Text); + end; + end; + ResultHeaders := ResultFilename + '|' + ResultFileDesc + '|' + ResultMD5Sum + '|' + IntToStr(ResultFileSize) + '|'; + if(ResultHeaders <> 'Test|Test|00000000000000000000000000000000|' + IntToStr(ResultFileSize) + '|') then + begin + LogMemo.Lines.Add(GetLangStr('HeaderData')); + LogMemo.Lines.Add(GetLangStr('FileName') + ' ' + ResultFilename); + LogMemo.Lines.Add(GetLangStr('FileDesc') + ' ' + ResultFileDesc); + LogMemo.Lines.Add('MD5: ' + ResultMD5Sum); + LogMemo.Lines.Add(GetLangStr('FileSize') + ' ' + IntToStr(ResultFileSize)); + LFileName.Caption := ResultFilename; + LFileDescription.Caption := ResultFileDesc; + LFileMD5.Caption := ResultMD5Sum; + HeaderFileName := ResultFilename; + HeaderMD5 := ResultMD5Sum; + HeaderFileSize := ResultFileSize; + if (CurrentUpdateStep = 0) and FileExists(PluginPath+HeaderFileName) then + DeleteFile(PluginPath+HeaderFileName); + TrueHeader := True; + end + else + begin + LogMemo.Lines.Add(GetLangStr('InvalidResponseHeader')); + LogMemo.Lines.Add(GetLangStr('InvalidResponseHeaderDesc')); + HeaderFileName := 'Test'; + HeaderMD5 := '00000000000000000000000000000000'; + HeaderFileSize := 0; + TrueHeader := False; + end; + end; + HeadersStrList.Free; +end; + +procedure TMainForm.IMDownloader1MD5Checked(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: string); +begin + MD5InMemory := MD5Str; + IMMD5Correct := MD5Correct; + IMSizeCorrect := SizeCorrect; +end; + +procedure TMainForm.IMDownloader1StartDownload(Sender: TObject); +begin + QueryPerformanceFrequency(iCounterPerSec); + QueryPerformanceCounter(C1); + ButtonUpdateEnableStop; + LStatus.Caption := GetLangStr('InitDownload'); + LStatus.Hint := 'InitDownload'; + LAmount.Caption := '0 '+GetLangStr('Kb'); + LSpeed.Caption := '0 '+GetLangStr('KbSec'); + LogMemo.Lines.Add(GetLangStr('InitDownloadFromURL') + ' ' + IMDownloader1.URL); +end; + +procedure TMainForm.ButtonUpdateStopClick(Sender: TObject); +begin + // + IMDownloader1.BreakDownload; + // + IMCancelCopy := True; +end; + +procedure TMainForm.CBUseProxyClick(Sender: TObject); +begin + if CBUseProxy.Checked then + begin + EProxyAddress.Enabled := True; + EProxyPort.Enabled := True; + CBProxyAuth.Enabled := True; + end + else + begin + EProxyAddress.Enabled := False; + EProxyPort.Enabled := False; + CBProxyAuth.Enabled := False; + end; +end; + +procedure TMainForm.CBProxyAuthClick(Sender: TObject); +begin + if CBProxyAuth.Checked then + begin + EProxyUser.Enabled := True; + EProxyUserPasswd.Enabled := True; + end + else + begin + EProxyUser.Enabled := False; + EProxyUserPasswd.Enabled := False; + end; +end; + +procedure TMainForm.ButtonUpdateEnableStart; +begin + ButtonUpdate.OnClick := ButtonUpdateStartClick; + ButtonUpdate.Caption := GetLangStr('UpdateButton'); + ButtonUpdate.Hint := 'UpdateButton'; + ButtonSettings.Enabled := True; + CBIMClientType.Enabled := True; + CBDBType.Enabled := True; +end; + +procedure TMainForm.ButtonUpdateEnableStop; +begin + ButtonUpdate.OnClick := ButtonUpdateStopClick; + ButtonUpdate.Caption := GetLangStr('StopButton'); + ButtonUpdate.Hint := 'StopButton'; + ButtonSettings.Enabled := False; + CBIMClientType.Enabled := False; + CBDBType.Enabled := False; +end; + +procedure TMainForm.CBDBTypeChange(Sender: TObject); +begin + DBType := CBDBType.Items[CBDBType.ItemIndex]; +end; + +procedure TMainForm.CBIMClientTypeChange(Sender: TObject); +begin + IMClientType := CBIMClientType.Items[CBIMClientType.ItemIndex]; +end; + +{ } +procedure TMainForm.CBLangChange(Sender: TObject); +begin + FLanguage := CBLang.Items[CBLang.ItemIndex]; + DefaultLanguage := CBLang.Items[CBLang.ItemIndex]; + CoreLanguageChanged; +end; + +{ } +procedure TMainForm.FindLangFile; +var + SR: TSearchRec; + I: Integer; +begin + CBLang.Items.Clear; + if FindFirst(PluginPath + dirLangs + '\*.*', faAnyFile or faDirectory, SR) = 0 then + begin + repeat + if (SR.Attr = faDirectory) and ((SR.Name = '.') or (SR.Name = '..')) then // . .. + begin + Continue; // + end; + if MatchStrings(SR.Name, '*.xml') then + begin + // + CBLang.Items.Add(ExtractFileNameEx(SR.Name, False)); + end; + until FindNext(SR) <> 0; + FindClose(SR); + end; + if CBLang.Items.Count > 0 then + begin + for I := 0 to CBLang.Items.Count-1 do + begin + if CBLang.Items[I] = CoreLanguage then + CBLang.ItemIndex := I; + end; + end + else + begin + CBLang.Items.Add(GetLangStr('NotFoundLangFile')); + CBLang.ItemIndex := 0; + CBLang.Enabled := False; + end; +end; + +{ WM_LANGUAGECHANGED } +procedure TMainForm.OnLanguageChanged(var Msg: TMessage); +begin + LoadLanguageStrings; +end; + +{ } +procedure TMainForm.CoreLanguageChanged; +var + LangFile: String; +begin + if CoreLanguage = '' then + Exit; + try + LangFile := PluginPath + dirLangs + CoreLanguage + '.xml'; + if FileExists(LangFile) then + LangDoc.LoadFromFile(LangFile) + else + begin + if FileExists(PluginPath + dirLangs + defaultLangFile) then + LangDoc.LoadFromFile(PluginPath + dirLangs + defaultLangFile) + else + begin + MsgDie(ProgramsName, 'Not found any language file!'); + Exit; + end; + end; + Global.CoreLanguage := CoreLanguage; + SendMessage(MainFormHandle, WM_LANGUAGECHANGED, 0, 0); + //SendMessage(AboutFormHandle, WM_LANGUAGECHANGED, 0, 0); + except + on E: Exception do + MsgDie(ProgramsName, 'Error on CoreLanguageChanged: ' + E.Message + sLineBreak + + 'CoreLanguage: ' + CoreLanguage); + end; +end; + +{ } +procedure TMainForm.LoadLanguageStrings; +begin + if IMClientType <> 'Unknown' then + Caption := ProgramsName + ' for ' + IMClientType + ' (' + MyAccount + ')' + else + Caption := ProgramsName; + if ButtonUpdate.Hint = 'UpdateButton' then + begin + ButtonUpdate.Caption := GetLangStr('UpdateButton'); + ButtonUpdate.Hint := 'UpdateButton'; + end + else + begin + ButtonUpdate.Caption := GetLangStr('StopButton'); + ButtonUpdate.Hint := 'StopButton'; + end; + ButtonSettings.Caption := GetLangStr('SettingsButton'); + LIMClientType.Caption := GetLangStr('IMClientType'); + LDBType.Caption := GetLangStr('LDBType'); + LLanguage.Caption := GetLangStr('Language'); + TabSheetSettings.Caption := GetLangStr('GeneralSettings'); + TabSheetConnectSettings.Caption := GetLangStr('ConnectionSettings'); + TabSheetLog.Caption := GetLangStr('Logs'); + GBSettings.Caption := GetLangStr('GeneralSettings'); + GBConnectSettings.Caption := GetLangStr('ConnectionSettings'); + CBUseProxy.Caption := GetLangStr('UseProxy'); + LProxyAddress.Caption := GetLangStr('ProxyAddress'); + LProxyPort.Caption := GetLangStr('ProxyPort'); + CBProxyAuth.Caption := GetLangStr('ProxyAuth'); + LProxyUser.Caption := GetLangStr('ProxyUser'); + LProxyUserPasswd.Caption := GetLangStr('ProxyUserPasswd'); + EProxyAddress.Left := LProxyAddress.Left + LProxyAddress.Width + 5; + LProxyPort.Left := EProxyAddress.Left + EProxyAddress.Width + 5; + EProxyPort.Left := LProxyPort.Left + LProxyPort.Width + 5; + GBUpdater.Caption := GetLangStr('Update'); + LStatus.Caption := GetLangStr(LStatus.Hint); + LAmountDesc.Caption := GetLangStr('Amount'); + LSpeedDesc.Caption := GetLangStr('Speed'); + LFileNameDesc.Caption := GetLangStr('FileName'); + LFileDesc.Caption := GetLangStr('FileDesc'); + LAmount.Left := LAmountDesc.Left + LAmountDesc.Width + 5; + LSpeed.Left := LSpeedDesc.Left + LSpeedDesc.Width + 5; + LFileName.Left := LFileNameDesc.Left + LFileNameDesc.Width + 5; + LFileDescription.Left := LFileDesc.Left + LFileDesc.Width + 5; + if ButtonSettings.Enabled then + begin + LFileName.Caption := GetLangStr('Unknown'); + LFileDescription.Caption := GetLangStr('Unknown'); + LFileMD5.Caption := GetLangStr('Unknown'); + end; +end; + +function TMainForm.EndTask(TaskName, FormName: String): Boolean; +begin + Result := False; + if IsProcessRun(TaskName, FormName) then + begin + LogMemo.Lines.Add(Format(GetLangStr('InMemoryFoundProcess'), [TaskName, IntToStr(GetProcessID(TaskName))])); + LogMemo.Lines.Add(GetLangStr('SendExitCommand')); + OnSendMessageToOneComponent(FormName, '009'); + Sleep(1200); + LogMemo.Lines.Add(Format(GetLangStr('SearchProcessInMemory'), [TaskName])); + if IsProcessRun(TaskName, FormName) then + begin + LogMemo.Lines.Add(Format(GetLangStr('InMemoryFoundProcess'), [TaskName, IntToStr(GetProcessID(TaskName))])); + LogMemo.Lines.Add(Format(GetLangStr('KillProcess'), [TaskName])); + if KillTask(TaskName, FormName) = 1 then + begin + LogMemo.Lines.Add(Format(GetLangStr('KillProcessDone'), [TaskName])); + Result := True; + end + else + begin + if Global_IMProcessPID <> 0 then + begin + LogMemo.Lines.Add(Format(GetLangStr('NotKillProcess'), [TaskName])); + LogMemo.Lines.Add(Format(GetLangStr('SeDebugPrivilege'), [TaskName])); + if ProcessTerminate(Global_IMProcessPID) then + begin + LogMemo.Lines.Add(Format(GetLangStr('SeDebugPrivilegeDone'), [TaskName])); + Result := True; + end + else + begin + LogMemo.Lines.Add(Format(GetLangStr('NotKillSeDebugPrivilege'), [TaskName])); + Result := False; + end; + end; + end; + end + else + begin + LogMemo.Lines.Add(Format(GetLangStr('InMemoryNotFoundProcess'), [TaskName])); + Result := True; + end; + end + else + begin + LogMemo.Lines.Add(Format(GetLangStr('InMemoryNotFoundProcess'), [TaskName])); + Result := True; + end; +end; + +{ WM_COPYDATA } +procedure TMainForm.OnControlReq(var Msg : TWMCopyData); +var + ControlStr, EncryptControlStr: String; + copyDataType : TCopyDataType; + GotChars: Integer; +begin + copyDataType := TCopyDataType(Msg.CopyDataStruct.dwData); + if copyDataType = cdtString then + begin + GotChars := Msg.CopyDataStruct.cbData div SizeOf(Char); + SetLength(EncryptControlStr, GotChars); + Move(Msg.CopyDataStruct.lpData^, PChar(EncryptControlStr)^, GotChars * sizeof(Char)); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnControlReq: : ' + EncryptControlStr, 1); + ControlStr := DecryptStr(EncryptControlStr); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnControlReq: : ' + ControlStr, 1); + //Msg.Result := 2006; + if ControlStr = 'Russian' then + begin + FLanguage := 'Russian'; + CoreLanguageChanged; + end + else if ControlStr = 'English' then + begin + FLanguage := 'English'; + CoreLanguageChanged; + end; + // 001 - HistoryToDB.ini + if ControlStr = '001' then + begin + // + LoadINI(ProfilePath, true); + end; + // 004 - - + if ControlStr = '0040' then // + AntiBoss(False); + if ControlStr = '0041' then // + AntiBoss(True); + // 003 - + {if (ControlStr = '003') and (ButtonUpdate.Enabled) then + Close;} + // 009 - + if ControlStr = '009' then + begin + IMDownloader1.BreakDownload; + Close; + end; + end; +end; + +{ - } +procedure TMainForm.AntiBoss(HideAllForms: Boolean); +begin + if not Assigned(MainForm) then Exit; + if HideAllForms then + begin + ShowWindow(MainForm.Handle, SW_HIDE); + MainForm.Hide; + //ShowWindow(AboutForm.Handle, SW_HIDE); + //AboutForm.Hide; + end + else + begin + // , + if Global_MainForm_Showing then + begin + ShowWindow(MainForm.Handle, SW_SHOW); + MainForm.Show; + // , + if MainForm.WindowState = wsMinimized then + begin + MainForm.FormStyle := fsStayOnTop; + MainForm.WindowState := wsNormal; + MainForm.FormStyle := fsNormal; + end; + if MainForm.WindowState = wsNormal then + begin + MainForm.FormStyle := fsStayOnTop; + MainForm.FormStyle := fsNormal; + end; + end; + {if Global_AboutForm_Showing then + begin + ShowWindow(AboutForm.Handle, SW_SHOW); + AboutForm.Show; + end;} + end; +end; + +procedure TMainForm.RunIMClient(IMClientName: String; IMProcessArray: TProcessInfoArray); +var + i: Integer; +begin + for i := Low(IMProcessArray) to High(IMProcessArray) do + begin + if LowerCase(IMClientName) = LowerCase(IMProcessArray[i].ProcessName) then + begin + if FileExists(IMProcessArray[i].ProcessPath) then + begin + LogMemo.Lines.Add(Format(GetLangStr('StartProgram'), [IMProcessArray[i].ProcessPath + IMProcessArray[i].ProcessParamCmd])); + ShellExecute(0, 'open', PWideChar(IMProcessArray[i].ProcessPath), PWideChar(' '+IMProcessArray[i].ProcessParamCmd), nil, SW_SHOWNORMAL); + Sleep(500); + if IsProcessRun(IMProcessArray[i].ProcessName) then + LogMemo.Lines.Add(Format(GetLangStr('StartProgramDone'), [IMProcessArray[i].ProcessPath])) + else + LogMemo.Lines.Add(Format(GetLangStr('StartProgramFail'), [IMProcessArray[i].ProcessPath])); + end; + end; + end; +end; + +procedure TMainForm.RunAllIMClients; +begin + if IMClientType = 'QIP' then + RunIMClient('qip.exe', QIPProcessInfo); + if (IMClientType = 'Miranda') or (IMClientType = 'MirandaNG') then + {$IfDef WIN32} + RunIMClient('miranda32.exe', MirandaProcessInfo); + {$Else} + RunIMClient('miranda64.exe', MirandaProcessInfo); + {$EndIf} + if IMClientType = 'RnQ' then + begin + RunIMClient('R&Q.exe', RnQProcessInfo); + RunIMClient('rnq.exe', RnQProcessInfo); + end; + if IMClientType = 'Skype' then + begin + if SystemLang = 'Russian' then + begin + if FileExists(PluginPath + 'installupdater-ru.cmd') then + ShellExecute(0, 'open', PWideChar(PluginPath + 'installupdater-ru.cmd'), nil, nil, SW_HIDE) + else + RunIMClient('skype.exe', SkypeProcessInfo); + end + else + begin + if FileExists(PluginPath + 'installupdater-en.cmd') then + ShellExecute(0, 'open', PWideChar(PluginPath + 'installupdater-en.cmd'), nil, nil, SW_HIDE) + else + RunIMClient('skype.exe', SkypeProcessInfo); + end; + end; + // Dropbox + {if not IsProcessRun('Dropbox.exe') then + RunIMClient('Dropbox.exe', DropboxProcessInfo);} +end; + +function CopyProgressFunc(TotalFileSize: Int64; TotalBytesTransferred: Int64; + StreamSize: Int64; StreamBytesTransferred: Int64; dwStreamNumber: DWORD; + dwCallbackReason: DWORD; hSourceFile: THandle; hDestinationFile: THandle; + lpData: Pointer): DWORD; stdcall; +begin + MainForm.ProgressBarDownloads.Position := 100 * TotalBytesTransferred div TotalFileSize; + Application.ProcessMessages; + CopyProgressFunc := PROGRESS_CONTINUE; +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/NTNative.pas b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/NTNative.pas new file mode 100644 index 0000000000..0f6a2bd831 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/NTNative.pas @@ -0,0 +1,210 @@ +unit NTNative; + +interface + +uses Classes, SysUtils, Windows; + +type + Pointer32 = ULONG; + THANDLE32 = ULONG; + + _UNICODE_STRING = record + Length: Word; + MaximumLength: Word; + Buffer: LPWSTR; + end; + UNICODE_STRING = _UNICODE_STRING; + + //http://msdn.microsoft.com/en-us/library/windows/desktop/ms684280%28v=vs.85%29.aspx + PROCESS_BASIC_INFORMATION = record + Reserved1 : Pointer; + PebBaseAddress: Pointer; + Reserved2: array [0..1] of Pointer; + UniqueProcessId: ULONG_PTR; + Reserved3: Pointer; + end; + + + //http://undocumented.ntinternals.net/UserMode/Structures/RTL_DRIVE_LETTER_CURDIR.html + _RTL_DRIVE_LETTER_CURDIR = record + Flags: Word; + Length: Word; + TimeStamp: ULONG; + DosPath: UNICODE_STRING; + end; + RTL_DRIVE_LETTER_CURDIR = _RTL_DRIVE_LETTER_CURDIR; + + _CURDIR = record + DosPath: UNICODE_STRING; + Handle: THANDLE; + end; + CURDIR = _CURDIR; + + //http://undocumented.ntinternals.net/UserMode/Structures/RTL_USER_PROCESS_PARAMETERS.html + _RTL_USER_PROCESS_PARAMETERS = record + MaximumLength: ULONG; + Length: ULONG; + Flags: ULONG; + DebugFlags: ULONG; + ConsoleHandle: THANDLE; + ConsoleFlags: ULONG; + StandardInput: THANDLE; + StandardOutput: THANDLE; + StandardError: THANDLE; + CurrentDirectory: CURDIR; + DllPath: UNICODE_STRING; + ImagePathName: UNICODE_STRING; + CommandLine: UNICODE_STRING; + Environment: Pointer; + StartingX: ULONG; + StartingY: ULONG; + CountX: ULONG; + CountY: ULONG; + CountCharsX: ULONG; + CountCharsY: ULONG; + FillAttribute: ULONG; + WindowFlags: ULONG; + ShowWindowFlags: ULONG; + WindowTitle: UNICODE_STRING; + DesktopInfo: UNICODE_STRING; + ShellInfo: UNICODE_STRING; + RuntimeData: UNICODE_STRING; + CurrentDirectories: array[0..31] of RTL_DRIVE_LETTER_CURDIR; + end; + RTL_USER_PROCESS_PARAMETERS = _RTL_USER_PROCESS_PARAMETERS; + PRTL_USER_PROCESS_PARAMETERS = ^RTL_USER_PROCESS_PARAMETERS; + + _PEB = record + Reserved1 : array [0..1] of Byte; + BeingDebugged : Byte; + Reserved2 : Byte; + Reserved3 : array [0..1] of Pointer; + Ldr : Pointer; + ProcessParameters : PRTL_USER_PROCESS_PARAMETERS; + Reserved4 : array [0..102] of Byte; + Reserved5 : array [0..51] of Pointer; + PostProcessInitRoutine : Pointer; + Reserved6 : array [0..127] of byte; + Reserved7 : Pointer; + SessionId : ULONG; + end; + PEB=_PEB; + +{$IFDEF CPUX64} + _UNICODE_STRING32 = record + Length: Word; + MaximumLength: Word; + Buffer: Pointer32; + end; + UNICODE_STRING32 = _UNICODE_STRING32; + + _RTL_DRIVE_LETTER_CURDIR32 = record + Flags: Word; + Length: Word; + TimeStamp: ULONG; + DosPath: UNICODE_STRING32; + end; + RTL_DRIVE_LETTER_CURDIR32 = _RTL_DRIVE_LETTER_CURDIR32; + + _CURDIR32 = record + DosPath: UNICODE_STRING32; + Handle: THANDLE32; + end; + CURDIR32 = _CURDIR32; + + _RTL_USER_PROCESS_PARAMETERS32 = record + MaximumLength: ULONG; + Length: ULONG; + Flags: ULONG; + DebugFlags: ULONG; + ConsoleHandle: THANDLE32; + ConsoleFlags: ULONG; + StandardInput: THANDLE32; + StandardOutput: THANDLE32; + StandardError: THANDLE32; + CurrentDirectory: CURDIR32; + DllPath: UNICODE_STRING32; + ImagePathName: UNICODE_STRING32; + CommandLine: UNICODE_STRING32; + Environment: Pointer32; + StartingX: ULONG; + StartingY: ULONG; + CountX: ULONG; + CountY: ULONG; + CountCharsX: ULONG; + CountCharsY: ULONG; + FillAttribute: ULONG; + WindowFlags: ULONG; + ShowWindowFlags: ULONG; + WindowTitle: UNICODE_STRING32; + DesktopInfo: UNICODE_STRING32; + ShellInfo: UNICODE_STRING32; + RuntimeData: UNICODE_STRING32; + CurrentDirectories: array[0..31] of RTL_DRIVE_LETTER_CURDIR32; + end; + RTL_USER_PROCESS_PARAMETERS32 = _RTL_USER_PROCESS_PARAMETERS32; + PRTL_USER_PROCESS_PARAMETERS32 = ^RTL_USER_PROCESS_PARAMETERS32; + + _PEB32 = record + Reserved1 : array [0..1] of Byte; + BeingDebugged : Byte; + Reserved2 : Byte; + Reserved3 : array [0..1] of Pointer32; + Ldr : Pointer32; + ProcessParameters : Pointer32;//PRTL_USER_PROCESS_PARAMETERS; + Reserved4 : array [0..102] of Byte; + Reserved5 : array [0..51] of Pointer32; + PostProcessInitRoutine : Pointer32; + Reserved6 : array [0..127] of byte; + Reserved7 : Pointer32; + SessionId : ULONG; + end; + PEB32=_PEB32; +{$ENDIF} + +type + TIsWow64Process = function(Handle:THandle; var IsWow64 : BOOL) : BOOL; stdcall; +var + _IsWow64Process : TIsWow64Process; + +function NtQueryInformationProcess(ProcessHandle : THandle; ProcessInformationClass : DWORD; ProcessInformation : Pointer; ProcessInformationLength : ULONG; ReturnLength : PULONG ): LongInt; stdcall; external 'ntdll.dll'; +function NtQueryVirtualMemory(ProcessHandle : THandle; BaseAddress : Pointer; MemoryInformationClass : DWORD; MemoryInformation : Pointer; MemoryInformationLength : ULONG; ReturnLength : PULONG ): LongInt; stdcall; external 'ntdll.dll'; +function ProcessIsX64(hProcess: DWORD): Boolean; +procedure Init_IsWow64Process; + +implementation + +procedure Init_IsWow64Process; +var + hKernel32 : Integer; +begin + hKernel32 := LoadLibrary(kernel32); + if (hKernel32 = 0) then RaiseLastOSError; + try + _IsWow64Process := GetProcAddress(hkernel32, 'IsWow64Process'); + finally + FreeLibrary(hKernel32); + end; +end; + +function ProcessIsX64(hProcess: DWORD): Boolean; +var + IsWow64: BOOL; +begin + Result := False; + {$IFNDEF CPUX64} + Exit; + {$ENDIF} + if not Assigned(_IsWow64Process) then + Init_IsWow64Process; + + if Assigned(_IsWow64Process) then + begin + if (_IsWow64Process(hProcess, IsWow64)) then + Result := not IsWow64 + else + RaiseLastOSError; + end; +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/jedi.inc b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/jedi.inc new file mode 100644 index 0000000000..c31a08c04a --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/jedi.inc @@ -0,0 +1,1430 @@ +{$IFNDEF JEDI_INC} +{$DEFINE JEDI_INC} + +{**************************************************************************************************} +{ } +{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");} +{ you may not use this file except in compliance with the License. You may obtain a copy of the } +{ License at http://www.mozilla.org/MPL/ } +{ } +{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF } +{ ANY KIND, either express or implied. See the License for the specific language governing rights } +{ and limitations under the License. } +{ } +{ The Original Code is: jedi.inc. } +{ The Initial Developer of the Original Code is Project JEDI http://www.delphi-jedi.org } +{ } +{ Alternatively, the contents of this file may be used under the terms of the GNU Lesser General } +{ Public License (the "LGPL License"), in which case the provisions of the LGPL License are } +{ applicable instead of those above. If you wish to allow use of your version of this file only } +{ under the terms of the LGPL License and not to allow others to use your version of this file } +{ under the MPL, indicate your decision by deleting the provisions above and replace them with } +{ the notice and other provisions required by the LGPL License. If you do not delete the } +{ provisions above, a recipient may use your version of this file under either the MPL or the } +{ LGPL License. } +{ } +{ For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html } +{ } +{**************************************************************************************************} +{ } +{ This file defines various generic compiler directives used in different libraries, e.g. in the } +{ JEDI Code Library (JCL) and JEDI Visual Component Library Library (JVCL). The directives in } +{ this file are of generic nature and consist mostly of mappings from the VERXXX directives } +{ defined by Delphi, C++Builder and FPC to friendly names such as DELPHI5 and } +{ SUPPORTS_WIDESTRING. These friendly names are subsequently used in the libraries to test for } +{ compiler versions and/or whether the compiler supports certain features (such as widestrings or } +{ 64 bit integers. The libraries provide an additional, library specific, include file. For the } +{ JCL e.g. this is jcl.inc. These files should be included in source files instead of this file } +{ (which is pulled in automatically). } +{ } +{**************************************************************************************************} +{ } +{ Last modified: $Date:: 2012-09-04 16:01:38 +0200 (út, 04 9 2012) $ } +{ Revision: $Rev:: 161 $ } +{ Author: $Author:: outchy $ } +{ } +{**************************************************************************************************} + +(* + +- Development environment directives + + This file defines two directives to indicate which development environment the + library is being compiled with. Currently this can either be Delphi, Kylix, + C++Builder or FPC. + + Directive Description + ------------------------------------------------------------------------------ + DELPHI Defined if compiled with Delphi + KYLIX Defined if compiled with Kylix + DELPHICOMPILER Defined if compiled with Delphi or Kylix/Delphi + BCB Defined if compiled with C++Builder + CPPBUILDER Defined if compiled with C++Builder (alias for BCB) + BCBCOMPILER Defined if compiled with C++Builder or Kylix/C++ + DELPHILANGUAGE Defined if compiled with Delphi, Kylix or C++Builder + BORLAND Defined if compiled with Delphi, Kylix or C++Builder + FPC Defined if compiled with FPC + +- Platform Directives + + Platform directives are not all explicitly defined in this file, some are + defined by the compiler itself. They are listed here only for completeness. + + Directive Description + ------------------------------------------------------------------------------ + WIN32 Defined when target platform is 32 bit Windows + WIN64 Defined when target platform is 64 bit Windows + MSWINDOWS Defined when target platform is 32 bit Windows + LINUX Defined when target platform is Linux + UNIX Defined when target platform is Unix-like (including Linux) + CLR Defined when target platform is .NET + +- Architecture directives. These are auto-defined by FPC + CPU32 and CPU64 are mostly for generic pointer size dependant differences rather + than for a specific architecture. + + CPU386 Defined when target platform is native x86 (win32) + CPUx86_64 Defined when target platform is native x86_64 (win64) + CPU32 Defined when target is 32-bit + CPU64 Defined when target is 64-bit + CPUASM Defined when target assembler is available + +- Visual library Directives + + The following directives indicate for a visual library. In a Delphi/BCB + (Win32) application you need to define the VisualCLX symbol in the project + options, if you want to use the VisualCLX library. Alternatively you can use + the IDE expert, which is distributed with the JCL to do this automatically. + + Directive Description + ------------------------------------------------------------------------------ + VCL Defined for Delphi/BCB (Win32) exactly if VisualCLX is not defined + VisualCLX Defined for Kylix; needs to be defined for Delphi/BCB to + use JCL with VisualCLX applications. + + +- Other cross-platform related defines + + These symbols are intended to help in writing portable code. + + Directive Description + ------------------------------------------------------------------------------ + PUREPASCAL Code is machine-independent (as opposed to assembler code) + Win32API Code is specific for the Win32 API; + use instead of "{$IFNDEF CLR} {$IFDEF MSWINDOWS}" constructs + + +- Delphi Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. These directives are only defined if + the compiler is Delphi (ie DELPHI is defined). + + Directive Description + ------------------------------------------------------------------------------ + DELPHI1 Defined when compiling with Delphi 1 (Codename WASABI/MANGO) + DELPHI2 Defined when compiling with Delphi 2 (Codename POLARIS) + DELPHI3 Defined when compiling with Delphi 3 (Codename IVORY) + DELPHI4 Defined when compiling with Delphi 4 (Codename ALLEGRO) + DELPHI5 Defined when compiling with Delphi 5 (Codename ARGUS) + DELPHI6 Defined when compiling with Delphi 6 (Codename ILLIAD) + DELPHI7 Defined when compiling with Delphi 7 (Codename AURORA) + DELPHI8 Defined when compiling with Delphi 8 (Codename OCTANE) + DELPHI2005 Defined when compiling with Delphi 2005 (Codename DIAMONDBACK) + DELPHI9 Alias for DELPHI2005 + DELPHI10 Defined when compiling with Delphi 2006 (Codename DEXTER) + DELPHI2006 Alias for DELPHI10 + DELPHI11 Defined when compiling with Delphi 2007 for Win32 (Codename SPACELY) + DELPHI2007 Alias for DELPHI11 + DELPHI12 Defined when compiling with Delphi 2009 for Win32 (Codename TIBURON) + DELPHI2009 Alias for DELPHI12 + DELPHI14 Defined when compiling with Delphi 2010 for Win32 (Codename WEAVER) + DELPHI2010 Alias for DELPHI14 + DELPHI15 Defined when compiling with Delphi XE for Win32 (Codename FULCRUM) + DELPHIXE Alias for DELPHI15 + DELPHI16 Defined when compiling with Delphi XE2 for Win32 (Codename PULSAR) + DELPHIXE2 Alias for DELPHI16 + DELPHI17 Defined when compiling with Delphi XE3 for Win32 (Codename WATERDRAGON) + DELPHIXE3 Alias for DELPHI17 + DELPHI1_UP Defined when compiling with Delphi 1 or higher + DELPHI2_UP Defined when compiling with Delphi 2 or higher + DELPHI3_UP Defined when compiling with Delphi 3 or higher + DELPHI4_UP Defined when compiling with Delphi 4 or higher + DELPHI5_UP Defined when compiling with Delphi 5 or higher + DELPHI6_UP Defined when compiling with Delphi 6 or higher + DELPHI7_UP Defined when compiling with Delphi 7 or higher + DELPHI8_UP Defined when compiling with Delphi 8 or higher + DELPHI2005_UP Defined when compiling with Delphi 2005 or higher + DELPHI9_UP Alias for DELPHI2005_UP + DELPHI10_UP Defined when compiling with Delphi 2006 or higher + DELPHI2006_UP Alias for DELPHI10_UP + DELPHI11_UP Defined when compiling with Delphi 2007 for Win32 or higher + DELPHI2007_UP Alias for DELPHI11_UP + DELPHI12_UP Defined when compiling with Delphi 2009 for Win32 or higher + DELPHI2009_UP Alias for DELPHI12_UP + DELPHI14_UP Defined when compiling with Delphi 2010 for Win32 or higher + DELPHI2010_UP Alias for DELPHI14_UP + DELPHI15_UP Defined when compiling with Delphi XE for Win32 or higher + DELPHIXE_UP Alias for DELPHI15_UP + DELPHI16_UP Defined when compiling with Delphi XE2 for Win32 or higher + DELPHIXE2_UP Alias for DELPHI16_UP + DELPHI17_UP Defined when compiling with Delphi XE3 for Win32 or higher + DELPHIXE3_UP Alias for DELPHI17_UP + + +- Kylix Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. These directives are only defined if + the compiler is Kylix (ie KYLIX is defined). + + Directive Description + ------------------------------------------------------------------------------ + KYLIX1 Defined when compiling with Kylix 1 + KYLIX2 Defined when compiling with Kylix 2 + KYLIX3 Defined when compiling with Kylix 3 (Codename CORTEZ) + KYLIX1_UP Defined when compiling with Kylix 1 or higher + KYLIX2_UP Defined when compiling with Kylix 2 or higher + KYLIX3_UP Defined when compiling with Kylix 3 or higher + + +- Delphi Compiler Versions (Delphi / Kylix, not in BCB mode) + + Directive Description + ------------------------------------------------------------------------------ + DELPHICOMPILER1 Defined when compiling with Delphi 1 + DELPHICOMPILER2 Defined when compiling with Delphi 2 + DELPHICOMPILER3 Defined when compiling with Delphi 3 + DELPHICOMPILER4 Defined when compiling with Delphi 4 + DELPHICOMPILER5 Defined when compiling with Delphi 5 + DELPHICOMPILER6 Defined when compiling with Delphi 6 or Kylix 1, 2 or 3 + DELPHICOMPILER7 Defined when compiling with Delphi 7 + DELPHICOMPILER8 Defined when compiling with Delphi 8 + DELPHICOMPILER9 Defined when compiling with Delphi 2005 + DELPHICOMPILER10 Defined when compiling with Delphi Personality of BDS 4.0 + DELPHICOMPILER11 Defined when compiling with Delphi 2007 for Win32 + DELPHICOMPILER12 Defined when compiling with Delphi Personality of BDS 6.0 + DELPHICOMPILER14 Defined when compiling with Delphi Personality of BDS 7.0 + DELPHICOMPILER15 Defined when compiling with Delphi Personality of BDS 8.0 + DELPHICOMPILER16 Defined when compiling with Delphi Personality of BDS 9.0 + DELPHICOMPILER17 Defined when compiling with Delphi Personality of BDS 10.0 + DELPHICOMPILER1_UP Defined when compiling with Delphi 1 or higher + DELPHICOMPILER2_UP Defined when compiling with Delphi 2 or higher + DELPHICOMPILER3_UP Defined when compiling with Delphi 3 or higher + DELPHICOMPILER4_UP Defined when compiling with Delphi 4 or higher + DELPHICOMPILER5_UP Defined when compiling with Delphi 5 or higher + DELPHICOMPILER6_UP Defined when compiling with Delphi 6 or Kylix 1, 2 or 3 or higher + DELPHICOMPILER7_UP Defined when compiling with Delphi 7 or higher + DELPHICOMPILER8_UP Defined when compiling with Delphi 8 or higher + DELPHICOMPILER9_UP Defined when compiling with Delphi 2005 + DELPHICOMPILER10_UP Defined when compiling with Delphi 2006 or higher + DELPHICOMPILER11_UP Defined when compiling with Delphi 2007 for Win32 or higher + DELPHICOMPILER12_UP Defined when compiling with Delphi 2009 for Win32 or higher + DELPHICOMPILER14_UP Defined when compiling with Delphi 2010 for Win32 or higher + DELPHICOMPILER15_UP Defined when compiling with Delphi XE for Win32 or higher + DELPHICOMPILER16_UP Defined when compiling with Delphi XE2 for Win32 or higher + DELPHICOMPILER17_UP Defined when compiling with Delphi XE3 for Win32 or higher + + +- C++Builder Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. These directives are only defined if + the compiler is C++Builder (ie BCB is defined). + + Directive Description + ------------------------------------------------------------------------------ + BCB1 Defined when compiling with C++Builder 1 + BCB3 Defined when compiling with C++Builder 3 + BCB4 Defined when compiling with C++Builder 4 + BCB5 Defined when compiling with C++Builder 5 (Codename RAMPAGE) + BCB6 Defined when compiling with C++Builder 6 (Codename RIPTIDE) + BCB10 Defined when compiling with C++Builder Personality of BDS 4.0 (also known as C++Builder 2006) (Codename DEXTER) + BCB11 Defined when compiling with C++Builder Personality of RAD Studio 2007 (also known as C++Builder 2007) (Codename COGSWELL) + BCB12 Defined when compiling with C++Builder Personality of RAD Studio 2009 (also known as C++Builder 2009) (Codename TIBURON) + BCB14 Defined when compiling with C++Builder Personality of RAD Studio 2010 (also known as C++Builder 2010) (Codename WEAVER) + BCB15 Defined when compiling with C++Builder Personality of RAD Studio XE (also known as C++Builder XE) (Codename FULCRUM) + BCB16 Defined when compiling with C++Builder Personality of RAD Studio XE2 (also known as C++Builder XE2) (Codename PULSAR) + BCB17 Defined when compiling with C++Builder Personality of RAD Studio XE3 (also known as C++Builder XE3) (Codename WATERDRAGON) + BCB1_UP Defined when compiling with C++Builder 1 or higher + BCB3_UP Defined when compiling with C++Builder 3 or higher + BCB4_UP Defined when compiling with C++Builder 4 or higher + BCB5_UP Defined when compiling with C++Builder 5 or higher + BCB6_UP Defined when compiling with C++Builder 6 or higher + BCB10_UP Defined when compiling with C++Builder Personality of BDS 4.0 or higher + BCB11_UP Defined when compiling with C++Builder Personality of RAD Studio 2007 or higher + BCB12_UP Defined when compiling with C++Builder Personality of RAD Studio 2009 or higher + BCB14_UP Defined when compiling with C++Builder Personality of RAD Studio 2010 or higher + BCB15_UP Defined when compiling with C++Builder Personality of RAD Studio XE or higher + BCB16_UP Defined when compiling with C++Builder Personality of RAD Studio XE2 or higher + BCB17_UP Defined when compiling with C++Builder Personality of RAD Studio XE3 or higher + + +- RAD Studio / Borland Developer Studio Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated IDE. These directives are only defined if + the IDE is Borland Developer Studio Version 2 or above. + + Note: Borland Developer Studio 2006 is marketed as Delphi 2006 or C++Builder 2006, + but those provide only different labels for identical content. + + Directive Description + ------------------------------------------------------------------------------ + BDS Defined when compiling with BDS version of dcc32.exe (Codename SIDEWINDER) + BDS2 Defined when compiling with BDS 2.0 (Delphi 8) (Codename OCTANE) + BDS3 Defined when compiling with BDS 3.0 (Delphi 2005) (Codename DIAMONDBACK) + BDS4 Defined when compiling with BDS 4.0 (Borland Developer Studio 2006) (Codename DEXTER) + BDS5 Defined when compiling with BDS 5.0 (CodeGear RAD Studio 2007) (Codename HIGHLANDER) + BDS6 Defined when compiling with BDS 6.0 (CodeGear RAD Studio 2009) (Codename TIBURON) + BDS7 Defined when compiling with BDS 7.0 (Embarcadero RAD Studio 2010) (Codename WEAVER) + BDS8 Defined when compiling with BDS 8.0 (Embarcadero RAD Studio XE) (Codename FULCRUM) + BDS9 Defined when compiling with BDS 9.0 (Embarcadero RAD Studio XE2) (Codename PULSAR) + BDS10 Defined when compiling with BDS 10.0 (Embarcadero RAD Studio XE3) (Codename WATERDRAGON) + BDS2_UP Defined when compiling with BDS 2.0 or higher + BDS3_UP Defined when compiling with BDS 3.0 or higher + BDS4_UP Defined when compiling with BDS 4.0 or higher + BDS5_UP Defined when compiling with BDS 5.0 or higher + BDS6_UP Defined when compiling with BDS 6.0 or higher + BDS7_UP Defined when compiling with BDS 7.0 or higher + BDS8_UP Defined when compiling with BDS 8.0 or higher + BDS9_UP Defined when compiling with BDS 9.0 or higher + BDS10_UP Defined when compiling with BDS 10.0 or higher + +- Compiler Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. Unlike the DELPHI_X and BCB_X + directives, these directives are indepedent of the development environment. + That is, they are defined regardless of whether compilation takes place using + Delphi or C++Builder. + + Directive Description + ------------------------------------------------------------------------------ + COMPILER1 Defined when compiling with Delphi 1 + COMPILER2 Defined when compiling with Delphi 2 or C++Builder 1 + COMPILER3 Defined when compiling with Delphi 3 + COMPILER35 Defined when compiling with C++Builder 3 + COMPILER4 Defined when compiling with Delphi 4 or C++Builder 4 + COMPILER5 Defined when compiling with Delphi 5 or C++Builder 5 + COMPILER6 Defined when compiling with Delphi 6 or C++Builder 6 + COMPILER7 Defined when compiling with Delphi 7 + COMPILER8 Defined when compiling with Delphi 8 + COMPILER9 Defined when compiling with Delphi 9 + COMPILER10 Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 + COMPILER11 Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 + COMPILER12 Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 + COMPILER14 Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 + COMPILER15 Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 + COMPILER16 Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 + COMPILER17 Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 + COMPILER1_UP Defined when compiling with Delphi 1 or higher + COMPILER2_UP Defined when compiling with Delphi 2 or C++Builder 1 or higher + COMPILER3_UP Defined when compiling with Delphi 3 or higher + COMPILER35_UP Defined when compiling with C++Builder 3 or higher + COMPILER4_UP Defined when compiling with Delphi 4 or C++Builder 4 or higher + COMPILER5_UP Defined when compiling with Delphi 5 or C++Builder 5 or higher + COMPILER6_UP Defined when compiling with Delphi 6 or C++Builder 6 or higher + COMPILER7_UP Defined when compiling with Delphi 7 + COMPILER8_UP Defined when compiling with Delphi 8 + COMPILER9_UP Defined when compiling with Delphi Personalities of BDS 3.0 + COMPILER10_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 or higher + COMPILER11_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 or higher + COMPILER12_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 or higher + COMPILER14_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 or higher + COMPILER15_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 or higher + COMPILER16_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 or higher + COMPILER17_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 or higher + + +- RTL Versions + + Use e.g. following to determine the exact RTL version since version 14.0: + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF Declared(RTLVersion) and (RTLVersion >= 14.2)} + // code for Delphi 6.02 or higher, Kylix 2 or higher, C++Builder 6 or higher + ... + {$IFEND} + {$ENDIF} + + Directive Description + ------------------------------------------------------------------------------ + RTL80_UP Defined when compiling with Delphi 1 or higher + RTL90_UP Defined when compiling with Delphi 2 or higher + RTL93_UP Defined when compiling with C++Builder 1 or higher + RTL100_UP Defined when compiling with Delphi 3 or higher + RTL110_UP Defined when compiling with C++Builder 3 or higher + RTL120_UP Defined when compiling with Delphi 4 or higher + RTL125_UP Defined when compiling with C++Builder 4 or higher + RTL130_UP Defined when compiling with Delphi 5 or C++Builder 5 or higher + RTL140_UP Defined when compiling with Delphi 6, Kylix 1, 2 or 3 or C++Builder 6 or higher + RTL150_UP Defined when compiling with Delphi 7 or higher + RTL160_UP Defined when compiling with Delphi 8 or higher + RTL170_UP Defined when compiling with Delphi Personalities of BDS 3.0 or higher + RTL180_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 or higher + RTL185_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 or higher + RTL190_UP Defined when compiling with Delphi.NET of BDS 5.0 or higher + RTL200_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 or higher + RTL210_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 or higher + RTL220_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 or higher + RTL230_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 or higher + RTL240_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 or higher + + +- CLR Versions + + Directive Description + ------------------------------------------------------------------------------ + CLR Defined when compiling for .NET + CLR10 Defined when compiling for .NET 1.0 (may be overriden by FORCE_CLR10) + CLR10_UP Defined when compiling for .NET 1.0 or higher + CLR11 Defined when compiling for .NET 1.1 (may be overriden by FORCE_CLR11) + CLR11_UP Defined when compiling for .NET 1.1 or higher + CLR20 Defined when compiling for .NET 2.0 (may be overriden by FORCE_CLR20) + CLR20_UP Defined when compiling for .NET 2.0 or higher + + +- Feature Directives + + The features directives are used to test if the compiler supports specific + features, such as method overloading, and adjust the sources accordingly. Use + of these directives is preferred over the use of the DELPHI and COMPILER + directives. + + Directive Description + ------------------------------------------------------------------------------ + SUPPORTS_CONSTPARAMS Compiler supports const parameters (D1+) + SUPPORTS_SINGLE Compiler supports the Single type (D1+) + SUPPORTS_DOUBLE Compiler supports the Double type (D1+) + SUPPORTS_EXTENDED Compiler supports the Extended type (D1+) + SUPPORTS_CURRENCY Compiler supports the Currency type (D2+) + SUPPORTS_THREADVAR Compiler supports threadvar declarations (D2+) + SUPPORTS_OUTPARAMS Compiler supports out parameters (D3+) + SUPPORTS_VARIANT Compiler supports variant (D2+) + SUPPORTS_WIDECHAR Compiler supports the WideChar type (D2+) + SUPPORTS_WIDESTRING Compiler supports the WideString type (D3+/BCB3+) + SUPPORTS_INTERFACE Compiler supports interfaces (D3+/BCB3+) + SUPPORTS_DISPINTERFACE Compiler supports dispatch interfaces (D3+/BCB3+) + SUPPORTS_DISPID Compiler supports dispatch ids (D3+/BCB3+/FPC) + SUPPORTS_EXTSYM Compiler supports the $EXTERNALSYM directive (D4+/BCB3+) + SUPPORTS_NODEFINE Compiler supports the $NODEFINE directive (D4+/BCB3+) + SUPPORTS_LONGWORD Compiler supports the LongWord type (unsigned 32 bit) (D4+/BCB4+) + SUPPORTS_INT64 Compiler supports the Int64 type (D4+/BCB4+) + SUPPORTS_UINT64 Compiler supports the UInt64 type (D XE+ ?) + SUPPORTS_DYNAMICARRAYS Compiler supports dynamic arrays (D4+/BCB4+) + SUPPORTS_DEFAULTPARAMS Compiler supports default parameters (D4+/BCB4+) + SUPPORTS_OVERLOAD Compiler supports overloading (D4+/BCB4+) + SUPPORTS_IMPLEMENTS Compiler supports implements (D4+/BCB4+) + SUPPORTS_DEPRECATED Compiler supports the deprecated directive (D6+/BCB6+) + SUPPORTS_PLATFORM Compiler supports the platform directive (D6+/BCB6+) + SUPPORTS_LIBRARY Compiler supports the library directive (D6+/BCB6+/FPC) + SUPPORTS_LOCAL Compiler supports the local directive (D6+/BCB6+) + SUPPORTS_SETPEFLAGS Compiler supports the SetPEFlags directive (D6+/BCB6+) + SUPPORTS_EXPERIMENTAL_WARNINGS Compiler supports the WARN SYMBOL_EXPERIMENTAL and WARN UNIT_EXPERIMENTAL directives (D6+/BCB6+) + SUPPORTS_INLINE Compiler supports the inline directive (D9+/FPC) + SUPPORTS_FOR_IN Compiler supports for in loops (D9+) + SUPPORTS_NESTED_CONSTANTS Compiler supports nested constants (D9+) + SUPPORTS_NESTED_TYPES Compiler supports nested types (D9+) + SUPPORTS_REGION Compiler supports the REGION and ENDREGION directives (D9+) + SUPPORTS_ENHANCED_RECORDS Compiler supports class [operator|function|procedure] for record types (D9.NET, D10+) + SUPPORTS_CLASS_FIELDS Compiler supports class fields (D9.NET, D10+) + SUPPORTS_CLASS_HELPERS Compiler supports class helpers (D9.NET, D10+) + SUPPORTS_CLASS_OPERATORS Compiler supports class operators (D9.NET, D10+) + SUPPORTS_CLASS_CTORDTORS Compiler supports class contructors/destructors (D14+) + SUPPORTS_STRICT Compiler supports strict keyword (D9.NET, D10+) + SUPPORTS_STATIC Compiler supports static keyword (D9.NET, D10+) + SUPPORTS_FINAL Compiler supports final keyword (D9.NET, D10+) + SUPPORTS_METHODINFO Compiler supports the METHODINFO directives (D10+) + SUPPORTS_GENERICS Compiler supports generic implementations (D11.NET, D12+) + SUPPORTS_DEPRECATED_DETAILS Compiler supports additional text for the deprecated directive (D11.NET, D12+) + ACCEPT_DEPRECATED Compiler supports or ignores the deprecated directive (D6+/BCB6+/FPC) + ACCEPT_PLATFORM Compiler supports or ignores the platform directive (D6+/BCB6+/FPC) + ACCEPT_LIBRARY Compiler supports or ignores the library directive (D6+/BCB6+) + SUPPORTS_CUSTOMVARIANTS Compiler supports custom variants (D6+/BCB6+) + SUPPORTS_VARARGS Compiler supports varargs (D6+/BCB6+) + SUPPORTS_ENUMVALUE Compiler supports assigning ordinalities to values of enums (D6+/BCB6+) + SUPPORTS_DEPRECATED_WARNINGS Compiler supports deprecated warnings (D6+/BCB6+) + SUPPORTS_LIBRARY_WARNINGS Compiler supports library warnings (D6+/BCB6+) + SUPPORTS_PLATFORM_WARNINGS Compiler supports platform warnings (D6+/BCB6+) + SUPPORTS_UNSAFE_WARNINGS Compiler supports unsafe warnings (D7) + SUPPORTS_WEAKPACKAGEUNIT Compiler supports the WEAKPACKAGEUNIT directive + SUPPORTS_COMPILETIME_MESSAGES Compiler supports the MESSAGE directive + SUPPORTS_PACKAGES Compiler supports Packages + HAS_UNIT_LIBC Unit Libc exists (Kylix, FPC on Linux/x86) + HAS_UNIT_RTLCONSTS Unit RTLConsts exists (D6+/BCB6+/FPC) + HAS_UNIT_TYPES Unit Types exists (D6+/BCB6+/FPC) + HAS_UNIT_VARIANTS Unit Variants exists (D6+/BCB6+/FPC) + HAS_UNIT_STRUTILS Unit StrUtils exists (D6+/BCB6+/FPC) + HAS_UNIT_DATEUTILS Unit DateUtils exists (D6+/BCB6+/FPC) + HAS_UNIT_CONTNRS Unit contnrs exists (D6+/BCB6+/FPC) + HAS_UNIT_HTTPPROD Unit HTTPProd exists (D9+) + HAS_UNIT_GIFIMG Unit GifImg exists (D11+) + HAS_UNIT_ANSISTRINGS Unit AnsiStrings exists (D12+) + HAS_UNIT_PNGIMAGE Unit PngImage exists (D12+) + HAS_UNIT_CHARACTER Unit Character exists (D12+) + XPLATFORM_RTL The RTL supports crossplatform function names (e.g. RaiseLastOSError) (D6+/BCB6+/FPC) + SUPPORTS_UNICODE string type is aliased to an unicode string (WideString or UnicodeString) (DX.NET, D12+) + SUPPORTS_UNICODE_STRING Compiler supports UnicodeString (D12+) + SUPPORTS_INT_ALIASES Types Int8, Int16, Int32, UInt8, UInt16 and UInt32 are defined in the unit System (D12+) + HAS_UNIT_RTTI Unit RTTI is available (D14+) + SUPPORTS_CAST_INTERFACE_TO_OBJ The compiler supports casts from interfaces to objects (D14+) + SUPPORTS_DELAYED_LOADING The compiler generates stubs for delaying imported function loads (D14+) + HAS_UNIT_REGULAREXPRESSIONSAPI Unit RegularExpressionsAPI is available (D15+) + HAS_UNIT_SYSTEM_UITYPES Unit System.UITypes is available (D16+) + HAS_UNIT_SYSTEM_ACTIONS Unit System.Actions is available (D17+) + + +- Compiler Settings + + The compiler settings directives indicate whether a specific compiler setting + is in effect. This facilitates changing compiler settings locally in a more + compact and readible manner. + + Directive Description + ------------------------------------------------------------------------------ + ALIGN_ON Compiling in the A+ state (no alignment) + BOOLEVAL_ON Compiling in the B+ state (complete boolean evaluation) + ASSERTIONS_ON Compiling in the C+ state (assertions on) + DEBUGINFO_ON Compiling in the D+ state (debug info generation on) + IMPORTEDDATA_ON Compiling in the G+ state (creation of imported data references) + LONGSTRINGS_ON Compiling in the H+ state (string defined as AnsiString) + IOCHECKS_ON Compiling in the I+ state (I/O checking enabled) + WRITEABLECONST_ON Compiling in the J+ state (typed constants can be modified) + LOCALSYMBOLS Compiling in the L+ state (local symbol generation) + LOCALSYMBOLS_ON Alias of LOCALSYMBOLS + TYPEINFO_ON Compiling in the M+ state (RTTI generation on) + OPTIMIZATION_ON Compiling in the O+ state (code optimization on) + OPENSTRINGS_ON Compiling in the P+ state (variable string parameters are openstrings) + OVERFLOWCHECKS_ON Compiling in the Q+ state (overflow checing on) + RANGECHECKS_ON Compiling in the R+ state (range checking on) + TYPEDADDRESS_ON Compiling in the T+ state (pointers obtained using the @ operator are typed) + SAFEDIVIDE_ON Compiling in the U+ state (save FDIV instruction through RTL emulation) + VARSTRINGCHECKS_ON Compiling in the V+ state (type checking of shortstrings) + STACKFRAMES_ON Compiling in the W+ state (generation of stack frames) + EXTENDEDSYNTAX_ON Compiling in the X+ state (Delphi extended syntax enabled) +*) + +{$DEFINE BORLAND} + +{ Set FreePascal to Delphi mode } +{$IFDEF FPC} + {$MODE DELPHI} + {$ASMMODE Intel} + {$UNDEF BORLAND} + {$DEFINE CPUASM} + // FPC defines CPU32, CPU64 and Unix automatically +{$ENDIF} + +{$IFDEF BORLAND} + {$IFDEF LINUX} + {$DEFINE KYLIX} + {$ENDIF LINUX} + {$IFNDEF CLR} + {$IFNDEF CPUX86} + {$IFNDEF CPUX64} + {$DEFINE CPU386} // For Borland compilers select the x86 compat assembler by default + {$DEFINE CPU32} // Assume Borland compilers are 32-bit (rather than 64-bit) + {$DEFINE CPUASM} + {$ELSE ~CPUX64} + {$DEFINE CPU64} + {$DEFINE CPUASM} + {$DEFINE DELPHI64_TEMPORARY} + {$ENDIF ~CPUX64} + {$ELSE ~CPUX86} + {$DEFINE CPU386} + {$DEFINE CPU32} + {$DEFINE CPUASM} + {$ENDIF ~CPUX86} + {$ENDIF ~CLR} +{$ENDIF BORLAND} + +{------------------------------------------------------------------------------} +{ VERXXX to COMPILERX, DELPHIX and BCBX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BORLAND} + {$IFDEF KYLIX} + {$I kylix.inc} // FPC incompatible stuff + {$ELSE ~KYLIX} + + {$DEFINE UNKNOWN_COMPILER_VERSION} + + {$IFDEF VER80} + {$DEFINE COMPILER1} + {$DEFINE DELPHI1} + {$DEFINE DELPHICOMPILER1} + {$DEFINE RTL80_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER90} + {$DEFINE COMPILER2} + {$DEFINE DELPHI2} + {$DEFINE DELPHICOMPILER2} + {$DEFINE RTL90_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER93} + {$DEFINE COMPILER2} + {$DEFINE BCB1} + {$DEFINE BCB} + {$DEFINE RTL93_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER100} + {$DEFINE COMPILER3} + {$DEFINE DELPHI3} + {$DEFINE DELPHICOMPILER3} + {$DEFINE RTL100_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER110} + {$DEFINE COMPILER35} + {$DEFINE BCB3} + {$DEFINE BCB} + {$DEFINE RTL110_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER120} + {$DEFINE COMPILER4} + {$DEFINE DELPHI4} + {$DEFINE DELPHICOMPILER4} + {$DEFINE RTL120_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER125} + {$DEFINE COMPILER4} + {$DEFINE BCB4} + {$DEFINE BCB} + {$DEFINE RTL125_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER130} + {$DEFINE COMPILER5} + {$IFDEF BCB} + {$DEFINE BCB5} + {$ELSE} + {$DEFINE DELPHI5} + {$DEFINE DELPHICOMPILER5} + {$ENDIF} + {$DEFINE RTL130_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER140} + {$DEFINE COMPILER6} + {$IFDEF BCB} + {$DEFINE BCB6} + {$ELSE} + {$DEFINE DELPHI6} + {$DEFINE DELPHICOMPILER6} + {$ENDIF} + {$DEFINE RTL140_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER150} + {$DEFINE COMPILER7} + {$DEFINE DELPHI7} + {$DEFINE DELPHICOMPILER7} + {$DEFINE RTL150_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER160} + {$DEFINE BDS2} + {$DEFINE BDS} + {$IFDEF CLR} + {$DEFINE CLR10} + {$ENDIF CLR} + {$DEFINE COMPILER8} + {$DEFINE DELPHI8} + {$DEFINE DELPHICOMPILER8} + {$DEFINE RTL160_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER170} + {$DEFINE BDS3} + {$DEFINE BDS} + {$IFDEF CLR} + {$DEFINE CLR11} + {$ENDIF CLR} + {$DEFINE COMPILER9} + {$DEFINE DELPHI9} + {$DEFINE DELPHI2005} // synonym to DELPHI9 + {$DEFINE DELPHICOMPILER9} + {$DEFINE RTL170_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER180} + {$DEFINE BDS} + {$IFDEF CLR} + {$DEFINE CLR11} + {$ENDIF CLR} + {$IFDEF VER185} + {$DEFINE BDS5} + {$DEFINE COMPILER11} + {$IFDEF BCB} + {$DEFINE BCB11} + {$ELSE} + {$DEFINE DELPHI11} + {$DEFINE DELPHI2007} // synonym to DELPHI11 + {$DEFINE DELPHICOMPILER11} + {$ENDIF} + {$DEFINE RTL185_UP} + {$ELSE ~~VER185} + {$DEFINE BDS4} + {$DEFINE COMPILER10} + {$IFDEF BCB} + {$DEFINE BCB10} + {$ELSE} + {$DEFINE DELPHI10} + {$DEFINE DELPHI2006} // synonym to DELPHI10 + {$DEFINE DELPHICOMPILER10} + {$ENDIF} + {$DEFINE RTL180_UP} + {$ENDIF ~VER185} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER190} // Delphi 2007 for .NET + {$DEFINE BDS} + {$DEFINE BDS5} + {$IFDEF CLR} + {$DEFINE CLR20} + {$ENDIF CLR} + {$DEFINE COMPILER11} + {$DEFINE DELPHI11} + {$DEFINE DELPHI2007} // synonym to DELPHI11 + {$DEFINE DELPHICOMPILER11} + {$DEFINE RTL190_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER190} + + {$IFDEF VER200} // RAD Studio 2009 + {$DEFINE BDS} + {$DEFINE BDS6} + {$IFDEF CLR} + {$DEFINE CLR20} + {$ENDIF CLR} + {$DEFINE COMPILER12} + {$IFDEF BCB} + {$DEFINE BCB12} + {$ELSE} + {$DEFINE DELPHI12} + {$DEFINE DELPHI2009} // synonym to DELPHI12 + {$DEFINE DELPHICOMPILER12} + {$ENDIF BCB} + {$IFDEF CLR} + {$DEFINE RTL190_UP} + {$ELSE} + {$DEFINE RTL200_UP} + {$ENDIF} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER200} + + {$IFDEF VER210} // RAD Studio 2010 + {$DEFINE BDS} + {$DEFINE BDS7} + {$DEFINE COMPILER14} + {$IFDEF BCB} + {$DEFINE BCB14} + {$ELSE} + {$DEFINE DELPHI14} + {$DEFINE DELPHI2010} // synonym to DELPHI14 + {$DEFINE DELPHICOMPILER14} + {$ENDIF BCB} + {$DEFINE RTL210_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER210} + + {$IFDEF VER220} // RAD Studio XE + {$DEFINE BDS} + {$DEFINE BDS8} + {$DEFINE COMPILER15} + {$IFDEF BCB} + {$DEFINE BCB15} + {$ELSE} + {$DEFINE DELPHI15} + {$DEFINE DELPHIXE} // synonym to DELPHI15 + {$DEFINE DELPHICOMPILER15} + {$ENDIF BCB} + {$DEFINE RTL220_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER220} + + {$IFDEF VER230} // RAD Studio XE2 + {$DEFINE BDS} + {$DEFINE BDS9} + {$DEFINE COMPILER16} + {$IFDEF BCB} + {$DEFINE BCB16} + {$ELSE} + {$DEFINE DELPHI16} + {$DEFINE DELPHIXE2} // synonym to DELPHI16 + {$DEFINE DELPHICOMPILER16} + {$ENDIF BCB} + {$DEFINE RTL230_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER230} + + {$IFDEF VER240} // RAD Studio XE3 + {$DEFINE BDS} + {$DEFINE BDS10} + {$DEFINE COMPILER17} + {$IFDEF BCB} + {$DEFINE BCB17} + {$ELSE} + {$DEFINE DELPHI17} + {$DEFINE DELPHIXE3} // synonym to DELPHI17 + {$DEFINE DELPHICOMPILER17} + {$ENDIF BCB} + {$DEFINE RTL240_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER240} + + {$IFDEF UNKNOWN_COMPILER_VERSION} // adjust for newer version (always use latest version) + {$DEFINE BDS} + {$DEFINE BDS10} + {$DEFINE COMPILER17} + {$IFDEF BCB} + {$DEFINE BCB17} + {$ELSE} + {$DEFINE DELPHI17} + {$DEFINE DELPHIXE3} // synonym to DELPHI17 + {$DEFINE DELPHICOMPILER17} + {$ENDIF BCB} + {$DEFINE RTL240_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$ENDIF ~KYLIX} + + {$IFDEF BCB} + {$DEFINE CPPBUILDER} + {$DEFINE BCBCOMPILER} + {$ELSE ~BCB} + {$DEFINE DELPHI} + {$DEFINE DELPHICOMPILER} + {$ENDIF ~BCB} + +{$ENDIF BORLAND} + +{------------------------------------------------------------------------------} +{ DELPHIX_UP from DELPHIX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHI17} {$DEFINE DELPHI17_UP} {$ENDIF} +{$IFDEF DELPHI16} {$DEFINE DELPHI16_UP} {$ENDIF} +{$IFDEF DELPHI15} {$DEFINE DELPHI15_UP} {$ENDIF} +{$IFDEF DELPHI14} {$DEFINE DELPHI14_UP} {$ENDIF} +{$IFDEF DELPHI12} {$DEFINE DELPHI12_UP} {$ENDIF} +{$IFDEF DELPHI11} {$DEFINE DELPHI11_UP} {$ENDIF} +{$IFDEF DELPHI10} {$DEFINE DELPHI10_UP} {$ENDIF} +{$IFDEF DELPHI9} {$DEFINE DELPHI9_UP} {$ENDIF} +{$IFDEF DELPHI8} {$DEFINE DELPHI8_UP} {$ENDIF} +{$IFDEF DELPHI7} {$DEFINE DELPHI7_UP} {$ENDIF} +{$IFDEF DELPHI6} {$DEFINE DELPHI6_UP} {$ENDIF} +{$IFDEF DELPHI5} {$DEFINE DELPHI5_UP} {$ENDIF} +{$IFDEF DELPHI4} {$DEFINE DELPHI4_UP} {$ENDIF} +{$IFDEF DELPHI3} {$DEFINE DELPHI3_UP} {$ENDIF} +{$IFDEF DELPHI2} {$DEFINE DELPHI2_UP} {$ENDIF} +{$IFDEF DELPHI1} {$DEFINE DELPHI1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ DELPHIX_UP from DELPHIX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHI17_UP} + {$DEFINE DELPHIXE3_UP} // synonym to DELPHI17_UP + {$DEFINE DELPHI16_UP} +{$ENDIF} + +{$IFDEF DELPHI16_UP} + {$DEFINE DELPHIXE2_UP} // synonym to DELPHI16_UP + {$DEFINE DELPHI15_UP} +{$ENDIF} + +{$IFDEF DELPHI15_UP} + {$DEFINE DELPHIXE_UP} // synonym to DELPHI15_UP + {$DEFINE DELPHI14_UP} +{$ENDIF} + +{$IFDEF DELPHI14_UP} + {$DEFINE DELPHI2010_UP} // synonym to DELPHI14_UP + {$DEFINE DELPHI12_UP} +{$ENDIF} + +{$IFDEF DELPHI12_UP} + {$DEFINE DELPHI2009_UP} // synonym to DELPHI12_UP + {$DEFINE DELPHI11_UP} +{$ENDIF} + +{$IFDEF DELPHI11_UP} + {$DEFINE DELPHI2007_UP} // synonym to DELPHI11_UP + {$DEFINE DELPHI10_UP} +{$ENDIF} + +{$IFDEF DELPHI10_UP} + {$DEFINE DELPHI2006_UP} // synonym to DELPHI10_UP + {$DEFINE DELPHI9_UP} +{$ENDIF} + +{$IFDEF DELPHI9_UP} + {$DEFINE DELPHI2005_UP} // synonym to DELPHI9_UP + {$DEFINE DELPHI8_UP} +{$ENDIF} + +{$IFDEF DELPHI8_UP} {$DEFINE DELPHI7_UP} {$ENDIF} +{$IFDEF DELPHI7_UP} {$DEFINE DELPHI6_UP} {$ENDIF} +{$IFDEF DELPHI6_UP} {$DEFINE DELPHI5_UP} {$ENDIF} +{$IFDEF DELPHI5_UP} {$DEFINE DELPHI4_UP} {$ENDIF} +{$IFDEF DELPHI4_UP} {$DEFINE DELPHI3_UP} {$ENDIF} +{$IFDEF DELPHI3_UP} {$DEFINE DELPHI2_UP} {$ENDIF} +{$IFDEF DELPHI2_UP} {$DEFINE DELPHI1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BCBX_UP from BCBX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BCB17} {$DEFINE BCB17_UP} {$ENDIF} +{$IFDEF BCB16} {$DEFINE BCB16_UP} {$ENDIF} +{$IFDEF BCB15} {$DEFINE BCB15_UP} {$ENDIF} +{$IFDEF BCB14} {$DEFINE BCB14_UP} {$ENDIF} +{$IFDEF BCB12} {$DEFINE BCB12_UP} {$ENDIF} +{$IFDEF BCB11} {$DEFINE BCB11_UP} {$ENDIF} +{$IFDEF BCB10} {$DEFINE BCB10_UP} {$ENDIF} +{$IFDEF BCB6} {$DEFINE BCB6_UP} {$ENDIF} +{$IFDEF BCB5} {$DEFINE BCB5_UP} {$ENDIF} +{$IFDEF BCB4} {$DEFINE BCB4_UP} {$ENDIF} +{$IFDEF BCB3} {$DEFINE BCB3_UP} {$ENDIF} +{$IFDEF BCB1} {$DEFINE BCB1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BCBX_UP from BCBX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BCB17_UP} {$DEFINE BCB16_UP} {$ENDIF} +{$IFDEF BCB16_UP} {$DEFINE BCB15_UP} {$ENDIF} +{$IFDEF BCB15_UP} {$DEFINE BCB14_UP} {$ENDIF} +{$IFDEF BCB14_UP} {$DEFINE BCB12_UP} {$ENDIF} +{$IFDEF BCB12_UP} {$DEFINE BCB11_UP} {$ENDIF} +{$IFDEF BCB11_UP} {$DEFINE BCB10_UP} {$ENDIF} +{$IFDEF BCB10_UP} {$DEFINE BCB6_UP} {$ENDIF} +{$IFDEF BCB6_UP} {$DEFINE BCB5_UP} {$ENDIF} +{$IFDEF BCB5_UP} {$DEFINE BCB4_UP} {$ENDIF} +{$IFDEF BCB4_UP} {$DEFINE BCB3_UP} {$ENDIF} +{$IFDEF BCB3_UP} {$DEFINE BCB1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BDSX_UP from BDSX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BDS10} {$DEFINE BDS10_UP} {$ENDIF} +{$IFDEF BDS9} {$DEFINE BDS9_UP} {$ENDIF} +{$IFDEF BDS8} {$DEFINE BDS8_UP} {$ENDIF} +{$IFDEF BDS7} {$DEFINE BDS7_UP} {$ENDIF} +{$IFDEF BDS6} {$DEFINE BDS6_UP} {$ENDIF} +{$IFDEF BDS5} {$DEFINE BDS5_UP} {$ENDIF} +{$IFDEF BDS4} {$DEFINE BDS4_UP} {$ENDIF} +{$IFDEF BDS3} {$DEFINE BDS3_UP} {$ENDIF} +{$IFDEF BDS2} {$DEFINE BDS2_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BDSX_UP from BDSX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BDS10_UP} {$DEFINE BDS9_UP} {$ENDIF} +{$IFDEF BDS9_UP} {$DEFINE BDS8_UP} {$ENDIF} +{$IFDEF BDS8_UP} {$DEFINE BDS7_UP} {$ENDIF} +{$IFDEF BDS7_UP} {$DEFINE BDS6_UP} {$ENDIF} +{$IFDEF BDS6_UP} {$DEFINE BDS5_UP} {$ENDIF} +{$IFDEF BDS5_UP} {$DEFINE BDS4_UP} {$ENDIF} +{$IFDEF BDS4_UP} {$DEFINE BDS3_UP} {$ENDIF} +{$IFDEF BDS3_UP} {$DEFINE BDS2_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ DELPHICOMPILERX_UP from DELPHICOMPILERX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHICOMPILER17} {$DEFINE DELPHICOMPILER17_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER16} {$DEFINE DELPHICOMPILER16_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER15} {$DEFINE DELPHICOMPILER15_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER14} {$DEFINE DELPHICOMPILER14_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER12} {$DEFINE DELPHICOMPILER12_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER11} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER10} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER9} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER8} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER7} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER6} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER5} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER4} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER3} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER2} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER1} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ DELPHICOMPILERX_UP from DELPHICOMPILERX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHICOMPILER17_UP} {$DEFINE DELPHICOMPILER16_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER16_UP} {$DEFINE DELPHICOMPILER15_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER15_UP} {$DEFINE DELPHICOMPILER14_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER14_UP} {$DEFINE DELPHICOMPILER12_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER12_UP} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER11_UP} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER10_UP} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER9_UP} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER7_UP} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER6_UP} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER5_UP} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER4_UP} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER3_UP} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER2_UP} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ COMPILERX_UP from COMPILERX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF COMPILER17} {$DEFINE COMPILER17_UP} {$ENDIF} +{$IFDEF COMPILER16} {$DEFINE COMPILER16_UP} {$ENDIF} +{$IFDEF COMPILER15} {$DEFINE COMPILER15_UP} {$ENDIF} +{$IFDEF COMPILER14} {$DEFINE COMPILER14_UP} {$ENDIF} +{$IFDEF COMPILER12} {$DEFINE COMPILER12_UP} {$ENDIF} +{$IFDEF COMPILER11} {$DEFINE COMPILER11_UP} {$ENDIF} +{$IFDEF COMPILER10} {$DEFINE COMPILER10_UP} {$ENDIF} +{$IFDEF COMPILER9} {$DEFINE COMPILER9_UP} {$ENDIF} +{$IFDEF COMPILER8} {$DEFINE COMPILER8_UP} {$ENDIF} +{$IFDEF COMPILER7} {$DEFINE COMPILER7_UP} {$ENDIF} +{$IFDEF COMPILER6} {$DEFINE COMPILER6_UP} {$ENDIF} +{$IFDEF COMPILER5} {$DEFINE COMPILER5_UP} {$ENDIF} +{$IFDEF COMPILER4} {$DEFINE COMPILER4_UP} {$ENDIF} +{$IFDEF COMPILER35} {$DEFINE COMPILER35_UP} {$ENDIF} +{$IFDEF COMPILER3} {$DEFINE COMPILER3_UP} {$ENDIF} +{$IFDEF COMPILER2} {$DEFINE COMPILER2_UP} {$ENDIF} +{$IFDEF COMPILER1} {$DEFINE COMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ COMPILERX_UP from COMPILERX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF COMPILER17_UP} {$DEFINE COMPILER16_UP} {$ENDIF} +{$IFDEF COMPILER16_UP} {$DEFINE COMPILER15_UP} {$ENDIF} +{$IFDEF COMPILER15_UP} {$DEFINE COMPILER14_UP} {$ENDIF} +{$IFDEF COMPILER14_UP} {$DEFINE COMPILER12_UP} {$ENDIF} +{$IFDEF COMPILER12_UP} {$DEFINE COMPILER11_UP} {$ENDIF} +{$IFDEF COMPILER11_UP} {$DEFINE COMPILER10_UP} {$ENDIF} +{$IFDEF COMPILER10_UP} {$DEFINE COMPILER9_UP} {$ENDIF} +{$IFDEF COMPILER9_UP} {$DEFINE COMPILER8_UP} {$ENDIF} +{$IFDEF COMPILER8_UP} {$DEFINE COMPILER7_UP} {$ENDIF} +{$IFDEF COMPILER7_UP} {$DEFINE COMPILER6_UP} {$ENDIF} +{$IFDEF COMPILER6_UP} {$DEFINE COMPILER5_UP} {$ENDIF} +{$IFDEF COMPILER5_UP} {$DEFINE COMPILER4_UP} {$ENDIF} +{$IFDEF COMPILER4_UP} {$DEFINE COMPILER35_UP} {$ENDIF} +{$IFDEF COMPILER35_UP} {$DEFINE COMPILER3_UP} {$ENDIF} +{$IFDEF COMPILER3_UP} {$DEFINE COMPILER2_UP} {$ENDIF} +{$IFDEF COMPILER2_UP} {$DEFINE COMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ RTLX_UP from RTLX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF RTL240_UP} {$DEFINE RTL230_UP} {$ENDIF} +{$IFDEF RTL230_UP} {$DEFINE RTL220_UP} {$ENDIF} +{$IFDEF RTL220_UP} {$DEFINE RTL210_UP} {$ENDIF} +{$IFDEF RTL210_UP} {$DEFINE RTL200_UP} {$ENDIF} +{$IFDEF RTL200_UP} {$DEFINE RTL190_UP} {$ENDIF} +{$IFDEF RTL190_UP} {$DEFINE RTL185_UP} {$ENDIF} +{$IFDEF RTL185_UP} {$DEFINE RTL180_UP} {$ENDIF} +{$IFDEF RTL180_UP} {$DEFINE RTL170_UP} {$ENDIF} +{$IFDEF RTL170_UP} {$DEFINE RTL160_UP} {$ENDIF} +{$IFDEF RTL160_UP} {$DEFINE RTL150_UP} {$ENDIF} +{$IFDEF RTL150_UP} {$DEFINE RTL145_UP} {$ENDIF} +{$IFDEF RTL145_UP} {$DEFINE RTL142_UP} {$ENDIF} +{$IFDEF RTL142_UP} {$DEFINE RTL140_UP} {$ENDIF} +{$IFDEF RTL140_UP} {$DEFINE RTL130_UP} {$ENDIF} +{$IFDEF RTL130_UP} {$DEFINE RTL125_UP} {$ENDIF} +{$IFDEF RTL125_UP} {$DEFINE RTL120_UP} {$ENDIF} +{$IFDEF RTL120_UP} {$DEFINE RTL110_UP} {$ENDIF} +{$IFDEF RTL110_UP} {$DEFINE RTL100_UP} {$ENDIF} +{$IFDEF RTL100_UP} {$DEFINE RTL93_UP} {$ENDIF} +{$IFDEF RTL93_UP} {$DEFINE RTL90_UP} {$ENDIF} +{$IFDEF RTL90_UP} {$DEFINE RTL80_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ Check for CLR overrides of default detection } +{------------------------------------------------------------------------------} + +{$IFDEF CLR} + {$IFDEF FORCE_CLR10} + {$DEFINE CLR10} + {$UNDEF CLR11} + {$UNDEF CLR20} + {$ENDIF FORCE_CLR10} + + {$IFDEF FORCE_CLR11} + {$UNDEF CLR10} + {$DEFINE CLR11} + {$UNDEF CLR20} + {$ENDIF FORCE_CLR11} + + {$IFDEF FORCE_CLR20} + {$UNDEF CLR10} + {$UNDEF CLR11} + {$DEFINE CLR20} + {$ENDIF FORCE_CLR20} +{$ENDIF CLR} + +{------------------------------------------------------------------------------} +{ CLRX from CLRX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF CLR10} {$DEFINE CLR10_UP} {$ENDIF} +{$IFDEF CLR11} {$DEFINE CLR11_UP} {$ENDIF} +{$IFDEF CLR20} {$DEFINE CLR20_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ CLRX_UP from CLRX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF CLR20_UP} {$DEFINE CLR11_UP} {$ENDIF} +{$IFDEF CLR11_UP} {$DEFINE CLR10_UP} {$ENDIF} + +{------------------------------------------------------------------------------} + +{$IFDEF DELPHICOMPILER} + {$DEFINE DELPHILANGUAGE} +{$ENDIF} + +{$IFDEF BCBCOMPILER} + {$DEFINE DELPHILANGUAGE} +{$ENDIF} + +{------------------------------------------------------------------------------} +{ KYLIXX_UP from KYLIXX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF KYLIX3} {$DEFINE KYLIX3_UP} {$ENDIF} +{$IFDEF KYLIX2} {$DEFINE KYLIX2_UP} {$ENDIF} +{$IFDEF KYLIX1} {$DEFINE KYLIX1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ KYLIXX_UP from KYLIXX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF KYLIX3_UP} {$DEFINE KYLIX2_UP} {$ENDIF} +{$IFDEF KYLIX2_UP} {$DEFINE KYLIX1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ Map COMPILERX_UP to friendly feature names } +{------------------------------------------------------------------------------} + +{$IFDEF FPC} + {$IFDEF VER1_0} + Please use FPC 2.0 or higher to compile this. + {$ELSE} + {$DEFINE SUPPORTS_OUTPARAMS} + {$DEFINE SUPPORTS_WIDECHAR} + {$DEFINE SUPPORTS_WIDESTRING} + {$IFDEF HASINTF} + {$DEFINE SUPPORTS_INTERFACE} + {$ENDIF} + {$IFDEF HASVARIANT} + {$DEFINE SUPPORTS_VARIANT} + {$ENDIF} + {$IFDEF FPC_HAS_TYPE_SINGLE} + {$DEFINE SUPPORTS_SINGLE} + {$ENDIF} + {$IFDEF FPC_HAS_TYPE_DOUBLE} + {$DEFINE SUPPORTS_DOUBLE} + {$ENDIF} + {$IFDEF FPC_HAS_TYPE_EXTENDED} + {$DEFINE SUPPORTS_EXTENDED} + {$ENDIF} + {$IFDEF HASCURRENCY} + {$DEFINE SUPPORTS_CURRENCY} + {$ENDIF} + {$DEFINE SUPPORTS_THREADVAR} + {$DEFINE SUPPORTS_CONSTPARAMS} + {$DEFINE SUPPORTS_LONGWORD} + {$DEFINE SUPPORTS_INT64} + {$DEFINE SUPPORTS_DYNAMICARRAYS} + {$DEFINE SUPPORTS_DEFAULTPARAMS} + {$DEFINE SUPPORTS_OVERLOAD} + {$DEFINE ACCEPT_DEPRECATED} // 2.2 also gives warnings + {$DEFINE ACCEPT_PLATFORM} // 2.2 also gives warnings + {$DEFINE ACCEPT_LIBRARY} + {$DEFINE SUPPORTS_EXTSYM} + {$DEFINE SUPPORTS_NODEFINE} + + {$DEFINE SUPPORTS_CUSTOMVARIANTS} + {$DEFINE SUPPORTS_VARARGS} + {$DEFINE SUPPORTS_ENUMVALUE} + {$IFDEF LINUX} + {$DEFINE HAS_UNIT_LIBC} + {$ENDIF LINUX} + {$DEFINE HAS_UNIT_CONTNRS} + {$DEFINE HAS_UNIT_TYPES} + {$DEFINE HAS_UNIT_VARIANTS} + {$DEFINE HAS_UNIT_STRUTILS} + {$DEFINE HAS_UNIT_DATEUTILS} + {$DEFINE HAS_UNIT_RTLCONSTS} + + {$DEFINE XPLATFORM_RTL} + + {$IFDEF VER2_2} + {$DEFINE SUPPORTS_DISPINTERFACE} + {$DEFINE SUPPORTS_IMPLEMENTS} + {$DEFINE SUPPORTS_DISPID} + {$ELSE} + {$UNDEF SUPPORTS_DISPINTERFACE} + {$UNDEF SUPPORTS_IMPLEMENTS} + {$endif} + {$UNDEF SUPPORTS_UNSAFE_WARNINGS} + {$ENDIF} +{$ENDIF FPC} + +{$IFDEF CLR} + {$DEFINE SUPPORTS_UNICODE} +{$ENDIF CLR} + +{$IFDEF COMPILER1_UP} + {$DEFINE SUPPORTS_CONSTPARAMS} + {$DEFINE SUPPORTS_SINGLE} + {$DEFINE SUPPORTS_DOUBLE} + {$DEFINE SUPPORTS_EXTENDED} + {$DEFINE SUPPORTS_PACKAGES} +{$ENDIF COMPILER1_UP} + +{$IFDEF COMPILER2_UP} + {$DEFINE SUPPORTS_CURRENCY} + {$DEFINE SUPPORTS_THREADVAR} + {$DEFINE SUPPORTS_VARIANT} + {$DEFINE SUPPORTS_WIDECHAR} +{$ENDIF COMPILER2_UP} + +{$IFDEF COMPILER3_UP} + {$DEFINE SUPPORTS_OUTPARAMS} + {$DEFINE SUPPORTS_WIDESTRING} + {$DEFINE SUPPORTS_INTERFACE} + {$DEFINE SUPPORTS_DISPINTERFACE} + {$DEFINE SUPPORTS_DISPID} + {$DEFINE SUPPORTS_WEAKPACKAGEUNIT} +{$ENDIF COMPILER3_UP} + +{$IFDEF COMPILER35_UP} + {$DEFINE SUPPORTS_EXTSYM} + {$DEFINE SUPPORTS_NODEFINE} +{$ENDIF COMPILER35_UP} + +{$IFDEF COMPILER4_UP} + {$DEFINE SUPPORTS_LONGWORD} + {$DEFINE SUPPORTS_INT64} + {$DEFINE SUPPORTS_DYNAMICARRAYS} + {$DEFINE SUPPORTS_DEFAULTPARAMS} + {$DEFINE SUPPORTS_OVERLOAD} + {$DEFINE SUPPORTS_IMPLEMENTS} +{$ENDIF COMPILER4_UP} + +{$IFDEF COMPILER6_UP} + {$DEFINE SUPPORTS_DEPRECATED} + {$DEFINE SUPPORTS_LIBRARY} + {$DEFINE SUPPORTS_PLATFORM} + {$DEFINE SUPPORTS_LOCAL} + {$DEFINE SUPPORTS_SETPEFLAGS} + {$DEFINE SUPPORTS_EXPERIMENTAL_WARNINGS} + {$DEFINE ACCEPT_DEPRECATED} + {$DEFINE ACCEPT_PLATFORM} + {$DEFINE ACCEPT_LIBRARY} + {$DEFINE SUPPORTS_DEPRECATED_WARNINGS} + {$DEFINE SUPPORTS_LIBRARY_WARNINGS} + {$DEFINE SUPPORTS_PLATFORM_WARNINGS} + {$DEFINE SUPPORTS_CUSTOMVARIANTS} + {$DEFINE SUPPORTS_VARARGS} + {$DEFINE SUPPORTS_ENUMVALUE} + {$DEFINE SUPPORTS_COMPILETIME_MESSAGES} +{$ENDIF COMPILER6_UP} + +{$IFDEF COMPILER7_UP} + {$DEFINE SUPPORTS_UNSAFE_WARNINGS} +{$ENDIF COMPILER7_UP} + +{$IFDEF COMPILER9_UP} + {$DEFINE SUPPORTS_FOR_IN} + {$DEFINE SUPPORTS_INLINE} + {$DEFINE SUPPORTS_NESTED_CONSTANTS} + {$DEFINE SUPPORTS_NESTED_TYPES} + {$DEFINE SUPPORTS_REGION} + {$IFDEF CLR} + {$DEFINE SUPPORTS_ENHANCED_RECORDS} + {$DEFINE SUPPORTS_CLASS_FIELDS} + {$DEFINE SUPPORTS_CLASS_HELPERS} + {$DEFINE SUPPORTS_CLASS_OPERATORS} + {$DEFINE SUPPORTS_STRICT} + {$DEFINE SUPPORTS_STATIC} + {$DEFINE SUPPORTS_FINAL} + {$ENDIF CLR} +{$ENDIF COMPILER9_UP} + +{$IFDEF COMPILER10_UP} + {$DEFINE SUPPORTS_ENHANCED_RECORDS} + {$DEFINE SUPPORTS_CLASS_FIELDS} + {$DEFINE SUPPORTS_CLASS_HELPERS} + {$DEFINE SUPPORTS_CLASS_OPERATORS} + {$DEFINE SUPPORTS_STRICT} + {$DEFINE SUPPORTS_STATIC} + {$DEFINE SUPPORTS_FINAL} + {$DEFINE SUPPORTS_METHODINFO} +{$ENDIF COMPILER10_UP} + +{$IFDEF COMPILER11_UP} + {$IFDEF CLR} + {$DEFINE SUPPORTS_GENERICS} + {$DEFINE SUPPORTS_DEPRECATED_DETAILS} + {$ENDIF CLR} +{$ENDIF COMPILER11_UP} + +{$IFDEF COMPILER12_UP} + {$DEFINE SUPPORTS_GENERICS} + {$DEFINE SUPPORTS_DEPRECATED_DETAILS} + {$DEFINE SUPPORTS_INT_ALIASES} + {$IFNDEF CLR} + {$DEFINE SUPPORTS_UNICODE} + {$DEFINE SUPPORTS_UNICODE_STRING} + {$ENDIF CLR} +{$ENDIF COMPILER12_UP} + +{$IFDEF COMPILER14_UP} + {$DEFINE SUPPORTS_CLASS_CTORDTORS} + {$DEFINE HAS_UNIT_RTTI} + {$DEFINE SUPPORTS_CAST_INTERFACE_TO_OBJ} + {$DEFINE SUPPORTS_DELAYED_LOADING} +{$ENDIF COMPILER14_UP} + +{$IFDEF COMPILER16_UP} + {$DEFINE USE_64BIT_TYPES} +{$ENDIF COMPILER16_UP} + +{$IFDEF RTL130_UP} + {$DEFINE HAS_UNIT_CONTNRS} +{$ENDIF RTL130_UP} + +{$IFDEF RTL140_UP} + {$IFDEF LINUX} + {$DEFINE HAS_UNIT_LIBC} + {$ENDIF LINUX} + {$DEFINE HAS_UNIT_RTLCONSTS} + {$DEFINE HAS_UNIT_TYPES} + {$DEFINE HAS_UNIT_VARIANTS} + {$DEFINE HAS_UNIT_STRUTILS} + {$DEFINE HAS_UNIT_DATEUTILS} + {$DEFINE XPLATFORM_RTL} +{$ENDIF RTL140_UP} + +{$IFDEF RTL170_UP} + {$DEFINE HAS_UNIT_HTTPPROD} +{$ENDIF RTL170_UP} + +{$IFDEF RTL185_UP} + {$DEFINE HAS_UNIT_GIFIMG} +{$ENDIF RTL185_UP} + +{$IFDEF RTL200_UP} + {$DEFINE HAS_UNIT_ANSISTRINGS} + {$DEFINE HAS_UNIT_PNGIMAGE} + {$DEFINE HAS_UNIT_CHARACTER} +{$ENDIF RTL200_UP} + +{$IFDEF RTL220_UP} + {$DEFINE SUPPORTS_UINT64} + {$DEFINE HAS_UNIT_REGULAREXPRESSIONSAPI} +{$ENDIF RTL220_UP} + +{$IFDEF RTL230_UP} + {$DEFINE HAS_UNITSCOPE} + {$DEFINE HAS_UNIT_SYSTEM_UITYPES} +{$ENDIF RTL230_UP} + +{$IFDEF RTL240_UP} + {$DEFINE HAS_UNIT_SYSTEM_ACTIONS} +{$ENDIF RTL240_UP} + +{------------------------------------------------------------------------------} +{ Cross-platform related defines } +{------------------------------------------------------------------------------} + +{$IFNDEF CPUASM} + {$DEFINE PUREPASCAL} +{$ENDIF ~CPUASM} + +{$IFDEF WIN32} + {$DEFINE MSWINDOWS} // predefined for D6+/BCB6+ + {$DEFINE Win32API} +{$ENDIF} + +{$IFDEF DELPHILANGUAGE} + {$IFDEF LINUX} + {$DEFINE UNIX} + {$ENDIF} + + {$IFNDEF CONSOLE} + {$IFDEF LINUX} + {$DEFINE VisualCLX} + {$ENDIF} + {$IFNDEF VisualCLX} + {$DEFINE VCL} + {$ENDIF} + {$ENDIF ~CONSOLE} +{$ENDIF DELPHILANGUAGE} + +{------------------------------------------------------------------------------} +{ Compiler settings } +{------------------------------------------------------------------------------} + +{$IFOPT A+} {$DEFINE ALIGN_ON} {$ENDIF} +{$IFOPT B+} {$DEFINE BOOLEVAL_ON} {$ENDIF} +{$IFDEF COMPILER2_UP} + {$IFOPT C+} {$DEFINE ASSERTIONS_ON} {$ENDIF} +{$ENDIF} +{$IFOPT D+} {$DEFINE DEBUGINFO_ON} {$ENDIF} +{$IFOPT G+} {$DEFINE IMPORTEDDATA_ON} {$ENDIF} +{$IFDEF COMPILER2_UP} + {$IFOPT H+} {$DEFINE LONGSTRINGS_ON} {$ENDIF} +{$ENDIF} + +// Hints +{$IFOPT I+} {$DEFINE IOCHECKS_ON} {$ENDIF} +{$IFDEF COMPILER2_UP} + {$IFOPT J+} {$DEFINE WRITEABLECONST_ON} {$ENDIF} +{$ENDIF} +{$IFOPT L+} {$DEFINE LOCALSYMBOLS} {$DEFINE LOCALSYMBOLS_ON} {$ENDIF} +{$IFOPT M+} {$DEFINE TYPEINFO_ON} {$ENDIF} +{$IFOPT O+} {$DEFINE OPTIMIZATION_ON} {$ENDIF} +{$IFOPT P+} {$DEFINE OPENSTRINGS_ON} {$ENDIF} +{$IFOPT Q+} {$DEFINE OVERFLOWCHECKS_ON} {$ENDIF} +{$IFOPT R+} {$DEFINE RANGECHECKS_ON} {$ENDIF} + +// Real compatibility +{$IFOPT T+} {$DEFINE TYPEDADDRESS_ON} {$ENDIF} +{$IFOPT U+} {$DEFINE SAFEDIVIDE_ON} {$ENDIF} +{$IFOPT V+} {$DEFINE VARSTRINGCHECKS_ON} {$ENDIF} +{$IFOPT W+} {$DEFINE STACKFRAMES_ON} {$ENDIF} + +// Warnings +{$IFOPT X+} {$DEFINE EXTENDEDSYNTAX_ON} {$ENDIF} + +// for Delphi/BCB trial versions remove the point from the line below +{.$UNDEF SUPPORTS_WEAKPACKAGEUNIT} + +{$ENDIF ~JEDI_INC} diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/readme-dev.txt b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/readme-dev.txt new file mode 100644 index 0000000000..4ee09c3d24 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/readme-dev.txt @@ -0,0 +1,38 @@ +HistoryToDBUpdater +------------------ + +Утилита установки/обновления компонентов плагинов RnQHistoryToDB, QIPHistoryToDB, MirandaIMHistoryToDB, MirandaNGHistoryToDB. + +Автор: Михаил Григорьев +E-Mail: sleuthhound@gmail.com +ICQ: 161867489 +WWW: http://www.im-history.ru +Лицензия: GNU GPLv3 + +Системные требования: +--------------------- +ОС: Win2000/XP/2003/Vista/7 +IM-клиент: Любой +БД: MySQL 4.0, 4.1, 5.0, 5.1 + PostgreSQL 7.1 - 8.3 + Oracle 8i - 11i + SQLite 3 + Firebird 2.x + +Необходимые компоненты для сборки плагина: +------------------------------------------ + +1. Embarcadero RAD Studio XE3 + +2. IM-History Downloader Component + See also directory IMDownloaderComponent + +3. DCPcrypt Cryptographic Component Library v2 + http://www.cityinthesky.co.uk/ + +Описание параметров запуска: +---------------------------- + +HistoryToDBUpdater.exe <1> + +<1> - (Необязательный параметр) - Путь до файла настроек HistoryToDB.ini (Например: "C:\Program Files\QIP Infium\Profiles\username@qip.ru\Plugins\QIPHistoryToDB\") diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dpr b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dpr new file mode 100644 index 0000000000..8942f8b61d --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dpr @@ -0,0 +1,15 @@ +program DownLoaderTest; + +uses + Forms, + DownLoaderTestUnit in 'DownLoaderTestUnit.pas' {MainForm}; + +{$R *.res} + +begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.Title := 'IM Downloader Demo'; + Application.CreateForm(TMainForm, MainForm); + Application.Run; +end. diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dproj b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dproj new file mode 100644 index 0000000000..c0b14483c0 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dproj @@ -0,0 +1,109 @@ + + + {8B841E47-C817-4F26-8ACF-89048F0E7C42} + DownLoaderTest.dpr + True + Release + Win32 + Application + VCL + DCC32 + 12.3 + + + true + + + true + Base + true + + + true + Base + true + + + 00400000 + false + false + false + false + false + WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) + + + 0 + RELEASE;$(DCC_Define) + false + false + + + DEBUG;$(DCC_Define) + true + false + + + + MainSource + + +
MainForm
+
+ + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + +
+ + + + Delphi.Personality.12 + VCLApplication + + + + DownLoaderTest.dpr + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1049 + 1251 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + True + + + 12 + +
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.res b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.res new file mode 100644 index 0000000000..fc1937e1c7 Binary files /dev/null and b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.res differ diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.dfm b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.dfm new file mode 100644 index 0000000000..b245bf8704 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.dfm @@ -0,0 +1,125 @@ +object MainForm: TMainForm + Left = 0 + Top = 0 + Caption = 'TIMDownloadThread Test' + ClientHeight = 252 + ClientWidth = 608 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + Position = poDesktopCenter + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object ToolBar1: TToolBar + Left = 0 + Top = 0 + Width = 608 + Height = 25 + ButtonHeight = 27 + ButtonWidth = 79 + Caption = 'ToolBar1' + List = True + ShowCaptions = True + TabOrder = 0 + object Edit1: TEdit + Left = 0 + Top = 0 + Width = 385 + Height = 27 + TabOrder = 0 + end + object TBDownload: TToolButton + Left = 385 + Top = 0 + AutoSize = True + Caption = #1057#1082#1072#1095#1072#1090#1100 + ImageIndex = 0 + OnClick = TBDownloadClick + end + object TBStopDownload: TToolButton + Left = 444 + Top = 0 + AutoSize = True + Caption = #1054#1089#1090#1072#1085#1086#1074#1080#1090#1100 + ImageIndex = 1 + Visible = False + OnClick = TBStopDownloadClick + end + object TBView: TToolButton + Left = 521 + Top = 0 + AutoSize = True + Caption = #1042#1099#1074#1077#1089#1090#1080 + DropdownMenu = PopupMenu1 + ImageIndex = 2 + Style = tbsDropDown + Visible = False + OnClick = TBViewClick + end + end + object StatusBar1: TStatusBar + Left = 0 + Top = 233 + Width = 608 + Height = 19 + Panels = <> + SimplePanel = True + end + object RichEdit1: TRichEdit + Left = 0 + Top = 25 + Width = 608 + Height = 191 + Align = alClient + Font.Charset = RUSSIAN_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + ReadOnly = True + ScrollBars = ssBoth + TabOrder = 2 + end + object ProgressBar1: TProgressBar + Left = 0 + Top = 216 + Width = 608 + Height = 17 + Align = alBottom + TabOrder = 3 + end + object IMDownloader_Demo: TIMDownloader + OnError = IMDownloader_DemoError + OnAccepted = IMDownloader_DemoAccepted + OnHeaders = IMDownloader_DemoHeaders + OnMD5Checked = IMDownloader_DemoMD5Checked + OnDownloading = IMDownloader_DemoDownloading + OnStartDownload = IMDownloader_DemoStartDownload + OnBreak = IMDownloader_DemoBreak + Left = 72 + Top = 40 + end + object SaveDialog1: TSaveDialog + Left = 136 + Top = 96 + end + object PopupMenu1: TPopupMenu + Left = 224 + Top = 120 + object ViewAsTest: TMenuItem + Caption = #1054#1090#1086#1073#1088#1072#1079#1080#1090#1100' '#1082#1072#1082' '#1090#1077#1082#1089#1090 + Default = True + OnClick = ViewAsTestClick + end + object SaveToFile: TMenuItem + Caption = #1057#1086#1093#1088#1072#1085#1080#1090#1100' '#1074' '#1092#1072#1081#1083 + OnClick = SaveToFileClick + end + end +end diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.pas b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.pas new file mode 100644 index 0000000000..2ca42ac174 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.pas @@ -0,0 +1,176 @@ +unit DownLoaderTestUnit; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, uIMDownLoader, StdCtrls, ToolWin, ComCtrls, Menus; + +type + TMainForm = class(TForm) + IMDownloader_Demo: TIMDownloader; + Edit1: TEdit; + ToolBar1: TToolBar; + StatusBar1: TStatusBar; + RichEdit1: TRichEdit; + SaveDialog1: TSaveDialog; + TBDownload: TToolButton; + TBStopDownload: TToolButton; + TBView: TToolButton; + ViewAsTest: TMenuItem; + SaveToFile: TMenuItem; + PopupMenu1: TPopupMenu; + ProgressBar1: TProgressBar; + procedure FormShow(Sender: TObject); + procedure IMDownloader_DemoError(Sender: TObject; E: TIMDownLoadError); + procedure IMDownloader_DemoAccepted(Sender: TObject); + procedure IMDownloader_DemoStartDownload(Sender: TObject); + procedure IMDownloader_DemoBreak(Sender: TObject); + procedure ViewAsTestClick(Sender: TObject); + procedure SaveToFileClick(Sender: TObject); + procedure TBDownloadClick(Sender: TObject); + procedure TBStopDownloadClick(Sender: TObject); + procedure TBViewClick(Sender: TObject); + procedure IMDownloader_DemoDownloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal); + procedure IMDownloader_DemoHeaders(Sender: TObject; Headers: string); + procedure IMDownloader_DemoMD5Checked(Sender: TObject; MD5Correct, + SizeCorrect: Boolean; MD5Str: string); + private + { Private declarations } + public + { Public declarations } + end; + +var + MainForm: TMainForm; + +const + uURL = 'http://im-history.ru/update/get.php?file=HistoryToDB-Update'; + +implementation + +{$R *.dfm} + +procedure TMainForm.FormShow(Sender: TObject); +begin + Edit1.Text := uURL; + IMDownloader_Demo.DirPath := ExtractFilePath(Application.ExeName); +end; + +procedure TMainForm.IMDownloader_DemoAccepted(Sender: TObject); +begin + ProgressBar1.Visible := False; + TBStopDownload.Visible := false; + TBDownload.Visible := true; + TBView.Visible := true; + Edit1.ReadOnly := false; + StatusBar1.SimpleText := + ' . : ' + IntToStr + (IMDownloader_Demo.AcceptedSize); + //RichEdit1.Lines.Append('MD5 : '+MD5DigestToStr(MD5Stream(IMDownloader_Demo.OutStream))); +end; + +procedure TMainForm.IMDownloader_DemoBreak(Sender: TObject); +begin + ProgressBar1.Visible := False; + TBStopDownload.Visible := false; + TBStopDownload.Enabled := true; + TBDownload.Visible := true; + TBView.Visible := IMDownloader_Demo.AcceptedSize > 0; + Edit1.ReadOnly := false; + StatusBar1.SimpleText := + ' . : ' + IntToStr + (IMDownloader_Demo.AcceptedSize); +end; + +procedure TMainForm.IMDownloader_DemoDownloading(Sender: TObject; AcceptedSize, + MaxSize: Cardinal); +begin + StatusBar1.SimpleText := ' : ' + IntToStr(AcceptedSize); + ProgressBar1.Visible := MaxSize > AcceptedSize; + ProgressBar1.Max := MaxSize; + ProgressBar1.Position := AcceptedSize; +end; + +procedure TMainForm.IMDownloader_DemoError(Sender: TObject; E: TIMDownLoadError); +var + s: string; +begin + ProgressBar1.Visible := False; + TBStopDownload.Visible := false; + TBDownload.Visible := true; + TBView.Visible := IMDownloader_Demo.AcceptedSize > 0; + Edit1.ReadOnly := false; + case E of + deInternetOpen: s := ' . '; + deInternetOpenUrl: s := ' . '; + deDownloadingFile: s := ' . '; + deRequest: s := ' -. '; + end; + StatusBar1.SimpleText := + s + ' : ' + IntToStr + (IMDownloader_Demo.AcceptedSize); +end; + +procedure TMainForm.IMDownloader_DemoHeaders(Sender: TObject; Headers: string); +begin + RichEdit1.Lines.Text := Headers; +end; + +procedure TMainForm.IMDownloader_DemoMD5Checked(Sender: TObject; MD5Correct, + SizeCorrect: Boolean; MD5Str: string); +begin + if MD5Correct then + RichEdit1.Lines.Append(' MD5 = '+MD5Str+' - !') + else + RichEdit1.Lines.Append(' MD5 = '+MD5Str+' - !'); + if SizeCorrect then + RichEdit1.Lines.Append(' = '+IntToStr(IMDownloader_Demo.AcceptedSize)+' - !') + else + RichEdit1.Lines.Append(' = '+IntToStr(IMDownloader_Demo.AcceptedSize)+' - !'); +end; + +procedure TMainForm.IMDownloader_DemoStartDownload(Sender: TObject); +begin + TBDownload.Visible := false; + TBStopDownload.Visible := true; + TBView.Visible := false; + Edit1.ReadOnly := true; + StatusBar1.SimpleText := ' ...'; +end; + +procedure TMainForm.ViewAsTestClick(Sender: TObject); +begin + RichEdit1.Lines.LoadFromStream(IMDownloader_Demo.OutStream); +end; + +procedure TMainForm.SaveToFileClick(Sender: TObject); +begin + if Edit1.Text = uURL then + SaveDialog1.FileName := 'HistoryToDBCreateDB.rar'; + if SaveDialog1.Execute then + IMDownloader_Demo.OutStream.SaveToFile(SaveDialog1.FileName); +end; + +procedure TMainForm.TBDownloadClick(Sender: TObject); +begin + IMDownloader_Demo.URL := Edit1.Text; + //IMDownloader_Demo.Proxy := '192.168.42.240:1522'; + IMDownloader_Demo.Proxy := '172.29.72.168:8080'; + IMDownloader_Demo.Download; +end; + +procedure TMainForm.TBStopDownloadClick(Sender: TObject); +begin + StatusBar1.SimpleText := ' '; + TBStopDownload.Enabled := false; + IMDownloader_Demo.BreakDownload; +end; + +procedure TMainForm.TBViewClick(Sender: TObject); +begin + TBView.DropdownMenu.Popup(TBView.ClientOrigin.X, + TBView.ClientOrigin.Y + TBView.Height); +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dcr b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dcr new file mode 100644 index 0000000000..2311dc0fef Binary files /dev/null and b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dcr differ diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dpk b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dpk new file mode 100644 index 0000000000..f925b6df62 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dpk @@ -0,0 +1,38 @@ +package IMDownloader; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS OFF} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO OFF} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE RELEASE} +{$ENDIF IMPLICITBUILDING} +{$IMPLICITBUILD ON} + +requires + rtl, + vcl; + +contains + uIMDownloader in 'uIMDownloader.pas', + uMD5 in 'uMD5.pas'; + +end. diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dproj b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dproj new file mode 100644 index 0000000000..092d815fc7 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dproj @@ -0,0 +1,168 @@ + + + {BF7E5A55-CA0C-4DDD-B399-17FA1A2FF83F} + IMDownloader.dpk + True + Release + Package + VCL + DCC32 + 14.3 + Win32 + 3 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) + 4 + 1049 + CompanyName=;FileDescription=;FileVersion=1.0.0.4;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + false + false + RELEASE;$(DCC_Define) + 00400000 + true + false + false + 0 + false + true + false + false + + + true + IMDownloader_Icon.ico + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + vcl;rtl;$(DCC_UsePackage) + $(BDS)\bin\default_app.manifest + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + 1033 + IMDownloader_Icon.ico + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + vcl;rtl;$(DCC_UsePackage) + $(BDS)\bin\default_app.manifest + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + 1033 + 0 + .\$(Platform)\$(Config) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + 1033 + 0 + .\$(Platform)\$(Config) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + DEBUG;$(DCC_Define) + true + false + + + + MainSource + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + + + Delphi.Personality.12 + Package + + + + IMDownloader.dpk + + + True + False + 1 + 0 + 0 + 4 + False + False + False + False + False + 1049 + 1251 + + + + + 1.0.0.4 + + + + + + 1.0.0.0 + + + + + + True + True + + + 12 + + diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.res b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.res new file mode 100644 index 0000000000..ebc501849a Binary files /dev/null and b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.res differ diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader_Icon.ico b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader_Icon.ico new file mode 100644 index 0000000000..379ec80d91 Binary files /dev/null and b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader_Icon.ico differ diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uIMDownloader.pas b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uIMDownloader.pas new file mode 100644 index 0000000000..168fc21a7f --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uIMDownloader.pas @@ -0,0 +1,612 @@ +{ ################################################################################### } +{ # # } +{ # IMDownloader # } +{ # # } +{ # Base on Downloader www.webdelphi.ru # } +{ # http://www.webdelphi.ru/2009/10/mnogopotochnost-v-svoix-prilozheniyax-chast-2/ # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ # Downloader: # } +{ # + ( Proxy, ProxyBypass, # } +{ # AuthUserName, AuthPassword, ProxyAuthUserName, ProxyAuthPassword) # } +{ # + DirPath - MD5. # } +{ # ( MD5 ). MD5 # } +{ # MD5 , . # } +{ # + OnHeaders - . # } +{ # + OnMD5Checked - MD5 . # } +{ # # } +{ ################################################################################### } + +unit uIMDownloader; + +interface + +uses Classes, WinInet, SysUtils, Dialogs, Windows, Forms, uMD5; + +const + Accept = 'Accept: */*' + sLineBreak; + ProxyConnection = 'Proxy-Connection: Keep-Alive' + sLineBreak; + Lang = 'Accept-Language: ru' + sLineBreak; + Agent = + 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; ' + + 'Windows NT 5.1; SV1; .NET CLR 2.0.50727)' + sLineBreak; + +type + PMemoryStream = ^TMemoryStream; + TIMDownloadError = (deInternetOpen, deInternetOpenUrl, deDownloadingFile, deConnect, deRequest); + TErrorEvent = procedure(Sender: TObject; E: TIMDownloadError) of object; + TDownloadingEvent = procedure(Sender: TObject; AcceptedSize, MaxSize: Cardinal) of object; + THeadersEvent = procedure(Sender: TObject; Headers: String) of object; + TMD5Event = procedure(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: String) of object; + + TIMDownloadThread = class(TThread) + private + fURL: String; + fProxy: String; + fProxyBypass: String; + fAuthUserName: String; + fAuthPassword: String; + fProxyAuthUserName: String; + fProxyAuthPassword: String; + fDirPath: String; + MemoryStream: TMemoryStream; + Err: TIMDownloadError; + fError: TErrorEvent; + fAccepted: TNotifyEvent; + fBreak: TNotifyEvent; + fDownloading: TDownloadingEvent; + fHeaders: THeadersEvent; + AcceptedSize: Cardinal; + AllSize: Cardinal; + Headers: String; + MD5Str: String; + MD5Correct: Boolean; + SizeCorrect: Boolean; + fMD5: TMD5Event; + procedure toError; + procedure toHeaders; + procedure toDownloading; + procedure toAccepted; + procedure toBreak; + procedure toMD5; + procedure Complete; + function ErrorResult(E: Boolean; eType: TIMDownloadError): Boolean; + function GetQueryInfo(hRequest: Pointer; Flag: Integer): String; + protected + procedure Execute; override; + public + constructor Create(CreateSuspennded: Boolean; const URL, Proxy, ProxyBypass, AuthUserName, AuthPassword, ProxyAuthUserName, ProxyAuthPassword, DirPath: String; Stream: PMemoryStream); + property URL: string read fURL; + property Proxy: string read fProxy; // + property ProxyBypass: string read fProxyBypass; // + property AuthUserName: string read fAuthUserName; // Authorization: Basic + property AuthPassword: string read fAuthPassword; // Authorization: Basic + property ProxyAuthUserName: string read fProxyAuthUserName; // + property ProxyAuthPassword: string read fProxyAuthPassword; // + property DirPath: string read fDirPath write fDirPath; // MD5 + property OnError: TErrorEvent read fError write fError; + property OnAccepted: TNotifyEvent read fAccepted write fAccepted; + property OnBreak: TNotifyEvent read fBreak write fBreak; + property OnDownloading: TDownloadingEvent read fDownloading write fDownloading; + property OnHeaders: THeadersEvent read fHeaders write fHeaders; + property OnMD5Checked: TMD5Event read fMD5 write fMD5; + end; + + TIMDownloader = class(TComponent) + private + fOutStream: TMemoryStream; + fURL: String; + fProxy: String; + fProxyBypass: String; + fAuthUserName: String; + fAuthPassword: String; + fProxyAuthUserName: String; + fProxyAuthPassword: String; + fDirPath: String; + Downloader: TIMDownloadThread; + fOnError: TErrorEvent; + fOnAccepted: TNotifyEvent; + fOnBreak: TNotifyEvent; + fOnStartDownload: TNotifyEvent; + fInDowloading: Boolean; + fAcceptedSize: Cardinal; + fMyHeaders: String; + fMyMD5Str: String; + fMyMD5Correct: Boolean; + fMySizeCorrect: Boolean; + fHeaders: THeadersEvent; + fDownloading: TDownloadingEvent; + fMD5: TMD5Event; + procedure AcceptDownload(Sender: TObject); + procedure Break_Download(Sender: TObject); + procedure Downloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal); + procedure GetHeaders(Sender: TObject; Headers: String); + procedure GetMD5(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: String); + procedure ErrorDownload(Sender: TObject; Error: TIMDownloadError); + public + procedure Download; + procedure BreakDownload; + property OutStream: TMemoryStream read fOutStream; + property InDowloading: Boolean read fInDowloading; + property AcceptedSize: Cardinal read fAcceptedSize; + property MyHeaders: String read fMyHeaders; + property MyMD5Str: String read fMyMD5Str; + property MyMD5Correct: Boolean read fMyMD5Correct; + property MySizeCorrect: Boolean read fMySizeCorrect; + published + property URL: string read fURL write fURL; + property Proxy: string read fProxy write fProxy; // + property ProxyBypass: string read fProxyBypass write fProxyBypass; // + property AuthUserName: string read fAuthUserName write fAuthUserName; // Authorization: Basic + property AuthPassword: string read fAuthPassword write fAuthPassword; // Authorization: Basic + property ProxyAuthUserName: string read fProxyAuthUserName write fProxyAuthUserName; // + property ProxyAuthPassword: string read fProxyAuthPassword write fProxyAuthUserName; // + property DirPath: string read fDirPath write fDirPath; // MD5 + property OnError: TErrorEvent read fOnError write fOnError; + property OnAccepted: TNotifyEvent read fOnAccepted write fOnAccepted; + property OnHeaders: THeadersEvent read fHeaders write fHeaders; + property OnMD5Checked: TMD5Event read fMD5 write fMD5; + property OnDownloading: TDownloadingEvent read fDownloading write fDownloading; + property OnStartDownload: TNotifyEvent read fOnStartDownload write fOnStartDownload; + property OnBreak: TNotifyEvent read fOnBreak write fOnBreak; + end; + +{$R IMDownloader.dcr} + +procedure Register; + +implementation + +procedure Register; +begin + RegisterComponents('IM-History', [TIMDownloader]); +end; + +procedure TIMDownloadThread.toHeaders; +begin + if Assigned(fHeaders) then + fHeaders(Self, Headers); +end; + +procedure TIMDownloadThread.toMD5; +begin + if Assigned(fMD5) then + fMD5(Self, MD5Correct, SizeCorrect, MD5Str); +end; + +procedure TIMDownloadThread.toDownloading; +begin + if Assigned(fDownloading) then + fDownloading(Self, AcceptedSize, AllSize); +end; + +procedure TIMDownloadThread.toAccepted; +begin + if Assigned(fAccepted) then + fAccepted(Self); +end; + +procedure TIMDownloadThread.toBreak; +begin + if Assigned(fBreak) then + fBreak(Self); +end; + +procedure TIMDownloadThread.Complete; +begin + if Terminated then + Synchronize(toBreak) + else + Synchronize(toAccepted); +end; + +procedure TIMDownloadThread.toError; +begin + if Assigned(fError) then + OnError(Self, err); +end; + +function TIMDownloadThread.ErrorResult(E: Boolean; eType: TIMDownloadError): Boolean; +begin + Result := E; + if E then + begin + err := eType; + toError; + end; +end; + +function TIMDownloadThread.GetQueryInfo(hRequest: Pointer; Flag: Integer): String; +var + Code: String; + Size, Index: Cardinal; +begin + SetLength(Code, 8); // - + Size := Length(Code); + Index := 0; + if HttpQueryInfo(hRequest, Flag ,PChar(Code), Size, Index) then + Result := Code + else + if GetLastError = ERROR_INSUFFICIENT_BUFFER then // + begin + SetLength(Code, Size); + Size := Length(Code); + if HttpQueryInfo(hRequest, Flag, PChar(Code), Size, Index) then + Result := Code; + end + else + begin + //FErrorCode := GetLastError; + Result := ''; + end; +end; + +procedure TIMDownloadThread.Execute; +var + Buffer: Array [0 .. 1024] of Byte; + BytesRead: Cardinal; + FSession, FConnect, FRequest: hInternet; + dwBuffer: array [0 .. 1024] of Byte; + dwBufferLen, dwIndex: DWORD; + FHost, FScript, SRequest, ARequest: String; + ProxyReqRes, ProxyReqLen: Cardinal; + TempHeaders, TempMD5, DownloadsFileName, DownloadsFileMD5: String; + + function DelHttp(sURL: String): String; + var + HttpPos: Integer; + begin + HttpPos := Pos('http://', sURL); + if HttpPos > 0 then Delete(sURL, HttpPos, 7); + Result := Copy(sURL, 1, Pos('/', sURL) - 1); + if Result = '' then Result := sURL; + end; + + function ParseHeadersMD5andSize(HeaderStr: String): String; + var + HeadersStrList: TStringList; + I: Integer; + Size: String; + Ch: Char; + ResultFilename, ResultMD5Sum, ResultHeaders: String; + ResultFileSize: Integer; + begin + ResultFilename := 'Test'; + ResultMD5Sum := '00000000000000000000000000000000'; + ResultFileSize := 0; + // TStringList + HeadersStrList := TStringList.Create; + HeadersStrList.Clear; + HeadersStrList.Text := HeaderStr; + HeadersStrList.Delete(HeadersStrList.Count-1); // CRLF + if HeadersStrList.Count > 0 then + begin + for I := 0 to HeadersStrList.Count - 1 do + begin + // + // Content-Disposition: attachment; filename="-" + // HTTP- + // get.php + if pos('content-disposition', LowerCase(HeadersStrList[I])) > 0 then + begin + ResultFilename := HeadersStrList[I]; + Delete(ResultFilename, 1, Pos('"', HeadersStrList[I])); + Delete(ResultFilename, Length(ResultFilename),1); + //LogMemo.Lines.Add('Filename: '+ResultFilename); + end; + // + // Content-MD5Sum: MD5 + // HTTP- + // get.php + if pos('content-md5sum', LowerCase(HeadersStrList[I])) > 0 then + begin + ResultMD5Sum := HeadersStrList[I]; + Delete(ResultMD5Sum, 1, Pos(':', HeadersStrList[I])); + Delete(ResultMD5Sum, 1,1); + end; + // + // Content-Length: + if pos('content-length', LowerCase(HeadersStrList[i])) > 0 then + begin + Size := ''; + for Ch in HeadersStrList[I]do + if Ch in ['0'..'9'] then + Size := Size + Ch; + ResultFileSize := StrToIntDef(Size,-1); + end; + end; + Result := ResultFilename + '|' + LowerCase(ResultMD5Sum) + '|' + IntToStr(ResultFileSize) + '|'; + end; + HeadersStrList.Free; + end; + + { S , -, + Sep. , + S } + function Tok(Sep: String; var S: String): String; + + function isoneof(c, s: string): Boolean; + var + iTmp: integer; + begin + Result := False; + for iTmp := 1 to Length(s) do + begin + if c = Copy(s, iTmp, 1) then + begin + Result := True; + Exit; + end; + end; + end; + + var + c, t: String; + begin + if s = '' then + begin + Result := s; + Exit; + end; + c := Copy(s, 1, 1); + while isoneof(c, sep) do + begin + s := Copy(s, 2, Length(s) - 1); + c := Copy(s, 1, 1); + end; + t := ''; + while (not isoneof(c, sep)) and (s <> '') do + begin + t := t + c; + s := Copy(s, 2, length(s) - 1); + c := Copy(s, 1, 1); + end; + Result := t; + end; + +begin + // WinInet + if fProxy = '' then + FSession := InternetOpen('IM-History Download Master', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0) + else + begin + FSession := InternetOpen('IM-History Download Master', INTERNET_OPEN_TYPE_PROXY, PChar(fProxy), PChar(fProxyBypass), 0); + if fProxyAuthUserName <> '' then + begin + InternetSetOption(FSession, INTERNET_OPTION_PROXY_USERNAME, @fProxyAuthUserName, Length(fProxyAuthUserName)); + InternetSetOption(FSession, INTERNET_OPTION_PROXY_PASSWORD, @fProxyAuthPassword, Length(fProxyAuthPassword)); + end; + end; + if ErrorResult(FSession = nil, deInternetOpen) then + Exit; + if Assigned(FSession) then + begin + // + // + ARequest := fURL; + FHost := DelHttp(ARequest); + FScript := ARequest; + Delete(FScript, 1, Pos(FHost, FScript) + Length(FHost)); + // + if fAuthUserName = '' then // Basic- + FConnect := InternetOpenURL(FSession, PChar(fURL), nil, 0, INTERNET_FLAG_RELOAD, 0) + else + FConnect := InternetConnect(FSession, PChar(FHost), INTERNET_DEFAULT_HTTP_PORT, PChar(fAuthUserName), + PChar(fAuthPassword), INTERNET_SERVICE_HTTP, 0, 0); + if ErrorResult(FConnect = nil, deInternetOpenUrl) then + Exit; + dwIndex := 0; + dwBufferLen := Length(dwBuffer); + if fProxy <> '' then + begin + // + FRequest := HttpOpenRequest(FConnect, 'GET', PChar(FScript), nil, '', nil, 0, 0); + // + HttpAddRequestHeaders(FRequest, Accept, Length(Accept), HTTP_ADDREQ_FLAG_ADD); + HttpAddRequestHeaders(FRequest, ProxyConnection, Length(ProxyConnection), HTTP_ADDREQ_FLAG_ADD); + HttpAddRequestHeaders(FRequest, Lang, Length(Lang), HTTP_ADDREQ_FLAG_ADD); + HttpAddRequestHeaders(FRequest, Agent, Length(Agent), HTTP_ADDREQ_FLAG_ADD); + // : + ProxyReqLen := 0; + ProxyReqRes := 0; + SRequest := ' '; + HttpQueryInfo(FRequest, HTTP_QUERY_RAW_HEADERS_CRLF or + HTTP_QUERY_FLAG_REQUEST_HEADERS, @SRequest[1], ProxyReqLen, ProxyReqRes); + if ProxyReqLen > 0 then + begin + SetLength(SRequest, ProxyReqLen); + HttpQueryInfo(FRequest, HTTP_QUERY_RAW_HEADERS_CRLF or + HTTP_QUERY_FLAG_REQUEST_HEADERS, @SRequest[1], ProxyReqLen, ProxyReqRes); + end; + // + if ErrorResult(not HttpSendRequest(FRequest, nil, 0, nil, 0), deRequest) then Exit; + end; + if fProxy = '' then + begin + // + Headers := GetQueryInfo(FConnect, HTTP_QUERY_RAW_HEADERS_CRLF); + Synchronize(toHeaders); + // + if HttpQueryInfo(FConnect, HTTP_QUERY_CONTENT_LENGTH, @dwBuffer, dwBufferLen, dwIndex) then + AllSize := StrToInt('0' + PChar(@dwBuffer)); + end + else + begin + // + Headers := GetQueryInfo(FRequest, HTTP_QUERY_RAW_HEADERS_CRLF); + Synchronize(toHeaders); + // + if HttpQueryInfo(FRequest, HTTP_QUERY_CONTENT_LENGTH, @dwBuffer, dwBufferLen, dwIndex) then + AllSize := StrToInt('0' + PChar(@dwBuffer)); + end; + // MD5 + TempHeaders := ParseHeadersMD5andSize(Headers); + DownloadsFileName := Tok('|', TempHeaders); + DownloadsFileMD5 := Tok('|', TempHeaders); + if FileExists(fDirPath+DownloadsFileName) then + TempMD5 := LowerCase(MD5DigestToStr(MD5File(fDirPath+DownloadsFileName))) + else + TempMD5 := '00000000000000000000000000000000'; + if LowerCase(DownloadsFileMD5) <> TempMD5 then + begin + repeat + if Terminated then + Break; + FillChar(Buffer, SizeOf(Buffer), 0); + if fProxy = '' then + begin + if ErrorResult(not InternetReadFile(FConnect, @Buffer, Length(Buffer), BytesRead), deDownloadingFile) then + Exit + else + MemoryStream.Write(Buffer, BytesRead); + end + else + begin + if ErrorResult(not InternetReadFile(FRequest, @Buffer, Length(Buffer), BytesRead), deDownloadingFile) then + Exit + else + MemoryStream.Write(Buffer, BytesRead); + end; + AcceptedSize := MemoryStream.Size; + Synchronize(toDownloading); + until (BytesRead = 0); + MemoryStream.Position := 0; + // MD5 + MD5Str := LowerCase(MD5DigestToStr(MD5Stream(MemoryStream))); + TempHeaders := ParseHeadersMD5andSize(Headers); + DownloadsFileName := Tok('|', TempHeaders); + if Tok('|', TempHeaders) = MD5Str then + MD5Correct := True + else + MD5Correct := False; + if Tok('|', TempHeaders) = IntToStr(MemoryStream.Size) then + SizeCorrect := True + else + SizeCorrect := False; + Synchronize(toMD5); + end + else + begin + AcceptedSize := 0; + Synchronize(toDownloading); + MD5Str := 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; + MD5Correct := True; + SizeCorrect := True; + Synchronize(toMD5); + end; + // + if Assigned(FRequest) then + InternetCloseHandle(FRequest); + if Assigned(FConnect) then + InternetCloseHandle(FConnect); + InternetCloseHandle(FSession); + Pointer(MemoryStream) := nil; + Complete; + end; +end; + +constructor TIMDownloadThread.Create(CreateSuspennded: Boolean; const URL, Proxy, ProxyBypass, AuthUserName, AuthPassword, ProxyAuthUserName, ProxyAuthPassword, DirPath: String; Stream: PMemoryStream); +begin + inherited Create(CreateSuspennded); + FreeOnTerminate := True; + Pointer(MemoryStream) := Stream; + AcceptedSize := 0; + Headers := ''; + MD5Str := ''; + MD5Correct := False; + SizeCorrect := False; + fURL := URL; + fProxy := Proxy; + fProxyBypass := ProxyBypass; + fAuthUserName := AuthUserName; + fAuthPassword := AuthPassword; + fProxyAuthUserName := ProxyAuthUserName; + fProxyAuthPassword := ProxyAuthPassword; + fDirPath := DirPath; +end; + +procedure TIMDownloader.Download; +begin + fInDowloading := True; + if Assigned(Downloader) then + Downloader.Terminate; + if Assigned(fOutStream) then + FreeAndNil(fOutStream); + fAcceptedSize := 0; + fMyHeaders := ''; + fMyMD5Str := ''; + fMyMD5Correct := False; + fMySizeCorrect := False; + fOutStream := TMemoryStream.Create; + Downloader := TIMDownloadThread.Create(True, fURL, fProxy, fProxyBypass, fAuthUserName, fAuthPassword, fProxyAuthUserName, fProxyAuthPassword, fDirPath, Pointer(fOutStream)); + Downloader.OnAccepted := AcceptDownload; + Downloader.OnError := ErrorDownload; + Downloader.OnHeaders := GetHeaders; + Downloader.OnDownloading := Downloading; + Downloader.OnBreak := Break_Download; + Downloader.OnMD5Checked := GetMD5; + Downloader.Resume; + if Assigned(fOnStartDownload) then + fOnStartDownload(Self); +end; + +procedure TIMDownloader.BreakDownload; +begin + if not InDowloading then + Exit; + if Assigned(Downloader) then + Downloader.Terminate; +end; + +procedure TIMDownloader.Break_Download(Sender: TObject); +begin + fInDowloading := False; + Downloader := nil; + if Assigned(fOnBreak) then + fOnBreak(Self); +end; + +procedure TIMDownloader.AcceptDownload(Sender: TObject); +begin + fInDowloading := False; + Downloader := nil; + if Assigned(fOnAccepted) then + fOnAccepted(Self); +end; + +procedure TIMDownloader.GetHeaders(Sender: TObject; Headers: String); +begin + fMyHeaders := Headers; + if Assigned(fHeaders) then + fHeaders(Self, Headers); +end; + +procedure TIMDownloader.GetMD5(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: String); +begin + fMyMD5Str := MD5Str; + fMyMD5Correct := MD5Correct; + fMySizeCorrect := SizeCorrect; + if Assigned(fMD5) then + fMD5(Self, MD5Correct, SizeCorrect, MD5Str); +end; + +procedure TIMDownloader.Downloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal); +begin + fAcceptedSize := AcceptedSize; + if Assigned(fDownloading) then + fDownloading(Self, AcceptedSize, MaxSize); +end; + +procedure TIMDownloader.ErrorDownload(Sender: TObject; Error: TIMDownloadError); +begin + fInDowloading := False; + Downloader := nil; + fOutStream := nil; + if Assigned(fOnError) then + fOnError(Self, Error); +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uMD5.pas b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uMD5.pas new file mode 100644 index 0000000000..81a6f4697b --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uMD5.pas @@ -0,0 +1,456 @@ +{******************************************************************} +{ - MD5 } +{ } +{ by delphibase.endimus.com } +{ : Windows, SysUtils, Classes } +{ : Dimka Maslov, mainbox@endimus.ru, ICQ:148442121, - } +{ Copyright: http://www.faqs.org/rfcs/rfc1321.html } +{ : 19 2002 . } +{******************************************************************} + +{******************************************************************} +{ MD5 Hashsum Evaluation Unit For Borland Delphi } +{ } +{ Copyright 2002 by Dimka Maslov } +{ E-mail: mainbox@endimus.com, } +{ Web-site: http://www.endimus.com } +{ } +{ Derived from the RSA Data Security, Inc. } +{ MD5 Message-Digest Algorithm described in RFC 1321 } +{ http://www.faqs.org/rfcs/rfc1321.html } +{******************************************************************} + +unit uMD5; + +Interface + +Uses Windows, SysUtils, Classes; + +Type +{ The TMD5Digest record is the type of results of + the MD5 hashsum evaluation functions. The contents + of a record may be used as four 32-bit integer values + or as an array of 16 bytes } +{ TMD5Digest + -. + + 4 , + 16 } + PMD5Digest = ^TMD5Digest; + + TMD5Digest = Record + Case Integer Of + 0: (A, B, C, D: LongInt); + 1: (v: Array[0..15] Of Byte); + End; + +{ The MD5String function evaluates the MD5 hashsum for + a string. The S parameter specifies a string to + evaluate hashsum } +// - +Function MD5String(Const S: String): TMD5Digest; + +{ The MD5File function evaluates the MD5 hashsum for + a file. The FileName parameter specifies the name + of a file to evaluate hashsum } +// - +Function MD5File(Const FileName: String): TMD5Digest; + +{ The MD5Stream function evaluates the MD5 hashsum for + a stream. The Stream parameters specifies the + TStream descendant class object to evaluate hashsum } +// - Stream +Function MD5Stream(Const Stream: TStream): TMD5Digest; + +{ The MD5Buffer function evaluates the MD5 hashsum for + any memory buffer. The Buffer parameters specifies a + buffer to evaluate hashsum. The Size parameter specifies + the size (in bytes) of a buffer } +// - +Function MD5Buffer(Const Buffer; Size: Integer): TMD5Digest; + +{ The MD5DigestToStr function converts the result of + a hashsum evaluation function into a string of + hexadecimal digits } +// - +Function MD5DigestToStr(Const Digest: TMD5Digest): String; + + +{ The MD5DigestCompare function compares two + TMD5Digest record variables. This function returns + TRUE if parameters are equal or FALSE otherwise } +// - +Function MD5DigestCompare(Const Digest1, Digest2: TMD5Digest): Boolean; + +{ +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +} + +Implementation + +Type + UINT4 = LongWord; + + PArray4UINT4 = ^TArray4UINT4; + TArray4UINT4 = Array[0..3] Of UINT4; + PArray2UINT4 = ^TArray2UINT4; + TArray2UINT4 = Array[0..1] Of UINT4; + PArray16Byte = ^TArray16Byte; + TArray16Byte = Array[0..15] Of Byte; + PArray64Byte = ^TArray64Byte; + TArray64Byte = Array[0..63] Of Byte; + + PByteArray = ^TByteArray; + TByteArray = Array[0..0] Of Byte; + + PUINT4Array = ^TUINT4Array; + TUINT4Array = Array[0..0] Of UINT4; + + PMD5Context = ^TMD5Context; + TMD5Context = Record + state: TArray4UINT4; + count: TArray2UINT4; + buffer: TArray64Byte; + End; + +Const + S11 = 7; + S12 = 12; + S13 = 17; + S14 = 22; + S21 = 5; + S22 = 9; + S23 = 14; + S24 = 20; + S31 = 4; + S32 = 11; + S33 = 16; + S34 = 23; + S41 = 6; + S42 = 10; + S43 = 15; + S44 = 21; + +Var + Padding: TArray64Byte = + ($80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + +Function _F(x, y, z: UINT4): UINT4; +Begin + Result := (((x) And (y)) Or ((Not x) And (z))); +End; + +Function _G(x, y, z: UINT4): UINT4; +Begin + Result := (((x) And (z)) Or ((y) And (Not z))); +End; + +Function _H(x, y, z: UINT4): UINT4; +Begin + Result := ((x) Xor (y) Xor (z)); +End; + +Function _I(x, y, z: UINT4): UINT4; +Begin + Result := ((y) Xor ((x) Or (Not z))); +End; + +Function ROTATE_LEFT(x, n: UINT4): UINT4; +Begin + Result := (((x) Shl (n)) Or ((x) Shr (32 - (n)))); +End; + +Procedure FF(Var a: UINT4; b, c, d, x, s, ac: UINT4); +Begin + a := a + _F(b, c, d) + x + ac; + a := ROTATE_LEFT(a, s); + a := a + b; +End; + +Procedure GG(Var a: UINT4; b, c, d, x, s, ac: UINT4); +Begin + a := a + _G(b, c, d) + x + ac; + a := ROTATE_LEFT(a, s); + a := a + b; +End; + +Procedure HH(Var a: UINT4; b, c, d, x, s, ac: UINT4); +Begin + a := a + _H(b, c, d) + x + ac; + a := ROTATE_LEFT(a, s); + a := a + b; +End; + +Procedure II(Var a: UINT4; b, c, d, x, s, ac: UINT4); +Begin + a := a + _I(b, c, d) + x + ac; + a := ROTATE_LEFT(a, s); + a := a + b; +End; + +Procedure MD5Encode(Output: PByteArray; Input: PUINT4Array; Len: LongWord); +Var + i, j: LongWord; +Begin + j := 0; + i := 0; + While j < Len Do Begin + output[j] := Byte(input[i] And $FF); + output[j + 1] := Byte((input[i] Shr 8) And $FF); + output[j + 2] := Byte((input[i] Shr 16) And $FF); + output[j + 3] := Byte((input[i] Shr 24) And $FF); + Inc(j, 4); + Inc(i); + End; +End; + +Procedure MD5Decode(Output: PUINT4Array; Input: PByteArray; Len: LongWord); +Var + i, j: LongWord; +Begin + j := 0; + i := 0; + While j < Len Do Begin + Output[i] := UINT4(input[j]) Or (UINT4(input[j + 1]) Shl 8) Or + (UINT4(input[j + 2]) Shl 16) Or (UINT4(input[j + 3]) Shl 24); + Inc(j, 4); + Inc(i); + End; +End; + +Procedure MD5_memcpy(Output: PByteArray; Input: PByteArray; Len: LongWord); +Begin + Move(Input^, Output^, Len); +End; + +Procedure MD5_memset(Output: PByteArray; Value: Integer; Len: LongWord); +Begin + FillChar(Output^, Len, Byte(Value)); +End; + +Procedure MD5Transform(State: PArray4UINT4; Buffer: PArray64Byte); +Var + a, b, c, d: UINT4; + x: Array[0..15] Of UINT4; +Begin + a := State[0]; b := State[1]; c := State[2]; d := State[3]; + MD5Decode(PUINT4Array(@x), PByteArray(Buffer), 64); + + FF(a, b, c, d, x[0], S11, $D76AA478); + FF(d, a, b, c, x[1], S12, $E8C7B756); + FF(c, d, a, b, x[2], S13, $242070DB); + FF(b, c, d, a, x[3], S14, $C1BDCEEE); + FF(a, b, c, d, x[4], S11, $F57C0FAF); + FF(d, a, b, c, x[5], S12, $4787C62A); + FF(c, d, a, b, x[6], S13, $A8304613); + FF(b, c, d, a, x[7], S14, $FD469501); + FF(a, b, c, d, x[8], S11, $698098D8); + FF(d, a, b, c, x[9], S12, $8B44F7AF); + FF(c, d, a, b, x[10], S13, $FFFF5BB1); + FF(b, c, d, a, x[11], S14, $895CD7BE); + FF(a, b, c, d, x[12], S11, $6B901122); + FF(d, a, b, c, x[13], S12, $FD987193); + FF(c, d, a, b, x[14], S13, $A679438E); + FF(b, c, d, a, x[15], S14, $49B40821); + + GG(a, b, c, d, x[1], S21, $F61E2562); + GG(d, a, b, c, x[6], S22, $C040B340); + GG(c, d, a, b, x[11], S23, $265E5A51); + GG(b, c, d, a, x[0], S24, $E9B6C7AA); + GG(a, b, c, d, x[5], S21, $D62F105D); + GG(d, a, b, c, x[10], S22, $2441453); + GG(c, d, a, b, x[15], S23, $D8A1E681); + GG(b, c, d, a, x[4], S24, $E7D3FBC8); + GG(a, b, c, d, x[9], S21, $21E1CDE6); + GG(d, a, b, c, x[14], S22, $C33707D6); + GG(c, d, a, b, x[3], S23, $F4D50D87); + + GG(b, c, d, a, x[8], S24, $455A14ED); + GG(a, b, c, d, x[13], S21, $A9E3E905); + GG(d, a, b, c, x[2], S22, $FCEFA3F8); + GG(c, d, a, b, x[7], S23, $676F02D9); + GG(b, c, d, a, x[12], S24, $8D2A4C8A); + + HH(a, b, c, d, x[5], S31, $FFFA3942); + HH(d, a, b, c, x[8], S32, $8771F681); + HH(c, d, a, b, x[11], S33, $6D9D6122); + HH(b, c, d, a, x[14], S34, $FDE5380C); + HH(a, b, c, d, x[1], S31, $A4BEEA44); + HH(d, a, b, c, x[4], S32, $4BDECFA9); + HH(c, d, a, b, x[7], S33, $F6BB4B60); + HH(b, c, d, a, x[10], S34, $BEBFBC70); + HH(a, b, c, d, x[13], S31, $289B7EC6); + HH(d, a, b, c, x[0], S32, $EAA127FA); + HH(c, d, a, b, x[3], S33, $D4EF3085); + HH(b, c, d, a, x[6], S34, $4881D05); + HH(a, b, c, d, x[9], S31, $D9D4D039); + HH(d, a, b, c, x[12], S32, $E6DB99E5); + HH(c, d, a, b, x[15], S33, $1FA27CF8); + HH(b, c, d, a, x[2], S34, $C4AC5665); + + II(a, b, c, d, x[0], S41, $F4292244); + II(d, a, b, c, x[7], S42, $432AFF97); + II(c, d, a, b, x[14], S43, $AB9423A7); + II(b, c, d, a, x[5], S44, $FC93A039); + II(a, b, c, d, x[12], S41, $655B59C3); + II(d, a, b, c, x[3], S42, $8F0CCC92); + II(c, d, a, b, x[10], S43, $FFEFF47D); + II(b, c, d, a, x[1], S44, $85845DD1); + II(a, b, c, d, x[8], S41, $6FA87E4F); + II(d, a, b, c, x[15], S42, $FE2CE6E0); + II(c, d, a, b, x[6], S43, $A3014314); + II(b, c, d, a, x[13], S44, $4E0811A1); + II(a, b, c, d, x[4], S41, $F7537E82); + II(d, a, b, c, x[11], S42, $BD3AF235); + II(c, d, a, b, x[2], S43, $2AD7D2BB); + II(b, c, d, a, x[9], S44, $EB86D391); + + Inc(State[0], a); + Inc(State[1], b); + Inc(State[2], c); + Inc(State[3], d); + + MD5_memset(PByteArray(@x), 0, SizeOf(x)); +End; + + +Procedure MD5Init(Var Context: TMD5Context); +Begin + FillChar(Context, SizeOf(Context), 0); + Context.state[0] := $67452301; + Context.state[1] := $EFCDAB89; + Context.state[2] := $98BADCFE; + Context.state[3] := $10325476; +End; + +Procedure MD5Update(Var Context: TMD5Context; Input: PByteArray; InputLen: LongWord); +Var + i, index, partLen: LongWord; + +Begin + index := LongWord((context.count[0] Shr 3) And $3F); + Inc(Context.count[0], UINT4(InputLen) Shl 3); + If Context.count[0] < UINT4(InputLen) Shl 3 Then Inc(Context.count[1]); + Inc(Context.count[1], UINT4(InputLen) Shr 29); + partLen := 64 - index; + If inputLen >= partLen Then Begin + MD5_memcpy(PByteArray(@Context.buffer[index]), Input, PartLen); + MD5Transform(@Context.state, @Context.buffer); + i := partLen; + While i + 63 < inputLen Do Begin + MD5Transform(@Context.state, PArray64Byte(@Input[i])); + Inc(i, 64); + End; + index := 0; + End Else i := 0; + MD5_memcpy(PByteArray(@Context.buffer[index]), PByteArray(@Input[i]), inputLen - i); +End; + + +Procedure MD5Final(Var Digest: TMD5Digest; Var Context: TMD5Context); +Var + bits: Array[0..7] Of Byte; + index, padLen: LongWord; +Begin + MD5Encode(PByteArray(@bits), PUINT4Array(@Context.count), 8); + index := LongWord((Context.count[0] Shr 3) And $3F); + If index < 56 Then padLen := 56 - index Else padLen := 120 - index; + MD5Update(Context, PByteArray(@PADDING), padLen); + MD5Update(Context, PByteArray(@Bits), 8); + MD5Encode(PByteArray(@Digest), PUINT4Array(@Context.state), 16); + MD5_memset(PByteArray(@Context), 0, SizeOf(Context)); +End; + +Function MD5DigestToStr(Const Digest: TMD5Digest): String; +Var + i: Integer; +Begin + Result := ''; + For i := 0 To 15 Do Result := Result + IntToHex(Digest.v[i], 2); +End; + +Function MD5String(Const S: String): TMD5Digest; +Begin + Result := MD5Buffer(PChar(S)^, Length(S)); +End; + +Function MD5File(Const FileName: String): TMD5Digest; +Var + F: TFileStream; +Begin + F := TFileStream.Create(FileName, fmOpenRead); + Try + Result := MD5Stream(F); + Finally + F.Free; + End; +End; + +Function MD5Stream(Const Stream: TStream): TMD5Digest; +Var + Context: TMD5Context; + Buffer: Array[0..4095] Of Byte; + Size: Integer; + ReadBytes: Integer; + TotalBytes: Integer; + SavePos: Integer; +Begin + MD5Init(Context); + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + Try + Stream.Seek(0, soFromBeginning); + Repeat + ReadBytes := Stream.Read(Buffer, SizeOf(Buffer)); + Inc(TotalBytes, ReadBytes); + MD5Update(Context, @Buffer, ReadBytes); + Until (ReadBytes = 0) Or (TotalBytes = Size); + Finally + Stream.Seek(SavePos, soFromBeginning); + End; + MD5Final(Result, Context); +End; + +Function MD5Buffer(Const Buffer; Size: Integer): TMD5Digest; +Var + Context: TMD5Context; +Begin + MD5Init(Context); + MD5Update(Context, PByteArray(@Buffer), Size); + MD5Final(Result, Context); +End; + +Function MD5DigestCompare(Const Digest1, Digest2: TMD5Digest): Boolean; +Begin + Result := False; + If Digest1.A <> Digest2.A Then Exit; + If Digest1.B <> Digest2.B Then Exit; + If Digest1.C <> Digest2.C Then Exit; + If Digest1.D <> Digest2.D Then Exit; + Result := True; +End; + +End. diff --git a/plugins/MirandaNGHistoryToDB/MapStream.pas b/plugins/MirandaNGHistoryToDB/MapStream.pas new file mode 100644 index 0000000000..af0b67409a --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/MapStream.pas @@ -0,0 +1,185 @@ +{ ############################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.5 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ############################################################################ } + +//*****************************************************************// +// // +// TMapStream // +// Copyright BrandsPatch LLC // +// http://www.explainth.at // +// // +// All Rights Reserved // +// // +// Permission is granted to use, modify and redistribute // +// the code in this Delphi unit on the condition that this // +// notice is retained unchanged. // +// // +// BrandsPatch declines all responsibility for any losses, // +// direct or indirect, that may arise as a result of using // +// this code. // +// // +//*****************************************************************// +unit MapStream; + +interface + +uses Windows, SysUtils, Classes, SyncObjs; + +const MAXINTMINUS = MAXINT - 1; + +type TMapBytes = array[0..MAXINTMINUS] of Byte; + PMapBytes = ^TMapBytes; + +type TMapStream = class(TObject) +private + FHandle: THandle; + FPosition: Integer; + FSize: Integer; + FTimeOut: Integer; + procedure SetPosition(Value: Integer); + function CountGood(Count: Integer):Boolean; + function GrabEvent: Boolean; + procedure ReleaseEvent; +protected + FEvent: TEvent; + FMemory: PMapBytes; +public + property Position: Integer read FPosition write SetPosition; + constructor CreateEx(const AName: String; ASize,ATimeOut: Integer); + destructor Destroy; override; + function Clear: Boolean; + function CopyFrom(AStream: TStream;Count: Integer): Boolean; + function ReadBuffer(P: Pointer; Count: Integer): Boolean; + function WriteBuffer(P: Pointer; Count: Integer): Boolean; +end; + +type ENoMapping = class(Exception); + +implementation + +// MapStream Create & Destroy +constructor TMapStream.CreateEx(const AName:String;ASize,ATimeOut:Integer); +begin + inherited Create; + FSize := ASize; + FTimeOut := ATimeOut; + if (FSize < 1) or (FSize > MAXINTMINUS) then FSize:=MAXWORD; + if (FTimeOut < 1) or (FTimeOut > 5000) then FTimeOut:=2000; + //2000ms timeout for safety + FHandle:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,FSize,PChar(AName)); + //See the Windows Kernel32 CreateFileMapping function for information + if (FHandle = 0) then ENoMapping.Create(Format('%s file mapping failed.',[AName])) + else begin + FMemory:=MapViewOfFile(FHandle,FILE_MAP_ALL_ACCESS,0,0,0); + + FEvent:=TEvent.Create(nil,True,True,Format('ExplainThat_%s_MAP',[AName])); + {1. map a view of the file mapping into the address + space of the parent application + + 2. create an event to prevent simultaneous access + to the map by different apps. We try to make the + event name unique so we don't end up with a handle to + an unrelated event that already exists + } + end; +end; + +destructor TMapStream.Destroy; +begin + UnMapViewOfFile(FMemory); + CloseHandle(FHandle); + FEvent.Free; + inherited; +end; + +function TMapStream.CountGood(Count:Integer):Boolean; +begin + Result:=(FPosition + Count < FSize); +end; + +function TMapStream.GrabEvent:Boolean; +begin + Result:=True; + with FEvent do + begin + case WaitFor(FTimeOut) of + wrSignaled:ReSetEvent; + {locks the event for exclusive use by this app. Funny name, ReSetEvent, not + our choice!} + else Result:=False; + end; + end; +end; + +procedure TMapStream.ReleaseEvent; +begin + FEvent.SetEvent; //unlock the event so other apps can use it +end; + +// MapStream Manipulation +function TMapStream.Clear:Boolean; +begin + if GrabEvent then + try + FillChar(FMemory^[0],FSize,0); + FPosition:=0; + Result:=True; + finally ReleaseEvent end else Result:=False; +end; + +function TMapStream.CopyFrom(AStream:TStream;Count:Integer):Boolean; + + function SizeGood:Boolean; + var i,ASize:Integer; + begin + ASize:=AStream.Size; + if (Count = 0) or (Count > ASize) then + begin + Count:=ASize; + AStream.Position:=0; + end; + Result:=(FPosition + Count < FSize); + {make sure the copy block is not too big. Incidentally, also make Count = 0 + as in Delphi.TStream} + end; + +begin + if SizeGood and GrabEvent then + try + AStream.ReadBuffer(Byte(FMemory^[FPosition]),Count); + Result:=True; + finally ReleaseEvent end else Result:=False; +end; + +function TMapStream.ReadBuffer(P:Pointer;Count:Integer):Boolean; +begin + if CountGood(Count) and GrabEvent then + try + Move(FMemory^[FPosition],P^,Count); + inc(FPosition,Count); + Result:=True; + finally ReleaseEvent end else Result:=False; +end; + +function TMapStream.WriteBuffer(P:Pointer;Count:Integer):Boolean; +begin + if CountGood(Count) and GrabEvent then + try + Move(P^,FMemory^[FPosition],Count); + inc(FPosition,Count); + Result:=True; + finally ReleaseEvent end else Result:=False; +end; + +procedure TMapStream.SetPosition(Value:Integer); +begin + if (Value < FSize) and (Value >= 0) then FPosition:=Value; +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/Menu.pas b/plugins/MirandaNGHistoryToDB/Menu.pas new file mode 100644 index 0000000000..15d51a11b7 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/Menu.pas @@ -0,0 +1,326 @@ +{ ################################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.5 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ################################################################################ } + +unit Menu; + +{$I jedi.inc} + +interface + +uses + Windows, Classes, SysUtils, ShellApi, MsgExport, m_api, Database, Global; + +type + TMenuItem = record + Name: String; + Icon: String; + Position: Integer; + Proc: TMIRANDASERVICEPARAM; + Flags: DWord; + end; + +var + MainMenuItems: Array [1..9] of TMenuItem; + MainMenuHandle: Array [1..9] of THandle; + MenuHandle: Array [1..9] of THandle; + ChildExport: TExportForm; + +procedure MenuMainItemsInit; cdecl; forward; +procedure RebuildMainMenu; cdecl; forward; +{$ifdef DELPHIXE_UP} +function MainMenuSync(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward; +function MainMenuGetContactList(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward; +function MainMenuCheckUpdate(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward; +function MainMenuExportAllHistory(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward; +function MainMenuCheckMD5Hash(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward; +function MainMenuCheckAndDeleteMD5Hash(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward; +function MainMenuUpdateContactList(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward; +function MainMenuSettings(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward; +function MainMenuAbout(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward; +{$ELSE} +function MainMenuSync(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward; +function MainMenuGetContactList(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward; +function MainMenuCheckUpdate(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward; +function MainMenuExportAllHistory(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward; +function MainMenuCheckMD5Hash(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward; +function MainMenuCheckAndDeleteMD5Hash(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward; +function MainMenuUpdateContactList(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward; +function MainMenuSettings(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward; +function MainMenuAbout(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward; +{$endif DELPHIXE_UP} + +implementation + +uses Contacts, About, FSMonitor; + +{ } +procedure MenuMainItemsInit; +begin + MainMenuItems[1].Name := WideStringToString(GetLangStr('SyncButton'), CP_ACP); + MainMenuItems[1].Icon := 'ICON_0'; + MainMenuItems[1].Position := 000000; + MainMenuItems[1].Proc := MainMenuSync; + + MainMenuItems[2].Name := WideStringToString(GetLangStr('ExportAllHistoryButton'), CP_ACP); + MainMenuItems[2].Icon := ''; + MainMenuItems[2].Position := 100000; + MainMenuItems[2].Proc := MainMenuExportAllHistory; + + MainMenuItems[3].Name := WideStringToString(GetLangStr('GetContactListButton'), CP_ACP); + MainMenuItems[3].Icon := ''; + MainMenuItems[3].Position := 100001; + MainMenuItems[3].Proc := MainMenuGetContactList; + + MainMenuItems[4].Name := WideStringToString(GetLangStr('CheckMD5Hash'), CP_ACP); + MainMenuItems[4].Icon := ''; + MainMenuItems[4].Position := 100002; + MainMenuItems[4].Proc := MainMenuCheckMD5Hash; + + MainMenuItems[5].Name := WideStringToString(GetLangStr('CheckAndDeleteMD5Hash'), CP_ACP); + MainMenuItems[5].Icon := ''; + MainMenuItems[5].Position := 100003; + MainMenuItems[5].Proc := MainMenuCheckAndDeleteMD5Hash; + + MainMenuItems[6].Name := WideStringToString(GetLangStr('UpdateContactListButton'), CP_ACP); + MainMenuItems[6].Icon := ''; + MainMenuItems[6].Position := 100004; + MainMenuItems[6].Proc := MainMenuUpdateContactList; + + MainMenuItems[7].Name := WideStringToString(GetLangStr('CheckUpdateButton'), CP_ACP); + MainMenuItems[7].Icon := ''; + MainMenuItems[7].Position := 100004; + MainMenuItems[7].Proc := MainMenuCheckUpdate; + + MainMenuItems[8].Name := WideStringToString(GetLangStr('SettingsButton'), CP_ACP); + MainMenuItems[8].Icon := ''; + MainMenuItems[8].Position := 200000; + MainMenuItems[8].Proc := MainMenuSettings; + + MainMenuItems[9].Name := WideStringToString(GetLangStr('AboutButton'), CP_ACP); + MainMenuItems[9].Icon := ''; + MainMenuItems[9].Position := 300000; + MainMenuItems[9].Proc := MainMenuAbout; +end; + +{ } +procedure RebuildMainMenu; +var + I: Integer; + Mi: TCListMenuItem; +begin + // + MenuMainItemsInit; + // + for I := Low(MenuHandle) to High(MenuHandle) do + begin + ZeroMemory(@Mi, SizeOf(Mi)); + Mi.cbSize := SizeOf(Mi); + Mi.flags := CMIM_FLAGS; + Mi.flags := Mi.flags or CMIM_NAME; + Mi.szName.a := pAnsiChar(AnsiString(MainMenuItems[I].Name)); + CallService(MS_CLIST_MODIFYMENUITEM, MenuHandle[I], Windows.LPARAM(@Mi)); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - RebuildMainMenu: ' + 'MainMenuName = ' + MainMenuItems[I].Name, 2); + end; +end; + +{ } +{$ifdef DELPHIXE_UP} +function MainMenuSync(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; +{$ELSE} +function MainMenuSync(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; +{$endif DELPHIXE_UP} +begin + Result := 0; + OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '002'); +end; + +{ } +{$ifdef DELPHIXE_UP} +function MainMenuExportAllHistory(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; +{$ELSE} +function MainMenuExportAllHistory(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; +{$endif DELPHIXE_UP} +begin + Result := 0; + if ExportFormDestroy then + ChildExport := TExportForm.Create(nil); + if not ChildExport.Showing then + ChildExport.Show + else + ChildExport.BringFormToFront(ChildExport); +end; + +{ } +{$ifdef DELPHIXE_UP} +function MainMenuGetContactList(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; +{$ELSE} +function MainMenuGetContactList(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; +{$endif DELPHIXE_UP} +var + hContact: Cardinal; + ContactProto, ContactID, ContactName, GroupName: AnsiString; + AccountCount: Integer; + AccountName: ^PPROTOACCOUNT; +begin + // + hContact := CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while hContact <> 0 do + begin + ContactProto := GetContactProto(hContact); + ContactID := GetContactID(hContact, ContactProto); + ContactName := GetContactDisplayName(hContact, '', True); + GroupName := GetDBStr(hContact , 'CList' , 'Group' , GetLangStr('ContactNotInTheList')); + if ContactName = '' then + ContactName := TranslateW('Unknown Contact'); + if ContactID = '' then + ContactID := TranslateW('Unknown Contact'); + if not ((MatchStrings(LowerCase(ContactProto), 'skype*')) or (ContactID = TranslateW('Unknown Contact')) or MatchStrings(LowerCase(ContactProto), 'metacontacts*')) then + WriteInLog(ProfilePath, Format('%s;%s;%s;%d', [ContactID, ContactName, GroupName, StrContactProtoToInt(ContactProto)]), 3); + hContact := CallService(MS_DB_CONTACT_FINDNEXT, hContact, 0); + end; + AccountCount := 0; + // ProtoList.csv + if (CallService(MS_PROTO_ENUMACCOUNTS, Integer(@AccountCount), Integer(@AccountName)) = 0) and (AccountCount <> 0) then + begin + while AccountCount > 0 do + begin + if not((AccountName^.szModuleName = 'MetaContacts') or (MatchStrings(LowerCase(AccountName^.szModuleName), 'skype*'))) then + //if not MatchStrings(LowerCase(AccountName^.szModuleName), 'skype*') then + WriteInLog(ProfilePath, Format('%s;%s;%d;%s;%s;%s', [AccountName^.szModuleName, GetMyContactID(AccountName^.szModuleName), StrContactProtoToInt(AccountName^.szProtoName), GetMyContactDisplayName(AccountName^.szModuleName), '', '']), 4); + Inc(AccountName); + Dec(AccountCount); + end; + end; + // + if ContactListLogOpened then + CloseLogFile(3); + if ProtoListLogOpened then + CloseLogFile(4); + Result := 0; + if (FileExists(ProfilePath + ContactListName)) and (FileExists(ProfilePath + ProtoListName)) then + MsgInf(htdPluginShortName, GetLangStr('SaveContactListCompleted')) + else + MsgInf(htdPluginShortName, GetLangStr('SaveContactListErr')); +end; + +{ MD5- } +{$ifdef DELPHIXE_UP} +function MainMenuCheckMD5Hash(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; +{$ELSE} +function MainMenuCheckMD5Hash(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; +{$endif DELPHIXE_UP} +begin + Result := 0; + OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '0050'); +end; + +{ MD5- } +{$ifdef DELPHIXE_UP} +function MainMenuCheckAndDeleteMD5Hash(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; +{$ELSE} +function MainMenuCheckAndDeleteMD5Hash(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; +{$endif DELPHIXE_UP} +begin + Result := 0; + OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '0051'); +end; + +{ } +{$ifdef DELPHIXE_UP} +function MainMenuUpdateContactList(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; +{$ELSE} +function MainMenuUpdateContactList(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; +{$endif DELPHIXE_UP} +begin + Result := 0; + if FileExists(ProfilePath+ContactListName) then + OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '007') + else + MsgInf(htdPluginShortName, Format(GetLangStr('SendUpdateContactListErr'), [ContactListName])); +end; + +{ } +{$ifdef DELPHIXE_UP} +function MainMenuCheckUpdate(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; +{$ELSE} +function MainMenuCheckUpdate(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; +{$endif DELPHIXE_UP} +var + WinName: String; +begin + // HistoryToDBUpdater + WinName := 'HistoryToDBUpdater'; + if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater , + begin + WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')'; + if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater , + begin + if FileExists(PluginPath + 'HistoryToDBUpdater.exe') then + begin + // + ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBUpdater.exe'), PWideChar(' "'+ProfilePath+'"'), nil, SW_SHOWNORMAL); + end + else + MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_UPDATER'), [PluginPath + 'HistoryToDBUpdater.exe'])); + end + else // + OnSendMessageToOneComponent(WinName, '0040'); + end + else // + OnSendMessageToOneComponent(WinName, '0040'); +end; + +{ } +{$ifdef DELPHIXE_UP} +function MainMenuSettings(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; +{$ELSE} +function MainMenuSettings(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; +{$endif DELPHIXE_UP} +var + WinName: String; +begin + Result := 0; + // HistoryToDBViewer + WinName := 'HistoryToDBViewer'; + if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBViewer , + begin + WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')'; + if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBViewer , + begin + if FileExists(PluginPath + 'HistoryToDBViewer.exe') then + begin + // + StopWatch; + WriteCustomINI(ProfilePath, 'SettingsFormRequestSend', '1'); + StartWatch(ProfilePath, FILE_NOTIFY_CHANGE_LAST_WRITE, False, @ProfileDirChangeCallBack); + ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'" 4'), nil, SW_SHOWNORMAL); + end + else + MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_VIEWER'), [PluginPath + 'HistoryToDBViewer.exe'])); + end + else // + OnSendMessageToOneComponent(WinName, '005'); + end + else // + OnSendMessageToOneComponent(WinName, '005'); +end; + +{ } +{$ifdef DELPHIXE_UP} +function MainMenuAbout(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; +{$ELSE} +function MainMenuAbout(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; +{$endif DELPHIXE_UP} +begin + Result := 0; + AboutForm.Show; +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dpr b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dpr new file mode 100644 index 0000000000..3f59234df9 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dpr @@ -0,0 +1,935 @@ +{ ############################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.5 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ############################################################################ } + +library MirandaNGHistoryToDB; + +{$I Global.inc} + +uses + madExcept, + madLinkDisAsm, + madListHardware, + madListProcesses, + madListModules, + m_api, + Windows, + SysUtils, + XMLIntf, + XMLDoc, + ShellApi, + WideStrUtils, + JclStringConversions, + Contacts in 'Contacts.pas', + Database in 'Database.pas', + Menu in 'Menu.pas', + About in 'About.pas', + MsgExport in 'MsgExport.pas' {ExportForm}, + Global in 'Global.pas', + FSMonitor in 'FSMonitor.pas', + MapStream in 'MapStream.pas'; + +// use it to make plugin unicode-aware +{$DEFINE UNICODE} + +// tell Miranda about this plugin ExVersion +function MirandaPluginInfoEx(mirandaVersion:DWORD): PPLUGININFOEX; cdecl; +begin + PluginInfo.cbSize:= SizeOf(TPLUGININFOEX); + PluginInfo.shortName:= htdPluginShortName; + PluginInfo.version:= htdVersion; + PluginInfo.description:= htdDescription_EN; + PluginInfo.author:= htdAuthor_EN; + PluginInfo.authorEmail:= htdAuthorEmail; + PluginInfo.copyright:= htdCopyright_EN; + PluginInfo.homepage:= htdHomePageURL; + PluginInfo.flags:= UNICODE_AWARE; + PluginInfo.uuid:= MIID_HISTORYTODBDLL; + Result := @PluginInfo; +end; + +var + {$ifdef REPLDEFHISTMOD} + PluginInterfaces: array[0..1] of TGUID; + {$else} + PluginInterfaces: array[0..0] of TGUID; + {$endif REPLDEFHISTMOD} + + PluginStatus: Boolean = False; + StartExport: Boolean = False; + StartUpdate: Boolean = False; + DefaultINICopy: Boolean = False; + + HookModulesLoad, + HookBuildMenu, + HookContactMenu, + HookSystemHistoryMenu, + {$ifdef REPLDEFHISTMOD} + HookShowMainHistory, + {$endif REPLDEFHISTMOD} + HookEventAdded, + //HookTTBLoaded, + HookShowHistoryAPI, + HookShowContactHistoryAPI, + HookShowVersionAPI: THandle; + //hTTBButton: THandle = 0; + DialogMainWindow: HWND = 0; + +const + hLangpack: THANDLE = 0; + +function OnModulesLoad(awParam:WPARAM; alParam:LPARAM): Integer; cdecl; forward; +function OnBuildContactMenu(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; forward; +function OnEventAdded(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; forward; +//function OnTTBLoaded(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; forward; +function OpenHistoryWindow(wParam:WPARAM;lParam:LPARAM): Integer; cdecl; forward; + +// tell Miranda about supported interfaces +function MirandaPluginInterfaces:PMUUID; cdecl; +begin + {$ifdef REPLDEFHISTMOD} + PluginInterfaces[0]:=MIID_UIHISTORY; + PluginInterfaces[1]:=MIID_LAST; + {$else} + PluginInterfaces[0]:=MIID_LAST; + {$endif REPLDEFHISTMOD} + Result := @PluginInterfaces; +end; + +{ } +function OpenHistoryWindow(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; +var + ContactProto, ContactID, ContactName: AnsiString; + MyContactName, MyContactID: AnsiString; + ProtoType: Integer; + WinName: String; +begin + Result := 0; + ContactProto := GetContactProto(wParam); + ContactID := GetContactID(wParam, ContactProto); + ContactName := GetContactDisplayName(wParam, '', True); + MyContactName := GetMyContactDisplayName(ContactProto); + MyContactID := GetMyContactID(ContactProto); + if ContactID = '' then + ContactID := TranslateW('Unknown Contact'); + if ContactName = '' then + ContactName := TranslateW('Unknown Contact'); + if MyContactID = '' then + MyContactID := TranslateW('Unknown Contact'); + if MyContactName = '' then + MyContactName := TranslateW('Unknown Contact'); + // . + if ContactProto = MyAccount then + ContactProto := 'ICQ'; + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - PluginContactMenuCommand: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName, 2); + // + ProtoType := StrContactProtoToInt(ContactProto); + // N + WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')'; + if SearchMainWindow(pWideChar(WinName)) then + begin + // : + // : + // 008|0|UserID|UserName|ProtocolType + // : + // 008|2|ChatName + OnSendMessageToOneComponent(WinName, '008|0|'+ContactID+'|'+ContactName+'|'+IntToStr(ProtoType)); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - PluginContactMenuCommand: - 008|0|'+ContactID+'|'+ContactName+'|'+IntToStr(ProtoType), 2); + end + else + begin + if FileExists(PluginPath + 'HistoryToDBViewer.exe') then + begin + if MatchStrings(LowerCase(ContactProto), 'skype*') then // Skype + begin + // ( -) + Glogal_History_Type := 2; + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - PluginContactMenuCommand: ' + PluginPath + 'HistoryToDBViewer.exe' + ' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactName+'"', 2); + ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactName+'"'), nil, SW_SHOWNORMAL); + end + else + begin + // ( IM-) + Glogal_History_Type := 0; + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - PluginContactMenuCommand: ' + PluginPath + 'HistoryToDBViewer.exe' + ' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactID+'" "'+ContactName+'" '+IntToStr(ProtoType), 2); + ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactID+'" "'+ContactName+'" '+IntToStr(ProtoType)), nil, SW_SHOWNORMAL); + end; + end + else + MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_VIEWER'), [PluginPath + 'HistoryToDBViewer.exe'])); + end; +end; + +{ } +function OnBuildContactMenu(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; +var + MenuItem: TCLISTMENUITEM; + ContactProto, ContactID, ContactName: AnsiString; +begin + Result := 0; + ContactProto := GetContactProto(awParam); + // + ZeroMemory(@MenuItem, SizeOf(MenuItem)); + MenuItem.cbSize := SizeOf(MenuItem); + MenuItem.flags := CMIM_FLAGS; + if (ContactProto = MyAccount) or + MatchStrings(LowerCase(ContactProto), 'icq*') or + MatchStrings(LowerCase(ContactProto), 'jabber*') or + MatchStrings(LowerCase(ContactProto), 'aim*') or + MatchStrings(LowerCase(ContactProto), 'irc*') or + MatchStrings(LowerCase(ContactProto), 'msn*') or + MatchStrings(LowerCase(ContactProto), 'yahoo*') or + MatchStrings(LowerCase(ContactProto), 'gadu*') or + MatchStrings(LowerCase(ContactProto), 'skype*') or + MatchStrings(LowerCase(ContactProto), 'vkonta*') then + begin // + ContactID := GetContactID(awParam, ContactProto); + ContactName := GetContactDisplayName(awParam, '', True); + if ContactName = '' then + ContactName := TranslateW('Unknown Contact'); + if ContactID = '' then + ContactID := TranslateW('Unknown Contact'); + // . + if ContactProto = MyAccount then + ContactProto := 'ICQ'; + MenuItem.flags := MenuItem.flags or CMIM_NAME; + MenuItem.szName.a := pAnsiChar(AnsiString(Format(WideStringToString(GetLangStr('ShowContactHistory'), CP_ACP), [ContactName, ContactID]))); + CallService(MS_CLIST_MODIFYMENUITEM, HookContactMenu, lParam(@MenuItem)); + if EnableDebug then // + WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnBuildContactMenu: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto, 2); + end + else // + begin + MenuItem.flags := MenuItem.flags or CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, HookContactMenu, lParam(@MenuItem)); + if EnableDebug then // + begin + ContactID := GetContactID(awParam, ContactProto); + ContactName := GetContactDisplayName(awParam, '', True); + if ContactName = '' then + ContactName := TranslateW('Unknown Contact'); + if ContactID = '' then + ContactID := TranslateW('Unknown Contact'); + // . + if ContactProto = MyAccount then + ContactProto := 'ICQ'; + WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnBuildContactMenu: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto, 2); + end; + end; +end; + +{ } +function OnEventAdded(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; +var + ContactProto, ContactID, ContactName: AnsiString; + MyContactName, MyContactID: AnsiString; + BlobSize, ProtoType: Integer; + DBEventInfo: TDBEventInfo; + msgA: PAnsiChar; + msgW: PChar; + msgLen, LenW: Cardinal; + I: Integer; + Msg_RcvrNick, Msg_RcvrAcc, Msg_SenderNick, Msg_SenderAcc, Msg_Text, MD5String: WideString; + Date_Str, MsgStatus: String; + InsertSQLData, EncInsertSQLData, WinName: String; + ASize: Integer; + hContact: THandle; +begin + Result := 0; + ZeroMemory(@DBEventInfo, SizeOf(DBEventInfo)); + DBEventInfo.cbSize := SizeOf(DBEventInfo); + DBEventInfo.pBlob := nil; + BlobSize := CallService(MS_DB_EVENT_GETBLOBSIZE, lParam, 0); + GetMem(DBEventInfo.pBlob, BlobSize); + DBEventInfo.cbBlob := BlobSize; + if (CallService(MS_DB_EVENT_GET, lParam, Integer(@DBEventInfo)) = 0) and (DBEventInfo.eventType = EVENTTYPE_MESSAGE and EVENTTYPE_URL) then + begin + // + msgA := PAnsiChar(DBEventInfo.pBlob); + msgW := nil; + msgLen := lstrlenA(PAnsiChar(DBEventInfo.pBlob)) + 1; + if msgLen > DBEventInfo.cbBlob then + msgLen := DBEventInfo.cbBlob; + if Boolean(DBEventInfo.flags and DBEF_UTF) then + begin + SetLength(Msg_Text, msgLen); + LenW := Utf8ToWideChar(PChar(Msg_Text), msgLen, msgA, msgLen - 1, CP_ACP); + if Integer(LenW) > 0 then + SetLength(Msg_Text, LenW - 1) + else + Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1); + end + else + begin + LenW := 0; + if DBEventInfo.cbBlob >= msgLen * SizeOf(Char) then + begin + msgW := PChar(msgA + msgLen); + for i := 0 to ((DBEventInfo.cbBlob - msgLen) div SizeOf(Char)) - 1 do + if msgW[i] = #0 then + begin + LenW := i; + Break; + end; + end; + if (LenW > 0) and (LenW < msgLen) then + SetString(Msg_Text, msgW, LenW) + else + Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1); + end; + // + hContact := wParam; + ContactProto := GetContactProto(hContact); + ProtoType := StrContactProtoToInt(ContactProto); + // , + // .. + if ProtoType = 15 then + Exit; + // + ContactID := GetContactID(hContact, ContactProto); + ContactName := GetContactDisplayName(hContact, '', True); + // + MyContactName := GetMyContactDisplayName(ContactProto); + MyContactID := GetMyContactID(ContactProto); + // . + if ContactProto = MyAccount then + ContactProto := 'ICQ'; + ProtoType := StrContactProtoToInt(ContactProto); + // End + if ContactID = '' then + ContactID := TranslateW('Unknown Contact'); + if ContactName = '' then + ContactName := TranslateW('Unknown Contact'); + if MyContactID = '' then + MyContactID := TranslateW('Unknown Contact'); + if MyContactName = '' then + MyContactName := TranslateW('Unknown Contact'); + // MyContactID ContactName + // + {if (ProtoType = 15) and (MyContactID = TranslateW('Unknown Contact')) and (MyContactName <> TranslateW('Unknown Contact')) then + MyContactID := MyContactName; + if (ProtoType = 15) and (ContactName = TranslateW('Unknown Contact')) and (ContactID <> TranslateW('Unknown Contact')) then + ContactName := ContactID;} + // , .. + Msg_SenderNick := PrepareString(pWideChar(AnsiToWideString(MyContactName, CP_ACP))); + Msg_SenderAcc := PrepareString(pWideChar(AnsiToWideString(MyContactID, CP_ACP))); + Msg_SenderNick := WideStringToUTF8(Msg_SenderNick); + Msg_SenderAcc := WideStringToUTF8(Msg_SenderAcc); + Msg_RcvrNick := PrepareString(pWideChar(AnsiToWideString(ContactName, CP_ACP))); + Msg_RcvrAcc := PrepareString(pWideChar(AnsiToWideString(ContactID, CP_ACP))); + Msg_RcvrNick := WideStringToUTF8(Msg_RcvrNick); + Msg_RcvrAcc := WideStringToUTF8(Msg_RcvrAcc); + Msg_Text := WideStringToUTF8(PrepareString(pWideChar(Msg_Text))); + MD5String := Msg_RcvrAcc + FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + Msg_Text; + if (DBType = 'oracle') or (DBType = 'oracle-9i') then + Date_Str := FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + else + Date_Str := FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)); + if MatchStrings(LowerCase(ContactProto), 'skype*') then + begin + // ( ) + if (DBEventInfo.flags and DBEF_SENT) = 0 then + MsgStatus := '0' // + else + MsgStatus := '1'; // + // + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2); + if (MatchStrings(DBType, 'oracle*')) then // Oracle, SQL- CHAT_MSG_LOG_ORACLE + InsertSQLData := Format(CHAT_MSG_LOG_ORACLE, [DBUserName, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]) + else + InsertSQLData := Format(CHAT_MSG_LOG, [DBUserName, MsgStatus, Date_Str, Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]); + end + else + begin + // ( ) + if (DBEventInfo.flags and DBEF_SENT) = 0 then + MsgStatus := '1' // + else + MsgStatus := '0'; // + // + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2); + if (MatchStrings(DBType, 'oracle*')) then // Oracle, SQL- MSG_LOG_ORACLE + InsertSQLData := Format(MSG_LOG_ORACLE, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_Text, EncryptMD5(MD5String)]) + else + InsertSQLData := Format(MSG_LOG, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, Date_Str, Msg_Text, EncryptMD5(MD5String)]); + end; + // MMF + if SyncMethod = 0 then + begin + WinName := 'HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')'; + if SearchMainWindow(pWideChar(WinName)) then + begin + EncInsertSQLData := EncryptStr(InsertSQLData); + ASize := 2*Length(EncInsertSQLData); + with FMap do + begin + Clear; + WriteBuffer(@ASize,Sizeof(Integer)); + WriteBuffer(PChar(EncInsertSQLData),ASize); + end; + // , + OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '010'); + end + else + WriteInLog(ProfilePath, InsertSQLData, 0); + end + else // SQL- + WriteInLog(ProfilePath, InsertSQLData, 0); + // + if SyncMethod = 2 then + begin + if (SyncInterval > 4) and (SyncInterval < 8) then + begin + Inc(MessageCount); + if (SyncInterval = 5) and (MessageCount = 10) then + begin + OnSendMessageToAllComponent('002'); + MessageCount := 0; + end; + if (SyncInterval = 6) and (MessageCount = 20) then + begin + OnSendMessageToAllComponent('002'); + MessageCount := 0; + end; + if (SyncInterval = 7) and (MessageCount = 30) then + begin + OnSendMessageToAllComponent('002'); + MessageCount := 0; + end; + end; + if SyncInterval = 9 then + begin + Inc(MessageCount); + if MessageCount = SyncMessageCount then + begin + OnSendMessageToAllComponent('002'); + MessageCount := 0; + end; + end; + end; + end; +end; + +{function OnTTBLoaded(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; +var + TTB: TTBButtonV2; +begin + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnTTBLoaded', 2); + if hTTBButton <> 0 then + begin + if ServiceExists(MS_TTB_REMOVEBUTTON)>0 then + begin + CallService(MS_TTB_REMOVEBUTTON, WPARAM(hTTBButton),0); + hTTBButton := 0; + end; + end; + if ShowPluginButton then + begin + if ServiceExists(MS_TTB_ADDBUTTON) > 0 then + begin + ZeroMemory(@TTB, SizeOf(TTB)); + TTB.cbSize := SizeOf(TTB); + TTB.pszServiceUp := MHTD_SHOWSERVICE; + TTB.pszServiceDown:= MHTD_SHOWSERVICE; + TTB.hIconUp := LoadImage(hInstance, 'ICON_0', IMAGE_ICON, 16, 16, 0); + TTB.hIconDn := ttb.hIconUp; + TTB.dwFlags := TTBBF_VISIBLE; + TTB.name := htdDBName; + hTTBButton := CallService(MS_TTB_ADDBUTTON, WPARAM(@TTB), 0); + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnTTBLoaded: .', 2); + end; + end; + Result := 0; +end;} + +{ C MS_MHTD_SHOWHISTORY + m_historytodb.inc } +function HTDBShowHistory(wParam { 0 } : WPARAM; lParam { 0 } : LPARAM): int_ptr; cdecl; +var + WinName: String; +begin + Result := 0; + // HistoryToDBViewer + WinName := 'HistoryToDBViewer'; + if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBViewer , + begin + WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')'; + if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBViewer , + begin + if FileExists(PluginPath + 'HistoryToDBViewer.exe') then + begin + ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'"'), nil, SW_SHOWNORMAL); + end + else + MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_VIEWER'), [PluginPath + 'HistoryToDBViewer.exe'])); + end + else // + OnSendMessageToOneComponent(WinName, '0040'); + end + else // + OnSendMessageToOneComponent(WinName, '0040'); +end; + +{ C MS_MHTD_SHOWCONTACTHISTORY + m_historytodb.inc } +function HTDBShowContactHistory(wParam { hContact } : WPARAM; lParam { 0 } : LPARAM): int_ptr; cdecl; +begin + Result := OpenHistoryWindow(wParam, 0); +end; + +{ C MS_MHTD_GETVERSION + m_historytodb.inc } +function HTDBGetVersion(wParam { 0 } : WPARAM; lParam { 0 } : LPARAM): int_ptr; cdecl; +begin + Result := htdVersion; +end; + +function OnModulesLoad(awParam{0}:WPARAM; alParam{0}:LPARAM):integer; cdecl; +var + Mi: TCListMenuItem; + //{$ifdef REPLDEFHISTMOD} + Si: TCListMenuItem; + //{$endif REPLDEFHISTMOD} + AutoCoreLang, UpdTmpPath, WinName: String; + I: Byte; + MenuMainService: PAnsiChar; + //IMUPD: TUpdate; +begin + // - + MsgLogOpened := False; + ErrLogOpened := False; + DebugLogOpened := False; + ContactListLogOpened := False; + ProtoListLogOpened := False; + ImportLogOpened := False; + // + EncryptInit; + // + if FileExists(ExtractFilePath(ParamStr(0))+'Langpack_russian.txt') then + AutoCoreLang := 'Russian' + else + AutoCoreLang := 'English'; + // + OnSendMessageToAllComponent('003'); + // + if FileExists(PluginPath + DefININame) then + begin + if FileExists(ProfilePath + ININame) then + RenameFile(ProfilePath + ININame, ProfilePath + ININame + '.' + FormatDateTime('ddmmyyhhmmss', Now)); + if CopyFileEx(PChar(PluginPath + DefININame), PChar(ProfilePath + ININame), nil, nil, nil, COPY_FILE_FAIL_IF_EXISTS) then + begin + DefaultINICopy := True; + if FileExists(ProfilePath + ININame) then + DeleteFile(PluginPath + DefININame); + end; + end; + // + if (GetDBInt(htdDBName, 'FirstRun.FirstActivate', 0) = 0) or (DefaultINICopy) then + begin + if AutoCoreLang = 'Russian' then + begin + case MessageBox(DialogMainWindow, PWideChar(' ' + htdPluginShortName + '.' + #13 + + ' .' + #13 + + ' ?'), PWideChar(htdPluginShortName),36) of + 6: StartExport := True; // + 7: StartExport := False; // + end; + end + else + begin + case MessageBox(DialogMainWindow, PWideChar('The first time you activate the plugin ' + htdPluginShortName + '.' + #13 + + 'To work correctly, check your plug-in connection to the database.' + #13 + + 'Do you want to start exporting the history?'), PWideChar(htdPluginShortName),36) of + 6: StartExport := True; // + 7: StartExport := False; // + end; + end; + end; + // + if GetDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 0) = 0 then + begin + if AutoCoreLang = 'Russian' then + begin + //MsgInf(htdPluginShortName, ' ' + htdPluginShortName + '.' + #13 + ' .' + #13 + ' ' + htdPluginShortName + '.') + case MessageBox(DialogMainWindow, PWideChar(' ' + htdPluginShortName + '.' + #13 + + ' .' + #13 + + ' ?'), PWideChar(htdPluginShortName),36) of + 6: StartUpdate := True; // + 7: StartUpdate := False; // + end; + end + else + begin + //MsgInf(htdPluginShortName, 'The first time you activate the plugin ' + htdPluginShortName + '.' + #13 + 'To work correctly, check your plug-in connection to the database.' + #13 + 'Thank you for using the plugin ' + htdPluginShortName + '.'); + case MessageBox(DialogMainWindow, PWideChar('The first time you activate the plugin ' + htdPluginShortName + '.' + #13 + + 'To work correctly, the plugin must run the update plugin via the Internet.' + #13 + + 'Do you want to start the update process?'), PWideChar(htdPluginShortName),36) of + 6: StartUpdate := True; // + 7: StartUpdate := False; // + end; + end; + end; + // + if AutoCoreLang <> DefaultLanguage then + begin + CoreLanguage := AutoCoreLang; + WriteCustomINI(ProfilePath, 'DefaultLanguage', CoreLanguage); + end + else + CoreLanguage := DefaultLanguage; + // + LangDoc := NewXMLDocument(); + CoreLanguageChanged; + // IM + WriteCustomINI(ProfilePath, 'IMClientType', htdIMClientName); + WriteCustomINI(ProfilePath, 'IMClientPlatformType', htdPlatform); + // + WriteCustomINI(ProfilePath, 'SettingsFormRequestSend', '0'); + // About Export + if not Assigned(AboutForm) then + AboutForm := TAboutForm.Create(nil); + ExportFormDestroy := True; + // API - + HookShowHistoryAPI := CreateServiceFunction(MS_MHTD_SHOWHISTORY, @HTDBShowHistory); + // API - + HookShowContactHistoryAPI := CreateServiceFunction(MS_MHTD_SHOWCONTACTHISTORY, @HTDBShowContactHistory); + // API - + HookShowVersionAPI := CreateServiceFunction(MS_MHTD_GETVERSION, @HTDBGetVersion); + // + MenuMainItemsInit; + // + FillChar(Mi, SizeOf(Mi), 0); + Mi.cbSize := SizeOf(Mi); + Mi.szPopupName.a := '&' + htdPluginShortName; + Mi.popupPosition := 500000; + Mi.hIcon := LoadImage(hInstance,'ICON_0',IMAGE_ICON,16,16,0); + Mi.flags := 0; + for I := Low(MainMenuItems) to High(MainMenuItems) do + begin + if MainMenuItems[I].Icon = '' then + Mi.hIcon := 0 + else + Mi.hIcon := LoadImage(hInstance, pChar(MainMenuItems[I].Icon), IMAGE_ICON, 16, 16, 0); + Mi.szName.a := pAnsiChar(AnsiString(MainMenuItems[I].Name)); + MenuMainService := pAnsiChar(AnsiString(Format('%s/MainMenuCommand%d', [htdPluginShortName, I]))); + //if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - Load: ' + 'MenuMainName = ' + MenuMainItems[I].Name + ' | MenuMainService = ' + MenuMainService, 2); + MainMenuHandle[I] := CreateServiceFunctionParam(MenuMainService, @MainMenuItems[I].Proc, I); + Mi.pszService := MenuMainService; + Mi.Position := MainMenuItems[I].Position; + MenuHandle[I] := CallService(MS_CLIST_ADDMAINMENUITEM, 0, Windows.LPARAM(@Mi)); + end; + // + //{$ifdef REPLDEFHISTMOD} + FillChar(Si, SizeOf(Si), 0); + Si.cbSize := SizeOf(Si); + Si.Position := 500060000; + Si.szName.a := pAnsiChar(AnsiString(Format(WideStringToString(GetLangStr('IMButtonCaption'), CP_ACP), [htdPluginShortName]))); + Si.pszService := MS_MHTD_SHOWHISTORY;//MS_HISTORY_SHOWCONTACTHISTORY; + Si.hIcon := LoadImage(hInstance,'ICON_0',IMAGE_ICON,16,16,0);; + HookSystemHistoryMenu := CallService(MS_CLIST_ADDMAINMENUITEM,0,LPARAM(@Si)); + //{$endif REPLDEFHISTMOD} + // + CreateServiceFunction(htdPluginShortName+'/ContactMenuCommand', @OpenHistoryWindow); + Mi.pszContactOwner := nil; // + Mi.cbSize := SizeOf(Mi); + Mi.position := 1000090000; + Mi.flags := 0; + Mi.hIcon := LoadImage(hInstance,'ICON_0',IMAGE_ICON,16,16,0); + Mi.szName.a := pAnsiChar(WideStringToString(GetLangStr('ShowOneContactHistory'), CP_ACP)); + Mi.pszService := htdPluginShortName+'/ContactMenuCommand'; + HookContactMenu := CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, LPARAM(@Mi)); + // + HookBuildMenu := HookEvent(ME_CLIST_PREBUILDCONTACTMENU, OnBuildContactMenu); + // + HookEventAdded := HookEvent(ME_DB_EVENT_ADDED, OnEventAdded); + // + {$ifdef REPLDEFHISTMOD} + HookShowMainHistory := CreateServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY, @OpenHistoryWindow); + {$endif REPLDEFHISTMOD} + // TopToolBar + //HookTTBLoaded := HookEvent(ME_TTB_MODULELOADED, OnTTBLoaded); + // Register in updater + {if Boolean(ServiceExists(MS_UPDATE_REGISTER)) then + begin + ZeroMemory(@IMUPD,SizeOf(IMUPD)); + IMUPD.cbSize := SizeOf(IMUPD); + IMUPD.szComponentName := htdPluginShortName; + IMUPD.pbVersion := @hppVersionStr[1]; + IMUPD.cpbVersion := Length(hppVersionStr); + // File listing section + //IMUPD.szUpdateURL = UPDATER_AUTOREGISTER; + IMUPD.szUpdateURL := htdFLUpdateURL; + IMUPD.szVersionURL := htdFLVersionURL; + IMUPD.pbVersionPrefix := htdFLVersionPrefix; + IMUPD.cpbVersionPrefix := Length(htdFLVersionPrefix); + // Alpha-beta section + IMUPD.szBetaUpdateURL := htdUpdateURL; + IMUPD.szBetaVersionURL := htdVersionURL; + IMUPD.pbBetaVersionPrefix := htdVersionPrefix; + IMUPD.cpbBetaVersionPrefix := Length(htdVersionPrefix); + IMUPD.szBetaChangelogURL := htdChangelogURL; + CallService(MS_UPDATE_REGISTER, 0, LPARAM(@IMUPD)); + end;} + // dbeditor + CallService(MS_DBEDIT_REGISTERSINGLEMODULE, WPARAM(PAnsiChar(htdDBName)), 0); + { + FILE_NOTIFY_CHANGE_FILE_NAME = $00000001;// + FILE_NOTIFY_CHANGE_DIR_NAME = $00000002;// + FILE_NOTIFY_CHANGE_ATTRIBUTES = $00000004;// + FILE_NOTIFY_CHANGE_SIZE = $00000008;// + FILE_NOTIFY_CHANGE_LAST_WRITE = $00000010;// + FILE_NOTIFY_CHANGE_LAST_ACCESS = $00000020;// + FILE_NOTIFY_CHANGE_CREATION = $00000040;// + FILE_NOTIFY_CHANGE_SECURITY = $00000100;// + } + StartWatch(ProfilePath, FILE_NOTIFY_CHANGE_LAST_WRITE, False, @ProfileDirChangeCallBack); + // MMF + if SyncMethod = 0 then + FMap := TMapStream.CreateEx('HistoryToDB for ' + htdIMClientName + ' ('+MyAccount+')',MAXDWORD,2000); + // + PluginStatus := True; + // . + MessageCount := 0; + // + WriteDBInt(htdDBName, 'FirstRun.FirstActivate', 1); + // HistoryToDBUpdater.exe + UpdTmpPath := GetUserTempPath + 'IMHistory\'; + if FileExists(UpdTmpPath + 'HistoryToDBUpdater.exe') then + begin + // HistoryToDBUpdater + WinName := 'HistoryToDBUpdater'; + if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater , + begin + WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')'; + if SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater , + OnSendMessageToOneComponent(WinName, '009'); + end + else // + OnSendMessageToOneComponent(WinName, '009'); + Sleep(800); + // + if DeleteFile(PluginPath + 'HistoryToDBUpdater.exe') then + begin + if CopyFileEx(PChar(UpdTmpPath + 'HistoryToDBUpdater.exe'), PChar(PluginPath + 'HistoryToDBUpdater.exe'), nil, nil, nil, COPY_FILE_FAIL_IF_EXISTS) then + begin + DeleteFile(UpdTmpPath + 'HistoryToDBUpdater.exe'); + if CoreLanguage = 'Russian' then + MsgInf(htdPluginShortName, Format(' %s .', ['HistoryToDBUpdater.exe'])) + else + MsgInf(htdPluginShortName, Format('Update utility %s successfully updated.', ['HistoryToDBUpdater.exe'])); + end; + end + else + begin + DeleteFile(UpdTmpPath + 'HistoryToDBUpdater.exe'); + if CoreLanguage = 'Russian' then + MsgDie(htdPluginShortName, Format(' %s .', [PluginPath + 'HistoryToDBUpdater.exe'])) + else + MsgDie(htdPluginShortName, Format('Error update utility %s', [PluginPath + 'HistoryToDBUpdater.exe'])); + end; + end; + // HistoryToDBUpdater.exe + if FileExists(PluginPath + 'HistoryToDBUpdater.upd') then + begin + // HistoryToDBUpdater + WinName := 'HistoryToDBUpdater'; + if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater , + begin + WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')'; + if SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater , + OnSendMessageToOneComponent(WinName, '009'); + end + else // + OnSendMessageToOneComponent(WinName, '009'); + Sleep(800); + // + if DeleteFile(PluginPath + 'HistoryToDBUpdater.exe') then + begin + if CopyFileEx(PChar(PluginPath + 'HistoryToDBUpdater.upd'), PChar(PluginPath + 'HistoryToDBUpdater.exe'), nil, nil, nil, COPY_FILE_FAIL_IF_EXISTS) then + begin + DeleteFile(PluginPath + 'HistoryToDBUpdater.upd'); + if CoreLanguage = 'Russian' then + MsgInf(htdPluginShortName, Format(' %s .', ['HistoryToDBUpdater.exe'])) + else + MsgInf(htdPluginShortName, Format('Update utility %s successfully updated.', ['HistoryToDBUpdater.exe'])); + end; + end + else + begin + DeleteFile(PluginPath + 'HistoryToDBUpdater.upd'); + if CoreLanguage = 'Russian' then + MsgDie(htdPluginShortName, Format(' %s .', [PluginPath + 'HistoryToDBUpdater.exe'])) + else + MsgDie(htdPluginShortName, Format('Error update utility %s', [PluginPath + 'HistoryToDBUpdater.exe'])); + end; + end; + // + if StartUpdate then + begin + if FileExists(PluginPath + 'HistoryToDBUpdater.exe') then + begin + // + WriteDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 1); + // + ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBUpdater.exe'), PWideChar(' "'+ProfilePath+'"'), nil, SW_SHOWNORMAL); + end + else + MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_UPDATER'), [PluginPath + 'HistoryToDBUpdater.exe'])); + end + else + begin + // + if GetDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 0) = 0 then + WriteDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 1); // + end; + // + if StartExport then + begin + if ExportFormDestroy then + ChildExport := TExportForm.Create(nil); + if Assigned(ChildExport) then + begin + if not ChildExport.Showing then + ChildExport.Show + else + ChildExport.BringFormToFront(ChildExport); + end; + end; + // , HistoryToDBSync + if not StartUpdate then + begin + if FileExists(PluginPath + 'HistoryToDBSync.exe') then + begin + WinName := 'HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')'; + if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBSync for QIP , + ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBSync.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'"'), nil, SW_SHOWNORMAL) + end + else + begin + if CoreLanguage = 'Russian' then + MsgInf(htdPluginShortName, Format(' %s .' + #13 + ' .', [PluginPath + 'HistoryToDBSync.exe'])) + else + MsgInf(htdPluginShortName, Format('The history synchronization program %s not found.' + #13 + 'Begin the process of updating the plugin.', [PluginPath + 'HistoryToDBSync.exe'])); + end; + end; + Result := 0; +end; + +function Load():Integer; cdecl; +var + ProfileName, TmpProfilePath: String; + Str: PAnsiChar; +begin + CallService(MS_LANGPACK_REGISTER,WPARAM(@hLangpack),LPARAM(@PluginInfo)); + // + hppCodepage := CallService(MS_LANGPACK_GETCODEPAGE, 0, 0); + if (hppCodepage = CALLSERVICE_NOTFOUND) or (hppCodepage = CP_ACP) then + hppCodepage := GetACP(); + // - + MetaContactsEnabled := Boolean(ServiceExists(MS_MC_GETMOSTONLINECONTACT)); + if MetaContactsEnabled then + begin + Str := pAnsiChar(CallService(MS_MC_GETPROTOCOLNAME, 0, 0)); + if Assigned(Str) then + MetaContactsProto := AnsiString(Str) + else + MetaContactsEnabled := False; + end; + // + SetLength(DllPath, MAX_PATH); + SetLength(DllPath, GetModuleFileNameW(hInstance, @DllPath[1], MAX_PATH)); + PluginPath := ExtractFilePath(DllPath); + // (USERNAME\USERNAME.dat) + SetLength(TmpProfilePath, MAX_PATH); + CallService(MS_DB_GETPROFILEPATH, MAX_PATH, lParam(@TmpProfilePath[1])); + SetLength(TmpProfilePath, StrLen(pAnsiChar(@TmpProfilePath[1]))); + TmpProfilePath := pAnsiChar(TmpProfilePath) + PathDelim; + // + SetLength(ProfileName, MAX_PATH); + CallService(MS_DB_GETPROFILENAME, MAX_PATH, lParam(@ProfileName[1])); + SetLength(ProfileName, StrLen(pAnsiChar(@ProfileName[1]))); + // USERNAME.dat + TmpProfilePath := TmpProfilePath + ExtractFileNameEx(TmpProfilePath+pAnsiChar(ProfileName), False) + PathDelim; + if DirectoryExists(TmpProfilePath) then + ProfilePath := TmpProfilePath + else + ProfilePath := ExtractFilePath(DllPath); + // + LoadINI(ProfilePath); + // , + MyAccount := ExtractFileNameEx(pAnsiChar(ProfileName), False); + WriteCustomINI(ProfilePath, 'MyAccount', MyAccount); + // + HookModulesLoad := HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoad); + Result := 0; +end; + +function Unload: int; cdecl; +var + I: Byte; +begin + Result := 0; + if PluginStatus then + begin + // + StopWatch; + if Assigned(AboutForm) then FreeAndNil(AboutForm); + if Assigned(ExportForm) then FreeAndNil(ExportForm); + // + for I := Low(MainMenuHandle) to High(MainMenuHandle) do + begin + DestroyServiceFunction(MainMenuHandle[I]); + DestroyServiceFunction(MenuHandle[I]); + end; + {$ifdef REPLDEFHISTMOD} + DestroyServiceFunction(HookShowMainHistory); + {$endif REPLDEFHISTMOD} + DestroyServiceFunction(HookShowHistoryAPI); + DestroyServiceFunction(HookShowContactHistoryAPI); + DestroyServiceFunction(HookShowVersionAPI); + //{$ifdef REPLDEFHISTMOD} + UnhookEvent(HookSystemHistoryMenu); + //{$endif REPLDEFHISTMOD} + UnhookEvent(HookContactMenu); + //UnhookEvent(HookTTBLoaded); + UnhookEvent(HookEventAdded); + UnhookEvent(HookBuildMenu); + UnhookEvent(HookModulesLoad); + // + OnSendMessageToAllComponent('003'); + // - + if MsgLogOpened then + CloseLogFile(0); + if ErrLogOpened then + CloseLogFile(1); + if DebugLogOpened then + CloseLogFile(2); + if ContactListLogOpened then + CloseLogFile(3); + if ProtoListLogOpened then + CloseLogFile(4); + // + EncryptFree; + // MMF + if Assigned(FMap) then + FMap.Free; + // . + LangDoc.Active := False; + end; +end; + +exports + MirandaPluginInfoEx, + MirandaPluginInterfaces, + Load, + Unload; + +begin +end. + diff --git a/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dproj b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dproj new file mode 100644 index 0000000000..3fc30e6265 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dproj @@ -0,0 +1,226 @@ + + + {E69B7AEB-9B0F-45CB-A345-314CBE1E2449} + MirandaNGHistoryToDB.dpr + True + Release + Library + None + DCC32 + 14.4 + Win32 + 3 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + 1049 + System;Xml;Data;Datasnap;Web;Soap;Winapi;Vcl;$(DCC_Namespace) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + false + false + 00400000 + false + true + false + false + + + 1033 + true + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + C:\Program Files\QIP Infium\ + C:\Program Files\QIP Infium\infium.exe + C:\Program Files\QIP Infium\;$(Debugger_DebugSourcePath) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + true + 1033 + + + false + false + false + ..\..\include\delphi;..\..\plugins\ExternalAPI\delphi;$(DCC_UnitSearchPath) + false + RELEASE;$(DCC_Define) + 0 + + + C:\Program Files\Miranda NG + C:\Program Files\Miranda NG\Miranda32.exe + C:\Program Files\Miranda NG;$(Debugger_DebugSourcePath) + + ..\..\bin10\Release\Plugins\ + ..\..\bin10\Release\Obj\hpp\ + true + madExcept;$(DCC_Define) + 3 + true + 2 + 5 + CompanyName=http://www.im-history.ru;FileDescription=MirandaNGHistoryToDB;FileVersion=2.5.0.0;InternalName=MirandaNGHistoryToDB;LegalCopyright=Michael Grigorev;LegalTrademarks=http://www.im-history.ru;OriginalFilename=MirandaNGHistoryToDB.dll;ProductName=MirandaNGHistoryToDB;ProductVersion=2.5.0.0;Comments=http://www.im-history.ru + true + None + 1033 + ..\..\bin10\Release\Obj\hpp\ + ..\..\bin10\Release\Plugins\ + + + + ..\..\bin10\Release64\Plugins\ + ..\..\bin10\Release64\Obj\hpp\ + true + madExcept;$(DCC_Define) + 3 + true + 2 + 5 + CompanyName=http://www.im-history.ru;FileDescription=MirandaNGHistoryToDB;FileVersion=2.5.0.0;InternalName=MirandaNGHistoryToDB;LegalCopyright=Michael Grigorev;LegalTrademarks=http://www.im-history.ru;OriginalFilename=MirandaNGHistoryToDB.dll;ProductName=MirandaNGHistoryToDB;ProductVersion=2.5.0.0;Comments=http://www.im-history.ru + true + None + 1033 + ..\..\bin10\Release64\Obj\hpp\ + ..\..\bin10\Release64\Plugins\ + + + 3 + DEBUG;$(DCC_Define) + false + true + + + + MainSource + + + + + + +
ExportForm
+
+ + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + +
+ + + + Delphi.Personality.12 + VCLApplication + + + + MirandaNGHistoryToDB.dpr + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1049 + 1251 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + C:\Program Files\QIP Infium\infium.exe + C:\Program Files\QIP Infium\ + C:\Program Files\QIP Infium\ + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + False + True + True + + + 12 + + + + False + + False + copy_langs.bat + False + + + + False + + False + copy_langs.bat + False + +
diff --git a/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.mes b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.mes new file mode 100644 index 0000000000..1fcb334c1d --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.mes @@ -0,0 +1,163 @@ +[GeneralSettings] +MesVersion=4 +HandleExceptions=1 +LinkInCode=1 +AppendMapFileToBinary=1 +NoOwnMadExceptSettings=0 +CheckFileCrc=1 +CheckForFrozenMainThread=0 +FreezeTimeout=60000 +ReportLeaks=0 +WindowsLogo=0 +CrashOnBuffer=0 +CrashOnUnderrun=0 +AutomaticallySaveBugReport=1 +AutoSaveBugReportIfNotSent=1 +AutomaticallyMailBugReport=0 +AutoMailProgressBox=0 +CopyBugReportToClipboard=0 +SuspendAllRunningThreads=0 +ShowPleaseWaitBox=1 +PleaseWaitIcon=plwait1 +AutomaticallyContinueApplication=0 +AutomaticallyRestartApplication=0 +AutomaticallyCloseApplication=0 +SendInBackground=1 +SendHelper=196608 +Send32Icon=send321 +UploadViaHttp=0 +HttpServer= +HttpSsl=0 +HttpPort=0 +HttpAccount= +HttpPassword= +UploadToFogBugz=0 +UploadToBugZilla=0 +UploadToMantis=0 +BugTrackerAccount= +BugTrackerPassword= +BugTrackerProject= +BugTrackerArea= +BugTrackerAssignTo= +MailAsSmtpServer=0 +MailAsSmtpClient=0 +SmtpServer= +SmtpSsl=0 +SmtpTls=0 +SmtpPort=0 +SmtpAccount= +SmtpPassword= +MailViaMapi=1 +MailViaMailto=1 +MailAddress=sleuthhound@gmail.com +BugReportFile=bugreport.txt +AttachBugReport=1 +AttachBugReportFile=1 +DeleteBugReportFile=1 +BugReportSendAs=bugreport.txt +BugReportZip= +ScreenShotDepth=8 +ScreenShotAppOnly=0 +ScreenShotSendAs=screenshot.png +ScreenShotZip= +AdditionalAttachments= +AppendBugReports=1 +BugReportFileSize=100000 +DontSaveDuplicateExceptions=1 +DontSaveDuplicateFreezings=1 +DuplicateExceptionDefinition=1 +DuplicateFreezeDefinition=2 +ShowExceptionBox=1 +OkBtnText=&OK +DetailsBtnText=&Details +PleaseWaitTitle=Information +PleaseWaitText=Please wait a moment... +BugTrackerTitle=%25appname%25, %25exceptMsg%25 +BugTrackerDescr=error details: %0d%0a%25errorDetails%25 +MailSubject=bug report +MailBody=please find the bug report attached +SendBoxTitle=Sending bug report... +PrepareAttachMsg=Preparing attachments... +MxLookupMsg=Searching for mail server... +ConnectMsg=Connecting to server... +SendMailMsg=Sending mail... +FieldsMsg=Setting fields... +SendAttachMsg=Sending attachments... +SendFinalizeMsg=Finalizing... +MailFailureMsg=Sorry, sending the bug report didn't work. +VersionVariable= +[ExceptionBox] +ShowButtonMailBugReport=1 +ShowButtonSaveBugReport=0 +ShowButtonPrintBugReport=0 +ShowButtonShowBugReport=1 +ShowButtonContinueApplication=1 +ShowButtonRestartApplication=1 +ShowButtonCloseApplication=1 +IconButtonSendBugReport=send1 +IconButtonSaveBugReport=save1 +IconButtonPrintBugReport=print1 +IconButtonShowBugReport=show1 +IconButtonContinueApplication=continue1 +IconButtonCantContinueApplication=cantContinue1 +IconButtonRestartApplication=restart1 +IconButtonCloseApplication=close1 +FocusedButton=0 +SendAssistant=SendAssistant +SaveAssistant=SaveAssistant +PrintAssistant=PrintAssistant +AutomaticallyShowBugReport=0 +NoOwnerDrawButtons=0 +BigExceptionIcon=big1 +TitleBar=%25appname%25 +ExceptionMessage=An error occurred in the application. +FrozenMessage=The application seems to be frozen. +BitFaultMsg=The file "%25modname%25" seems to be corrupt! +MailBugReportText=send bug report +SaveBugReportText=save bug report +PrintBugReportText=print bug report +ShowBugReportText=show bug report +ContinueApplicationText=continue application +RestartApplicationText=restart application +CloseApplicationText=close application +[BugReport] +ListThreads=1 +ListModules=1 +ListHardware=1 +ShowCpuRegisters=1 +ShowStackDump=1 +Disassembly=1 +HideUglyItems=0 +ShowRelativeAddrs=1 +ShowRelativeLines=1 +FormatDisassembly=0 +LimitDisassembly=5 +EnabledPlugins=modules|processes|hardware +[Filters] +Filter1ExceptionClasses=EDBEditError +Filter1DontCreateBugReport=1 +Filter1DontCreateScreenshot=1 +Filter1DontSuspendThreads=1 +Filter1DontCallHandlers=1 +Filter1ShowBox=3 +Filter1Assis= +Filter2ExceptionClasses= +Filter2DontCreateBugReport=0 +Filter2DontCreateScreenshot=0 +Filter2DontSuspendThreads=0 +Filter2DontCallHandlers=0 +Filter2ShowBox=0 +Filter2Assis= +GeneralDontCreateBugReport=0 +GeneralDontCreateScreenshot=0 +GeneralDontSuspendThreads=0 +GeneralDontCallHandlers=0 +GeneralShowBox=0 +GeneralAssis= +[Assistants] +Assistant1=SendAssistant|Send Assistant|ContactForm|DetailsForm|ScrShotForm +Assistant2=SaveAssistant|Save Assistant|ContactForm|DetailsForm +Assistant3=PrintAssistant|Print Assistant|ContactForm|DetailsForm +Forms1=TPF0%0eTMEContactForm%0bContactForm%07Message%0c%13%00%00%00Contact Information%08MinWidth%04%00%00%00%00%08OnAction%0c%1b%00%00%00madExcept.HandleContactForm%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c%0a%00%00%00your name:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%08NameEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%09%0aOutputName%0c%0c%00%00%00contact name%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%08INVLabel%06Label2%07Caption%0c%0b%00%00%00your email:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%09EmailEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00contact email%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%0bINVCheckBox%08MemCheck%07Caption%0c%0b%00%00%00remember me%07Checked%08%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%00 +Forms2=TPF0%0eTMEDetailsForm%0bDetailsForm%07Message%0c%0d%00%00%00Error Details%08MinWidth%04%00%00%00%00%08OnAction%0c%00%00%00%00%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c'%00%00%00in which situation did the error occur?%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%0bDetailsMemo%07Colored%09%07Enabled%09%05Lines%04%09%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00error details%0aOutputType%07%0dnvoOwnSection%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%00 +Forms3=TPF0%0eTMEScrShotForm%0bScrShotForm%0dActiveControl%07%0bContinueBtn%07Message%0c%18%00%00%00Screenshot Configuration%08MinWidth%04%00%00%00%00%08OnAction%0c%1e%00%00%00madExcept.HandleScreenshotForm%05Timer%04%fa%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%0bINVCheckBox%0bAttachCheck%07Caption%0c%25%00%00%00attach a screenshot to the bug report%07Checked%09%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%08INVImage%0aScrShotImg%06Border%09%09Clickable%09%07Enabled%09%04File%0c%00%00%00%00%06Height%04%00%00%00%00%07Spacing%04%00%00%00%00%05Width%04%00%00%00%00%00%00%08INVLabel%06Label1%07Caption%0c%15%00%00%00(click to edit image)%07Enabled%09%07Spacing%04%00%00%00%00%00%00%00 diff --git a/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.res b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.res new file mode 100644 index 0000000000..e7d67124de Binary files /dev/null and b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.res differ diff --git a/plugins/MirandaNGHistoryToDB/MsgExport.dfm b/plugins/MirandaNGHistoryToDB/MsgExport.dfm new file mode 100644 index 0000000000..1a244adc27 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/MsgExport.dfm @@ -0,0 +1,4447 @@ +object ExportForm: TExportForm + Left = 0 + Top = 0 + ActiveControl = Page1 + BorderIcons = [biSystemMenu, biMinimize] + BorderStyle = bsSingle + Caption = 'MirandaNGHistoryToDB - '#1069#1082#1089#1087#1086#1088#1090' '#1080#1089#1090#1086#1088#1080#1080 + ClientHeight = 266 + ClientWidth = 561 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + Icon.Data = { + 0000010001001010000001000000680400001600000028000000100000002000 + 0000010020000000000000040000000000000000000000000000000000000000 + 0000000000000000000000000000FF1F2A000000000000000000000000000000 + 00000000000000000000FF1F2A00000000000000000000000000000000000000 + 00000000000000000000FF1F2A00FEEFA900FF1F2A00CDCDCD00CDCDCD00CDCD + CD00CDCDCD00FF1F2A00FEEFA900FF1F2A000000000000000000000000000000 + 000000000000FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F + 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A0000000000000000000000 + 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FECF4D00FFCC + 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A0000000000FF1F + 2A00FEEFA900FFE55F00FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC + 4A00FFD35000FFE55F00FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A000000 + 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC + 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A00000000000000 + 000000000000FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F + 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A0000000000000000000000 + 000000000000C1BDB600FF1F2A00FEEFA900FF1F2A00C1B7AF00D2BEB900D2BE + B900D2BEB900FF1F2A00FEEFA900FF1F2A00C1BDB60000000000000000000000 + 000000000000BAB7AF00A39A8F00FF1F2A00CAC1B800DFD5CC00FAE2DF00F7DB + D900DFD5CC00CAC1B800FF1F2A00A39A8F00BAB7AF0000000000000000000000 + 000000000000B1AB9F00C9C2B900CFC7BF00D5CCC400DCD3CA00E8DDD500E4D6 + CF00E4D6CF00D5CCC400CFC7BF00C9C2B900B1AB9F0000000000000000000000 + 000000000000B0AB9E00C7C0B600CCC4BB00D3C9C100DAD0C700EBE1DA00E4D9 + D100DDD2CA00DBCDC500DDCAC400DBC4BF00C1ADA40000000000000000000000 + 000000000000AFAA9D00C8C1B700E8E3DB00F5F0E800FDF8F200FBF7F000FCF7 + F100FDF8F200F7F0EA00ECE3DC00CDC3BB00B2AA9E0000000000000000000000 + 000000000000AEA89C00FBF5EF00EEE7DE00E0D8CE00DDD5CC00DDD4CB00DDD4 + CB00DDD5CC00E0D7CE00EDE6DE00FBF6EF00AEA89C0000000000000000000000 + 000000000000AFA99D00E1D8CE00E1D7CE00DFD6CC00DFD5CB00DFD5CB00DFD5 + CB00DFD5CB00DFD6CC00E1D7CE00E1D8CE00AFA99D0000000000000000000000 + 000000000000D9D9D900B6B0A400D6CFC400E6DED500EFE7DD00EEE6DC00EEE6 + DC00EFE7DD00E6DED500D6CFC400B6B0A400D9D9D90000000000000000000000 + 00000000000000000000D9D9D900C4C0B700AEA99C00AEA89C00AEA89C00AEA8 + 9C00AEA89C00AEA99C00C4C0B700D9D9D900000000000000000000000000F7EF + FFFFE007FFFFC003FFFF8001FFFF0000FFFF8001FFFFC003FFFFC003FFFFC003 + FFFFC003FFFFC003FFFFC003FFFFC003FFFFC003FFFFC003FFFFE007FFFF} + OldCreateOrder = False + Position = poDesktopCenter + OnClose = FormClose + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object IMExportWizard: TJvWizard + Left = 0 + Top = 0 + Width = 561 + Height = 266 + ActivePage = Page1 + ButtonBarHeight = 42 + ButtonStart.Caption = 'To &'#1055#1077#1088#1074#1072#1103' '#1089#1090#1088#1072#1085#1080#1094#1072 + ButtonStart.NumGlyphs = 1 + ButtonStart.Width = 85 + ButtonLast.Caption = 'To &'#1055#1086#1089#1083#1077#1076#1085#1103#1103' '#1089#1090#1088#1072#1085#1080#1094#1072 + ButtonLast.NumGlyphs = 1 + ButtonLast.Width = 85 + ButtonBack.Caption = '< &'#1053#1072#1079#1072#1076 + ButtonBack.NumGlyphs = 1 + ButtonBack.Width = 75 + ButtonNext.Caption = '&'#1044#1072#1083#1077#1077' >' + ButtonNext.NumGlyphs = 1 + ButtonNext.Width = 75 + ButtonFinish.Caption = '&'#1042#1099#1081#1090#1080 + ButtonFinish.NumGlyphs = 1 + ButtonFinish.Width = 75 + ButtonCancel.Caption = #1054#1090#1084#1077#1085#1072 + ButtonCancel.NumGlyphs = 1 + ButtonCancel.ModalResult = 2 + ButtonCancel.Width = 75 + ButtonHelp.Caption = '&'#1055#1086#1084#1086#1097#1100 + ButtonHelp.NumGlyphs = 1 + ButtonHelp.Width = 75 + ShowRouteMap = False + OnFinishButtonClick = IMExportWizardFinishButtonClick + OnCancelButtonClick = IMExportWizardCancelButtonClick + DesignSize = ( + 561 + 266) + object Page1: TJvWizardWelcomePage + Header.Height = 100 + Header.Title.Color = clNone + Header.Title.Text = #1044#1086#1073#1088#1086' '#1087#1086#1078#1072#1083#1086#1074#1072#1090#1100' '#1074' '#1084#1072#1089#1090#1077#1088' '#1101#1082#1089#1087#1086#1088#1090#1072' '#1080#1089#1090#1086#1088#1080#1080 + Header.Title.Anchors = [akLeft, akTop, akRight] + Header.Title.Font.Charset = DEFAULT_CHARSET + Header.Title.Font.Color = clWindowText + Header.Title.Font.Height = -16 + Header.Title.Font.Name = 'Tahoma' + Header.Title.Font.Style = [fsBold] + Header.Subtitle.Color = clNone + Header.Subtitle.Text = + #1044#1072#1085#1085#1099#1081' '#1084#1072#1089#1090#1077#1088' '#1087#1086#1084#1086#1078#1077#1090' '#1042#1072#1084' '#1101#1082#1089#1087#1086#1088#1090#1080#1088#1086#1074#1072#1090#1100' '#1080#1089#1090#1086#1088#1080#1102' Miranda '#1074#1086' '#1074#1085#1077#1096 + + #1085#1102#1102' '#1073#1072#1079#1091' '#1076#1072#1085#1085#1099#1093'. '#1069#1082#1089#1087#1086#1088#1090' '#1073#1091#1076#1077#1090' '#1087#1088#1086#1080#1079#1074#1077#1076#1077#1085' '#1074' '#1092#1072#1081#1083' '#1092#1086#1088#1084#1072#1090#1072' sql-ins' + + 'ert. '#1055#1088#1080' '#1089#1080#1085#1093#1088#1086#1085#1080#1079#1072#1094#1080#1080' '#1101#1090#1080' '#1076#1072#1085#1085#1099#1077' '#1073#1091#1076#1091#1090' '#1087#1077#1088#1077#1076#1072#1085#1099' '#1074' '#1073#1072#1079#1091' '#1076#1072#1085#1085#1099#1093'.' + Header.Subtitle.Anchors = [akLeft, akTop, akRight, akBottom] + Header.Subtitle.Font.Charset = DEFAULT_CHARSET + Header.Subtitle.Font.Color = clWindowText + Header.Subtitle.Font.Height = -11 + Header.Subtitle.Font.Name = 'Tahoma' + Header.Subtitle.Font.Style = [] + Header.ShowDivider = False + Image.Alignment = iaCenter + Image.Layout = ilCenter + EnabledButtons = [bkBack, bkNext, bkFinish, bkCancel] + WaterMark.Color = clCaptionText + WaterMark.Image.Picture.Data = { + 07544269746D617086080200424D86080200000000003600000028000000C800 + 0000DE000000010018000000000050080200120B0000120B0000000000000000 + 0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFF4DED4F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2 + C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685 + 61C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F0D2C6F0D2C6F0 + D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4E5B19BE5B19BE5B19B + F8E9E2FFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B19BE5B19BF0D2C6FFFFFFFFFF + FFFFFFFFF0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6F0 + D2C6F0D2C6F0D2C6F0D2C6E5B19BC75828E5B19BFFFFFFFBF4F1E5B19BE5B19B + E5B19BF8E9E2F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFBF4F1E9BCA9E5B19BE5B19BECC7B7FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6E5B19BE5B19BECC7B7F8E9E2F0D2 + C6FBF4F1FFFFFFFBF4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0 + D2C6FFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFF4DED4F0D2C6 + FFFFFFFFFFFFFBF4F1F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C75828C75828DA9070 + FFFFFFFFFFFFFBF4F1D68561C75828C75828C75828C75828C75828F4DED4FFFF + FFE1A68CC75828C75828C75828C75828C75828DA9070FFFFFFFFFFFFC75828D6 + 8561FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C75828C75828 + C75828C75828C75828E5B19BFBF4F1CB6336C75828C75828C75828CB6336C758 + 28D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BCA9CB + 6336C75828C75828C75828C75828DA9070FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFD68561C75828C75828C75828C75828C75828CB6336E5B19BFFFF + FFFFFFFFE5B19BC75828C75828C75828C75828CB6336C75828F0D2C6FFFFFFF0 + D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFF + E5B19BC75828DA9070FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFF0D2 + C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFD68561C75828F0D2C6F0D2C6ECC7B7D27953C75828E9BCA9FFFFFFE5B1 + 9BC75828DA9070F8E9E2FFFFFFE9BCA9CE6E45F0D2C6F0D2C6C75828CB6336EC + C7B7FFFFFFF4DED4DD9B7ED68561FFFFFFFFFFFFC75828D68561FFFFFFFFFFFF + FFFFFFFFFFFFF4DED4CE6E45C75828E9BCA9F0D2C6F0D2C6E5B19BC75828DD9B + 7EF8E9E2E5B19BC75828DD9B7EFFFFFFF8E9E2DD9B7EC75828D68561FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1CB6336CB6336E9BCA9FFFFFF + F8E9E2DD9B7ED68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685 + 61C75828E5B19BF0D2C6F0D2C6E5B19BCB6336C75828ECC7B7FFFFFFCB6336CB + 6336F4DED4FFFFFFE9BCA9CE6E45C75828F0D2C6FFFFFFF0D2C6C75828E5B19B + FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFE5B19BC75828C758 + 28E5B19BFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFF0D2C6C75828C75828FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C758 + 28FFFFFFFFFFFFFFFFFFECC7B7C75828E5B19BFFFFFFCE6E45C75828FBF4F1FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9B7EC75828ECC7B7FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFE9BCA9C75828E1A68CFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFE5B19BC7 + 5828ECC7B7FFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFE9BCA9C75828E1A68CFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FF + FFFFFFFFFFFFFFFFE9BCA9C75828D68561FFFFFFC75828D27953FFFFFFFFFFFF + FFFFFFE5B19BC75828F0D2C6FFFFFFF0D2C6C75828E5B19BF8E9E2C75828CE6E + 45FFFFFFD68561C75828FFFFFFFFFFFFE5B19BC75828C75828C75828F0D2C6FF + FFFFD68561C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BE5B19BE1 + A68CCE6E45CB6336F4DED4FFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFD68561C75828F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6FFFF + FFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB6336CB + 6336FFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFF0D2C6C75828CB6336E1A68C + E5B19BF0D2C6C75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFFFFFFF + F0D2C6C75828D68561FFFFFFD68561C75828D68561E5B19BECC7B7DD9B7EC758 + 28F0D2C6FFFFFFF0D2C6C75828E5B19BDD9B7EC75828C75828E9BCA9D68561C7 + 5828FFFFFFFFFFFFE5B19BC75828E5B19BCB6336CB6336FBF4F1D68561C75828 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFD68561C75828D68561D68561CE6E45C75828E5B19B + FFFFFFFFFFFFC75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685 + 61C75828C75828C75828C75828C75828C75828C75828FFFFFFFFFFFFC75828D6 + 8561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9070C75828F0D2C6FFFFFF + F0D2C6C75828E5B19BFFFFFFFFFFFFECC7B7D27953C75828C75828C75828C758 + 28D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828EC + C7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFF8E9E2D27953C75828E5B1 + 9BFFFFFFFBF4F1DD9B7ECB6336C75828C75828C75828C75828F0D2C6FFFFFFF0 + D2C6C75828D68561C75828D68561CE6E45CE6E45D27953C75828FFFFFFFFFFFF + E5B19BC75828F0D2C6E9BCA9C75828D27953D68561C75828FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFD68561C75828FFFFFFFFFFFFFFFFFFD27953CB6336FFFFFFFFFFFFD279 + 53C75828F4DED4FFFFFFFFFFFFFFFFFFF8E9E2FBF4F1E1A68CC75828F0D2C6FF + FFFFFFFFFFFFFFFFCE6E45C75828FFFFFFFFFFFFC75828D68561FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFF0D2C6C75828E5B1 + 9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6C75828D68561FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7C75828DA9070FFFFFFFFFFFF + FFFFFFFFFFFFF4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685 + 61C75828C75828C75828C75828C75828C75828D68561FBF4F1FFFFFFFFFFFFFF + FFFFFFFFFFFBF4F1F0D2C6DD9B7EC75828F0D2C6FFFFFFF0D2C6C75828C75828 + C75828F8E9E2E9BCA9C75828C75828C75828FFFFFFFFFFFFE5B19BC75828F0D2 + C6FFFFFFDD9B7EC75828C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C758 + 28E5B19BE5B19BE1A68CC75828CB6336FFFFFFFFFFFFECC7B7C75828CE6E45E9 + BCA9F0D2C6DD9B7EC75828F0D2C6F8E9E2CB6336CB6336E9BCA9F0D2C6DA9070 + C75828DD9B7EFFFFFFFFFFFFC75828CE6E45E5B19BE5B19BE5B19BE5B19BF8E9 + E2FFFFFFF0D2C6C75828D68561E5B19BDD9B7EC75828E5B19BFFFFFFFFFFFFE1 + A68CE1A68CECC7B7F0D2C6DA9070C75828DD9B7EFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFD27953C75828DD9B7EF0D2C6E9BCA9CE6E45D685 + 61FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828DD9B7EE5 + B19BE1A68CCB6336CE6E45F4DED4FFFFFFFFFFFFF4DED4DA9070E5B19BF0D2C6 + E9BCA9CB6336C75828F8E9E2FFFFFFF0D2C6C75828C75828DD9B7EFFFFFFFFFF + FFCE6E45C75828C75828FFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFBF4F1D2 + 7953C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C7 + 5828CE6E45E9BCA9FFFFFFFFFFFFFFFFFFE9BCA9CB6336C75828C75828C75828 + CE6E45F8E9E2FFFFFFECC7B7CB6336C75828C75828C75828D27953FBF4F1FFFF + FFFFFFFFC75828C75828C75828C75828C75828C75828F0D2C6FFFFFFF0D2C6C7 + 5828C75828C75828C75828C75828E5B19BFFFFFFFFFFFFD68561C75828C75828 + C75828C75828D27953FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFBF4F1D68561C75828C75828C75828C75828E5B19BFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFE9BCA9 + C75828DA9070FFFFFFFFFFFFF0D2C6C75828C75828C75828C75828C75828E9BC + A9FFFFFFFFFFFFF0D2C6C75828C75828F8E9E2FFFFFFFFFFFFE9BCA9C75828C7 + 5828FFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFF8E9E2CB6336C75828 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6F0D2C6F4DED4FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF0D2C6F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6F0D2C6F4DED4FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFF8E9E2F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFE9BCA9C75828D68561FFFF + FFFFFFFFFFFFFFFFFFFFF0D2C6F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685 + 61C75828D27953D68561D68561C75828C75828E5B19BFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1A68CD68561D68561D6 + 8561D68561DA9070E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFF8E9E2F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2 + C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7CE6E45C75828C758 + 28DA9070E9BCA9E5B19BF8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7C758 + 28DA9070FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFE5B19BE5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2E5B19BE9BCA9 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFBF4F1CB6336C75828DA9070E1A68CE1A68CE5B19BC7 + 5828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45C75828F8E9E2FF + FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFDA9070C75828F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB6336CB6336FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFF4DED4E5B1 + 9BE5B19BE5B19BECC7B7FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7E5 + B19BDD9B7EC75828CE6E45FFFFFFFFFFFFFFFFFFF8E9E2C75828CE6E45FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1ECC7B7E5B19BE5B19BE5B19BECC7 + B7FFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFF0 + D2C6F0D2C6FBF4F1FFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFFFFFFF + FFFFFFE5B19BC75828E5B19BE5B19BE5B19BE9BCA9FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFECC7B7E5B19BE5B19BE9BCA9F8E9E2FFFFFFE9BCA9C75828DD + 9B7EFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B19BE5B19BF4DED4FFFFFF + FFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B19BE9BCA9F8E9E2F0D2C6F8E9E2FFFF + FFFFFFFFF0D2C6F0D2C6E9BCA9E5B19BE5B19BF4DED4FFFFFFFFFFFFFFFFFFFB + F4F1F0D2C6F0D2C6E5B19BE5B19BE5B19BF8E9E2FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFECC7B7E5B19BE5B19BE9BCA9F8E9E2FFFFFFFFFFFFF8E9E2F0D2C6FBF4 + F1FFFFFFFFFFFFFFFFFFDD9B7EC75828E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFBF4F1F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2C6 + F4DED4FFFFFFFFFFFFFFFFFFF4DED4E5B19BE5B19BE5B19BE5B19BF8E9E2FFFF + FFFFFFFFFFFFFFFFFFFFF0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6F0 + D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828C75828C758 + 28C75828C75828FFFFFFFFFFFFFBF4F1D68561C75828C75828C75828C75828C7 + 5828C75828E5B19BFFFFFFFFFFFFF4DED4CE6E45C75828C75828C75828C75828 + C75828DD9B7EFFFFFFFFFFFFFFFFFFDA9070C75828F0D2C6FFFFFFFFFFFFFFFF + FFFFFFFFE9BCA9C75828C75828C75828C75828C75828C75828CE6E45F4DED4FF + FFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFDD9B7EC75828D27953FBF4F1 + FFFFFFFFFFFFECC7B7C75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758 + 28C75828C75828C75828C75828D27953F8E9E2FFFFFFFFFFFFF4DED4CE6E45C7 + 5828C75828C75828C75828C75828F4DED4FFFFFFCB6336CB6336FBF4F1FFFFFF + FFFFFFFFFFFFE5B19BC75828C75828C75828C75828E1A68CFFFFFFFFFFFFF0D2 + C6C75828C75828C75828C75828CB6336C75828E5B19BFFFFFFFFFFFFC75828C7 + 5828C75828C75828C75828C75828E5B19BFFFFFFFFFFFFF0D2C6C75828C75828 + C75828C75828C75828CB6336ECC7B7FFFFFFFFFFFFF4DED4CE6E45C75828C758 + 28C75828C75828C75828F4DED4FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFF + FFFFF4DED4C75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828 + D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFF + FFCE6E45C75828C75828C75828C75828C75828C75828E1A68CFFFFFFFFFFFFFF + FFFFC75828C75828FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828E5B19BFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6DD9B7EC75828DD9B7EF0D2C6FF + FFFFFFFFFFD68561C75828D27953ECC7B7FFFFFFFBF4F1E9BCA9CB6336D68561 + FFFFFFF8E9E2CB6336C75828DD9B7EF8E9E2FFFFFFECC7B7CB6336C75828E5B1 + 9BFFFFFFFFFFFFECC7B7C75828DD9B7EFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC7 + 5828DD9B7EF4DED4FFFFFFFBF4F1E5B19BC75828CB6336FFFFFFFFFFFFE5B19B + C75828F0D2C6FFFFFFDD9B7EC75828D27953FBF4F1FFFFFFFFFFFFFFFFFFDD9B + 7EC75828C75828E9BCA9FFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFBF4F1FB + F4F1E5B19BC75828D68561FFFFFFFFFFFFD68561C75828DD9B7EF8E9E2FBF4F1 + E9BCA9CE6E45F0D2C6FFFFFFE1A68CC75828E9BCA9FFFFFFFFFFFFFFFFFFF8E9 + E2F4DED4FFFFFFF0D2C6C75828C75828F8E9E2FFFFFFDA9070C75828E9BCA9FF + FFFFF0D2C6D68561C75828E5B19BFFFFFFFFFFFFC75828CE6E45F4DED4FFFFFF + F0D2C6D27953C75828F0D2C6FFFFFFF0D2C6C75828DA9070F8E9E2FFFFFFE9BC + A9CB6336CB6336FBF4F1FFFFFFD68561C75828DD9B7EF8E9E2FBF4F1E9BCA9CE + 6E45F0D2C6FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFD27953 + C75828F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFFFFC75828CE6E45E9 + BCA9FBF4F1FFFFFFF0D2C6D27953C75828E5B19BFFFFFFFFFFFFC75828C75828 + FFFFFFFFFFFFFFFFFFD68561C75828C75828E5B19BFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFECC7B7C75828 + CB6336FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFBF4F1E9BCA9FFFFFFE1A68CC758 + 28DA9070FFFFFFFFFFFFFFFFFFFFFFFFF4DED4C75828C75828FBF4F1FFFFFFFF + FFFFCB6336CB6336FBF4F1FFFFFFFFFFFFFFFFFFF0D2C6F4DED4FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFD27953C75828F0D2C6FFFFFFE5B19BC75828E5B19BDD9B + 7EC75828D27953FBF4F1FFFFFFFFFFFFFFFFFFF8E9E2C75828CB6336C75828D2 + 7953FFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD27953 + C75828F8E9E2F8E9E2C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF4DED4C75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFD68561C75828F0D2C6FFFFFFD68561C75828FBF4F1FFFFFFFFFFFFF0D2C6 + C75828E5B19BFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFECC7B7C758 + 28DD9B7EFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFE1A68CC75828E9 + BCA9F8E9E2C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + E5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFF + FFFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFFFFF0D2C6F8E9E2FF + FFFFF0D2C6C75828D68561FFFFFFFFFFFFE5B19BFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFECC7B7C75828D68561FFFFFFFFFFFFC75828C75828FFFFFFFFFFFFF0D2 + C6C75828C75828C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFE1A68CC75828E1A68CFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD27953C75828F0D2C6FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFD68561C75828ECC7B7FFFFFFFFFFFFE1A68CC75828 + E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9 + E2CB6336C75828F0D2C6FFFFFFE5B19BC75828C75828C75828D27953FBF4F1FF + FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BD68561C75828F4DED4FFFFFF + FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6F0D2 + C6C75828DD9B7EF0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F8E9E2FFFFFFFFFFFFD2 + 7953C75828F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828 + F0D2C6FFFFFFE5B19BC75828CE6E45E5B19BE9BCA9E5B19BC75828E5B19BFFFF + FFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFF0 + D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BF0D2C6C75828 + DD9B7EF0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F8E9E2FFFFFFE5B19BC75828F0D2 + C6FFFFFFFFFFFFFFFFFFFFFFFFFBF4F1C75828CE6E45FFFFFFFFFFFFFFFFFFFF + FFFFF0D2C6C75828D68561FFFFFFF0D2C6C75828D68561FFFFFFF0D2C6C75828 + D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1A68CC758 + 28D68561FFFFFFFFFFFFC75828C75828FFFFFFFFFFFFDA9070C75828D68561C7 + 5828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758 + 28E5B19BFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFC75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFF4DED4C75828D68561FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFF8E9E2E9BCA9E5B19BD68561C75828C75828CE6E45FF + FFFFFFFFFFE5B19BC75828CB6336C75828DD9B7EFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFCE6E45C75828F8E9E2E9BCA9C75828DD9B7EFFFFFFFFFFFFE5B19BC758 + 28F0D2C6FFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6F0D2C6C75828C75828C7 + 5828C75828C75828C75828C75828E5B19BFFFFFFFFFFFFE5B19BC75828E5B19B + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFF + FFE5B19BCE6E45C75828C75828C75828C75828E5B19BFFFFFFFFFFFFC75828D6 + 8561FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFF0D2C6C75828E5B19B + FFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BF0D2C6C75828C75828C75828C758 + 28C75828C75828C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFDA9070C75828F0D2C6FFFFFFFFFFFFFFFFFFF0D2C6C75828 + D68561FFFFFFD68561C75828C75828F4DED4F0D2C6C75828D68561FFFFFFFFFF + FFFFFFFFFFFFFFF0D2C6E5B19BDD9B7ECE6E45C75828C75828E9BCA9FFFFFFFF + FFFFC75828C75828FFFFFFF8E9E2C75828D68561E5B19BC75828E5B19BFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFF + FFFFD68561C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFC75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758 + 28E5B19BFFFFFFFFFFFFFFFFFFD27953C75828F8E9E2FFFFFFFFFFFFFFFFFFE1 + A68CC75828C75828C75828C75828CB6336DD9B7EFBF4F1FFFFFFFFFFFFE5B19B + C75828ECC7B7D27953C75828DD9B7EFFFFFFFFFFFFFFFFFFECC7B7C75828DD9B + 7EFFFFFFFFFFFFCE6E45C75828FBF4F1FFFFFFE5B19BC75828F0D2C6FFFFFFFF + FFFFFFFFFFD27953C75828F8E9E2FBF4F1C75828D68561FFFFFFFFFFFFFFFFFF + E9BCA9C75828E5B19BFFFFFFFFFFFFFBF4F1C75828CE6E45FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFF0D2C6E5B19BC75828E5B19BFFFFFFFFFFFFC75828D68561FFFFFFFFFFFF + FFFFFFECC7B7C75828DD9B7EFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFF + FFE1A68CC75828E9BCA9FBF4F1C75828D68561FFFFFFFFFFFFFFFFFFE9BCA9C7 + 5828E5B19BFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ECC7B7C75828DD9B7EFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561F8E9E2C758 + 28D27953C75828DD9B7EF0D2C6C75828D68561FFFFFFFFFFFFF4DED4CE6E45C7 + 5828C75828C75828C75828D27953ECC7B7FFFFFFFFFFFFFFFFFFC75828C75828 + FFFFFFDD9B7EC75828ECC7B7E5B19BC75828E5B19BFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFDA9070C75828 + E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB6336C758 + 28F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9B7EC75828E5B19BFFFFFFFF + FFFFFFFFFFE9BCA9C75828E1A68CFFFFFFFFFFFFF0D2C6C75828C75828E1A68C + F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FBF4 + F1D27953C75828DD9B7EFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFE5 + B19BC75828E5B19BFFFFFFE5B19BC75828CB6336E1A68CF0D2C6DA9070C75828 + D68561FFFFFFFFFFFFE1A68CC75828DA9070F0D2C6E9BCA9CB6336C75828F8E9 + E2FFFFFFFFFFFFFFFFFFDD9B7EC75828ECC7B7FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFD68561C75828F0D2C6FFFFFFFFFFFFD68561E5B19BF0D2C6ECC7B7D27953 + C75828E9BCA9FFFFFFFFFFFFC75828C75828D68561E9BCA9ECC7B7CE6E45C758 + 28F0D2C6FFFFFFF0D2C6C75828C75828DD9B7EECC7B7E5B19BCB6336CB6336FB + F4F1FFFFFFE1A68CC75828DA9070F0D2C6E9BCA9CB6336C75828F8E9E2FFFFFF + E5B19BC75828C75828D68561E5B19BD68561FFFFFFFFFFFFFFFFFFCE6E45C758 + 28FBF4F1FFFFFFFFFFFFF0D2C6C75828D68561DD9B7EC75828F0D2C6DD9B7EC7 + 5828E9BCA9C75828D68561FFFFFFFFFFFFD68561C75828D27953E9BCA9F0D2C6 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828C75828F8E9E2C75828CE6E + 45FFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9070C75828E9BCA9FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFCE6E45C75828F4DED4FFFFFFFFFFFFFFFFFFFBF4F1 + C75828CE6E45FFFFFFFFFFFFE5B19BC75828E1A68CFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFBF4F1D27953C7 + 5828E1A68CF8E9E2C75828D27953FFFFFFFFFFFFFFFFFFFBF4F1C75828CE6E45 + FFFFFFE5B19BC75828D68561C75828C75828C75828CE6E45F4DED4FFFFFFFFFF + FFFBF4F1DA9070C75828C75828C75828C75828E9BCA9FFFFFFFFFFFFFFFFFFFF + FFFFECC7B7C75828DD9B7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828 + F0D2C6FFFFFFFFFFFFC75828C75828C75828C75828C75828DD9B7EFFFFFFFFFF + FFFFFFFFC75828CE6E45CB6336C75828C75828C75828E1A68CFFFFFFFFFFFFF0 + D2C6C75828D27953C75828C75828C75828CB6336E9BCA9FFFFFFFFFFFFFBF4F1 + DA9070C75828C75828C75828C75828E9BCA9FFFFFFFFFFFFE5B19BC75828E1A6 + 8CCE6E45C75828C75828FFFFFFFFFFFFFFFFFFE1A68CC75828E9BCA9FFFFFFFF + FFFFF0D2C6C75828D27953C75828CE6E45FFFFFFF0D2C6C75828D27953C75828 + D68561FFFFFFFFFFFFC75828C75828FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFC75828C75828DD9B7EC75828E9BCA9FFFFFFE5B19BC7 + 5828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758 + 28E5B19BFFFFFFFFFFFFFBF4F1CB6336C75828E9BCA9FFFFFFFFFFFFFFFFFFFF + FFFFE5B19BD68561FFFFFFE9BCA9C75828CB6336F4DED4FFFFFFFFFFFFFFFFFF + DD9B7EC75828CE6E45FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9B7EC75828ECC7 + B7FFFFFFE5B19BC75828DA9070FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6E1A68CFF + FFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF8E9E2F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 + E9E2F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45 + C75828FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFF + FFFFFFFFF4DED4F0D2C6F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFC75828D6 + 8561FFFFFFF0D2C6F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19B + FBF4F1F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2 + C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFF8E9E2C75828D27953FFFFFFFFFFFFF0D2C6C75828 + C75828C75828E9BCA9FFFFFFFFFFFFD68561C75828C75828D68561FFFFFFFFFF + FFCB6336C75828F4DED4FFFFFFFFFFFFFFFFFFFBF4F1E1A68CF4DED4FFFFFFFF + FFFFC75828C75828C75828CE6E45FFFFFFFFFFFFE5B19BC75828E5B19BFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561CE6E45C75828CE6E45D68561FF + FFFFFFFFFFE9BCA9C75828C75828D27953E5B19BDD9B7ECE6E45C75828D68561 + FFFFFFFFFFFFDD9B7EC75828CB6336DD9B7EE5B19BD27953C75828CB6336F4DE + D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7C75828DA9070FFFFFFFBF4F1CB + 6336C75828D27953E5B19BE1A68CCE6E45C75828D68561FFFFFFFFFFFFE5B19B + C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1A68CC75828E5B19BFFFF + FFFFFFFFD68561D68561CB6336C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFD27953C75828F4DED4FFFFFFF0D2C6C75828C75828CE6E45FFFF + FFFFFFFFFFFFFFE9BCA9C75828C75828D68561FFFFFFFFFFFFE5B19BC75828CB + 6336DD9B7EE5B19BDA9070C75828C75828F0D2C6FFFFFFFFFFFFC75828C75828 + C75828E9BCA9FFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFD68561D68561D68561D68561D68561FFFFFFFFFFFFFFFFFF + F4DED4DD9B7ECB6336C75828C75828CE6E45E1A68CF8E9E2FFFFFFFFFFFFFFFF + FFE9BCA9D27953C75828C75828CB6336DD9B7EF8E9E2FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFCE6E45C75828FBF4F1FFFFFFFBF4F1DD9B7ECB6336 + C75828C75828CE6E45DA9070ECC7B7FFFFFFFFFFFFE5B19BC75828F0D2C6FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2C75828D27953FFFFFFFFFFFFD68561D6 + 8561D68561D68561F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BC + A9C75828E1A68CFFFFFFF4DED4D68561D68561E9BCA9FFFFFFFFFFFFFFFFFFFF + FFFFDA9070D68561E1A68CFFFFFFFFFFFFFFFFFFECC7B7D27953C75828C75828 + C75828D68561E1A68CFBF4F1FFFFFFFFFFFFD68561D68561DA9070FFFFFFFFFF + FFFFFFFFE9BCA9D68561E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFF4DED4F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFF0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB + F4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F4DED4FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6F4DED4FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFB + F4F1F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B19BE5B19B + F4DED4FFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF4DED4E5B19BE5B19BE9BCA9FBF4F1FFFFFFFFFFFFFFFFFFC75828D2 + 7953E9BCA9E5B19BE5B19BF8E9E2FFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F8E9E2 + FFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FBF4F1F0D2C6F0D2C6FFFFFFFFFF + FFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFF4DED4F0D2C6FFFFFFFFFFFF + FFFFFFFFFFFFECC7B7E5B19BE5B19BE9BCA9F8E9E2FFFFFFFFFFFFE5B19BC758 + 28E5B19BE5B19BE5B19BE9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC + C7B7E5B19BE5B19BE9BCA9F8E9E2FFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFF + FFFFFFFFFFFFF4DED4F0D2C6FFFFFFFFFFFFF4DED4F0D2C6FFFFFFFFFFFFFFFF + FFFFFFFFF0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFECC7B7E5B19BE5B19BE9 + BCA9FBF4F1FFFFFFFBF4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFF0D2C6F0D2C6 + FBF4F1FBF4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F0D2C6F0D2C6F0 + D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFD68561C75828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828D68561 + FFFFFFFFFFFFFFFFFFE1A68CC75828C75828C75828C75828C75828E5B19BFFFF + FFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFDD9B7EC75828C7 + 5828C75828C75828CB6336F4DED4FFFFFFFFFFFFC75828C75828C75828C75828 + C75828C75828E5B19BFFFFFFFFFFFFF0D2C6C75828CE6E45FBF4F1FFFFFFFFFF + FFE5B19BC75828F0D2C6FBF4F1D27953C75828E5B19BFFFFFFFFFFFFE5B19BC7 + 5828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828 + F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFF4DED4CE6E45C758 + 28C75828C75828C75828C75828F4DED4FFFFFFE5B19BC75828C75828C75828C7 + 5828C75828D27953F8E9E2FFFFFFFFFFFFF4DED4CE6E45C75828C75828C75828 + C75828C75828F4DED4FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD685 + 61C75828FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFC75828D6 + 8561FFFFFFFFFFFFF4DED4CE6E45C75828C75828C75828C75828CB6336FFFFFF + F0D2C6C75828E5B19BFFFFFFFFFFFFDD9B7EC75828D27953FBF4F1F0D2C6C758 + 28CE6E45FBF4F1FFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C75828C75828DA9070 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561 + C75828C75828F0D2C6FFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFFFFF0D2 + C6C75828D27953F0D2C6FFFFFFF0D2C6D68561E5B19BFFFFFFFFFFFFF0D2C6C7 + 5828E5B19BFFFFFFFFFFFFFFFFFFF0D2C6C75828D27953F4DED4FBF4F1E5B19B + C75828D68561FFFFFFFFFFFFC75828CE6E45F4DED4FFFFFFF0D2C6D27953C758 + 28F0D2C6FFFFFFF0D2C6C75828C75828D68561FFFFFFFFFFFFE5B19BC75828F0 + D2C6FFFFFFF8E9E2CB6336C75828F0D2C6FFFFFFE5B19BC75828F0D2C6FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFF + FFFFFFFFD68561C75828FFFFFFFFFFFFD68561C75828DD9B7EF8E9E2FBF4F1E9 + BCA9CE6E45F0D2C6FFFFFFE5B19BC75828E5B19BFBF4F1FBF4F1E5B19BC75828 + D68561FFFFFFFFFFFFD68561C75828DD9B7EF8E9E2FBF4F1E9BCA9CE6E45F0D2 + C6FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFF + FFFFD68561C75828C75828F0D2C6FFFFFFFFFFFFC75828D68561FFFFFFFFFFFF + D68561C75828E5B19BFBF4F1FBF4F1E5B19BCB6336FFFFFFF0D2C6C75828E5B1 + 9BFFFFFFDD9B7EC75828D27953FBF4F1FFFFFFF0D2C6C75828C75828D68561FF + FFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFD68561C75828F0D2C6F0D2C6ECC7B7D27953C75828E9BCA9FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828CE6E + 45FFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFFFFDD9B7EC75828ECC7B7FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFF + FFFFFFFFFFFFDD9B7EC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828F8E9 + E2FFFFFFC75828D68561FFFFFFFFFFFFFFFFFFECC7B7C75828DD9B7EFFFFFFF0 + D2C6C75828C75828C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFF + F4DED4C75828CB6336FBF4F1E5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C7 + 5828FFFFFFF8E9E2C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD27953C75828F8E9E2F8E9 + E2C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC7 + 5828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFD68561C75828 + C75828CB6336FBF4F1FFFFFFC75828D68561FFFFFFF8E9E2C75828D27953FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BE9BCA9C75828D2 + 7953FBF4F1FFFFFFFFFFFFF0D2C6C75828C75828C75828E5B19BFFFFFFE5B19B + C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C758 + 28FFFFFFFFFFFFFFFFFFECC7B7C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828D68561C75828E5B19BFFFFFFF0 + D2C6C75828D68561FFFFFFFFFFFFD68561C75828FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFD685 + 61C75828FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFC75828D6 + 8561FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFF0D2C6C75828E1A68C + D27953C75828F0D2C6E5B19BC75828F0D2C6FFFFFFFFFFFFE5B19BCB6336C758 + 28C75828C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFF0D2C6 + C75828DD9B7EF0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F8E9E2FFFFFFE5B19BC758 + 28F0D2C6FFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6F0D2C6C75828DD9B7EF0 + D2C6F0D2C6F0D2C6F0D2C6F0D2C6F8E9E2FFFFFFE5B19BC75828F0D2C6FFFFFF + FFFFFFFFFFFFD68561C75828FFFFFFFFFFFFD68561C75828E9BCA9C75828D685 + 61FFFFFFC75828D68561FFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFF0D2C6C75828CE6E45C75828CB6336F4DED4FFFFFFFFFFFF + FFFFFFF0D2C6C75828E1A68CD27953C75828F0D2C6E5B19BC75828F0D2C6FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BE5B19BE1 + A68CCE6E45CB6336F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFD68561C75828ECC7B7CB6336CB6336FBF4F1F0D2C6C75828D68561 + FFFFFFFFFFFFD68561C75828FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFF + FFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFC75828D68561FFFFFFFFFFFF + FFFFFFFFFFFFC75828D68561FFFFFFF0D2C6C75828E5B19BF4DED4CB6336CB63 + 36DD9B7EC75828F0D2C6FFFFFFF0D2C6C75828D27953ECC7B7F0D2C6DD9B7EC7 + 5828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828 + F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFF0D2C6C75828C75828C758 + 28C75828C75828C75828C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFF + FFFFFFFFFFE5B19BC75828F0D2C6F0D2C6C75828C75828C75828C75828C75828 + C75828C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD685 + 61C75828FFFFFFFFFFFFD68561C75828FFFFFFDD9B7EC75828E1A68CC75828D6 + 8561FFFFFFF0D2C6C75828E1A68CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + F0D2C6C75828D27953CB6336CB6336F4DED4FFFFFFFFFFFFFFFFFFF0D2C6C758 + 28E5B19BF4DED4CB6336CB6336DD9B7EC75828F0D2C6FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFD68561C75828D68561D68561CE6E45C75828E5B19B + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561 + C75828F0D2C6E9BCA9C75828DD9B7EF0D2C6C75828D68561FFFFFFFFFFFFE1A6 + 8CC75828E5B19BFFFFFFFFFFFFFFFFFFFBF4F1F8E9E2FFFFFFFFFFFFF0D2C6C7 + 5828E5B19BFFFFFFFFFFFFFFFFFFE1A68CC75828E9BCA9FFFFFFFFFFFFFFFFFF + CE6E45C75828FBF4F1FFFFFFC75828D68561FFFFFFFFFFFFFFFFFFECC7B7C758 + 28DD9B7EFFFFFFF0D2C6C75828E5B19BFFFFFFE9BCA9C75828C75828C75828F0 + D2C6FFFFFFE5B19BC75828ECC7B7FFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFF + FFFFFFFFD68561C75828FFFFFFFBF4F1C75828D68561FFFFFFFFFFFFFFFFFFE9 + BCA9C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD27953 + C75828F8E9E2FBF4F1C75828D68561FFFFFFFFFFFFFFFFFFE9BCA9C75828E5B1 + 9BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFF + FFFFD68561C75828FFFFFFFBF4F1D27953C75828C75828D68561FFFFFFFBF4F1 + C75828CE6E45FBF4F1FFFFFFFFFFFFFFFFFFF4DED4FFFFFFF0D2C6C75828E5B1 + 9BF0D2C6C75828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFE9 + BCA9C75828C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFD68561C75828FFFFFFFFFFFFFFFFFFD27953CB6336FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFF + FFD68561C75828E5B19BC75828D68561FFFFFFFFFFFFF8E9E2CB6336CB6336E5 + B19BF0D2C6E5B19BCB6336E5B19BE5B19BE5B19BDD9B7EC75828D68561E5B19B + E5B19BF0D2C6F8E9E2C75828CB6336E9BCA9F0D2C6DA9070C75828DD9B7EFFFF + FFFFFFFFC75828C75828D68561E9BCA9E9BCA9CB6336C75828F0D2C6FFFFFFF0 + D2C6C75828E5B19BFFFFFFFFFFFFDD9B7EC75828C75828F0D2C6FFFFFFE9BCA9 + C75828CE6E45E5B19BE5B19BD68561C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFE5B19BC75828DD9B7EE5B19BE5B19BE5B19BCE6E45C7 + 5828FFFFFFFFFFFFE1A68CC75828DA9070F0D2C6E9BCA9CB6336C75828F8E9E2 + FFFFFFE5B19BC75828CB6336E1A68CF0D2C6DA9070C75828D68561FFFFFFFFFF + FFE1A68CC75828DA9070F0D2C6E9BCA9CB6336C75828F8E9E2FFFFFFE5B19BC7 + 5828DD9B7EE5B19BE5B19BE5B19BCE6E45C75828FFFFFFFFFFFFD68561C75828 + FFFFFFFFFFFFF4DED4CB6336C75828D68561FFFFFFFFFFFFE1A68CC75828D685 + 61ECC7B7ECC7B7D68561C75828FFFFFFF0D2C6C75828E5B19BFFFFFFD27953C7 + 5828DD9B7EE9BCA9FFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFDD9B7EC75828 + C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C758 + 28E5B19BE5B19BE1A68CC75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFF0D2C6C75828CB + 6336C75828D68561FFFFFFFFFFFFFFFFFFF4DED4CE6E45C75828C75828C75828 + CB6336ECC7B7C75828C75828C75828C75828C75828C75828C75828E5B19BFFFF + FFE9BCA9CB6336C75828C75828C75828D68561FBF4F1FFFFFFFFFFFFC75828CE + 6E45CE6E45C75828C75828C75828E1A68CFFFFFFFFFFFFF0D2C6C75828E5B19B + FFFFFFFFFFFFFFFFFFD27953C75828F0D2C6FFFFFFFFFFFFE5B19BCB6336C758 + 28C75828C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFE5B19BC75828C75828C75828C75828C75828C75828C75828FFFFFFFFFFFF + FBF4F1DA9070C75828C75828C75828C75828E9BCA9FFFFFFFFFFFFE5B19BC758 + 28D68561C75828C75828C75828CE6E45F4DED4FFFFFFFFFFFFFBF4F1DA9070C7 + 5828C75828C75828C75828E9BCA9FFFFFFFFFFFFE5B19BC75828C75828C75828 + C75828C75828C75828C75828FFFFFFFFFFFFD68561C75828FFFFFFFFFFFFFFFF + FFECC7B7C75828D68561FFFFFFFFFFFFFFFFFFE1A68CC75828C75828C75828C7 + 5828D68561FFFFFFF0D2C6C75828E5B19BFFFFFFF4DED4D27953C75828D68561 + FFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFD27953C75828F0D2C6FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C7 + 5828CE6E45E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFDD9B7EC75828C75828D68561 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F0D2C6FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 + D2C6F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6 + F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9 + E2F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0 + D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6F0D2C6 + FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F0D2C6F8E9E2FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561 + C75828F0D2C6FFFFFFFFFFFFF8E9E2CB6336C75828D68561FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1A68CD68561F4DED4FFFF + FFFFFFFFFFFFFFE5B19BD68561E1A68CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD + FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFEFEFEFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFC + FCFCF7F7F7F1F1F1ECECECE5E5E5DEDEDED7D7D7D0D0D0CBCCCCC9C9C9C5C5C5 + C7C8C8CACBCBCCCCCCD1D1D1D8D8D8DFDFDFE6E6E6EEEEEEF4F4F4F8F8F8FBFB + FBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFCFCFCF9F9F9F9F9F9F7F7F7F6 + F6F6F6F6F6F7F7F7F6F6F6FAFAFAFBFBFBF9F9F9F8F8F7F7F7F6F8F8F7F8F8F7 + F8F8F7F8F8F7F8F8F7F8F8F7F8F8F7F8F8F7F8F8F7F9F8F8F9F8F8F9F8F8F9F8 + F8F9F8F8F9F8F8FBFBFBFFFFFFFBFBFBF8F8F8FAFAFAFBFBFBFCFCFCFCFCFCFD + FDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9 + F9F4F5F5F0F1F1F0F1F0F1F2F2F5F6F5FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F7F2F2F5F3F3F6F3F3F6F3 + F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6 + F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F2F2F5F9F9FAFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFEFEFEFBFBFBF7F7F7EFEFEFE7E7E7DEDEDED5D5D5CCCCCC + C3C3C3BABABAB2B2B2AFAFAFADAFAFAD9F97BC8265CC7A56C3805FB09A8CABAA + A9AAABABAFAFAFB4B4B4BCBCBCC5C5C5CFCFCFD7D7D7E0E0E0E8E8E8F0F0F0F7 + F7F7FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFCFCFCF9F9F9F6F6F6F4F4F4F1F1F1F0F0F0EBEBEBE8E8E8E5E5E5E4E4E4 + E5E6E6E6E6E6DDD5D0DBBEAFD8B39FD8B39FD8B3A0D8B3A0D9B3A1D9B3A1D9B4 + A1D9B4A1D9B4A1D9B4A1DAB5A2D9B4A2D9B5A1D9B5A1D9B5A2D9B3A0D9B3A0DE + C1B2E3DAD5EDEDEDEEEEEEEEEEEEF1F1F1F3F3F3F4F4F4F5F5F5F6F6F6F8F8F8 + FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFCFCFCFAFAFAF5F5F5EEEEEEE5E5E5CBCCCCA8ADAB85938C6D85795F7E6F5C + 7C6D607E706F867B899690B0B4B2D9D9D9ECECECEFEFEFF6F6F6FAFAFAFEFEFE + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFBFBDC96765825A587C6161856160836060835D5E835E5D82 + 5B5B815A5B805A5A7F59577F56577D56567D56567D55557C54557D54547E5454 + 7D52527C54547D54547D53517C4D4B73807D93E1E0E5FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7 + EFEFEFE7E7E7DEDEDED4D4D4CCCCCCC1C1C1BABABAB1B1B1ADADADABABABABAB + ABAEAFAFAFA29ACF8661EA7B48EE814BEC7D49D87F54B29A8DAFAFAFABACACAB + ABABABABABAEAEAEB4B4B4BCBCBCC4C4C4CFCFCFD7D7D7E1E1E1EAEAEAF2F2F2 + F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFD + FDFDFDFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBE9E9E9CFCFCFDADBDCBFA396E688 + 59E88552EA844FEA844EEA844FEB844FEB854FED8550EC8550EC864FEC864FEC + 8550EB854FEC8650ED8650EC8651ED8750ED8650ED8650ED8953E79063D0B6A8 + E3E3E3E2E2E2E4E4E4E7E7E7E9E9E9E9E9E9ECECECEEEEEEF3F3F3F8F8F8FDFD + FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7E9E9E9CD + CDCDB8B8B8848C8842715B307B5930865F33916734956A35966B349469318D63 + 2F845D327A59527665919694BCBCBCDDDDDDEFEFEFFBFBFBFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEADABB9 + 4C497375719E7E7BB1726FAD6C6BA86867A66362A55E5FA05A599D56559C5051 + 9D4B4B994747964444964140923D3E8F3B3B8F39388F36368D33328A28288620 + 1F82211F8426258525226D545174D7D7DCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF2F2F2EAEAEAE0E0E0D8D8D8CDCD + CDC5C5C5BCBCBCB2B2B2ADADADACACACACACACACACADADAFB0B1A8A3CD8966EE + 844DEA9C5DEEB86EECA863EB8750D8865BAFA29AB0B2B3ADADAEACACACACACAC + ACACACAEAEAEB4B4B4BFBFBFC8C8C8D1D1D1DADADAE4E4E4EDEDEDF4F4F4FCFC + FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFE6E6E6C5C6C7BFB0A7E58D5EED854EE5824DE5824DE6 + 824DE6844EE7844EE7844EE7854FE7854FE7854FE7854FE7854EE7854EE7854E + E7854EE7844FE7854EE7854EE5834EE6844EEE8850E48F5FCAB8ADD3D3D4D6D6 + D6D8D8D8DBDBDBDFDFDFE4E4E4E8E8E8EEEEEEF4F4F4FAFAFAFDFDFDFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7A4B1AB929995747B77377A5B + 32936731916734976B389E733BA3763DA6793CA5783AA175369C7035986C3597 + 6B3C70588083818F9C95D2D6D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFECCCAD257557A8C89B95F5CAA1C1B + 8117167E1D1B831E1A821C19811B1A7E17177D1212790F10760E0F7713137B14 + 157C0D0E760A0C750B0B750A0B750B0B760908760A097B1C1B851F1E85212087 + 292792222274676581EAE9ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEFEFEF9F9F9F1F1F1E7E7E7DEDEDED5D5D5CDCDCDC3C3C3BABABAB1B1B1AC + ACACACACACADADADACACACAEAFB0B1ADAAC29175EC854FF3B46BFBEC8FFEFC9D + FDF595F5C374F29053CE8E6AB1A9A3AFB0B1ADADADADADADACACACACACACACAC + ACB4B4B4BDBDBDC6C6C6CECECED8D8D8E1E1E1EAEAEAF3F3F3FCFCFCFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFE2E2E2C3C5C6B89784F98E52E6864FE88850E78750E88850E98850E98A51 + E98A51E98951E98951E98A51E98A51EA8B52EA8B52EA8B52E98B52EA8A51E98B + 51E98B51E98851E98A51EA8951F58E52C79374C8C9C9CECFD0D1D1D1D6D6D6DB + DBDBE2E2E2E7E7E7ECECECF4F4F4F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFCFCFC699E8355826C507162308D63339469318F643394 + 69379B703AA0753EA5793EA6783BA175389B7035986E379C7031815C57746644 + 8E6ABCCBC3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF4F4F77F7E9979759F6F6BB21010770F0F740E0D7708047408 + 03730A037208007200006E07077318177A1B187B100A75000070090A74141479 + 1312791313791111781C1C7C6B69A9B4B3D2A4A4CA4948940B0B7B28278E2321 + 5FB9B8C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF3F3F3EB + EBEBE0E0E0D7D7D7CFCFCFC6C6C6BCBCBCB4B4B4ADADADACACACADADADADADAD + AEAFAFB0AEADBD9882E98853F4B068FCF191FFFF9BFFFA97FFFF99FEFA95F7BF + 71F38E54C79679AFACA9ADADAEADADADADADADACACACACACACAEAEAEB6B6B6C0 + C0C0C8C8C8D1D1D1DADADAE3E3E3EDEDEDF6F6F6FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFEFEFEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFFFFE4E4E4C5C7C8 + B3907CFD9455E98B52EB8D52EB8D53EB8E54ED8E54EC8F54EC8E54EC8F54EE90 + 55ED9055ED9055ED8F55EE9055EE9055ED8F54EE9055ED9054EC8F54ED8F55EC + 8F54EB8E53F99557CA8D67CACBCBD0D1D1D4D3D3D9D9D9DFDFDFE5E5E5EAEAEA + F0F0F0F7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEFEFE6DA28933805A30694E2C875E309066308E6434946A379C6F3BA1743F + A5783EA4773AA174389B7036966B35976C2B805A2C6E4F389568C5D4CCFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 + F4F78181A28986AE413F963A3A8DAEABCE8684B81312790D0E760F0E7600006F + 242383918FBFC2C0DA8785B81D1A7C16147A8381B7AEACD0B2B0D2AAA8CC9E9C + C5A9A7CCE0DDEDFAF6FDE1DDEF7775B00A0B76211F8B26256AB4B5C4FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF1F1F1EAEAEADFDFDFD6D6D6 + CDCDCDC5C5C5BBBBBBB3B3B3AEAEAEADADADADADADACACADB0B1B1B59E90E68E + 5DF3A361FBE68AFFFF9AFFF693FFF592FFF592FFFC96FDED8DF8B068E78F59B4 + 9783A6A6A6ACADAEADADADACACACACACACADADADB5B5B5BFBFBFC7C7C7D0D0D0 + DADADAE2E2E2ECECECF5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9FAFA + FAFCFCFCFCFCFCF9F9F9F6F6F6F4F4F4F1F1F1F0F0F0EFEFEFEEEEEEEEEEEEEE + EEEEEFEFEFEEEEEEEEEEEEEEEEEEEEEEEEF0F0F0F0F0F0F2F2F2F5F5F5F8F8F8 + FBFBFBFDFDFDFBFBFBF9F9F9FCFCFCFFFFFFE6E6E6CACCCDB79580FF9A59EC90 + 54EE9055EE9255EF9357EF9257EF9357F09457EF9357F09458F19558F19558F0 + 9657F19558F19558F09457F09557F09457EF9457EF9357EF9357EF9256FD9B59 + C8906BD1D3D4D6D7D7D7D7D7DDDDDDE3E3E3EAEAEAEFEFEFF5F5F5FCFCFCFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F2F164A38629 + 81582A63472D835C3191662F8D64339369389A6F3AA0733CA3763DA578399D72 + 36996E34946B34966C287B56216F4B35996AB0C5BAFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F88A88A78C89B1 + 3E3C9555539EF3F1F9B7B5D60D0C7602026F00006D262483A5A2CBFDF9FEC7C5 + E0454597000069414293DCD9EBEAE6F3C0BFDAD1CFE3F5F1FAF6F3FAD7D4E8B9 + B6D5E3E0EFC1C0DB2425851614852E2C6EB8B8C6FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFCFCFCF3F3F3ECECECE1E1E1D8D8D8D0D0D0C7C7C7BEBE + BEB6B6B6ADADADACACACACADADAFB0B1B2A59BE19666F9A05EFAD580FFFD98FF + F593FFF595FFF99AFFF494FFF08FFFFA95FDE086FAA863E0915DA9988AAEB0B0 + ADAEAEADADADACACACAFAFAFB8B8B8BFBFBFCACACAD3D3D3DDDDDDE6E6E6F0F0 + F0F6F6F6FCFCFCFBFBFBF5F5F5EFEFEFE8E8E8E6E6E6E4E4E4E0E0E0DBDBDBD1 + D1D1CACACAC3C3C3BBBBBBB7B7B7B4B4B4B4B4B4B3B3B3B3B3B3B3B3B3B3B3B3 + B4B4B4B3B3B3B3B3B3B6B6B6BABABABEBEBEC7C7C7CECECED7D7D7DEDEDEE2E2 + E2E5E5E5E7E7E7F1F1F1E3E3E3D1CFCECC9F7FFE9C5BEF9557F09558F09758F2 + 9859F2985AF29859F29859F3995AF39A5BF39A5BF39A5BF49959F49A5AF49A5B + F39A5BF29A5AF39A5AF39A5AF2985AF3995AF1985AFD9E5CD3986ED7D6D5E0E1 + E1E2E2E2E8E8E8EDEDEDF4F4F4F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2DDD753A07B2D9165206745257752 + 34946832916732926836966C35966B389A7036996E399D72389B7034966C3191 + 6822734F26785334A16E8DB3A0FCFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F88B89A8918EB545449C54529DE6E4 + F0ACACD0090A7600006C2D2C87AEACD0F1EEF8B2B0D32B2A8400006A00006C4A + 4C99DCDAECBBB7D63534887C7BB2D5D3E7C8C6DF5C5BA13B3B8ED4D3E6C9C7DE + 2B2A881A1688302E70B8B8C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF9F9F9F1F1F1E7E7E7DEDEDED5D5D5CDCDCDC4C4C4BCBCBCB2B2B2AD + ADADAEAEAFB1ABA5D89A70FFA35FFACC79FEF794FFF492FFF190FFF89AFFFEA1 + FFF89AFFF191FFF291FFF694FED37EFFA963DE9E6EB1A9A1AFB1B2ACACACADAD + ADB4B4B4BEBEBEC5C5C5D0D0D0D9D9D9DFDFDFE3E3E3E6E6E6E9E9E9E8E8E8DE + DEDED3D3D3CBCBCBC2C2C2BABABAB3B3B3ACACACA4A4A49E9E9E9C9C9C969696 + 9191918E8E8E8C8C8C8B8B8B8B8B8B8D8D8D8E8E8E8D8D8D8C8C8C8B8B8B8B8B + 8B8D8D8D8F8F8F9393939B9B9B9D9D9DA2A2A2A8A8A8B1B1B1B9B9B9C2C2C2CC + CDCCD4D4D5D6CFCBE4A980FC9E5DF49C5BF39B5BF49C5CF59D5CF59E5DF59E5C + F59E5DF69F5DF6A05EF6A05EF6A05EF69F5DF7A05EF79F5EF7A05EF69F5DF69F + 5DF69E5DF69F5DF69E5DF59D5CF89E5DF6AB73E5DBD3F4F4F4F3F3F3F8F8F8FA + FAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFCBD9D24EA07A319B6C27785423714C2F8C63389B703698 + 6D3B9E73399C713EA17636976D3EA4773A9E723293692D865F2676512B845D35 + A67283A996FAFBFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF5F5F88B8AA99493B84A48A056539FDDDCEBC6C7DF7775B172 + 71AEAFADD1EBE8F4D9D7EA9C9AC7615FA4302C8900006B464796DBD8EAB5B2D5 + 201F802D2D8842429432328C00006D2B2B87D4D2E7C4C3DC2928861D1A8A312F + 72B8B7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB + FBFBF2F2F2E9E9E9E1E1E1D8D8D8CECECEC6C6C6BEBEBEB5B5B6B2AFAEC79F7F + F89E5EFDC274FFF191FFF492FFEE8FFFF697FFFC9DFFFC9DFFFB9DFFF798FFEE + 8FFFF190FEED8EFEC878FFAA65CEA17EB1AEABAFB0B1B7B7B7C2C2C2CACACAD0 + D0D0D1D1D1D1D1D1D1D1D1D2D2D2D6D6D6D4D4D4CBCBCBBDBDBDB2B2B2A8A8A8 + A1A1A19B9B9B9797979595959393938B8B8B8686868080807777777171716B6B + 6B6464646666666C6C6C7171716E6E6E6767676363636767676F6F6F7474747C + 7C7C8383838A8A8A909090949494959595969696979797959595A2A4A5CBC5C0 + E0A87EFEA661F6A05EF7A15EF8A15EF8A15EF8A35FF8A460FAA460F9A560F9A4 + 60F9A561F9A561F9A560F9A661F9A461FAA561F9A660FAA460FAA360F9A460F9 + A460F8A35FF8A25FFFB77AEFE6DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFD2DDD754A580339D6E348F663289602579543393693BA0743FA57942AA7D44 + AE8042AB7D41A97B3BA2742E8B622C835B349066318E6635A6758CB9A3FBFDFC + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 + F5F88D8CAD9895BA4D4BA05755A1D8D5E7E6E5EFEDECF3F1F1F6EDEDF5E4E2EF + E1E0EDE4E2EFE8E6F27372B000006A464495DDD9EABBB8D91D1D7F00006A0000 + 6F00007100006E3B3A8ED5D3E7C4C3DC2728871F1D8A333172B8B8C7FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9F9F9 + F2F2F2EAEAEADFDFDFD5D5D5CFD0D0CCCDCDC4AA95F6A163FDB96DFFE88CFFF4 + 93FFEC8EFFF293FFFB9BFFFB9CFFFA9AFFFB9BFFFB9AFFF293FFEA8DFEED8FFE + E68BFFC171F8A665C5AA92C5C4C3C5C6C6CACACACFCFCFD0D0D0CECECED0D0D0 + D6D6D6D6D6D6C8C8C8B8B8B8AAAAAAA5A5A5A5A5A5A4A4A4A0A0A09A9A9A9595 + 959292928D8D8D8585857F7F7F7979797373736B6B6B6464645D5D5D5F5F5F65 + 65656A6A6A6969696161615D5D5D6161616868687070707777777C7C7C848484 + 8A8A8A8D8D8D8383838383838080807C7D7D7E8081A5A09BCF9D73FFAD65FAA4 + 60FBA561FCA762FCA762FCA762FCA763FDA864FCA863FCA863FCA863FCA964FD + A964FCA964FCA864FCA963FCA964FCA863FDA863FCA863FCA762FCA763FCA763 + FFB97DFAF2EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7EBE961A98837 + A7743491683D9C702D845B2A835B36986D399E723DA37741A87B40A97B3EA578 + 379C702D885E36916639986C3392693AAC79A4C4B4FEFEFEFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F88E8DAE9B98BB + 5553A55F5CA6E6E1ECCAC6E06F6DB16A68AD6968AE6462AB6462AAABABD1F2F3 + F8807DB700006F474698DEDCEBB7B5D714147A00006900007000006E0000652B + 2B87D3D1E7C4C3DC27278623218C373574B8B8C7FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF7F7 + F7F2F2F2F6F7F7D5C9BDF9B272FFB56AFDDD86FFF192FFEB8EFEEF91FFFA99FF + FD9CFFFB9AFFFA99FFFA99FFFC9AFFF998FFED91FEE78DFEED90FDDE85FFBA6D + F5AE71D5C3B2E4E4E3DEDFDFDBDBDBDADADADBDBDBD3D3D3BFBFBFA7A7A79E9E + 9EAFAFAFB0B0B0ABABABABABABA6A6A6A0A0A09B9B9B9595958F8F8F8A8A8A83 + 83837D7D7D7878787272726B6B6B6464645E5E5E5F5F5F6565656A6A6A686868 + 6262625E5E5E6060606767677070707676767B7B7B8181818A8A8A8888887272 + 72727272757575747475737577877E73D19A66FFAE64FCA862FCAA64FCAA63FC + AA63FDAB64FDAB65FDAB64FCAA63FDAB65FCAA64FCAB64FDAC65FDAC65FDAB64 + FCAA64FCAA64FCAB65FDAB65FCAB64FCAA63FCA963FDAA64FCB275FFEBD9FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89B39F39AF7834976D3D9C71 + 399569287F58308F66399E72399D723CA1763EA5783CA276329168318D633A9A + 6E35916938A6754CAE80D1DAD6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F8908EB09D9CBE6461B06D6AB0EAE8 + F0C3C1DB4A479A3F3B94413E983B38943936919895C4F2F1F67F7DB70000764C + 4A9EDDDCEBC5C6DF5555A04140954644984544953F3D8F6160A4D9D8E9C4C2DC + 2C298827238F393777B8B8C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE5E0F8 + C28AFFB76CFDD480FFED90FEE98EFEEA8FFFF797FFFC9AFFFB98FFFA98FFFB99 + FFFA99FFFB99FFFB99FFF697FEE98EFEE58CFEE98FFED681FFB76BF9BD84E1D8 + CFEBECECDEDEDED2D2D2B3B3B39B9B9B8C8C8C8585858181819D9D9DB2B2B2AB + ABABA5A5A5A1A1A19D9D9D9898989393938E8E8E8A8A8A8383837D7D7D787878 + 7373736B6B6B6464645E5E5E5F5F5F6565656A6A6A6767676262625E5E5E6161 + 616868687070707575757B7B7B8282828A8A8A89898973737373737376767678 + 787976797D958573E3A164FFAE64FDAD67FCAD66FDAD66FDAD66FCAD66FCAD65 + FCAC65FCAC65FDAD65FCAC64FCAC64FDAD65FDAD66FDAC65FCAC65FDAD65FCAE + 65FCAC65FDAD65FCAD66FDAD66FCAD64FCB16EFEE0C7FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFCFD9D44FAD8039AB7837946B3B996E3590652F8B + 6137996E389A6E35956B37996E35966B3390643694683391683392693CB87F88 + B19CF6F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF6F5F89190B29F9DC06D69B57B77B7F2F0F3F3F2F3DFDDE8DD + DBE8DADBE9DAD9E8D9D6E6EBE7F0F9F5F77B79B50000723C3995DBD9E8F3F3F6 + DEDEECDDDDECDFDDECDEDEEBDCDAEADDDCEBF7F6FBC2C0DB2626862E2C913C3A + 77B8B8C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF9F6F7C59AFFB167FDCA79FEE88F + FEE68DFEE88EFFF395FFFA99FFF998FFF898FFF798FFF898FFF998FFF898FFF8 + 98FFF898FFF193FEE48CFEE48DFEE68EFECA7AFFB76AE3BA92D2CEC9B2B4B599 + 9A9A8C8B8B8383838080807E7E7E7A7A7A7E7E7EA0A0A0AEAEAEA7A7A7A1A1A1 + 9E9E9E9999999393938F8F8F8A8A8A8484847C7C7C7878787171716B6B6B6363 + 635D5D5D5E5E5E6464646868686464645D5D5D5A5A5A5E5E5E6767676E6E6E76 + 76767C7C7C82828288888881818174747474747476767676767672757992816F + E3A265FFB46AFCB66EFDB66FFCB56EFCB56EFCB36EFDB46EFDB46EFDB46EFCB3 + 6DFDB26BFCB26AFCB26AFDB169FDB169FDAF67FCAE66FDAF67FCAE67FCAF66FC + AE67FCAE66FCAE66FDB473FEE4CCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFDFDFD9BBBAA3FB47D39A673359565338D5F287B51277B4F287F5025 + 7B4E277E51287D522B7F5330895B31916339B17A59AD84D7DEDAFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 + F6F99190B3A3A0C17A76BA6661AEA39FCCA7A2CDA8A5CFA8A6CEA5A4CCA5A3CC + A2A0CC9A97C78583BB4A499D2A298C3938937370AF8C8ABE908EC1908FC18F8D + C18B8AC18B8BC08B8AC08583BC55539E14137E413E9C3E3C79B8B8C7FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFEFEFFDCB9FFB16BFDC073FEE48BFEE68EFEE48CFFEF92FFF8 + 98FFF898FFF697FFF697FFF698FFF697FFF597FFF697FFF596FFF497FFF496FE + EB92FEE18BFEE38DFEE08BFFC576FAB36CC7A8868B8D8D808588838483828282 + 7F7F7F7F7F7F7D7D7D797979848484A4A4A4ABABABA2A2A29D9D9D9898989191 + 918C8C8C8686867F7F7F7575756F6F6F6868685F5F5F5555554E4E4E4F4F4F57 + 57575C5C5C5B5B5B5858585656565D5D5D6565656D6D6D7171717E7E7E838383 + 8484847E7E7E74747476767676767676777773767A918270E3A265FFB970FDBB + 77FDBB75FDBC75FDBB75FCBA75FDBB75FCBA75FDBB75FDBA73FDBA73FDBA73FD + B973FCB771FDB971FCB870FDB56EFCB56EFDB46BFDB168FCAF67FDB067FDB067 + FCB571FEE2C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 + FAF986B89F39A9742B8B661D5E761B5A7F27667A336F7236726E31707725657E + 1A577F1F656C319E6C4DAA7CC2D5CCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F99391B6A8A5C4 + 8B87C34B46A44844A148449F4943A047439F44409D3F3B9A3B3799322D952926 + 8F6763ACA19ECAA6A3CC3F3C98120E8117158214128016148016148115128012 + 0C8007037B00007611117F4F4DA2424179B7B7C7FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE2 + C9FCB371FCBB71FDDD88FEE58DFEE18CFEE990FFF396FFF498FFF497FFF397FF + F397FFF598FFF397FFF297FFF296FFF297FFF296FEF297FFF196FEE78FFEDE8B + FEE28DFDDA87FFC272F0AE69AB93777F82847F81838180807F7F7F7F7F7F7F7F + 7F7D7D7D777777888888A4A4A4A1A1A19898989191918A8A8A8585858787878A + 8A8A8F8F8F9090908A8A8A8F8F8F9595958F8F8F9292929191919E9E9EC2C2C2 + C3C3C3BDBDBDB1B1B1ACACACA3A3A39595959494949999999898987F7F7F7272 + 7275757578787879797971767A998670EAA965FFBC73FCBE7AFDBD77FCBE78FD + BE78FCBD77FDBE77FCBE77FCBD77FCBD77FCBD77FDBD77FDBD76FDBC76FDBD76 + FCBD76FCBC75FDBC75FDBB73FCB972FCB66EFDB46BFDB269FCB169FED7B4FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEFEE5E8FA4 + 368AAE286AA4215E9F2660A0356BA23E71A53168A2235E9F2160A22D75A63892 + B089A2AEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F99492B8A9A6C6918CC56661B0908C + C4A9A6D0AFADD4B4B2D6B3AFD5ABA6D2AFABD49C98C9544FA58784BEB5B2D390 + 8CBF403C994F4BA09290C29693C39391C39A98C69896C48F8BC07E7AB64F4E9E + 1D1C86514FA449467BB8B7C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDDCFDBC7FFDB76CFED482FE + E38DFEDF8BFEE58EFEEE94FFF396FFF296FFF196FFF196FFF196FFF297FFF196 + FFF096FEF096FFF196FFF196FFEF95FEEF95FEED94FEE28DFEDB89FEDF8CFED3 + 82FFBF6EE3AB6A998C7A7A7F858081828080807F7F7F7F7F7F7D7D7D78787875 + 75758A8A8AA1A1A1A7A7A7B4B4B4C0C0C0C6C6C6CECECED4D4D4DEDEDEE3E3E3 + E3E3E3ECECECF6F6F6F3F3F3F5F5F5F2F2F2F3F3F3FFFFFFFFFFFFFFFFFFFBFB + FBF8F8F8F5F5F5F0F0F0E3E3E3D5D5D5C1C1C18B8B8B73737375757577777777 + 787870747AA58B70F5B067FFBE76FDC17EFDC07BFDC07BFDC17BFDC07BFDC17B + FDC17AFDC07AFDC07AFCC079FCC079FDC079FDC079FDBF79FDBF78FDBF78FCBF + 78FDBF77FDBE77FDBE76FCBC74FCB66DFDB369FDD7B0FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF678BA63797DC3C9CD94299 + CF4597CC4697CD4797CF4597CC4397CC4199CE3D9FE03488CC90A2AEFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF6F6F99594B9A8A4C89F99CCB9B6D8EFEEF6F0F0F7EFF0F7EF + F0F6EFEFF5F8F7F9FAF9FBAFACD34642A0736FB6AAA6CE5654A41B18883F3B98 + BEBDD9FCFAF9EEEAF3E8E5EFE9E5EFE8E5EFEBE8F0DDD9E86965AC524EA34C49 + 7EB8B8C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFF7EFFDC692FCB36AFDCF7FFEDF8CFEDE8BFDE08BFFEC93 + FEEF95FFF096FFF096FFF096FEF095FEF095FEF096FEEF95FEEF95FFEE95FFEF + 96FFEF95FEED95FFED95FFEE95FEE892FEDC8BFEDA8AFEDD8AFFCD7DFFBC6DCF + A36F87857F7B7F838180807E7F7E7C7C7C7A7A7A7E7E7E878787979797C2C2C2 + E5E5E5F2F2F2FBFBFBFEFEFEFEFEFEFEFEFEFBFBFBFDFDFDFBFBFBF4F4F4F3F3 + F3F4F4F4F2F2F2F2F2F2F3F3F3F2F2F2EAEAEAE2E2E2E9E9E9F0F0F0FAFAFAFD + FDFDFCFCFCFBFBFBF1F1F0B0B0B09A9A9A8E8E8E82828279797971757BA68D70 + F6B169FFC07AFDC380FDC37EFDC47EFDC47EFDC47EFDC47EFDC37EFDC37DFDC3 + 7DFDC37DFDC37DFCC27CFCC27BFCC17BFDC17CFDC27BFDC27BFDC17AFDC17AFD + C07AFCC17AFDBF76FDB86CFDD8B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF7F8F7A8B9B9397BA02E8FD9369AE547A5E75BB2EB65B9EB66 + BBE962B7EB54AEEA41A2E43499E82980C63778909FB2ACF2F4F3FDFDFDFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 + F6F99695BBA9A4CAADA8D3D9D5E7FAF6FAEFEBF4EBE8F3EBE9F3F1F0F7EDEEF5 + ADABD35E59AB6763B1716DB66D69B55B57AA5450A42D29913C3999B3B2D4F2F0 + F4E7E5EEE0DDEBDFDCEAE4E2EDF6F3F68F8CC15B58A84F4E7EB7B8C7FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF6 + FED2A6FDB36AFDC979FEDE8BFEDC8BFEDC8BFEE790FEED94FFEE95FEED95FEED + 95FFEE95FEED95FEED95FEED95FFEE96FFEE96FEEC95FEEC95FEEC95FFEC95FF + EB94FEEA94FFEA95FEE390FEDA8AFEDA8BFED889FFC879FABC6BBB9C737F8081 + 7C7F828180808B8B8B9797979F9F9FA9A9A9B0B0B0C3C3C3EBEBEBF4F4F4E5E5 + E5E1E1E1D8D8D8D3D3D3D0D0D0D1D1D1D0D0D0CACACAC9C9C9C8C8C8C8C8C8C8 + C8C8C8C8C8C3C3C3C1C1C1BDBDBDBEBEBEC0C0C0C2C2C2C5C5C5CDCDCDD9D9DA + DBDBDDA9AAACA2A3A4A2A3A49E9FA09394967E838AA89175F5B46CFFC57EFDC6 + 82FDC681FDC782FDC782FDC781FDC781FDC782FDC680FDC680FDC680FDC680FD + C57FFDC67FFDC67FFDC47FFDC57EFDC57EFDC47DFDC47DFDC47DFDC47CFDC27B + FDBB71FED4A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFF2F08E + AA993D8D893391C53189AC308797338B9B469DB863B4DF6AB9E858ABD33D95AB + 3189992E889A328AB73593BF398772A1B4A8FCFDFCFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F99896BDADA9CC + AAA6D2B8B5D7F3EFF6F6F2F6F2EDF5F7F3F8EAE7F1A7A2CF615CAD7D77BAD1CF + E49C9ACB514DA6605BAEBDBCDBA3A1CD2B2790302D93A3A0CAE6E5EEE9EAF0E4 + E2ECEDEDF2D4D2E45B59A7615FAC565482B8B8C7FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFDD8B7FCB56CFDC275FED8 + 89FEDB8BFED989FEE18FFFEB94FEEB94FFEB94FFEC95FEEB94FEEB95FFEC94FF + EC95FFEC95FEEB95FEEB96FEEB95FEEA95FFEB95FEE994FFEA94FEE794FEE894 + FEE893FEDF8EFDD789FDD889FDD486FFC776F6B86AAD9879888B8F969799A2A2 + A1AAAAAAABABABA7A7A79E9E9E959595A3A3A3C2C2C2C3C3C3BFBFBFBABABAB8 + B8B8BBBBBBB9B9B9BBBBBBBBBBBBBBBBBBBABABABABABABBBBBBBDBDBDBABABA + A9A9A99D9D9D9A9A9A9999999898989696969293958F92958E8F8E8585858B8C + 8B9192919798989798988C9297B89E7FF8BB70FFCA82FDCA86FDCA86FDC985FD + CA86FDC985FDCA85FDCA85FDC984FDC984FDC984FDC984FDC983FDC983FDC882 + FDC882FDC882FDC882FDC681FDC781FDC881FDC780FCC57FFDBF74FED19EFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8E1DC4B9A732F986B2B8362 + 298057258251248856298A612B8C77348F832A8C6E2689592183532881532B82 + 5C2C87642D9867779C8AE9EDEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6FA9997C0AFACCEAFA9D48D88C1C6C2 + DEEBE8F2F2EDF4E1DFEEA8A3CF736CB38983BEDBD7E9FDF8F9A5A0CE655FAE6A + 63B0C6C2DEFCFCFEA7A5CF393396332D938B88BFD4D4E5E3E3ECCFCEE17773B5 + 28248F726EB65A5884B7B7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFEE8CFFCBB76FDBE72FED284FED98AFED889FEDE8DFE + E793FEE893FEE894FEE894FEE994FFEA95FEEA94FFEA95FFEA95FEEA95FEE995 + FFE995FEE894FEE994FEE894FEE894FEE793FEE793FEE693FEE693FEE592FDDB + 8CFDD588FED78AFECF84FFC472EAB56FAC9E8C989CA19A9A9C9393938C8C8C8A + 8A8A898989858585858585A2A2A2BDBDBDBCBCBCBCBCBCBDBDBDBDBDBDBCBCBC + BCBCBCBBBBBBBBBBBBBABABABABABAB9B9B9BDBDBDADADAD9090909090909090 + 908F8F8F8D8D8D8A8B8B8A89869E8E7AB09573B19470AE9574AD9473AC9372B4 + 9B79B7A181DCAD76FFC477FECC88FDCD8AFECC89FDCC88FDCC89FDCB87FECC88 + FDCB87FDCA87FDCC87FDCC87FDCC87FDCC87FECC86FECB86FDCB85FDCC85FDCB + 85FDCA84FECA84FDCA83FDC983FDCA82FDC379FDC88BFEE7CBFEE4C7FEE4C6FE + E3C6FEE2C5FEE2C4FEECD8FFEEDBFEF2E4FFFEFDFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFDEE3E04F95742D95642A83572683572A93637EC2 + A19ED4B540A5761C925D76BF98A2D5B84FA97F2287592982572A81562C93643E + 986C9CB4A8F5F7F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF7F6FA9C99C1B1AED0B6B0D68A85BF8F8BC2A5A1CDAEA9D19A + 95C87F79BB938FC5D8D4E7FDFAFBF3EFF5ACA6D0746EB57772B7C5C1DEF9F5FA + FAF7FBB0ABD3504BA43F3C9C5F5CAA6E69B14D48A02B278F2E2B927E78BB5D5B + 88B7B8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + F3E6FDC68AFDBC70FECE80FDD78AFDD689FDD98BFEE492FEE794FEE693FEE694 + FEE793FEE793FEE794FFE795FFE795FEE794FEE894FEE794FEE794FEE694FEE6 + 94FEE695FEE693FEE594FEE594FEE494FDE492FEE593FEE190FED68AFDD388FE + D58BFECD7FFFC371DEB275918C817C7F848282838181818383838787878A8A8A + 8A8A8A979797B6B6B6BEBEBEBDBDBDBDBDBDBCBCBCBBBBBBB9B9B9B8B8B8B8B8 + B8B9B9B9B7B7B7B6B6B6BABABAA6A6A68B8B8B8F8F8F8F8F8F8D8D8D8B8C8D86 + 898BBB9D78F5C887FCD59CFBC57FFAB665FAB668F9B869FAB96AFBBA6BFCB769 + FEC379FECF8CFECF8DFDCE8BFDCE8BFDCE8BFDCF8BFDCE8AFDCF8BFECE8AFDCE + 8AFECE8AFECE8AFDCE89FDCE89FDCE89FDCD89FDCE88FDCD87FDCD87FDCD86FD + CC86FDCC87FECC86FDC77DFDC073FDC176FDC076FDBF74FDBF75FDBF74FDBA6C + FDC482FECE98FCC88CFEE0C0FFFDFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFDBE0DE4D8A6D2D906429845C248B5E6CBA95F4F0DDFFF8E2B4D7B779 + BF96EDEED6FFFBE9BBDBC1369C712181572C835C2D96675F9A7CCCD7D1FAFBFB + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 + F7FA9D9AC1B2ADD0B9B3D89490C3928EC28E89C08C87C08984BF9691C5D6D1E7 + F9F5F9F5F1F6EFEDF4B2AED5817CBB8581BCCCC9E2F3EFF7F8F3F9F9F3F7B2AE + D56D68B35752A84742A03F3A9D3A35983A3698837EC060608CB8B8C9FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF5FDD1A0FCBB6EFDCB7F + FED589FDD488FDD78AFEE190FEE493FEE493FEE493FEE594FEE593FEE693FEE6 + 94FFE595FFE694FEE594FEE694FEE694FEE594FEE594FEE594FEE494FEE494FE + E394FEE394FEE293FDE292FEE192FEE394FEDE90FDD489FED289FED28AFECA7D + FFC56FC3A16F7D7C7A7B7E818382838585858686868787878787878C8C8CA8A8 + A8B9B9B9B5B5B5B5B5B5B3B3B3B1B1B1B1B1B1B0B0B0AFAFAFAFAFAFAEAEAEAE + AEAEB2B2B2A1A1A18989898C8C8C8B8B8B888888858788848383E3AF71FFEABD + FFF5DFFFEAC5FFCA83FFC174FFC57AFFC57AFFC57AFDC277FDCA85FED291FED2 + 90FDD18FFDD290FDD28FFDD18FFDD18EFDD28EFED28EFDD28EFDD18DFDD18DFD + D08CFDD08CFDD18CFDD08CFDD08BFDCF8AFDD08AFDD08AFDD08AFDCF8AFECF89 + FDCE86FDCC84FDCC84FDCB83FDC980FDC77FFDC67BFDC880FFECD1FFFDFBFDE8 + C5FDC685FFF7EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE8DB09E30 + 9C6B2D8D632482582C9869BEE0C5F5E4C99A8A77C6BAA5EEE3C8A59683BDAA94 + F5F5DC6AB7931A85572C855D2D93654C9370BAC9C1FCFDFCFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F6FA9D9AC1B1ADCF + BCB8D89A95C39C96C49C97C59894C4948FC3BFBADAF8F5F9F0EDF5F3EFF6EFEC + F4B3AFD48983BF8C87C0CCC8E1F4F1F7EFEBF4F7F2F7EAE7F19996C87C76B87D + 78B97771B76762AF5C56AC9491C864628DB9B8C9FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFEFDFEE0BCFDBB6DFDC576FDD185FDD185FED286FEDC + 8CFEE291FEE190FEE292FDE392FEE393FEE494FEE494FEE494FEE494FEE593FE + E493FEE495FEE494FEE494FEE494FEE394FEE393FEE294FEE293FEE193FEE192 + FEE193FDDF90FEDE8FFEDF90FED88BFDCF86FDCF85FDCD82FFC875FBC36FAF99 + 767D7F808081828484848585858484848484848484849E9E9EB4B4B4B0B0B0B1 + B1B1B1B1B1B1B1B1B2B2B2B2B2B2B0B0B0B1B1B1B0B0B0AFAFAFB2B2B29B9B9B + 7E7E7E8484848484848484848283857F7E7EE2B070FFDEA6FFEFD6FFF5E1FEEC + CAFED69AFDD495FDD496FDD596FDD696FED594FED392FED493FED493FED593FE + D593FDD492FED592FDD491FDD491FDD491FDD390FDD390FDD490FDD38FFED38F + FED390FDD38EFDD28EFDD28DFED28DFDD28DFED18CFDD08CFDD08BFDD08BFDD0 + 8BFED18CFDD08AFDCE87FDCF8BFEE9C5FFFEFBFFFEFCFEE3B9FDC683FFF6ECFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDF0EE70A78A34A46F2D8E6324855A + 349D70D8EBD5E3DECD555452A4A299F0ECDC6464618B887FFFFFEB80C19F1A88 + 5A2B855D2E94673F976D9FB7ABF2F4F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F6FA9C99C1B0ADCFC0BBDCA09AC8A09B + C9A19CC89B97C59B98C5D2CFE4F9F9FAEDEDF4F3F3F7ECEBF4B2AFD28D87C08F + 88C0C9C4E0F3EFF6EFEBF4F1EDF5F4F0F6B2AFD3837DBC8782BE8882BF827DBC + 827CBCAAA6D1676390B9B8CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEEDD9FDC37EFEC378FED48FFDD592FED490FEDB93FEE196FEE295FEE49AFD + E193FEE193FEE194FEE193FEE194FEE294FEE295FEE495FEE394FEE294FEE294 + FEE294FEE294FEE194FEE194FEE094FDE093FDDF93FEDF92FEE094FEE099FEE2 + 9DFEE29DFFE19CFED997FED394FED494FED290FFCE7CE7BB728D867A7B7C7F80 + 80808080808080808181818080809A9A9AACACACA6A6A6A3A3A3A1A1A19C9C9C + 9999999696969292929090909090909393939797978282826A6A6A7272727575 + 7577777777787A77787BE2B170FFD187FDE6C1FEF0D5FEF1DCFFE5BCFDD596FD + D494FDD697FDD697FED696FED696FED696FDD695FED695FED796FED795FDD795 + FDD694FED794FDD794FED694FED694FDD693FED692FED592FDD693FDD591FDD4 + 91FED591FDD490FDD490FDD38FFDD38FFDD38FFED28EFED28EFDD18DFDD18CFD + CE85FEE3B5FFFAF0FFFFFDFFFBF3FDD69AFDC57EFFF7EDFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFF3F6F4A6BAAF3F8E692F946825865C319D6ECFE7D4FAF2 + E4C5BFB7E0DFDBFCFAF9CAC8C3D9D2C6FDFCEE7BC09F1887582B815C309A6B43 + 966ED4DBD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF7F6FA9D99C1B2ADD0C4BEDEA49ECDA5A1CFA6A0CDA29DCB9F + 99C8C7C4DEF8F8F9F0EFF5F5F5F9E9E8F1AEAACF928DC0918DC2C0BEDBF2F1F6 + F2EFF5F4F2F6EFEAF3A8A4CE8C87C1918CC3918AC38C85C18E88C2B5B0D66B69 + 94BABACCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF5FED6A6FDC47AFE + DA9FFFE5B7FEE4B7FEE8BBFEEDC0FEEFC3FEEFC6FEEBB4FDE29BFEE093FEE094 + FEE093FEE194FEE094FEE295FDE295FDE194FEE094FEE095FDE095FEE094FEE1 + 94FEE093FEE094FEDF94FDDF93FEDF91FEE09AFEE7ADFFEDB7FFEEB7FFEEB7FF + EBB4FFE3B0FEDEACFEDFB0FFD898F9CB79AA967178787778787A7B7B7B7B7B7B + 7A7A7A7878788C8C8C9A9A9A9191918989898383837878787070706868686262 + 625B5B5B5C5C5C6363636969696767676060606161616565656969696B6C6D6C + 6D6FD3A86EFFCB7CFEDBA3FEE9C5FEEFD5FFF1DBFEE3B7FDD798FDD899FED89B + FDD899FED899FED999FDD898FED899FDD999FED998FDD998FDD897FED997FED9 + 98FED998FED998FDD996FED896FED896FDD896FDD795FED894FED895FED794FD + D693FDD792FDD692FDD692FED591FED491FDD490FDD289FDDEA9FFF8EBFFFDF7 + FFFCF4FFF7E8FDD292FDC986FFF8F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFCED7D146A17636B47C2A8D6228956697CBB0FFFCF7FFFFFFFFFFFFFE + FBFBFFFFFFFFFFFFDCEBDE50AB841F8B5C319B6D37BD80589B7AE0E5E2FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 + F6F99A97C0B4AED0C7C2DFA8A3CDAAA6CFA9A5CFA9A3CFA29DCCAFA9D1E0DEEC + F5F5F8FBFCFCDDDAE9A6A1CB9B96C59994C3B2AFD1EDEDF3FBFBFBF3F3F8C9C6 + DF9892C4948FC39591C5948FC3928DC4948FC6BCB7DA6E6B96B9B8CBFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E9FDCD8EFDCC87FEE3B2FFE8C0FFECC8 + FFF3D4FFF7DFFFFAECFFFDF3FEE9B6FEDE94FEDF93FEDF93FEDF94FEDF94FEE0 + 94FEDF94FDDF94FDE094FEE094FEE095FDE095FEE094FEDF94FDDF93FEDE94FE + DE94FDDE93FEDC91FDE29AFCE2A7F3CC9AF1C795F4CF9AF7D5A0FAD8A2FBD8A4 + FDDAA7FFD397FBC677BFA26D7C7B7777797B7B7B7B7979797676767373738484 + 849191918989898282827C7C7C7777777171716969696262625C5C5C5D5D5D62 + 62626B6B6B6B6B6B6363636464646868686C6C6C6D6D6F6C6E70C5A06BFFC879 + FED694FEE0AAFFEBC7FFF1D6FFF1D9FEE3B2FDDA9AFEDC9EFDDB9DFDDB9DFEDB + 9DFDDB9CFEDB9DFDDB9CFDDB9CFEDB9CFDDB9BFDDB9BFEDB9AFEDC9BFEDC9BFD + DB9AFEDB9AFEDB9AFDDC9AFEDA98FEDA98FDDA98FEDA97FED997FDD995FDD995 + FDD895FED895FED895FDD58FFDDCA0FEF5E0FFFCF5FFF9ECFFF9EAFFF4E0FDD0 + 8EFED095FFFAF4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCED7D35D + A17F3BB77C34AE792A986A3BA0749AC7B0CCE4D7A1CCB882BCA1BFDCCFC1DDCD + 6DB4932B9A6B2FA9743DAD7740B77D88AD9BF4F6F5FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F9908DB8A7A2C8 + D7D4E8AFAACFABA5CEADA8CFABA6CEA9A3CEA59FCAB4AFD2D2D1E5DBD9E8BAB5 + D7A09BCAA09CCA9E9AC8A19DCAC4C1DCDBD9EAC6C2DC9E99C69793C29895C396 + 91C49692C38D8ABEA29DCCC2BFDD5E5C88B5B3C6FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF4E7FDC888FCC179FDD090FDDAA3FEE6B6FFEDC5FFF4D6FFF9 + ECFFFCF6FDDD9CFDD681FEDD94FEDD94FEDD94FDDD94FEDE94FEDE95FEDE95FE + DE95FDDE94FEDE95FEDE95FEDE94FEDE95FEDD95FEDC94FDDC94FEDC94FEDC94 + FFDF96F9D387E9A469E49762EAA76CF0B374F6BF7BF9C681FCC480FEBE76FBBB + 6DC3A77383827E7C7D7F7C7C7C7B7B7B7878787373738686869393938A8A8A84 + 84847D7D7D7979797373736A6A6A6464645D5D5D5E5E5E6565656C6C6C6D6D6D + 6565656565656969696C6C6C6D6D6E6D6E71CAA56DFFCA79FED693FDD897FDE2 + B0FEEECBFFF1D6FFEFD3FEE1AAFEDC9EFDDD9FFDDD9FFEDD9FFEDD9FFEDE9FFE + DE9FFEDD9EFEDD9EFEDD9EFDDD9DFEDD9DFEDE9DFEDE9DFEDE9DFEDD9CFEDD9C + FEDE9CFDDC9BFDDC9AFDDC9AFEDC9AFDDB99FEDC99FEDB98FDDA98FDDA97FDD9 + 93FEDC9DFFEFD0FFFAF1FFF8ECFFF6E4FEF4E0FFF2DCFECC85FED193FFFAF3FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E9E8CCDCD4B9D1C452AA81 + 37C08529A671309A6B4AA67B33A37225A16C44A57941A176289B6B33B87F46B0 + 7EA8CEBBC1D4CAD4DBD7FAFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBDB8C77770A1D3D2EBDAD6EABEB8 + D7B9B4D5B9B4D5B9B4D5B6B1D3B0ADD2B3AFD3B4AFD3AFA9D2AFAAD3B1ABD3B0 + AAD2ABA6D1AAA5D1ADA9D3A8A2CFA6A1CDA9A4CFA8A3CDA6A0CBA4A0CAADA8D1 + D5D1EB9C9BC0636186DFDEE4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 + E7FDC688FCB96FFDC47AFDD590FEE2A7FFE9B7FFF0CCFFF7E7FFFBF3FDD58DFD + D17DFDDE96FDDD95FDDC94FDDC94FEDC94FDDD94FDDD94FEDE95FEDE96FEDC94 + FEDC94FEDC95FDDD95FDDD95FEDB95FEDB95FDDB93FDDB96FFDD94FBCC78ECA2 + 5DE69256EB9F5DF0AA62F5B568F9BE6EFCBC6CFEB467FBB369C4A4738585807D + 7E7F7C7C7C7B7B7B7979797474748585859292928A8A8A8484847E7E7E797979 + 7373736B6B6B6464645D5D5D5F5F5F6565656C6C6C7272726969696363636A6A + 6A6D6D6D6E6F706D6E71BE9D6DFDC978FFD793FED894FEDA99FDE6B5FFEECBFF + F3D8FFEFCCFEE2A9FEDEA2FEE1A3FDE0A4FDE0A2FEE1A3FEE0A2FDE0A2FEE0A2 + FEDFA2FDDFA1FEDFA1FEE0A0FEE0A0FEE0A1FEDFA0FEDFA0FEDF9FFEDF9FFDDE + 9EFDDE9DFEDE9EFDDE9DFEDE9DFDDD9CFEDD9CFDDC98FDDC99FEECC6FFF9ECFF + F8EAFFF5E2FFF2D7FFF4DBFFF1D9FDCB83FDDAA6FFFCF8FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8D2CD63AC8938BF822FAC + 782698692C9D6F30A072289B6B289B6C35B98144B280ADCABCFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFF7F6F7A5A0BA7876ADBEBCD9D5D3E8D3D0E7D1CFE6D1 + CFE7D1CEE6D1CEE6CDCAE3CCC8E4CECCE5D0CDE5D1CCE5D1CCE6D0CBE6CCC7E4 + C7C5E1C9C8E3CECBE5CDCAE5CDC9E3CCC8E1CBC7DFCAC7DF9795BB5B5686C4C2 + CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E7FDC587FCB96FFE + C980FEDA95FEE1A8FFE7B9FFEDCCFFF8E6FFFCF3FDD48EFED07DFDDC96FEDC95 + FEDC95FDDC94FEDC94FDDB94FDDB94FEDC95FEDC96FEDC94FEDC94FEDC95FEDB + 95FDDB95FEDB96FEDB95FDDA94FEDB97FEDB93FCCB7AEFA762E69459EB9D5EF0 + A963F5B36AF9BF71FCC373FEB86BFBB067C4A0718483807D7E807C7C7C7A7A7A + 7878787777778888889393938A8A8A8484847E7E7E7979797272726A6A6A6363 + 635C5C5C5E5E5E6464646A6A6A7474747171716767676969696D6D6D6F6F706D + 6F72A48F6DF5C475FFD78EFDD893FED892FEDC9AFFE7B6FFEFCAFFF3D9FEEDC8 + FEE2A9FEE3A6FEE2A8FEE2A6FEE2A6FEE2A6FEE2A6FEE2A5FEE1A5FDE1A4FEE1 + A5FEE2A4FEE2A4FEE2A5FEE2A4FEE2A3FEE2A2FEE2A2FDE2A1FDE1A2FEE1A1FE + E1A1FEDFA0FDE0A0FEDF9FFDDE9BFDE9BBFEF8E9FFF7E7FFF5E0FFF1D3FFEFCF + FFF3D7FFF0D0FDCF85FEECD2FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3EBE77CB89B3BC48835AC7B33986F32 + 986E339C7137B88240B380A7C4B6FDFEFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFF8F8FAB3AFC97A73A46D69A0746EA1726DA1726DA1726DA1736DA1 + 736EA1736EA1736EA1726DA1716CA0706CA0706A9D6F699C6C699C6B67996A65 + 96686496666294656292676191575483706B93CDCBD8FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E7FDC585FDBB70FDCC81FDD794FEDEA6 + FEE5B7FFEECCFFF8E6FFFBF2FDD28DFDCD7CFEDB95FDD995FDD994FEDA95FEDA + 96FDDA95FDDA95FDDA95FDDA96FEDA96FEDA95FDDA96FDDA96FEDA96FED996FD + D995FED995FDD999FED994FBC879EEA561E59256EB9A5CF1A663F6B069FABC6E + FDC272FFBF70FAB268C4A1708685817E7F817E7D7D7C7C7C7979797C7C7C8B8B + 8B9090908888888181817A7A7A7575756F6F6F6767676161615A5A5A5C5C5C61 + 61616767676F6F6F7575756E6E6E6666666A6A6A6F6F6F6C70727C7872DB9E63 + FBB36EF9C183FBC686FCC786FDCF94FEE0B5FEE8C8FFEED5FEE7C0FDDAA2FDDA + A3FDDBA4FEDCA4FEDDA5FDDDA4FDDDA4FEDDA4FEDDA3FEDEA4FDDFA4FEDFA4FE + DFA3FDE0A3FEE0A3FDE0A3FEE1A3FEE1A3FEE0A3FEE1A3FDE1A2FEE1A3FEE1A3 + FEDF9EFFE6B2FFF6E2FFF8E8FFF5DEFFF2D2FFEFCAFFF0CFFFF2D4FFE2A6FDD7 + 93FFFAF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFD5DDD956A6803ACC8D37B58133A47637B68237C587 + 75A78FF8F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FEFEFED5D3DF8F8AAB746D927871967872977872977872977871977871977871 + 97787297787197767195767093766F92756E92736C91716B8E706B8C70698B6E + 698A686384847D95D9D8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF3E7FDC385FCBA6FFDCD82FDD694FDDEA8FEE7BAFEEFD0FEFA + EDFFFEF9FDD18EFDCC7CFDDA97FDD996FDD995FDD995FDD996FED996FDD996FD + D996FDD996FED996FED996FED996FED996FDD996FED896FDD895FED896FED899 + FED895FCC879F0A661E69056EB995BF0A561F5AE67F9BA6DFCBF70FFBF70FBB3 + 69D1AE7BA09E9B98999B9696969191918C8C8C8E8E8E9090908D8D8D8C8C8C86 + 86868383837E7E7E7F7F7F8C8C8C8B8B8B8585858787878B8B8B8989898D8D8D + 8F8F8F8F8F8F9090908585857A7A7A7375767073769D7D66E88E51F6A366F6B5 + 7BF8B97EFABA7EFDCA94FEDEB6FFE5C5FEEBD3FEDEB5FDD49FFDD5A2FDD6A3FD + D7A3FED8A4FDD9A3FDD9A3FEDAA4FDDAA3FEDCA4FEDCA4FEDCA4FEDDA4FEDDA4 + FDDDA5FDDEA4FEDFA4FEDFA4FEDFA4FEE0A4FEE0A4FDDF9FFEE3AAFFF2D7FFF8 + E6FFF5DEFEF1D2FFEEC6FFEEC7FFF1CFFEE6B1FDD283FEEDCCFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFBAC5BF46A87B3EC88D38C78B36C689609D81E0E4E2FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F3 + F6EDECF0EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1ED + EDF1EDECF0EDECF0EDECF0EDECF0EDECF0EDECF0EDECEFECECEFEBEAEEF2F1F3 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 + E5FDBD80FCB76DFDC87FFDD18EFDD99FFEE1B0FEE8C3FEF2DAFFF6E5FDCB87FD + C97BFED897FED796FED796FDD896FDD896FDD796FDD796FDD796FED797FDD896 + FDD896FED897FED797FDD796FED796FED796FED695FED899FED494FEC678F4AC + 64E78F56EA9659F1A25FF5AD67FAB86CFDBB6FFFBB6DFCAF65D9AB7CADAAA7A6 + A7A9A7A7A7A8A8A8A6A6A6AEAEAEBCBCBCC4C4C4D6D6D6E0E0E0E8E8E8EAEAEA + EAEAEAF0F0F0F0F0F0EFEFEFF0F0F0F0F0F0EFEFEFEEEEEEEEEEEEEFEFEFEFEF + EFCFCFCFBCBCBCBDBDBDAAABAC9B9B9ABF9170EC8F54F4A569F5B279F8B479FB + B87BFCCB98FFDDB6FEE5C7FEE8D0FDDBB0FDD5A1FDD6A4FED7A5FDD8A5FDD7A5 + FED9A5FDDAA5FDDAA6FEDBA5FEDBA5FEDCA6FEDDA5FEDDA5FDDDA6FEDEA5FDDE + A5FEDEA6FEDFA5FDDFA6FDDFA2FDE1A9FEEECDFFF6E2FFF3DBFFF0D0FEEAC0FE + EAC1FEECC6FFE8B8FED286FEDDA9FFFDF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFB + FACBD3CFABC1B768B39063A384DCDFDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E8FDBC84FDB067FC + B66CFCBA70FDBB74FCBD76FDC17AFDC37FFDC381FDB96FFDC47EFED194FDD093 + FED092FDD093FED193FDD093FDD193FDD193FDD093FDD193FDD193FDD193FDD0 + 93FDD093FED093FDD093FDCF92FED196FDCE91FDBB72F7A762F29858F59B59F9 + A25EFCAA62FFAF65FFB065FFAC60FCA55ED7AC83B6B5B2B9BBBCCACACADCDCDC + EFEFEFF7F7F7FBFBFBFCFCFCFCFCFCFDFDFDFAFAFAF9F9F9F9F9F9F4F4F4F3F3 + F3F4F4F4F3F3F3F4F4F4F4F4F4F4F4F4F5F5F5F1F1F1EDEDEDE3E3E3CACACAC2 + C2C2BFC0C0BABDBFB7B6B4D69A71EF9153F2A66BF5AF75F8B275F9B87BFCCD9B + FEDCB4FEE6CAFEE7CBFEDAADFDD6A5FED8A8FED9A8FDD8A8FED9A7FEDAA8FEDA + A8FDDBA7FDDBA7FEDCA8FDDCA7FDDCA7FEDEA8FDDEA7FEDEA8FEDEA7FDDFA7FE + DFA6FEE0A7FEEBC6FFF3E0FFF2D7FFEFCDFEE8BDFEE8B9FEEAC0FEE6B7FDD38B + FDD394FFF7ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 + F6F3F1F5F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF9FEDCBFFDBC84FCB67AFCB67AFCB67B + FCB77BFCB97AFCB87AFDB06AFCAF66FDC384FDCC92FDCB90FDCA8FFDCA90FECB + 91FDCB91FDCB91FDCC91FDCB91FDCB91FDCC91FDCB91FDCB91FDCA90FDCA90FD + CA90FDCA90FDCD95FDC88EFDB16AF9A862EFA766EAA667EBA466EAA365E8A062 + E79F62EEA465F0B37FDBCDBFE1E3E3F3F3F3F6F6F6F3F3F3F3F3F3EFEFEFE7E7 + E7E2E2E2DBDBDBD4D4D4CCCCCCCACACAC8C8C8BFBFBFBEBEBEBFBFBFBFBFBFBF + BFBFC0C0C0C2C2C2C2C2C2C2C2C2C2C2C2C3C3C3B2B2B2A0A0A0A4A4A3AAAAAA + ADB2B5B7ABA1DD905DF39456F1A76DF4AD73F7B074F8BA7DFDCF9FFEDCB5FEE6 + CAFEE5C6FED9ABFED7A9FDD9AAFED9AAFED9AAFEDAAAFEDBAAFDDBA9FDDBA9FE + DBA9FEDCAAFEDCAAFEDDAAFEDDA9FEDEA9FDDEA8FEDEA8FEDCA5FEE6BDFFF3DD + FFEFD4FFEDCDFFE8BBFEE4B3FEE6B9FEE8B9FED490FDCD83FFF0DDFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFDFCFFF8F3FFF2E8FFF2E7FFF3E8FFF3E8FFF4EBFFF2 + E8FEC797FCAC65FDC283FDCC93FECB92FDCA90FDCA92FDCB92FECB92FECA92FE + CB93FDCB92FECB93FECB93FDCB93FDCB92FDCB92FDCA92FDCA91FDC891FDCC96 + FDC88FFFB069EDA462B397779A90859B90829B8F829D9183A19487BFB5AAE2E5 + E5EBEDF0E8E8E8E4E4E4DCDCDCD3D3D3CACACABFBFBFBBBBBBBCBCBCBCBCBCBC + BCBCBCBCBCBBBBBBBBBBBBBCBCBCBDBDBDBBBBBBBBBBBBBCBCBCBBBBBBBBBBBB + BCBCBCBBBBBBBDBDBDBEBEBEBDBDBDA8A8A89292929090908F90908E9295A690 + 80E08853F1955AF2A56CF5AC71F5AD70F8BA80FCD0A3FDDAB5FEE6CBFEE3C3FD + D8ABFDD8ABFDDAACFDDAACFEDAACFDDBACFEDCACFEDCACFEDCACFDDDACFDDDAC + FDDDACFEDDABFEDDABFEDDABFDDDA8FFE3B6FFF0D7FEEFD3FEEBCAFEE5BBFEE0 + ACFEE3B0FDE5B5FDD799FDC87EFEE9CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCA3FDAA65FD + C184FDCB94FEC992FDC992FDC992FDCA92FEC992FECA92FECA92FDCA92FDCA93 + FDCA93FDCA92FDC992FDC992FDC892FDC993FDC791FDC996FBC58EFFAC65E99E + 5FA1907E838A90878C908D9296989CA09BA0A4B3B7BBD0D2D6D1D2D3C5C5C5B7 + B7B7B4B4B4B7B7B7B9B9B9BABABABCBCBCBCBCBCBCBCBCBCBCBCBBBBBBBBBBBB + BCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBABABAB9B9B9BABABABBBBBBBBBB + BBBBBBBBBEBEBEBCBCBC9F9F9F8D8D8D8C8C8C898A8C84898BA68570E3864FF0 + 955BF0A26AF2A76BF4A96BF8BA82FBD0A3FCDBB4FDE8D0FDE1BEFDD9ACFDDAAE + FDDAAFFEDAAFFDDBAFFDDCAFFDDCAFFEDCAEFDDCAEFDDCAFFEDDAEFEDDAEFEDD + AEFEDEACFEE1B3FFF0D4FFEED2FEEAC7FEE3B9FEDCA6FEDEA9FEE1AEFDD89CFD + C478FEDFB8FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFC9C8C8BCBCBCBCBCBCBCBCBCBABABA + D0D0D0FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDFBF7C79EFDA662FCBD80FDC891FDC58F + FCC58FFDC790FDC78FFDC690FDC790FDC790FDC690FDC690FDC890FCC690FCC5 + 90FCC690FCC58FFBC48FFBC38EFAC593F8BF8BFDA560E9975BA28F7C898C8F92 + 92939999999898989090919A9A9AACACACAFAFAFB0B0B0B4B4B4B7B7B7B8B8B8 + BABABABABABABABABABABABAB9B9B9B8B8B8B6B6B6B6B6B6B7B7B7B5B5B5B4B4 + B4B5B5B5B5B5B5B4B4B4B4B4B4B6B6B6B6B6B6B7B7B7B8B8B8B8B8B8B8B8B8BB + BBBBB3B3B39797978D8D8D8C8B8B86888B858686B18365E9864EEE965DEF9F66 + F1A267F3A86BF7BC86FBCEA0FCDAB6FEE7CEFEDFBBFDD9AFFEDBB1FEDBB1FEDB + B1FEDCB1FEDCB1FDDCB0FEDDB0FEDDB0FEDDB0FDDDAFFEDEAEFEE0B2FEEBCCFF + EDD2FFE6C3FEE1B7FED9A3FDD8A1FDDCA9FED89EFDC47BFDD19CFFF9F2FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFEBEBEBA6A6A6A5A6A6A8A3A6ABA3A7AAA2A7A7A5A6A0A1A1C2C2C2FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFEFCFBF5C29BF79F5EF9B77CF9C48EFAC18CF9C18BF9C28CF9C2 + 8CFAC28DFAC38DFAC38DF9C28CF9C28CFAC28CF9C28DF9C28CF8C28CF8C08BF7 + BF8BF8BF8AF7C18FF5BB87FA9F5FE691579F8B78898C8E8D8D8D888888838383 + 7A7A7A838383A8A8A8B4B4B4B4B4B4B6B6B6B7B7B7B8B8B8B8B8B8B7B7B7B7B7 + B7B5B5B5B5B5B5B5B5B5B4B4B4B2B2B2B2B2B2B1B1B1B1B1B1B0B0B0B0B0B0B0 + B0B0AFAFAFADADADAEAEAEB0B0B0B1B1B1B0B0B0B0B0B0B2B2B2B4B4B4A7A7A7 + 8D8D8D86868687868682858788847FC1815AEC884CEC955DEE9D65F0A167F3A8 + 6CF7BC89FBCEA2FDDCBAFEE8CFFDDDB9FEDAB2FEDCB4FEDCB4FDDCB3FDDCB3FE + DDB3FEDDB2FEDDB2FEDEB3FEDEB2FEDEB2FFE8C8FEECD1FDE5C1FEE1B6FDD79F + FDD49AFED7A2FED7A0FCC57FFDC383FFF2E4FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDDEDEDED2D2D2DCDCDCFFFFFFBFBFBFB9BA + BACDCCCDC1C9C5B9CDC2BACAC2C6C7C6CAC9C9AAAAAAFAFAFAF0F0F0D4D4D4D5 + D5D5EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFC + FBF2BB97F3995AF5B078F5BD89F6BC88F6BC88F6BC87F6BB87F7BD89F7BC88F6 + BC88F7BD89F5BD89F6BB89F5BB88F6BC89F6BB89F4BA88F5BB89F4B886F4BB8B + F3B584F6985AE28B54988572797D807978797575757878787C7C7C878787A9A9 + A9B3B3B3B0B0B0B2B2B2B2B2B2B1B1B1B0B0B0B1B1B1B0B0B0AFAFAFB0B0B0B0 + B0B0AEAEAEAEAEAEACACACADADADACACACACACACABABABACACACAAAAAAA9A9A9 + AAAAAAAAAAAAABABABABABABACACACADADADADADADAEAEAE9E9E9E8787878282 + 828483837B82868C8075D07E50EB864DEA935CED9960EF9B62F1A46AF6BB8AFA + CCA1FBDEBEFEE6CEFDDCB8FDDAB5FEDDB7FDDCB5FDDCB5FEDDB6FEDEB6FEDEB6 + FEDEB5FEDEB4FFE6C4FFECD2FEE3BEFDDFB5FED59EFDCF93FDD299FED49BFDC5 + 82FCBF7BFEEBD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFE2E2E2A1A1A1AFAFAFA6A6A6F2F2F2B4B4B4C5C2C4BEC0BF91D2B06E + D9A376D6A4AAC8B8CBC4C7AAAAAAF5F5F5C3C3C3AFAFAFAAAAABADADAEFEFEFE + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFCFBF1B895EF9356F2 + AB75F4B786F3B584F4B784F4B884F4B784F4B786F4B684F4B784F3B785F3B885 + F3B785F3B684F4B685F3B585F3B685F2B685F2B382F1B787EEAF80F39256DC82 + 4F887463686C6E7070707979787D7D7D7E7E7E878787A5A5A5ACACACAAAAAAAD + ADADACACACAAAAAAA8A8A8A8A8A8A9A9A9A8A8A8A9A9A9A8A8A8A6A6A6A5A5A5 + A3A3A3A4A4A4A4A4A4A4A4A4A3A3A3A3A3A3A2A2A2A3A3A3A4A4A4A4A4A4A5A5 + A5A6A6A6A5A5A5A5A5A5A5A5A5A6A6A6A7A7A79292927E7E7E7E7E7E7D7E7E76 + 7C7E947A69D47B4CE9844EE89059EB935DEC955CF0A269F6BD8CF9C99DFADEC1 + FCE6CCFCDCB8FCDCB8FDDDB9FDDDB8FEDDB8FEDFB9FDDFB7FDDEB6FEE3C1FFEA + D1FFE1BCFEDCAFFDD29DFDCA8CFDCC91FDCE94FDC583FDB974FEE3C8FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDBE + BEBED9D9D9B5B5B5F0F0F0AEAEAED0C7CBB2BFB968D09D44D9914DD89490C9AC + CCC4C8B0AFAFEAEAEAC3C3C3D1D1D1D5D5D6AAAAAAFBFBFBFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFCFBEFB694EB8C53EFA772F2B483F1B181 + F2B281F2B281F1B281F1B282F1B281F2B281F1B281F1B281F3B181F2B181F1B1 + 81F1B181F0B081F0B081EFAF7FEFB284ECAA7DF18D54D77B49836D5D6A6E7075 + 75767A7A797B7B7B7979798181819E9E9EA5A5A5A1A1A1A3A3A3A3A3A3A2A2A2 + A1A1A1A1A1A1A1A1A1A0A0A09F9F9F9A9A9A9696969090908C8C8C8A8A8A8686 + 868383838383838686868989898888888787878A8A8A8F8F8F9393939898989B + 9B9B9C9C9C9B9B9B9C9C9C999999838383757575787878747677737576A0765E + DC7947E8844EE78B57E99059EA945BEFA56FF5BC8EF7C79FFBE0C6FCE4C9FADB + BAFCDCBBFDDCBAFDDDBAFEDEBBFEDEB8FEE0BEFEE9D0FEE1BEFEDAACFDD19DFD + C688FDC88AFDCB8EFDC686FDB56DFED1A7FFFDFBFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFDFDFDE5E5E5DDDDDDDFDFDFE1E1E1E3E3E3AEAEAEC3C3C4CCCCCDAFAFAF + F6F6F6AAAAAAD8CCD2A6BFB254CD9039D0853DCF877AC8A0CAC5C7BDB8BAD8D8 + D8D8D8D8BDBDBDCACACAAAAAAAD8D8D8F9F9F9EEEEEEEDEDEDEDEDEDFAFAFAFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFEFCFBEDB392E6844FEBA06EEDAD7FEEAC7DEEAB7CEEAB7CEEAB + 7CEEAB7DEEAB7DEEAC7DEFAD7DEEAC7CEFAC7DEEAB7DEDAB7DEEAB7DECAA7CED + A97CECA87BECAB7FE9A477EC8650D577488871616D7173737374757575767676 + 7474747B7B7B9595959B9B9B9898989A9A9A9B9B9B9A9A9A9B9B9B9A9A9A9797 + 979393938D8D8D8686867F7F7F7979797272726B6B6B6666665F5F5F60606067 + 67676969696B6B6B7474747B7B7B8181818888888E8E8E9595959999999D9D9D + 9E9E9E9F9F9F9696967A7A7A7070707170706E6F726F7070AA7254E47945E481 + 4EE48854E88B57EA9059EEA470F4BB8DF7CAA3FBE4CDFBE0C6FBDBBCFBDCBEFC + DDBDFDDDBDFDDFBFFDE8CFFEE1C0FED6A8FECF9BFDC385FDC183FDC588FCC283 + FDB36EFEC28CFFF5ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFF1EFEDCBC1BAB1A095AE978AB29989B2998AAC9689B4A49ADDD6D1FEFE + FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BEBEBEACACAC + ABABABA6A6A6A5A5A5A7A7A7B4B4B4C7C7C9CBCBCEB3B3B3EAEAEAADADADDBCE + D593BDA642C58039C77D39C77D61C28DC6C6C7C7C0C4C5C6C5E9E9E9B6B6B6CF + CFD0BABABCA8A8A8A4A4A4A3A3A3A2A2A2A7A7A8A7A7A7ECECECFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFB + FAEBAC8FE2804BE89A6BEAA77AEBA578EBA677EBA678EBA577EBA478EBA578EB + A578EBA679EBA678EBA678E9A577EAA578E9A478E9A277E9A277E9A276E9A57B + E69E73E77D4BD27145866F606B6E706F70717272727171716D6D6D7676769393 + 939C9C9C9E9E9EA1A1A1A2A2A29F9F9F9C9C9C9797979393938E8E8E89898982 + 82827A7A7A7777777070706767676161615A5A5A5C5C5C636363636363666666 + 7676767E7E7E8484848989898D8D8D9393939999999E9E9EA2A2A2A5A5A5A8A8 + A89C9C9C8080807373726C6B6B62686B6B6764B36E4BE17644E17D4CE38350E5 + 8752E68C55EBA26EF2B789F6CBA8FAE4CFFADFC5FADBBFFADDBFFBDDBEFCE7CF + FCE0C3FBD0A2FBCA97FCBD81FBB97AFBBD80FDBF80FCB26DFCB57AFFEEE2FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E2DFAD9B9090715F7E59 + 3E76492A794A2A7B4C2B7A4C2B774B2A784C2D86634BA89385E9E4E1FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5AEAEAEE5E5E5E2E2E2E2E2E4E2E2 + E2E2E2E2D8D8D9CECECFC8C8C9CCCCCCE4E4E4B0B0B0D5C9D088BC9D41C0793F + C1793FC27958BE84BEC6C2C8C1C5BEBFBEF5F5F5B6B6B6D9D9D9D0D0D1E1E1E1 + E0E0E1E0E0E0DCDCDCE0E0E2C3C3C3D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFAE9A78CDE7A48E5 + 9465E8A074E89D72E8A073E8A073E89F73E89E72E79F72E79E72E89F73E89E73 + E89E73E79F74E79D73E79E73E69C72E69C72E69B71E59F76E3986EE47748CD6B + 42816A5C66696A6868686868686B6B6B6E6E6E7D7D7DA0A0A0AFAFAFACACACAA + AAAAA6A6A6A2A2A29D9D9D9898989393938E8E8E8B8B8B8484847D7D7D797979 + 7272726B6B6B6464645D5D5D5F5F5F6666666767676868687676767E7E7E8484 + 848989898F8F8F9393939999999E9E9EA2A2A2A5A5A5ABABABAFAFAF9F9F9F85 + 85847F7F7F7B7A7A636A6D726359C26A44E07242DE7948E07E4CE2814DE58854 + ECA271F0B488F5CCADFAE4D2F9DEC6FADCC0FBE5CFFBE0C6F9C99EF9C493F8B8 + 7FF7B072F9B477F9B779FAAF6DF9AC6DFDE6D5FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFEFEFEC8BCB483624D774A2C7B4D2B7F4F2D81512F80502E7D + 502D7E502D7F512E81512E7D4F2C754829947563EAE5E1FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFD1D1D1B3B3B3F2F2F2CACACAC6C6C7CACACAC4C4C4B8B8B9E6 + E6E6D8D8D7D2D2D1D2D3D3BCBBBCCDC7CA8ABE9E5DC8875CC9885FC98963C38A + B5C4BBCCC5CAB9B9B9F8F8F8BBBBBBF0F0F0CECECEBEBEBECBCBCCC9C9C9C2C2 + C2E4E4E4E0E0E1C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFAE3A68BDC7244E18B5DE4976CE4956A + E3956BE5966BE4956BE5956AE3956BE4966BE5966AE4956BE3956BE4966CE495 + 6AE3946BE2946BE29369E29269E1956DDF8E66E07044C9643E7B64565D616263 + 63647171707C7C7C858585929292AEAEAEB4B4B4ADADADA9A9A9A5A5A5A1A1A1 + 9D9D9D9898989393938E8E8E8B8B8B8484847D7D7D7979797373736B6B6B6565 + 655E5E5E5F5F5F6767676666666767677777777E7E7E8484848989898E8E8E93 + 93939999999D9D9DA1A1A1A5A5A5A9A9A9ADADADAFAFAF9A9A9A878787898989 + 868687767A7C8B6D5ECB6940E06E3FDC7546DE7949DF7C49E38855EBA475EFB1 + 86F5D0B4FAE5D3FAE1CEF9E1CCF6C9A1F5BC8DF4B17CF3A66BF3A96CF5AC71F5 + A86AF5A365FAD7BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFCB8 + A79D7D563B7D4E2C80502E7E502C7F52318A6143A07E65AF927DAE917C9F7D63 + 875D3E7D4F2C80522E7A4A2AAA9485FEFEFDFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 + C4C4C0C0C0FEFEFEB2B2B2C2C2C2CFCFCFC6C6C6ABABABF7F7F7D6D6D6E1E1E1 + BDBDBDCCC8CBC1C4C293C6A57DD59D76D19879D39972CB93A5C1AFD5CFD3B0B0 + B0FCFCFCBCBCBCFFFFFFCFCFCFB1B1B1D0D0D0CECECEAEAEAEDCDCDCF8F8F8B7 + B7B7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFDFBFAE0A389D76C42E08C63E39872E3966FE3966FE2976FE196 + 6FE2976FE19670E29670E3976FE29670E29670E29670E3966FE2966FE1956FE1 + 956EE0936FE19773DE906BDE6E43C35D3A7A60556B6E707B7C7D8C8C8C929292 + 8F8F8F949494AEAEAEB2B2B2ACACACAAAAAAA6A6A6A2A2A29E9E9E9999999494 + 949090908A8A8A8383837C7C7C7777777171716868686161615A5A5A5C5C5C63 + 63636464646767677676767D7D7D8383838888888E8E8E9494949A9A9A9E9E9E + A1A1A1A5A5A5A9A9A9ACACACB2B2B2AFAFAF9696968787878C8C8C8A8B8D8488 + 89A57A66D36A3EDA6B3DD97143DA7545DC7645E28755E9A072EDAF85F5D7C0FB + E7D9F4C6A4F0B284F0AB78ED9C63EE9C62EFA066F0A065F0965BF5BF9AFFFBF9 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFAFABAA89C7B503480512D7E502D + 8054339A765BCBB8ABE7DED7F1ECE8F7F4F1F7F4F1F2EDE9E4D9D2B0937E8255 + 347E502D8F6A50DCD1CAF2EDEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDD0D0D0FFFFFF + E3E3E4D5D5D5D3D3D3D5D5D5E6E6E6FFFFFFCDCDCDF1F1F1B2B2B2DBD4D8B2BE + B694CCA8A0E4B897DFB096DFB083D4A290B99FD9D3D7B4B3B3FDFDFDC2C2C2FF + FFFFF8F8F8DBDBDBD3D3D3D3D3D3D8D8D8F4F4F4FFFFFFB8B8B8F5F5F5FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFB + FADFA088D36B43E29A78E5A789E4A485E4A485E4A485E4A485E4A585E4A585E4 + A585E5A585E4A585E4A585E4A384E4A485E3A485E3A384E4A385E3A183E3A788 + E0A081DC734CC35B398F73688B8E909495969494949191918E8E8E939393ADAD + ADB3B3B3ADADADAAAAAAA6A6A6A2A2A29D9D9D9898989191918D8D8D8686867F + 7F7F7878787272726B6B6B6363635A5A5A5454545555555C5C5C606060686868 + 7474747B7B7B8282828787878B8B8B9090909797979C9C9CA1A1A1A5A5A5A9A9 + A9ADADADB0B0B0B6B6B6AEAEAE9393938787878B8B8B8B8D8E898D8EB1765BD3 + 663BD66A3ED66D40D86F41DA7242E08354E7A074F0C3A4F5D5BCEEB791EA9F6E + E8915BE88E57EA945DEB965DEA8E56EEA67BFDF1E9FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFD3C7C07A503580502D7E502D8A6142C2AD9DF1EBE7FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F4F2B79D8A7C4F2C895F42B8 + A090D7CAC1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFCBCBCBF1F1F1F4F4F4F8F8F8F8F8 + F8F8F8F8F5F5F5F1F1F1C3C3C3F9F9F9ADAEAEE3DFE2B4BAB57DB49381C59D88 + C59F82C39B68B58989AD97DDD8DBC0BFC0ECECECD3D3D3E8E8E8F3F3F3F7F7F7 + F8F8F8F8F8F8F7F7F7F1F1F1F0F0F0B9B9B9F4F4F4FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFBFADD9883D06741E0 + 9B7DE5AC90E4A88BE4A78BE4A78BE4A88BE6A78BE5A88BE4A78BE4A88BE4A88B + E4A88BE4A78AE3A68BE2A68BE3A58AE3A58AE2A388E4A88FE1A388D7704DC45A + 39A184799497999193929190909090908D8D8D979797B0B0B0B3B3B3ACACACA8 + A8A8A2A2A29C9C9C9797979191918B8B8B8787878C8C8C8F8F8F939393959595 + 9191919999999C9C9C9797979A9A9A9D9D9D9999999C9C9CA1A1A1A0A0A0A7A7 + A7A9A9A99E9E9E9999999D9D9D9E9E9E9F9F9F9F9F9FA5A5A5AAAAAAAFAFAFB4 + B4B4B9B9B9ABABAB8E8E8E8888888C8C8C898D908F8986BA6D4ED36036D4663C + D56A3FD66B40D76C3DE08A60EFC1A4F3D0B7ECB18CE28451E2804DE58753E48A + 56E58650F39665F9E6DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1EE + EB9576627D4F2D7D4F2D8D6648D8CABFFFFFFFFFFFFFFEFEFEEAE6E2CAC0B8B4 + A49AB5A59BCDC4BFF8F7F6FFFFFFF0EBE7967155845838B09580D0C0B4FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFE6E6E6CDCDCDC6C6C6C6C6C6C7C7C7C7C7C7C6C6C6C5C5C5CA + CACAE6E6E6EBEBEBB0B0B0E3E5E4CBC8C9BAB9BAB1B6B3B3B6B4B4B8B5B7B9B9 + CCC7CAE3E3E3C9CAC9D7D7D7FAFAFAD3D3D3C4C4C4C5C5C5C6C6C6C6C6C6C6C6 + C6C5C5C5C9C9C9DCDCDCFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFBFADC9581CB5B37D67E5CDB8C6CDA8868 + DA8867DA8868DA8868DB8969DA8A68DA8968DA8868DA8868DA8868D98868D987 + 68D88768D88667D78767D78466D8876AD68366CF5B3AC054379D827891969792 + 93939392929191918C8C8C999999AFAFAFAEAEAEA8A8A8A5A5A5A1A1A1A4A4A4 + AEAEAEB9B9B9C5C5C5CBCBCBD6D6D6DCDCDCE4E4E4E8E8E8EAEAEAF3F3F3F7F7 + F7F6F6F6F8F8F8F8F8F8F7F7F7F8F8F8F7F7F7F8F8F8F9F9F9F8F8F8F6F6F6ED + EDEDE0E0E0CCCCCCBDBDBDAFAFAFACACACADADADADADADB0B0B0B5B5B5BBBBBB + A5A5A58C8C8C8C8C8C8C8C8C878E8F96837AC26442D15C33D1623BD2663DD364 + 39D7764BE8AC8BEFC3A9E39670DB6E3EDD7949DE7D4CE27D4AEC8B5BECD1C4FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEC1B77F53357F502D89 + 5F41D4C5B9FFFFFFFFFFFFECE8E5AA988D7F5D46774F32794E2F784E2F764E33 + A18C7DF5F2F0FEFEFDB89F8D845838B79E8BD9CCC2FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFEFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFCFCFCFDFDFDFFFFFFD9D9D9 + B9B9B9E8E7E8D5D6D5C8CFCBC3CDC7C6CDC9C9CFCBCAD1CDD6D9D6EBEBEBD5D5 + D4C4C4C4FFFFFFFFFFFFFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFDFBFADA917EC75131CA603ECD6C4ACF6B4ACF6C4ACF6B4ACF6B + 4ACF6C4BCE6D4ACE6C4ACF6C4ACF6C4BCF6C4BCD6C4ACF6A4ACE6A4ACD6949CD + 6A49CD6849CC684AC96244C74729BD4D349980778C93949091918F8F8F8D8D8D + 8A8A8A9F9F9FB0B0B0AFAFAFB7B7B7C4C4C4D4D4D4E0E0E0EAEAEAF6F6F6FEFE + FEFFFFFFFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCF5F5F5F1F1F1F2F2F2F1F1F1F2 + F2F2F3F3F3F2F2F2F2F2F2F2F2F2F3F3F3F5F5F5F6F6F6F9F9F9FBFBFBFAFAFA + FAFAFAF5F5F5DFDFDFCCCCCCBFBFBFB8B8B8B5B5B5B8B8B8BBBBBBA1A1A18C8C + 8C8C8B8B8B8C8D8A8E8F9B7E72C35C3BCE5833CD5F38CE5F37D36E46DF926EE3 + 9F7CDC8159D5673AD76F43DB7143E37A4AD8B2A0FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFCFBFAA98E7B7D4F2D7E4F2EBAA18FFEFEFDFFFFFF + E1DBD78E725F794B2C80512D80502E80502D7F502D81512D7A4E2DBCAA9DFFFF + FFB9A1918A6142D7C8BEF0EBE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDC7C7C7F3EAF1ABCE + BA70CD9974D4A070D09C73D19D6FD09A81C79FE8E9E8E3DEE1BDBDBDFEFEFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFB + FAD89180C14B2DC65738CA6547CA6547CB6547CB6647CB6647CB6647CA6546CA + 6546CB6647CB6647CB6647CB6547CB6546CA6446C96446C96245C86345C96347 + C45A3DC04125B847309D80779498999495959292929595959B9B9BB2B2B2CACA + CADADADAE5E5E5EFEFEFF8F8F8FBFBFBF8F8F8EEEEEEE5E5E5E0E0E0D7D7D7D3 + D3D3D1D1D1D1D1D1D0D0D0CCCCCCCACACACACACACBCBCBCBCBCBCBCBCBCBCBCB + CBCBCBCBCBCBCBCBCBCACACACCCCCCD0D0D0D8D8D8E0E0E0EAEAEAEDEDEDEFEF + EFF1F1F1EEEEEEDDDDDDC9C9C9C0C0C0C0C0C0B7B7B79999998B8B8B8C8C8C8C + 8E8F8A8E8FA27464C75331CD5733C95732D06B46E09979E5A789DA825ED06136 + D3673DDE6E40D7997BDCD5D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFF6F3F197745A7D4F2D8F6649E6DDD7FFFFFFF0ECE99579667A4C2B8252 + 2F7E4F2D7E502D80502E8154337E4F2D7E4F2DA0816BF6F3F19979659C785EF8 + F6F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C1DBD9DAEDE7EA8BCBA869DCA085E7B57B + E2AD82E6B27DE6AF69CE97D7E1DBEFE7EBB9BAB9FBFBFBFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFCFCDBA297C24D31C1 + 4D32C65D41C65F42C85E42C85E42C85E42C85F42C75D41C75D41C75E41C75D42 + C65D42C75D42C75D41C65D41C55C41C55B40C55A40C65A40C15137BA381FB947 + 33B89D95B8BDBDB5B6B6B3B3B3BABABAC9C9C9DBDBDBE7E7E7EEEEEEEFEFEFE5 + E5E5D7D7D7D0D0D0CBCBCBC8C8C8C5C5C5C4C4C4C1C1C1C0C0C0C2C2C2C3C3C3 + C4C4C4C4C4C4C6C6C6C5C5C5C5C5C5C6C6C6C6C6C6C6C6C6C6C6C6C5C5C5C5C5 + C5C6C6C6C6C6C6C4C4C4C1C1C1BFBFBFBEBEBEC5C5C5D0D0D0D8D8D8DFDFDFE3 + E3E3E7E7E7DDDDDDCDCDCDC5C5C5B5B5B59696968C8C8C8E8E8E8C90918D8D8D + AD664FC64927C64E2CCE6847E0A085E6B198D88363CC5931D45F37C16A47D9CB + C3D2D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2EEEB916C + 507C4D2CA17F67F8F6F4FFFFFFCABAAF7C4F317F502D7C4E2C7F52319D7A61BF + A999C5B0A0A5846D805230A4856DD5C9C1835C40CCB9ABFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFB7B7B7F1ECEFE3E3E27CCCA15CDA9A7CE2AD8DE5B789E5B66DDFA5 + 5BCE92C7DECFFDF5F8AFAFAFF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEE0B5AFC24D35BC4329C05238C05339 + C25339C25339C15439C15339C15339C15339C15338C05239C15239C05338C050 + 37C05037BF5037C04F37BF5139C04F37BA412AB3220CB74737C6BBB9C7CFD0C6 + C5C5CFCFCFDBDBDBE1E1E1E2E2E2D8D8D8CDCDCDC5C5C5BFBFBFBEBEBEBCBCBC + BDBDBDC0C0C0C2C2C2C4C4C4C6C6C6C9C9C9C8C8C8C9C9C9CACACAC9C9C9CBCB + CBCACACACACACACBCBCBCCCCCCCCCCCCCBCBCBCACACAC9C9C9CACACAC9C9C9C7 + C7C7C3C3C3C3C3C3C0C0C0BDBDBDB9B9B9B7B7B7BABABAC6C6C6D1D1D1D6D6D6 + D9D9D9D4D4D4CCCCCCB2B2B29292928C8C8C8F8E8E878E8F908987C06850C040 + 1FCB6547E3AB95E9BFABD8886CCC4C25BB56377C6257BCC1C2D1D1D1FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F4F19B765A7E4F2CAA8C75FE + FEFEFEFEFDB59B887C4E2D7C4F2C825635B79D8AF4F0EDFFFFFFFFFFFFF4F0ED + A18066987A65937664AC8F79F8F5F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B1B2B1 + FFFBFFD5DED86BC99650D69155D5955DD69958D5954ED4904ECD89B0D4BEFFF7 + FDB5B5B5F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFF1DEDBC5614EB53822B93F29B93F29B83F29B83F2ABF3F + 28C53C23BC341CBC341EC23A22BF3720BB331EB62F1AB52C17B42C17B32B18B4 + 2B18B42B18B32916B12D17B22D19B8685AC1C0C0C4C9CACBCACAD1D1D1CECECE + C7C7C7BDBDBDB6B6B6B6B6B6B6B6B6B9B9B9C0C0C0C2C2C2C5C5C5C8C8C8C8C8 + C8CACACACBCBCBCBCBCBCBCBCBCCCCCCCCCCCCCCCCCCCCCCCCCDCDCDCDCDCDCC + CCCCCCCCCCCCCCCCCCCCCCCCCCCCCBCBCBCBCBCBC9C9C9C9C9C9C8C8C8C7C7C7 + C5C5C5C3C3C3BFBFBFBCBCBCB8B8B8B2B2B2B0B0B0B5B5B5BFBFBFC7C7C7CACA + CAC8C8C8ABABAB9090908A89898F8F8FA9B0B2C9B5B0BF583FC45134E2AC99EC + C7B7D5765BC14B2A8F685A5F6466A4A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFB9A18E7F512DA17F67FAF9F8FFFFFFBBA08B + 7E4F2E7B4E2CAC8C76F7F4F2FFFFFFFFFFFFFFFFFFFFFFFFA28573714B34A586 + 72F0EAE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3B3B4B4FFFFFFC6D8CE59C5 + 8A4AD28B49CE8A3FCB8340C98243CC854ACB869CCBB0FFF7FCC7C6C7E5E5E5FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEFDFDE3B8B1CE8175CA7466CA7365CB7365CD7365C27569B77E74C17D71B4 + 5A4C9E3F2FA64739AD4C3EB65549BB5B4EBA5A4DB8594CB6594CB65649B8574C + BB6A5CB77E72B7A19CBDBEBFC2C2C3C3C3C2BABABAADADADACACACAFAFAFB4B4 + B4B9B9B9BEBEBEC2C2C2C4C4C4C6C6C6C8C8C8C8C8C8C9C9C9CBCBCBCDCDCDCD + CDCDCDCDCDCECECECECECECECECECECECECFCFCFCFCFCFCECECECECECECECECE + CECECECECECECECECECDCDCDCBCBCBCBCBCBCBCBCBC9C9C9C7C7C7C6C6C6C4C4 + C4C0C0C0BDBDBDB9B9B9B4B4B4AEAEAEA8A8A8AAAAAAB2B2B2BABABABCBCBCA7 + A7A79B9B9BB1B1B1CBCDCECDD0D1C6A197BE4D34C95F46D0735CC85234AC6F5D + 8A8C8A6567689D9C9CD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F0EEDED6D2 + D3C9C3CDC4BEB4A3957E5D478F7161DED9D5FFFFFFD6C8BE865C3D7D4E2CBCA6 + 97FFFFFFFFFFFFFFFFFFFFFFFFBBADA3744B30A48671EFE8E4FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFDDDDDDB8B9B9FFFFFFB9D3C356C38640C77F34BE7532 + BC7330BA7030BB7059CB8B91C5A7FAF4F6D7D5D6D6D6D6FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC + F9F8F9F0EEF9EFEEF9EFEEFAEFEEF6F0EFF6F5F4E9E5E4ADACAB615C5A858080 + AAA5A3C9C3C1D2CECCCECAC8CCC8C6CBC8C5CFCBC8CDC8C5BAB9B9B2B3B3B4B6 + B7B2B3B3ABABABA3A3A3A2A2A2A8A8A8AFAFAFB5B5B5BCBCBCBEBEBEC2C2C2C4 + C4C4C6C6C6C7C7C7C9C9C9C9C9C9CACACACCCCCCCDCDCDCECECECFCFCFCFCFCF + CFCFCFD0D0D0D0D0D0CFCFCFCFCFCFCFCFCFD0D0D0D0D0D0D0D0D0D0D0D0D0D0 + D0CECECECDCDCDCCCCCCCBCBCBCACACAC8C8C8C6C6C6C4C4C4C2C2C2BEBEBEBD + BDBDB9B9B9B5B5B5AEAEAEA5A5A59D9D9D9E9E9EA7A7A7AFAFAFAEAEAEB0B0B0 + C0C0BFD3D4D5CFD1D1C79E94BC5D48BC543DC98A7BB7B3B2989D9F6D6D6D8B8B + 8BCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFEFEFED5CCC6AC9B8F957B6986624C7E573F7A543A7E5B + 407A573F7B56408A6D59A18C7DA99488835F46804F2D89664FC4B7B0E3DDDAD0 + C5BFA894888E6E59BEA896F5F2EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB + EBEBA3A3A3E2E2E2FDF9FDABCFB973CE985FCB8C49C07C5FC88C6BCC947BD49E + 86D8A673B690ECEAEBDFDEDEC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFF0F0EFA6ADAF5E6466969DA0C5CDCFD5DDDED4DC + DDD0D9DAD1D8DAD5DDDECCD4D5B0B8BAA2A8AAA4A8A8A0A1A19797979797979D + 9D9DA8A8A8B2B2B2B6B6B6BABABABDBDBDC0C0C0C3C3C3C5C5C5C7C7C7C9C9C9 + C9C9C9CBCBCBCCCCCCCDCDCDCDCDCDCECECED0D0D0D1D1D1D1D1D1D1D1D1D1D1 + D1D2D2D2D2D2D2D1D1D1D2D2D2D2D2D2D1D1D1D1D1D1D1D1D1CFCFCFCDCDCDCC + CCCCCBCBCBCBCBCBC9C9C9C7C7C7C5C5C5C3C3C3BFBFBFBDBDBDBBBBBBB8B8B8 + B3B3B3ADADADA6A6A69B9B9B9191919393939C9C9C9999999A9A9AB4B2B2D0D3 + D3D1D6D7CDC2BECCBBB5D2D3D3D3D8DAB0AFAF777878818181CDCDCDFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDED7 + D3A08A7B825D447649297D4E2C7E4F2D7E4F2C80502D7F502D80512E7F512E7F + 502E7C4C2A714627754A2A7E4F2D7A4C2C7A5339957865A38876BCA697E0D4CB + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACABCBCBCF9F8F9 + F4F1F28EC2A386D5A5A8E5BE89D5A683CF9F7AC99876C39463B4847EB093F4F1 + F3E2E1E2C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFECECEC9E9D9C6D6C6CB5B4B4D6D5D5D3D2D2CFCECED0CFCFD5D4D4C3 + C2C29F9E9E908F8F9190908F8E8E8B8B8B9393939F9F9FA7A7A7AFAFAFB3B3B3 + B6B6B6BABABABEBEBEC0C0C0C3C3C3C5C5C5C7C7C7C9C9C9CBCBCBCCCCCCCDCD + CDCECECECFCFCFD0D0D0D2D2D2D2D2D2D1D1D1D3D3D3D2D2D2D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D2D2D2D1D1D1D1D1D1D0D0D0CFCFCFCECECECDCDCDCBCBCB + C9C9C9C8C8C8C6C6C6C4C4C4C1C1C1BDBDBDBBBBBBB7B7B7B2B2B2AFAFAFACAC + ACA7A7A79B9B9B8B8B8B8585858A8A8A8B8B8B898989A5A5A5CCCCCCD3D7D8D2 + D7D8D1D3D3D6D5D5C6C6C68C8C8C888888CECECEFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFBBFB0A7815E47774A29804F2D81 + 512D7E4F2D7F5230946F52A78872B89F8CBFA7969476647B5D4CB59D8DC5AE9D + BFA897C3AE9EC8B5A6D0BEB1D7C9BFE6DED8FFFEFEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8C6C6C6F9FBFAF6F0F491B3A059A8 + 7A7AB99482B9988CBC9F9DC4ADAECCBCC0D4CAE6E9E8FFFFFFE2E2E2C6C5C5FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB9E + 9E9E7B7B7BCBCBCBD8D8D8D0D0D0D2D2D2DADADABEBFBF8D8D8D818181828282 + 7D7D7D8282829292929F9F9FA6A6A6A9A9A9AFAFAFB3B3B3B6B6B6BABABABFBF + BFC0C0C0C2C2C2C5C5C5C8C8C8CACACACBCBCBCDCDCDCECECED0D0D0D0D0D0D0 + D0D0D2D2D2D2D2D2D2D2D2D3D3D3D4D4D4D4D4D4D4D4D4D4D4D4D2D2D2D2D2D2 + D2D2D2D2D2D2D1D1D1D0D0D0CFCFCFCFCFCFCECECECCCCCCCACACAC7C7C7C5C5 + C5C4C4C4C1C1C1BDBDBDBABABAB7B7B7B4B4B4AFAFAFAAAAAAA6A6A6A3A3A399 + 99998A8A8A7A7A7A7A7A7A7C7C7C7676769C9B9BD1D1D1D4D3D3D0D0D0D3D3D3 + D5D5D59E9E9E888888CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFDFDBCABA27950347E4F2D80512D7D4E2C875C3CAD907AD6C6BB + EBE4DEF6F2F0FEFEFDFFFFFFC6B4A7754D36CFC0B6FFFFFFFEFEFEFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFDFDFDACACACD7D8D7FFFFFFFDFBFDDFE0E0C2CEC8CCDCD3DCE6E1EA + F0ECFBFAFBFFFCFFFBFAFAF8F7F8ECECECBDBDBDE6E6E6FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEAA4A4A4929292D6D6D6 + D6D6D6D1D1D1DBDBDBBCBCBC7F7F7F6C6C6C7171717171717F7F7F9090909B9B + 9BA2A2A2A7A7A7AAAAAAAEAEAEB3B3B3B7B7B7BBBBBBBFBFBFC1C1C1C4C4C4C6 + C6C6C8C8C8CACACACCCCCCCDCDCDCECECECFCFCFD1D1D1D1D1D1D3D3D3D3D3D3 + D3D3D3D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D3D3D3D3D3D3D3D3D3D2D2 + D2D1D1D1D0D0D0CFCFCFCECECECCCCCCCACACAC8C8C8C5C5C5C4C4C4C1C1C1BE + BEBEBABABAB7B7B7B4B4B4AFAFAFABABABA6A6A6A2A2A29D9D9D979797898989 + 7474746C6C6C6A6A6A646464959595D0D0D0D2D2D2D2D2D2D6D6D6B5B5B58F8F + 8FD4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEC2BA + 7D53397F512E7E502E7E512FA5856DDED2C9F7F4F2FFFFFFFEFEFEFAF8F7F6F4 + F2FCFBFAEBE4DF8F6546A58976FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AA + AAAAE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFEFBFDFAF9FAEEEDEDDDDCDDCCCCCC + C1C2C1CBCBCBD2D2D2EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFECECECB6B6B6B3B3B3DBDBDBD1D1D1D9D9D9C4C4 + C47C7C7C5C5C5C6161616666667979798F8F8F9696969A9A9AA1A1A1A6A6A6A9 + A9A9AFAFAFB3B3B3B7B7B7BABABABDBDBDC0C0C0C4C4C4C6C6C6C9C9C9CACACA + CCCCCCCDCDCDCECECED0D0D0D2D2D2D1D1D1D2D2D2D3D3D3D4D4D4D3D3D3D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D3D3D3D3D3D3D3D3D3D3D3D3D1D1D1D0D0D0CF + CFCFCDCDCDCBCBCBC9C9C9C8C8C8C5C5C5C4C4C4C0C0C0BDBDBDBBBBBBB8B8B8 + B4B4B4AEAEAEAAAAAAA6A6A6A2A2A29C9C9C9797979292928585856C6C6C5E5E + 5E5A5A5A606060A0A0A0D4D4D4D4D4D4D3D3D3D1D1D1A6A6A6D8D8D8FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDE9E68D6C567F502D7E502D7D4F + 2DB29783F3EFEBFFFFFFFEFEFEDCD4CFA9968A9279688B6F5BA08C7DD1C6BEA3 + 8672946F55F7F4F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDB3B3B3E7E7E7E0E0E0 + E5E5E5D9D9D9D1D1D1C1C1C1C9C9C9D2D2D2E5E5E5F7F7F7FBFBFBFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF1F1F1CDCDCDC7C7C7D7D7D7D8D8D8CACACA8989895B5B5B5454545C + 5C5C7474748989899090909595959A9A9AA1A1A1A7A7A7AAAAAAADADADB2B2B2 + B6B6B6BABABABDBDBDC0C0C0C2C2C2C6C6C6C9C9C9CACACACBCBCBCECECECECE + CED0D0D0D0D0D0D2D2D2D3D3D3D3D3D3D4D4D4D3D3D3D4D4D4D3D3D3D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D3D3D3D2D2D2D1D1D1D0D0D0CFCFCFCECECECCCCCC + CACACAC8C8C8C4C4C4C3C3C3C1C1C1BDBDBDBBBBBBB7B7B7B3B3B3AFAFAFABAB + ABA6A6A6A0A0A09B9B9B9696969090908B8B8B80808067676753535359595969 + 6969AEAEAEDADADAD3D3D3D9D9D9CBCBCBDADADAFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFEFEFEC6B5AA794A2C7F502D7D4E2CA38169F4EFECFFFFFFFB + FAF9B4A2987B563D794B2B7B4D2B7C4D2C794B2A7D583F7A563F947055EEE8E4 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFDFDFDFCACACAF1F1F1ACACACDFDFDFE9E9E9F6F6 + F6F9F9F9FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFF3F3F3C9 + C9C9DEDEDED8D8D8D2D2D29A9A9A6060605353535757576D6D6D8282828B8B8B + 8F8F8F9494949C9C9CA1A1A1A6A6A6AAAAAAADADADB2B2B2B6B6B6BABABABDBD + BDC1C1C1C2C2C2C4C4C4C8C8C8C9C9C9CBCBCBCECECECECECED0D0D0D1D1D1D1 + D1D1D3D3D3D4D4D4D4D4D4D5D5D5D5D5D5D4D4D4D5D5D5D5D5D5D4D4D4D4D4D4 + D4D4D4D2D2D2D2D2D2D2D2D2D0D0D0CFCFCFCDCDCDCCCCCCCACACAC7C7C7C5C5 + C5C3C3C3C0C0C0BCBCBCBABABAB7B7B7B2B2B2AEAEAEAAAAAAA5A5A5A0A0A09B + 9B9B9696969090908989898484847A7A7A6161615555555A5A5A767676C1C1C1 + D9D9D9D7D7D7D8D8D8D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 + F2F0A88D7A7C4E2C7D4E2C8E6648DDD1C7FFFFFFF9F8F6AF9A8D784D317F512D + 7F502D7E4F2D7E502D7F4F2D7D4E2C7B4C2B977258EBE3DEFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFCBCBCBE3E3E3EEEEEEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFF5F5F5C5C5C5E8E8E8DADADA + B0B0B06969695353535959596F6F6F7F7F7F8181818787878E8E8E9393939999 + 999F9F9FA5A5A5A9A9A9ADADADB1B1B1B4B4B4B9B9B9BCBCBCC0C0C0C2C2C2C4 + C4C4C7C7C7C9C9C9CACACACDCDCDCECECECFCFCFD1D1D1D1D1D1D2D2D2D3D3D3 + D2D2D2D3D3D3D4D4D4D5D5D5D5D5D5D4D4D4D3D3D3D3D3D3D3D3D3D2D2D2D1D1 + D1D0D0D0CFCFCFCECECECBCBCBCACACAC9C9C9C6C6C6C4C4C4C1C1C1BFBFBFBC + BCBCB8B8B8B5B5B5B1B1B1ACACACA9A9A9A4A4A49F9F9F9A9A9A9595958E8E8E + 8787878282828181817C7C7C626262575757565656909090D2D2D2DADADADCDC + DCDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEAE69C7A617D4F2D + 7C4E2CB09580FDFCFCFFFFFFCBBDB37E52367F502D7E502D7C4E2C8F6649A98B + 75B195809873577F502D99745AF0EBE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAE8 + E8E8DADADAC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFEFEFEFFFFFFF2F2F2CDCDCDE7E7E7C9C9C97E7E7E5555555959 + 597171718383838282828181818787878D8D8D9393939797979E9E9EA3A3A3A8 + A8A8ACACACB0B0B0B3B3B3B8B8B8BCBCBCBFBFBFC2C2C2C4C4C4C7C7C7C8C8C8 + C9C9C9CBCBCBCDCDCDCFCFCFD0D0D0D0D0D0D2D2D2D3D3D3D2D2D2D3D3D3D4D4 + D4D4D4D4D4D4D4D4D4D4D3D3D3D3D3D3D3D3D3D1D1D1D0D0D0CFCFCFCFCFCFCD + CDCDCCCCCCCACACAC7C7C7C5C5C5C3C3C3C1C1C1BDBDBDBBBBBBB8B8B8B5B5B5 + B1B1B1ACACACA8A8A8A4A4A49F9F9F9898989494948E8E8E8888888282828383 + 838585857F7F7F646464545454656565B4B4B4DEDEDEDFDFDFD5D5D5FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1ECE9A280677D4F2C7D4E2CC8B3A4FFFF + FFFEFEFDA98E7C7D4D2C7E4F2C7C4E2CA4846DE6DCD6FCFCFBFEFDFDECE5E096 + 70559C795FFAF8F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6C1C1C1BCBCBCE9E9E9 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF1F1F1E8E8E8D6D6D6A8A8A85F5F5F5555556F6F6F85858587878785 + 85858585858787878C8C8C9292929696969D9D9DA3A3A3A6A6A6AAAAAAAFAFAF + B3B3B3B7B7B7BBBBBBBEBEBEC1C1C1C3C3C3C6C6C6C7C7C7C9C9C9CBCBCBCCCC + CCCECECECFCFCFD0D0D0D1D1D1D0D0D0D1D1D1D3D3D3D3D3D3D1D1D1D3D3D3D3 + D3D3D1D1D1D2D2D2D1D1D1D1D1D1D0D0D0CDCDCDCECECECDCDCDCACACAC8C8C8 + C6C6C6C4C4C4C2C2C2C0C0C0BCBCBCBABABAB6B6B6B2B2B2AEAEAEABABABA7A7 + A7A1A1A19E9E9E9999999393938D8D8D8888888686868787878787878A8A8A7C + 7C7C5E5E5E5454548F8F8FD5D5D5E1E1E1D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFF9F7F6B69C8A7E502D7B4C2CBBA596FFFFFFFCFBFAA889737D + 4E2C7C4D2B9B765BEDE6E1FFFFFFFFFFFFFFFFFFFAF9F8A58875B79D89FEFEFD + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9DCDCDCDEDEDEFDFDFDFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDED + EDEDC8C8C87C7C7C5050506666668585858B8B8B888888888888878787888888 + 8B8B8B9292929696969B9B9BA1A1A1A6A6A6ABABABAEAEAEB2B2B2B6B6B6B9B9 + B9BCBCBCBFBFBFC1C1C1C4C4C4C5C5C5C7C7C7CACACACBCBCBCCCCCCCCCCCCCF + CFCFCFCFCFD0D0D0D1D1D1D2D2D2D1D1D1D2D2D2D0D0D0D2D2D2D2D2D2D0D0D0 + D0D0D0CFCFCFCECECECDCDCDCCCCCCCBCBCBC8C8C8C8C8C8C6C6C6C3C3C3C1C1 + C1BDBDBDBABABAB8B8B8B5B5B5B2B2B2AEAEAEAAAAAAA5A5A5A1A1A19C9C9C96 + 96969191918C8C8C8A8A8A8A8A8A8989898A8A8A8A8A8A8D8D8D767676585858 + 646464BEBEBEDFDFDFCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFDCD0C7865B3C7C4D2D977762F4F2F0FFFFFFB79C887D4E2C7C4E2CBCA697 + FFFFFFFFFFFFFFFFFFFFFFFFCBBEB69C7D69E6DDD6FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEE9E9E9A9A9A9606060 + 5959598181819090908C8C8C8C8C8C8C8C8C8B8B8B8C8C8C8C8C8C9090909494 + 949B9B9BA0A0A0A3A3A3A9A9A9ACACACB0B0B0B4B4B4B7B7B7BBBBBBBDBDBDC0 + C0C0C3C3C3C4C4C4C6C6C6C9C9C9C9C9C9CBCBCBCCCCCCCECECECFCFCFD0D0D0 + D0D0D0D0D0D0D0D0D0D1D1D1D0D0D0D1D1D1D1D1D1CFCFCFCFCFCFCECECECDCD + CDCDCDCDCBCBCBC9C9C9C8C8C8C7C7C7C5C5C5C2C2C2BEBEBEBCBCBCB9B9B9B6 + B6B6B3B3B3B0B0B0ADADADA9A9A9A4A4A49F9F9F9A9A9A9494949090908E8E8E + 8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8E8E8E8E8E8E6A6A6A5454549A9A9AD7D7 + D7CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFBFAC0A999 + 80512F774A29AB988DFEFEFEEAE2DC9B755984532F927460D9D2CDF7F6F5E4E0 + DCBCAFA69B7F6ED4C4B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFBFBFBCACACAAEADADA09E9EAEADADD6D6D6FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFEEEEEEE6E6E68686865555557070709090909191 + 918E8E8E8F8F8F8E8E8E8F8F8F8E8E8E8F8F8F8F8F8F9292929898989F9F9FA2 + A2A2A6A6A6A9A9A9AEAEAEB2B2B2B6B6B6B8B8B8BBBBBBBFBFBFC0C0C0C2C2C2 + C4C4C4C7C7C7C8C8C8CACACACBCBCBCCCCCCCCCCCCCDCDCDCECECECECECECFCF + CFCFCFCFCFCFCFCFCFCFCFCFCFCDCDCDCDCDCDCCCCCCCBCBCBCCCCCCCACACAC7 + C7C7C7C7C7C3C3C3C1C1C1C0C0C0BEBEBEBBBBBBB8B8B8B4B4B4B1B1B1AEAEAE + AAAAAAA5A5A5A1A1A19E9E9E9898989393939090909090909191919191919191 + 918F8F8F8F8F8F9090909595957F7F7F5F5F5F757575C5C5C5D8D8D8FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F5F3C1AA9A8E64457448 + 2A9B8575D3C8C1B8A6987B563B7045277F5C4596806F9E8674A98F7ED8CBC2FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7777676282626 + 0A09090100000A0909383535919191F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFEEEEEEDDDDDD6F6F6F58585889898997979791919191919192929292 + 92929292929292929292929292929393939797979D9D9DA1A1A1A6A6A6A9A9A9 + ABABABB0B0B0B4B4B4B8B8B8BABABABCBCBCBFBFBFC1C1C1C3C3C3C4C4C4C5C5 + C5C7C7C7C9C9C9CBCBCBCBCBCBCCCCCCCCCCCCCCCCCCCCCCCCCDCDCDCDCDCDCD + CDCDCCCCCCCACACACACACACACACAC9C9C9C8C8C8C7C7C7C5C5C5C4C4C4C2C2C2 + C0C0C0BEBEBEBCBCBCB9B9B9B6B6B6B2B2B2AFAFAFADADADA9A9A9A4A4A4A0A0 + A09B9B9B96969694949493939393939393939394949493939392929292929293 + 93939494949494946D6D6D616161B1B1B1E1E1E1FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDED2C9BA9F8C99775E957763A6 + 908197806F9A7A62A6856EB29885CEBEB2F4F0EDFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFF0F0F0646363040000092014226B452986581A53 + 36060B08090606838383F5F5F5FFFFFFF1F1F1B9B9B9A3A2A2C8C8C8FCFCFCFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEC8 + C8C86565656E6E6E9898989A9A9A969696979797979797969696979797969696 + 9797979797979696969696969A9A9A9F9F9FA3A3A3A6A6A6AAAAAAAFAFAFB2B2 + B2B5B5B5B7B7B7BBBBBBBCBCBCBEBEBEC0C0C0C3C3C3C3C3C3C5C5C5C7C7C7C8 + C8C8C9C9C9C9C9C9CACACACBCBCBCACACACCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + CBCBCBC9C9C9C7C7C7C6C6C6C4C4C4C4C4C4C1C1C1C0C0C0BEBEBEBBBBBBB8B8 + B8B7B7B7B4B4B4B2B2B2ADADADAAAAAAA7A7A7A3A3A39F9F9F99999997979798 + 98989898989898989999999797979898989898989898989898989999999D9D9D + 7F7F7F6363639D9D9DD9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3EEEBE0D4CBDACDC5E2D8D2EEE8E4 + F9F6F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFDFDFDA5A4A4090606153C283DC78043F59B47FFA33FE794339C670C201418 + 1515C6C6C6D9D9D95E5C5E201D1D0F0C0C2C28288C8C8CFCFCFCFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDBABABA606060858585 + 9E9E9E9C9C9C9B9B9B9B9B9B9A9A9A9A9A9A9B9B9B9B9B9B9A9A9A9B9B9B9A9A + 9A9999999A9A9A9D9D9DA0A0A0A3A3A3A7A7A7ACACACB0B0B0B3B3B3B6B6B6B9 + B9B9BABABABDBDBDC0C0C0C3C3C3C4C4C4C6C6C6C8C8C8C9C9C9CACACACBCBCB + CDCDCDCFCFCFCECECECECECECECECECECECECFCFCFCFCFCFCDCDCDCCCCCCCBCB + CBCBCBCBC9C9C9C7C7C7C5C5C5C3C3C3C0C0C0BDBDBDB9B9B9B6B6B6B2B2B2AE + AEAEAAAAAAA7A7A7A4A4A4A0A0A09D9D9D9B9B9B9C9C9C9C9C9C9B9B9B9C9C9C + 9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9D9D9D9393936B6B6B9191 + 91E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE59575805 + 0D082E986345FFA83CFE9B3BFA993EFF9E46FFA42B885B070A084A48493B393A + 0200001030201A513508110D181515B1B1B0FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFEEEEEEB4B4B4656565939393A4A4A49C9C9C9D9D + 9D9D9D9D9D9D9D9E9E9E9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9C9C9C9C + 9C9C9F9F9FA1A1A1A5A5A5ACACACB1B1B1B6B6B6BABABABDBDBDC2C2C2C3C3C3 + C5C5C5C7C7C7C9C9C9CACACACBCBCBCCCCCCCDCDCDCECECECFCFCFD0D0D0D0D0 + D0D0D0D0CFCFCFD0D0D0D0D0D0CECECECECECECECECECECECECDCDCDCBCBCBCA + CACAC8C8C8C5C5C5C4C4C4C2C2C2BFBFBFBCBCBCBABABAB5B5B5AFAFAFA9A9A9 + A4A4A49F9F9F9E9E9E9E9E9E9E9E9E9D9D9D9E9E9E9F9F9F9F9F9F9E9E9E9F9F + 9F9E9E9E9E9E9E9E9E9E9E9E9EA0A0A0A0A0A0717171868686E6E6E6FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E1E12D2B2B0D2D1C40D88A3FFFA1 + 39F59539F5953AF6953FFFA333BB7A0D2015030000020000205F3E3DD08A40E7 + 97309562050C08575455FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF3F3F39C9C9C6A6A6A9F9F9FA7A7A7A1A1A1A2A2A2A1A1A1A2A2A2A2 + A2A2A2A2A2A2A2A2A0A0A09F9F9FA1A1A1A2A2A2A2A2A2A4A4A4A7A7A7AAAAAA + B0B0B0B4B4B4B8B8B8BABABABDBDBDC1C1C1C3C3C3C5C5C5C6C6C6C8C8C8C9C9 + C9CACACACBCBCBCCCCCCCDCDCDCCCCCCCECECECECECECFCFCFCECECECECECECE + CECECFCFCFCDCDCDCECECECCCCCCCBCBCBCBCBCBC9C9C9C8C8C8C7C7C7C5C5C5 + C4C4C4C2C2C2C0C0C0BEBEBEBDBDBDBABABAB5B5B5B2B2B2B0B0B0AFAFAFADAD + ADAAAAAAA6A6A6A3A3A3A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A3A3A3A3A3A3A2 + A2A2A2A2A2A3A3A3A6A6A67D7D7D7E7E7EE0E0E0FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFE6E5E53937370D281A3FCF863FFFA039F5953AF6963AF6 + 963DFFA02FBB760C22160200001731243ED38941FFA83FFFA539D788071C133C + 3A3AEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F398 + 9898727272A5A5A5A9A9A9A5A5A5A5A5A5A5A5A5A5A5A5A4A4A4A5A5A5A6A6A6 + A6A6A6A8A8A8AAAAAAAFAFAFB4B4B4B4B4B4B5B5B5B5B5B5B6B6B6B7B7B7B9B9 + B9BBBBBBBDBDBDC0C0C0C2C2C2C3C3C3C5C5C5C6C6C6C7C7C7CACACAC9C9C9C9 + C9C9CBCBCBCBCBCBCECECECCCCCCCDCDCDCCCCCCCECECECDCDCDCDCDCDCDCDCD + CDCDCDCACACAC9C9C9C9C9C9C9C9C9C6C6C6C7C7C7C5C5C5C1C1C1C1C1C1BEBE + BEBCBCBCB9B9B9B8B8B8B8B8B8B7B7B7B8B8B8B9B9B9B8B8B8B6B6B6B6B6B6B5 + B5B5AFAFAFACACACA7A7A7A6A6A6A5A5A5A7A7A7A6A6A6A6A6A6A6A6A6A7A7A7 + A9A9A98B8B8B828282E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFF5F5F56260600608062B8B5C43FFA539F7963AF5953AF5953EFF9F32B8750C + 20150402022D825640F99C3CFB9B3DFF9C36D484071B12454444F2F2F2E7E7E7 + BDBDBDBBBBBBE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F49B9B9B808080ABABAB + AAAAAAA7A7A7A6A6A6A7A7A7A7A7A7A9A9A9ACACACAFAFAFB4B4B4B8B8B8B7B7 + B7B9B9B9BABABABBBBBBBABABABABABAB9B9B9B8B8B8B8B8B8B9B9B9BBBBBBBD + BDBDC0C0C0C1C1C1C3C3C3C4C4C4C6C6C6C8C8C8C8C8C8C8C8C8CACACACBCBCB + CBCBCBCBCBCBCBCBCBCCCCCCCCCCCCCCCCCCCACACAC9C9C9C9C9C9C9C9C9C8C8 + C8C8C8C8C7C7C7C6C6C6C4C4C4C2C2C2C1C1C1BFBFBFBDBDBDBBBBBBBABABABA + BABABBBBBBBABABABBBBBBBBBBBBBABABABBBBBBBBBBBBBBBBBBBBBBBBBABABA + B8B8B8B3B3B3AEAEAEABABABA8A8A8A8A8A8A9A9A9AAAAAAABABAB9191918484 + 84DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4F3F3F3B6B6B616 + 1414122E203FCF883EFF9F39F69639F5943FFFA039B777111E17070D0B35BB77 + 3EFF9F3BFB993FFFA235B071050F0A302E2E6B6B6B2F2D2D1714141714142C29 + 29838383EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A1A1A1848484AEAEAEADADADAAAAAAACAC + ACAEAEAEB2B2B2B8B8B8BBBBBBBCBCBCBCBCBCBDBDBDBCBCBCBCBCBCBBBBBBBB + BBBBBBBBBBBBBBBBBCBCBCBCBCBCBCBCBCBBBBBBBBBBBBBCBCBCBFBFBFC0C0C0 + C2C2C2C3C3C3C4C4C4C5C5C5C6C6C6C6C6C6C9C9C9C9C9C9C9C9C9CACACACBCB + CBCBCBCBCBCBCBCACACAC8C8C8C8C8C8C8C8C8C7C7C7C7C7C7C7C7C7C5C5C5C4 + C4C4C3C3C3C1C1C1C0C0C0BEBEBEBEBEBEBDBDBDBDBDBDBEBEBEBEBEBEBEBEBE + BEBEBEBDBDBDBEBEBEBDBDBDBDBDBDBEBEBEBDBDBDBEBEBEBEBEBEBDBDBDBDBD + BDBBBBBBB6B6B6B0B0B0ACACACACACACADADAD909090898989E1E1E1FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFE9E9E9A3A3A26F706D6566637374712626250200001F5339 + 3FE08E3FFF9E3AF7953FFFA03AA97210120F162B2139D4853DFF9E3DFF9F3EEA + 9321543B0402020704040503020B251720593E184D3408180F0B0707646464EF + EFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFF2F2F2ADADAD8C8C8CB0B0B0B4B4B4B6B6B6BBBBBBBEBEBEC1C1C1C1 + C1C1C2C2C2C0C0C0C0C0C0BFBFBFC0C0C0C0C0C0BFBFBFBFBFBFC0C0C0C0C0C0 + BFBFBFC1C1C1C0C0C0BFBFBFBFBFBFBFBFBFBFBFBFC1C1C1C2C2C2C2C2C2C3C3 + C3C4C4C4C5C5C5C6C6C6C7C7C7C7C7C7C8C8C8C8C8C8C9C9C9C9C9C9C9C9C9C8 + C8C8C7C7C7C7C7C7C8C8C8C6C6C6C6C6C6C6C6C6C4C4C4C3C3C3C3C3C3C1C1C1 + C1C1C1C1C1C1C2C2C2C1C1C1C2C2C2C2C2C2C2C2C2C1C1C1C2C2C2C2C2C2C2C2 + C2C1C1C1C1C1C1C1C1C1C2C2C2C1C1C1C2C2C2C1C1C1C3C3C3C2C2C2C2C2C2C2 + C2C2BFBFBFB7B7B7B2B2B2939393999999E7E7E7FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC + 6565650C0C0706060605060B0B0B0A090B0504010005030325634341EF973EFF + 9F3FFF9E3292620C09092152383FE7923FFFA342F79C3083590906060200000A + 0B0A266A483DD48745F6A044F49B3AB8791436230300009D9D9DFDFDFDFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5B3 + B3B3909090B1B1B1BEBEBEC4C4C4C6C6C6C5C5C5C4C4C4C4C4C4C4C4C4C5C5C5 + C4C4C4C4C4C4C4C4C4C4C4C4C3C3C3C4C4C4C4C4C4C5C5C5C4C4C4C4C4C4C4C4 + C4C5C5C5C4C4C4C5C5C5C4C4C4C3C3C3C3C3C3C3C3C3C4C4C4C4C4C4C5C5C5C5 + C5C5C6C6C6C6C6C6C7C7C7C6C6C6C8C8C8C8C8C8C8C8C8C7C7C7C6C6C6C6C6C6 + C7C7C7C6C6C6C6C6C6C6C6C6C4C4C4C5C5C5C5C5C5C4C4C4C5C5C5C5C5C5C4C4 + C4C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C4C4C4C4C4C4C4C4C4C5C5C5C5C5C5C4 + C4C4C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C4C4C4C5C5C5C5C5C5C7C7C7BFBFBF + B5B5B5929292A5A5A5ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B9B9B10110E0D0729210E + 7328128B230F751D1344090A090300000A090930855B46F9A644FFAB28805406 + 0505226B4740FCA045FFA836A06A0E17140100000E17122F895C42F2993EFF9E + 3AFD993BFF9B44FFA936AA7008140C484646E4E3E3FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAC7C7C7929292ABABAB + C1C1C1C8C8C8C8C8C8C8C8C8C8C8C8C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C8C8 + C8C8C8C8C7C7C7C8C8C8C7C7C7C7C7C7C8C8C8C7C7C7C8C8C8C8C8C8C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C8C8C8C7C7C7C7C7C7C7C7C7C8C8C8C8C8C8 + C8C8C8C6C6C6C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C9C9C9C8C8 + C8C8C8C8C9C9C9C9C9C9C8C8C8C8C8C8C8C8C8C9C9C9C9C9C9C9C9C9C9C9C9C8 + C8C8C9C9C9C9C9C9C8C8C8C8C8C8C8C8C8C9C9C9C8C8C8C7C7C7C9C9C9C8C8C8 + C8C8C8C8C8C8C9C9C9C8C8C8C8C8C8C8C8C8CACACAC0C0C0B8B8B8888888B2B2 + B2F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFEFEFE6566640205012918872B07E52401E62604E32F + 10D02718710B0D130000000F1914349A693DC7861444270000001D4D313ECE88 + 36A9710E1F1700000015291E349A6843F9A03CFF9C3AF69639F59539F6943DFF + 9E45EE9817452D1B1919D5D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD9D9D9939393A6A6A6C5C5C5C9C9C9CCCC + CCCACACACACACAC9C9C9CACACAC9C9C9CACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA + CACACACACACACACACACACACACACDCDCDCDCDCDCCCCCCCCCCCCCCCCCCCCCCCCCC + CCCCCDCDCDCCCCCCCDCDCDCDCDCDCCCCCCCDCDCDCCCCCCCBCBCBCDCDCDCDCDCD + CDCDCDCCCCCCCDCDCDCCCCCCCDCDCDCDCDCDCDCDCDCDCDCDCCCCCCCCCCCCCCCC + CCCDCDCDCDCDCDCBCBCBCCCCCCC1C1C1BBBBBB8C8C8CC6C6C6FBFBFBFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFF7E7F7D0205001D10592E0DD42400EF2200E12200E72C0ADF27167D + 0B0B170100000B0D0B101A131524231B3E3E14252216271A0D1611030101193B + 283AB97843FFA43DFD9C39F4943AF5963AF69639F5953BFF9A47F89F194F3514 + 1212D3D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFE5E5E59F9F9FA9A9A9C5C5C5CBCBCBD0D0D0CECECECECECECD + CDCDCECECECDCDCDCECECECECECECECECECECECECDCDCDCECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE + CECECFCFCFD0D0D0D0D0D0D0D0D0CFCFCFCFCFCFD0D0D0D0D0D0D0D0D0CFCFCF + D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFD0D0D0D0D0D0D0D0D0CFCFCFD0D0 + D0CFCFCFD0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFCFCFCFD0D0D0D0D0D0CF + CFCFCCCCCCC3C3C3B3B3B3A2A2A2DFDFDFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC + 32322F05050422136B2D0FBF2A08DF2604EA2400EF2906E22816890B08130603 + 03224F523EB5B648DBDB3AADAF193D410301011B3D2C3FD08841FFA73DFF9E3B + F9973AF7963AF69539F59539F79541FFA73DC9840F2719343232DDDCDCFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 + F0F0BEBEBEA8A8A8BEBEBECDCDCDD3D3D3D3D3D3D2D2D2D1D1D1D2D2D2D1D1D1 + D2D2D2D2D2D2D1D1D1D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D1D1D1D1D1D1D1 + D1D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D1D1D2D2D2D2D2D2D2 + D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D2D2 + D2D3D3D3D2D2D2D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3 + D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D4D4D4CCCCCCC3C3C3 + A2A2A2BABABAF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B21E201C0406 + 0218123E25157C28129F290EAE2E10D72E13AE0F0A1A194C4346E1E245FFFF41 + FFFF44FFFF43D5D51A32361C442C42E6943CF4993DF69943FF9F45FFA345FFA5 + 43FFA644FFA644E99C205F41030100767575F6F6F6FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD6D6D6A1A1A1 + B7B7B7CECECED3D3D3D6D6D6D4D4D4D4D4D4D4D4D4D5D5D5D4D4D4D4D4D4D5D5 + D5D4D4D4D5D5D5D4D4D4D4D4D4D4D4D4D5D5D5D5D5D5D5D5D5D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D5D5D5D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4 + D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D6D6D6D6D6D6D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D6D6D6D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5 + D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5CBCBCBC2C2C2A8A8A8CBCBCBF8F8 + F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFF8FBFDD3E8EEEDF5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 + EEF3D4E7EEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCD817F80201C1C0300000000000703030D + 0A0F1510291E165311073B0C0B0C319B9946FFFF40FDFF3EFBFC40FFFF49FFFF + 32878907100D1A4D321C5E3B2469452F855B36986736A26D35AA7133A06B205C + 3C0303022E2D2DD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEAB5B5B5B7B7B7CBCBCBD3D3 + D3D9D9D9D8D8D8D8D8D8D7D7D7D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D7D7D7D7D7D7D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D7 + D7D7D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 + D8D8D8D8D8D8D8D2D2D2CBCBCBB8B8B8BCBCBCE8E8E8FDFDFDFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDEEF293CFDF93C8 + D8ECF4F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5E7ED70B4CD93C3D6 + EBF4F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA + FAFABCBCBD322F2F0300000A110D0F1C161016140B0808010101000000000000 + 0000000F0E0E37A3A343FFFF3EFCFD3EFBFC3FFDFE44FFFF359898080F100000 + 000000000503030806060C090A0D0C0C0B0E0C0A0A090C0A0A474545BEBEBEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFF9F9F9D6D6D6BABABAC6C6C6D0D0D0D9D9D9DCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDDDDDDDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDDDDDDDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC + DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDDDDDDDADADACF + CFCFC7C7C7BABABAD2D2D2F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFCCE5EC85DAE876D4E4CAE2EAFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFEFE9FCEDD2FA1C96DAFC7DFEDF2FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B33F3D3E050504 + 23644336B47536BD7B3AAD73308E5E216F47276A472A5D421931240403032973 + 7547FBFC42FFFF40FFFF42FFFF48FEFE29656709140E0C23180F1C160E121108 + 0606010000020000020000040000333132CECECEFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFEAEAEAC2C2C2BEBEBECECECED7D7D7DFDFDFDFDFDFDEDEDEDFDFDF + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDEDEDEDEDEDEDEDEDEDE + DEDEDFDFDFDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE + DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDFDFDFDFDFDFDEDEDEDEDEDEDEDEDEDEDE + DEDFDFDFDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF + DFDFDEDEDEDEDEDEDEDEDEDFDFDFDEDEDEDEDEDED7D7D7CFCFCFC2C2C2C5C5C5 + E9E9E9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFCFE5EC86DBE881EDF7A8D8E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFF3F9FB6AC0DF31A6CD6FAEC4E6F0F5FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5856560401011D583A42E69444FFA842FF + A342FFA240FF9E3BF89940F29743E6973DC7841A492F0E1B1D34929346EAEB48 + F9F943E5E52E8385080B0E1531243CC37F3ECE883BB0762C8F5C237B4E2A754E + 1E4431080B09151212656465DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB + DCDCDCC3C3C3CACACAD3D3D3DEDEDEE1E1E1E1E1E1E2E2E2E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E2E2E2E2E2E2E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 + E1E1E1E1E1E1E2E2E2E1E1E1E1E1E1E1E1E1E2E2E2E1E1E1E1E1E1E2E2E2E2E2 + E2E2E2E2E1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E1E1E1E3E3E3E2E2E2E2 + E2E2E2E2E2E2E2E2E1E1E1E1E1E1E1E1E1E2E2E2E1E1E1E1E1E1E2E2E2E2E2E2 + E2E2E2E3E3E3E2E2E2DDDDDDD4D4D4CBCBCBC6C6C6DFDFDFFAFAFAFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7E8EF82D6E491FFFF + 8AD6E2EBF4F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECF5F6B3D7E0EEF6F8FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFD6E8EFBBDAE2FBFDFDFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFCBE3EC45C0E635A5C978B1C6F1F7F9FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFF353333010202349E6845FFA43BFB993AF5943AF7963BFB993B + FB9B3DFF9D41FFA845F09D286747000000090F101D47492E6A6A1E4445090607 + 060A070A130F2A765044E49644FFA93EFF9E3DFA9B42F39B3EDA9136AC721841 + 2C0300005F5D5EEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4D5D5D5CACA + CAD3D3D3DADADAE1E1E1E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E3E3E3E4E4E4E4E4E4E4E4E4E4E4E4E4E4 + E4E4E4E4E4E4E4E4E4E4E5E5E5E5E5E5E5E5E5E6E6E6E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E6E6E6E5E5E5E5E5E5E5E5E5E5E5E5 + E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E6E6E6E6E6E6E2E2 + E2D9D9D9D0D0D0C5C5C5D3D3D3F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFF1F7F994D0DE93FCFF85EFF79FD1DEFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFEFFFFA1D2DE6FC1D7E9F3F7FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFBEDFE95EB7CFC2DEE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FCFC + 69C2DF37C0EB3EA1C1A3CBDAFDFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 + 4647010100297C5142FB9E3BFE9C39F59539F59439F4943BFC9940FFA23ED487 + 2661420C110D0501010B130F090B06070505030202205D3C389F6B1023190101 + 011D493439C98141FFA63CFF9D3CFC9A3DFF9F41FFA13ED38817412C080505AB + AAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECD1D1D1D2D2D2D6D6D6DC + DCDCE5E5E5E8E8E8E6E6E6E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6 + E6E6E6E7E7E7E6E6E6E6E6E6E6E6E6E7E7E7E7E7E7E6E6E6E6E6E6E6E6E6E6E6 + E6E7E7E7E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E7E7E7E5E5E5E6E6E6E6E6E6E7 + E7E7E6E6E6E8E8E8E8E8E8E7E7E7E7E7E7E7E7E7E8E8E8E7E7E7E7E7E7E7E7E7 + E7E7E7E7E7E7E8E8E8E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E8E8E8E8E8E8E8E8 + E8E7E7E7E8E8E8E8E8E8E7E7E7E7E7E7E8E8E8E4E4E4DADADAD7D7D7D2D2D2CF + CFCFE9E9E9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFC7E2EA88E6F093FDFF7CD7E6C3DFE7FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFDFEDF271D2E771CEE4ECF5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4E2EC + 47BEDF78BDD3F4F9FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BCEDF3AC4F03BB9 + E063AEC8E1EEF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8988891B19190C2317 + 3BC58042FFA53EFF9F3EFF9E40FFA343F7A039B0731A39290502020000001839 + 2742BB7E2665450000000F1D1737C88045FFA935A16B0C0F0C0101011939283B + B97B43FDA33FFF9F3CFB9A3DFF9E46FFAE2C8B5E040101807E7FFAFAFAFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFDFDFDE8E8E8CDCDCDCBCBCBD9D9D9DFDFDFE7E7E7 + E9E9E9E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E7E7E7E8E8E8E8E8 + E8E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E7E7E7E8 + E8E8E8E8E8E7E7E7E8E8E8E8E8E8E7E7E7E7E7E7E8E8E8E8E8E8E7E7E7EAEAEA + EAEAEAEAEAEAE9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9EAEAEAEAEAEAEAEA + EAE9E9E9EAEAEAE9E9E9E9E9E9EAEAEAEAEAEAEAEAEAEAEAEAE9E9E9E9E9E9EA + EAEAEAEAEAEAEAEAE8E8E8DFDFDFDBDBDBD6D6D6D2D2D2E7E7E7FDFDFDFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFDFDA1D4E290 + F6FB89F2FB7ECDDCE6F1F5FFFFFFFFFFFFFFFFFFFFFFFFF5F9FB8CCEDF6CE5F7 + 71D0E2EBF6F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3E4EB4DC9EA41B1D0A0C8 + D6FDFEFEFFFFFFFFFFFFFFFFFFFFFFFFC5E0EA42C1EA36C4F04CAFD1B5D5E3FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6777676060202112F2034A2693EDE + 8E41E5943CCF842C7D54101F16030101020000162E2239C17F45EE9A21533A02 + 01011E3B2E3DDB8B40FFA642F69C2D7E55090A0702010115281D32966441E493 + 3FF39C3DF39A42E0931C5A3C0200009B9B9AFEFEFEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFDFDFDE8E8E8CFCFCFD6D6D6DEDEDEE2E2E2E9E9E9ECECECEBEB + EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEAEAEAEBEBEBEBEBEBEBEBEBEAEAEAEA + EAEAEAEAEAEBEBEBEAEAEAEAEAEAEBEBEBEAEAEAEAEAEAEAEAEAEBEBEBEAEAEA + EBEBEBEAEAEAEAEAEAEAEAEAEBEBEBEBEBEBEAEAEAEDEDEDECECECECECECECEC + ECECECECECECECECECECECECECECECECEDEDEDEDEDEDEBEBEBECECECEBEBEBEB + EBEBECECECEBEBEBEBEBEBEDEDEDEBEBEBECECECECECECECECECEBEBEBE8E8E8 + E3E3E3DEDEDED8D8D8D0D0D0E5E5E5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FAFC91DBE793F8FD80E9F479C6D5 + EFF6F8FFFFFFFFFFFFFFFFFFECF5F892D1E06DE1F370EAFD65CFE2D5EBEFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFA9DAE34BCFEF48CDED42A5C2AAD1DEF8FCFDFF + FFFFFFFFFFFFFFFFCFE5ED45C0E733C7F43CB6DE91CADCFEFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFEDEDED6867670B0808040805102E2018422E081A1204 + 010103000003000014231A39B17746FFAF32C57C10291C02010126503B40E290 + 3CFF9B3DFF9D42F299276847060303030000080A09153C2A19603D17603B143D + 280405043B3A3ADFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFEFEFEE9E9E9D0D0D0DADADAE3E3E3E7E7E7EAEAEAEDEDEDEEEEEEEDEDEDED + EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEEEEEEEEEEEEEDEDEDEDEDEDEDEDED + EEEEEEEEEEEEEDEDEDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEDEDEDEDEDEDEDED + EDEEEEEEEDEDEDEEEEEEEEEEEEEFEFEFEEEEEEEFEFEFEEEEEEEEEEEEEFEFEFEE + EEEEEEEEEEEEEEEEEEEEEEEFEFEFEEEEEEEEEEEEEEEEEEEFEFEFEFEFEFEFEFEF + EEEEEEEEEEEEEFEFEFEEEEEEEFEFEFEEEEEEE9E9E9E4E4E4E2E2E2D8D8D8D2D2 + D2E7E7E7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFF2FBFC96E3EC95F8FD7FE9F566C1D1C4DFE8FFFFFFFBFD + FEDFF0F588CDDF6EE3F473EEFE6BE7FA5FD2E7A7D2E0FDFEFEFFFFFFFFFFFFFF + FFFFF3F9FA82C9DF4DD4F54EDBFB42C5E4399EBE96C6D7E9F4F7FDFEFEFBFDFE + 9FCEDF3DC3ED32C6F437BDE886CBE0FEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFF3F3F39A9A9A424041211E1E221E1E2B28282625250502020F1914 + 36A36C43FFA341FFA53AB77813241A010000265D4140EB943CFF9B39F5953FFF + 9F41DF8F1F47330200000A06071B1717171313130F0F181515403D3EC7C7C7FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEE + EEEED7D7D7D9D9D9E3E3E3E8E8E8ECECECF0F0F0F1F1F1F1F1F1EFEFEFF0F0F0 + F0F0F0F0F0F0F0F0F0F0F0F0EFEFEFF0F0F0F0F0F0F0F0F0EFEFEFEFEFEFF0F0 + F0EFEFEFF0F0F0F0F0F0F0F0F0F0F0F0EFEFEFF0F0F0F0F0F0EFEFEFF0F0F0F0 + F0F0F1F1F1F1F1F1F0F0F0F1F1F1F0F0F0F0F0F0F1F1F1F1F1F1F0F0F0F1F1F1 + F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F0F0F0F0F0F0F1F1F1F1F1F1F0F0F0F2F2 + F2F2F2F2EFEFEFEBEBEBE9E9E9E2E2E2D5D5D5D1D1D1ECECECFEFEFEFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFF3FBFC9BE3EC9CF8FD83EFF96AD7E579C8DAAFDAE59DD5E376D2E575E9FA73 + EFFB6EDAE96BDEF264DCF276C7D6EDF5F8FFFFFFFFFFFFFFFFFFCEE7EE5AC7E3 + 4CD6F656CDE95AD8ED43C9E735AACC5DB3CE99CDDE95CDE04ABDE135C5F132C3 + F234BFEA85CEE4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FCFCFCECECECCCCCCCCCCCCCD4D4D45351510509062C875B43FA9F3CFE9E3EFF + 9F3198650E100F0200001F5F3E3CED943BFF9B39F4943AF89640FFA337B97A07 + 150F1D1A1B8C8C8CACACACA09F9FB3B2B2E7E7E7FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4DADADA + D7D7D7E1E1E1E9E9E9EEEEEEF0F0F0F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 + F2F2F2F2F1F1F1F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F1F1F1F2F2F2F2 + F2F2F1F1F1F2F2F2F1F1F1F2F2F2F2F2F2F1F1F1F2F2F2F2F2F2F3F3F3F3F3F3 + F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 + F3F3F3F3F3F3F3F2F2F2F2F2F2F3F3F3F3F3F3F2F2F2F2F2F2F1F1F1EDEDEDE7 + E7E7DFDFDFD0D0D0DADADAF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6FBFCA5DDE5B3 + FAFC95F4FD82EFFB7CEBFA7CE9F77AE9F87DF2FD77F2FC67CBE48DB7D378C7DE + 6EEAFA5DD3E595CDDBD6DFEDE0E1F1CDDDEB7ACDE050DAF74AD3F176B6D482B6 + D45CDAF04EDDF63AC4EB39BFE938C2EE34C4F031C0EF31C3F238C2E99CD3E4FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFD9D9D91E1C1C10362441E3913DFF9D3BFC9941FF9E23754C02010103 + 01011B623D39EF933CFF9C39F4943AF5953CFB9D40F49C256D47090606989898 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBE4E4E4D5D5D5D9D9 + D9E9E9E9EFEFEFF1F1F1F3F3F3F3F3F3F4F4F4F5F5F5F5F5F5F4F4F4F5F5F5F4 + F4F4F5F5F5F5F5F5F4F4F4F4F4F4F4F4F4F5F5F5F4F4F4F5F5F5F4F4F4F5F5F5 + F5F5F5F4F4F4F4F4F4F5F5F5F5F5F5F4F4F4F5F5F5F5F5F5F5F5F5F5F5F5F6F6 + F6F6F6F6F5F5F5F5F5F5F5F5F5F4F4F4F5F5F5F6F6F6F5F5F5F5F5F5F5F5F5F5 + F5F5F5F5F5F4F4F4F4F4F4F3F3F3F2F2F2EAEAEAE3E3E3D5D5D5CFCFCFE1E1E1 + FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FAFD97B3D9B0EBF3CDFFFFB2F9FD + 9FF7FE97FAFF90FAFE7CEDF561BCE26085D2767BCF70AAD97AECF766E3F755CC + E35EADD165A1D056B7DC50D6F24FDDF947C8E8698FD2787BD0639DDC6AD7EF5F + E7F74DDCF840D0F63BC9F339CAF236D0F43BA9DEAFC2E1FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3A2A207 + 05051A593B40FF9D3AF9963DFF9F3FE491204F36010000040101216E463AF295 + 3CFF9B3AF5963AF5963BF99844FFA236A66D030002726F70FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5DDDDDDD6D6D6E1E1E1EB + EBEBF3F3F3F6F6F6F5F5F5F5F5F5F7F7F7F6F6F6F6F6F6F6F6F6F7F7F7F7F7F7 + F6F6F6F6F6F6F7F7F7F7F7F7F7F7F7F7F7F7F6F6F6F6F6F6F6F6F6F7F7F7F6F6 + F6F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 + F6F6F6F6F6F6F6F6F7F7F7F6F6F6F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F4F4F4 + F5F5F5EFEFEFE4E4E4D8D8D8CDCDCDD9D9D9F4F4F4FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFEFEFFA555FCF5D8CDFC0EEF7D7FFFCC7FFFDA8F3F886D7 + EF60A1DD5B74DA6F79E3818AE9799CE183DDEF84F3FD65E0F857DFF656E1F755 + DDF752DBF74BD9F357B5E27E94E38089EA6875E15F84DC6AB9E76DDEF263E4F5 + 5BE3F650DEF33AB7E82057CF8585D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F0503031D634140FFA3 + 3CFF9E44FFA834A56C0C120E020001020000246A463EF89A3CFF9D39F49539F4 + 953CF99942FFA23295630200016B696AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEDEDEDD8D8D8D6D6D6E2E2E2EFEFEF + F7F7F7FBFBFBF9F9F9F7F7F7F8F8F8F9F9F9F9F9F9F9F9F9F8F8F8F8F8F8F9F9 + F9F9F9F9F9F9F9F9F9F9F8F8F8F8F8F8F8F8F8F9F9F9F9F9F9F8F8F8F9F9F9F9 + F9F9F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F9F9F9F9F9F9F9F9F9F8F8F8 + F9F9F9F8F8F8F9F9F9F9F9F9F8F8F8F8F8F8F8F8F8F3F3F3E8E8E8D7D7D7CACA + CAD3D3D3EBEBEBFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFF4F5FB696ED2192CD14A70D577A0DE78A5E05D8DD64C6DD34E5CD75F69DC69 + 78DD7282DF7887DE73A7DC8EE6F394F7FF7CECFD6AE4F95FE0FA50DAF74DBAE1 + 6C93D87D88DF6F81DE6574DC5963DA4B5ED54978D55093DA4E9CDD418DD82A53 + D21E27CD969ADEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFBCBCBC0C0A0A113D2842E59545FFA73CC3801437 + 26070505575757282525102C1E3BCB8342FFA63DFF9D3BFF9A40FFA642E59519 + 48300603038F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEDEDEDDBDBDBD8D8D8DBDBDBE8E8E8F5F5 + F5FDFDFDFDFDFDFAFAFAF8F8F8F9F9F9F9F9F9F9F9F9FAFAFAFAFAFAFAFAFAFA + FAFAF9F9F9F9F9F9F9F9F9FAFAFAFAFAFAF9F9F9FAFAFAFAFAFAFAFAFAFAFAFA + FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFBFBFBFAFAFAF9F9F9FAFAFAFBFB + FBFDFDFDFAFAFAEBEBEBDEDEDED2D2D2CACACAD4D4D4E9E9E9FDFDFDFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D3ED8D + 90DD878BDD8C93DB9096DB9497DC9A9CDE9FA3DFA2A7DFA5AAE0A7ADE0ABAEE1 + AAB0DEA2C7DF94DFE88BE7F178DFF063D6EB74C8DF9FBBDDADAEE0AAAFE0A6AC + DFA3A9E0A1A6DF9DA1DF999ADD9697DC9396DB9193DC8C8CDD9DA0DFE4E5F4FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFEEEEEE4A49490609061D573A267B501430210200005C5C5CE6E6E77B + 7A7A04000018473037B87745F29C45F49A3CCE852875500504043D3C3CDDDDDD + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1DDDDDDD7D7D7D6D6D6DCDCDCE8E8E8F5 + F5F5FFFFFFFEFEFEFDFDFDFCFCFCFAFAFAFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB + FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFCFCFCFDFDFDFCFCFCFCFCFCFCFC + FCFCFCFCFCFCFCFCFCFCFEFEFEFFFFFFFFFFFFF9F9F9E9E9E9DBDBDBD0D0D0C7 + C7C7CCCCCCD9D9D9EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDAEE + F3C3EAF2BCE8F3C0E6EFE7F2F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF + C0BF3734350200000200000C08085E5E5DD9D9D9FFFFFFD7D7D74F4C4E020000 + 0B22151E623F1F6641113020030102252324B4B4B4FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFAFAFAE7E7E7D8D8D8D5D5D5D2D2D2D3D3D3DEDEDE + ECECECFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7 + F7F7E7E7E7DADADAD2D2D2C6C6C6C1C1C1CCCCCCD3D3D3DEDEDEF8F8F8FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF959495 + 8C8A8BABAAABEBEBEBFFFFFFFFFFFFFFFFFFDDDDDD7D7B7C3331310908080908 + 08201D1D605E5EC0C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9EAEAEADEDEDEDBDBDBCFCFCFCDCDCDC8C8 + C8CBCBCBD1D1D1D9D9D9DFDFDFECECECF3F3F3F0F0F0EFEFEFEFEFEFEFEFEFF2 + F2F2E7E7E7D4D4D4CFCFCFC4C4C4C8C8C8BFBFBFB7B7B7B5B5B5B9B9B9C7C7C7 + D7D7D7D6D6D6DFDFDFFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD5D5D5B6B5B6B7B6B6C7C7C7EEEEEEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7E9E9E9E1E1E1D9D9D9DCDCDCCF + CFCFC1C1C1C3C3C3B9B9B9AAAAAAA8A8A8A4A4A4A6A6A6AAAAAAA3A3A3A6A6A6 + B9B9B9B8B8B8C9C9C9D4D4D4D4D4D4D8D8D8E3E3E3FBFBFBFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFDFDFDF5F5F5F5F5F5F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFDFDFDFAFAFAF7F7F7F7F7F7EBEBEBDADADAD8D8D8 + C8C8C8B8B8B8B6B6B6B3B3B3B4B4B4B7B7B7B3B3B3BDBDBDD7D7D7DADADAEAEA + EAF6F6F6F7F7F7F8F8F8FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFE1A68CD68561E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BCA9 + C75828C75828F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45C75828E5B1 + 9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6FBF4F1FFFF + FFFFFFFFFFFFFFFBF4F1F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFF4DED4F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F4DED4FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6F8E9E2FFFFFFFFFFFFFFFF + FFFFFFFFF0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F0D2C6FB + F4F1FFFFFFFFFFFFFFFFFFF0D2C6F0D2C6FBF4F1FFFFFFFFFFFFF4DED4F0D2C6 + F8E9E2FFFFFFFFFFFFFFFFFFF8E9E2F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFBF4 + F1F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFBF4F1F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFF4DED4 + F0D2C6F8E9E2FFFFFFFFFFFFF8E9E2F0D2C6F4DED4FFFFFFFFFFFFFFFFFFF8E9 + E2E5B19BE5B19BE5B19BE9BCA9FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 + BCA9E5B19BE5B19BE9BCA9FBF4F1FFFFFFFFFFFFFFFFFFECC7B7E5B19BE5B19B + E9BCA9FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F8E9E2FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BCA9C75828CB6336FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFF8E9E2F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFBF4F1F0D2C6 + F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4E5B19BE5B1 + 9BE9BCA9FBF4F1F4DED4F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45C75828E1A68CFFFFFFFFFFFFFFFFFFE1 + A68CC75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45C75828 + E1A68CFFFFFFFFFFFFFFFFFFE1A68CC75828CB6336FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFDD9B7EC75828D27953FFFFFFFFFFFFFFFFFFECC7B7C75828C7 + 5828F4DED4FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828F0D2C6FFFFFFFFFFFF + FFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFF + FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + F0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFF + FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFDD9B7EC75828C75828C75828C7 + 5828C75828CB6336E9BCA9FFFFFFFFFFFFFFFFFFD27953C75828C75828C75828 + C75828F0D2C6FFFFFFFBF4F1D27953C75828C75828C75828C75828CB6336F4DE + D4FFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFC75828C75828E9BCA9FFFFFFFFFFFFFFFFFFFFFFFF + E5B19BC75828C75828FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFE9BCA9C75828C75828C75828C75828CB6336CE + 6E45C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFF4DED4C75828C75828CE6E45FFFFFFFFFFFFFFFFFFCE6E45C75828C75828 + F4DED4FFFFFFFFFFFFFFFFFFFFFFFFF4DED4C75828C75828CE6E45FFFFFFFFFF + FFFFFFFFCE6E45C75828C75828F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB + 6336C75828C75828F8E9E2FFFFFFFFFFFFDD9B7EC75828C75828E5B19BFFFFFF + FFFFFFFFFFFFF0D2C6C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFC75828C758 + 28F0D2C6FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFE5B19BC7 + 5828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C758 + 28FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFE5B19BC7 + 5828D68561FFFFFFFFFFFFD68561CB6336E9BCA9FBF4F1FBF4F1E5B19BC75828 + CB6336FBF4F1FFFFFFECC7B7C75828C75828E5B19BF0D2C6E5B19BF8E9E2FFFF + FFD68561C75828CB6336E9BCA9ECC7B7D27953C75828CB6336FBF4F1FFFFFFFF + FFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + E9BCA9C75828C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828C758 + 28FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFCB6336C75828D27953F0D2C6E5B19BCE6E45C75828C75828E5B19B + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828 + C75828C75828F4DED4FFFFFFF4DED4C75828C75828C75828E5B19BFFFFFFFFFF + FFFFFFFFFFFFFFE5B19BC75828C75828C75828F4DED4FFFFFFF4DED4C75828C7 + 5828C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFF4DED4C75828C75828C75828 + E5B19BFFFFFFFFFFFFCB6336C75828C75828DA9070FFFFFFFFFFFFFFFFFFF8E9 + E2E5B19BE5B19BF8E9E2FFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFF + FFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFF + FFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFF + FFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFE5B19BC75828D68561FFFFFF + FFFFFFE9BCA9FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFF + FFE5B19BC75828D27953FFFFFFFFFFFFFFFFFFFFFFFFF4DED4C75828C75828F0 + D2C6FFFFFFFFFFFFFBF4F1CB6336C75828E5B19BFFFFFFFFFFFFD68561C75828 + E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD27953C75828C758 + 28C75828F0D2C6FFFFFFFFFFFFFFFFFFF0D2C6E5B19BE5B19BFFFFFFFFFFFFFF + FFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828 + C75828F8E9E2FFFFFFFFFFFFFBF4F1D27953C75828E5B19BFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9070C75828D27953C75828E1A6 + 8CFFFFFFE1A68CC75828D27953C75828DA9070FFFFFFFFFFFFFFFFFFFFFFFFDA + 9070C75828D27953C75828E1A68CFFFFFFE1A68CC75828D27953C75828DA9070 + FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D27953C75828D27953FFFFFFECC7 + B7C75828D27953C75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828 + E5B19BFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFF0D2 + C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561 + C75828E5B19BFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFBF4F1ECC7B7DA9070C75828C75828F4DED4FFFFFFE5B19BC75828D6 + 8561FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828CE6E45FFFFFFFFFFFFFFFFFF + FFFFFFDD9B7EC75828DA9070FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828D68561C75828DD9B7EFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828 + C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFF + FFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFCB6336C75828ECC7B7C75828CE6E45FFFFFFCE6E45C7 + 5828ECC7B7C75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFCB6336C75828ECC7B7 + C75828CE6E45FFFFFFCE6E45C75828ECC7B7C75828CB6336FFFFFFFFFFFFFFFF + FFFFFFFFDA9070C75828E5B19BD27953C75828F8E9E2DD9B7EC75828E5B19BCE + 6E45C75828F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFF + FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FF + FFFFFFFFFFFFFFFFF0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6FFFFFFFFFFFF + F0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFF + FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFE5B19BCE6E45C75828C7 + 5828C75828C75828DD9B7EFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFF + FFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758 + 28D68561FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFDD9B7EC75828D68561F4DED4C75828C75828F8E9E2FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD6 + 8561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 + DED4C75828C75828FFFFFFDA9070C75828E9BCA9C75828CE6E45FFFFFFCB6336 + C75828F4DED4FFFFFFFFFFFFF4DED4C75828C75828FFFFFFDA9070C75828E9BC + A9C75828CE6E45FFFFFFCB6336C75828F4DED4FFFFFFFFFFFFFFFFFFCB6336C7 + 5828F0D2C6E5B19BC75828E5B19BCB6336C75828F8E9E2DA9070C75828E5B19B + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828C758 + 28F0D2C6FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFE5B19BC7 + 5828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFF + C75828C75828C75828C75828C75828C75828FFFFFFFFFFFFF0D2C6C75828C758 + 28FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFE5B19BC7 + 5828D68561FFFFFFFFFFFFE5B19BC75828C75828CB6336D68561E5B19BF4DED4 + FFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFE5B1 + 9BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFF + FFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1C75828 + C75828E9BCA9FFFFFFCE6E45C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19B + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D68561 + FFFFFFE9BCA9C75828CB6336C75828E1A68CFFFFFFD68561C75828E5B19BFFFF + FFFFFFFFE5B19BC75828D68561FFFFFFE9BCA9C75828CB6336C75828E1A68CFF + FFFFD68561C75828E5B19BFFFFFFFFFFFFF4DED4C75828C75828FFFFFFF8E9E2 + C75828CB6336C75828D27953FFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFF + FFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFF + FFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFE5B19BE5B19BE5B1 + 9BE5B19BE5B19BE5B19BFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFF + FFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFE5B19BC75828D68561FFFFFF + FFFFFFD68561C75828D68561FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFECC7B7C75828C75828FB + F4F1FFFFFFFFFFFFFFFFFFD27953C75828E1A68CFFFFFFFFFFFFD68561C75828 + E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828CB6336FFFFFFFFFF + FFE5B19BC75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828 + C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E1A68CFFFFFFF8E9E2C758 + 28C75828C75828F4DED4FFFFFFE5B19BC75828D68561FFFFFFFFFFFFD68561C7 + 5828E1A68CFFFFFFF8E9E2C75828C75828C75828F4DED4FFFFFFE5B19BC75828 + D68561FFFFFFFFFFFFE5B19BC75828D27953FFFFFFFFFFFFCE6E45C75828C758 + 28E5B19BFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828 + CE6E45F0D2C6FFFFFFFFFFFFD27953C75828CB6336E5B19BFFFFFFFFFFFFE1A6 + 8CC75828CE6E45FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFF0D2C6C75828C75828E1A68CFBF4F1FFFFFFF4DED4C75828 + C75828E9BCA9FFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFDA9070C758 + 28DD9B7EFFFFFFFFFFFFFFFFFFF0D2C6E1A68CFFFFFFFFFFFFE5B19BC75828D6 + 8561FFFFFFFFFFFFFFFFFFFFFFFFFBF4F1CB6336C75828DD9B7EFFFFFFFFFFFF + E9BCA9C75828C75828F0D2C6FFFFFFFFFFFFD68561C75828C75828E5B19BFBF4 + F1FBF4F1F4DED4FFFFFFCE6E45C75828E1A68CFFFFFFFFFFFFFBF4F1C75828C7 + 5828E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828 + C75828D27953F0D2C6FFFFFFF4DED4FBF4F1F0D2C6C75828C75828FFFFFFFFFF + FFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFC75828C75828ECC7B7FFFFFFFFFFFFD27953C75828CE6E45FF + FFFFFFFFFFECC7B7C75828C75828FFFFFFFFFFFFC75828C75828ECC7B7FFFFFF + FFFFFFD27953C75828CE6E45FFFFFFFFFFFFECC7B7C75828C75828FFFFFFFFFF + FFD68561C75828E1A68CFFFFFFFFFFFFE1A68CC75828C75828F8E9E2FFFFFFFB + F4F1C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828C75828C75828D279 + 53CE6E45C75828C75828CE6E45C75828CE6E45D27953C75828C75828E1A68CFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + F0D2C6C75828C75828C75828C75828D68561CB6336C75828CB6336FBF4F1FFFF + FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFECC7B7C75828C75828DA9070E5 + B19BD27953C75828D68561FFFFFFE9BCA9CE6E45C75828CB6336D68561D68561 + D68561F4DED4FFFFFFE9BCA9C75828C75828CE6E45D27953C75828C75828DD9B + 7EFFFFFFFFFFFFFFFFFFD68561C75828CB6336C75828C75828C75828D68561E9 + BCA9C75828C75828F8E9E2FFFFFFFFFFFFFFFFFFDD9B7EC75828D27953FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828CB6336C758 + 28C75828C75828F0D2C6F0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD6 + 8561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4D6 + 8561D68561F8E9E2FFFFFFFFFFFFE9BCA9D68561E5B19BFFFFFFFFFFFFF8E9E2 + D68561D68561F4DED4F4DED4D68561D68561F8E9E2FFFFFFFFFFFFE9BCA9D685 + 61E5B19BFFFFFFFFFFFFF8E9E2D68561D68561F4DED4FFFFFFD68561D68561EC + C7B7FFFFFFFFFFFFF4DED4D68561DD9B7EFFFFFFFFFFFFFFFFFFDA9070D68561 + E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561D685 + 61F4DED4FFFFFFFFFFFFE1A68CD68561E5B19BDD9B7ECB6336C75828CB6336E5 + B19BFBF4F1E1A68CCB6336C75828C75828DD9B7EFBF4F1FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C758 + 28ECC7B7D27953C75828C75828D27953F4DED4FFFFFFFFFFFFFFFFFFE9BCA9D6 + 8561E1A68CFFFFFFFFFFFFFFFFFFECC7B7D27953C75828C75828C75828DA9070 + ECC7B7FFFFFFE9BCA9CE6E45C75828CB6336D68561D68561D68561F4DED4FFFF + FFFFFFFFECC7B7D27953C75828C75828CE6E45E5B19BFFFFFFFFFFFFFFFFFFFF + FFFFE1A68CD68561E9BCA9E9BCA9DA9070D68561E1A68CE5B19BD68561DD9B7E + FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6D68561D68561F8E9E2FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFF4DED4D68561D68561F8E9E2E1A68CD68561D68561F4 + DED4F4DED4D68561D68561FFFFFFFFFFFFFFFFFFFFFFFFE1A68CD68561E9BCA9 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D6 + 8561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFC75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + F0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6E5B19BE9BCA9FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B1 + 9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF} + WaterMark.Image.Alignment = iaCenter + WaterMark.Image.Layout = ilCenter + WaterMark.Width = 201 + end + object Page2: TJvWizardInteriorPage + Header.Height = 50 + Header.Title.Color = clNone + Header.Title.Text = #1052#1072#1089#1090#1077#1088' '#1101#1082#1089#1087#1086#1088#1090#1072' '#1080#1089#1090#1086#1088#1080#1080 + Header.Title.Anchors = [akLeft, akTop, akRight] + Header.Title.Font.Charset = DEFAULT_CHARSET + Header.Title.Font.Color = clWindowText + Header.Title.Font.Height = -16 + Header.Title.Font.Name = 'Tahoma' + Header.Title.Font.Style = [fsBold] + Header.Subtitle.Color = clNone + Header.Subtitle.Text = #1042#1099#1073#1077#1088#1080#1090#1077' '#1082#1086#1085#1090#1072#1082#1090#1099', '#1080#1089#1090#1086#1088#1080#1102' '#1082#1086#1090#1086#1088#1099#1093' '#1042#1099' '#1093#1086#1090#1080#1090#1077' '#1101#1082#1089#1087#1086#1088#1090#1080#1088#1086#1074#1072#1090#1100'.' + Header.Subtitle.Anchors = [akLeft, akTop, akRight, akBottom] + Header.Subtitle.Font.Charset = DEFAULT_CHARSET + Header.Subtitle.Font.Color = clWindowText + Header.Subtitle.Font.Height = -11 + Header.Subtitle.Font.Name = 'Tahoma' + Header.Subtitle.Font.Style = [] + EnabledButtons = [bkBack, bkNext, bkFinish, bkCancel] + ExplicitWidth = 0 + ExplicitHeight = 0 + object CBSelectAll: TCheckBox + Left = 16 + Top = 199 + Width = 97 + Height = 17 + Caption = #1042#1099#1073#1088#1072#1090#1100' '#1074#1089#1077#1093 + TabOrder = 0 + OnClick = CBSelectAllClick + end + object ContactList: TListView + Left = 16 + Top = 64 + Width = 529 + Height = 129 + Checkboxes = True + Columns = < + item + AutoSize = True + Caption = #1053#1080#1082 + end + item + Caption = #1055#1088#1086#1090#1086#1082#1086#1083 + Width = 100 + end + item + AutoSize = True + Caption = #1053#1086#1084#1077#1088 + end> + ColumnClick = False + RowSelect = True + TabOrder = 1 + ViewStyle = vsReport + OnChange = ContactListChange + OnChanging = ContactListChanging + end + end + object Page3: TJvWizardInteriorPage + Header.Height = 50 + Header.Title.Color = clNone + Header.Title.Text = #1052#1072#1089#1090#1077#1088' '#1101#1082#1089#1087#1086#1088#1090#1072' '#1080#1089#1090#1086#1088#1080#1080 + Header.Title.Anchors = [akLeft, akTop, akRight] + Header.Title.Font.Charset = DEFAULT_CHARSET + Header.Title.Font.Color = clWindowText + Header.Title.Font.Height = -16 + Header.Title.Font.Name = 'Tahoma' + Header.Title.Font.Style = [fsBold] + Header.Subtitle.Color = clNone + Header.Subtitle.Text = #1048#1076#1077#1090' '#1101#1082#1089#1087#1086#1088#1090' '#1080#1089#1090#1086#1088#1080#1080', '#1087#1086#1076#1086#1078#1076#1080#1090#1077'...' + Header.Subtitle.Anchors = [akLeft, akTop, akRight, akBottom] + Header.Subtitle.Font.Charset = DEFAULT_CHARSET + Header.Subtitle.Font.Color = clWindowText + Header.Subtitle.Font.Height = -11 + Header.Subtitle.Font.Name = 'Tahoma' + Header.Subtitle.Font.Style = [] + EnabledButtons = [bkBack, bkNext, bkFinish, bkCancel] + OnPage = Page3Page + ExplicitWidth = 0 + ExplicitHeight = 0 + object LExportDesc: TLabel + Left = 16 + Top = 77 + Width = 82 + Height = 13 + Caption = #1042#1099#1073#1088#1072#1085#1086' 0 '#1080#1079' 10' + end + object LExportDesc2: TLabel + Left = 16 + Top = 119 + Width = 63 + Height = 13 + Caption = #1048#1085#1092#1086#1088#1084#1072#1094#1080#1103 + end + object PBTotalExport: TProgressBar + Left = 16 + Top = 96 + Width = 529 + Height = 17 + TabOrder = 0 + end + end + object Page4: TJvWizardInteriorPage + Header.Height = 50 + Header.Title.Color = clNone + Header.Title.Text = #1052#1072#1089#1090#1077#1088' '#1101#1082#1089#1087#1086#1088#1090#1072' '#1080#1089#1090#1086#1088#1080#1080 + Header.Title.Anchors = [akLeft, akTop, akRight] + Header.Title.Font.Charset = DEFAULT_CHARSET + Header.Title.Font.Color = clWindowText + Header.Title.Font.Height = -16 + Header.Title.Font.Name = 'Tahoma' + Header.Title.Font.Style = [fsBold] + Header.Subtitle.Color = clNone + Header.Subtitle.Text = #1069#1082#1089#1087#1086#1088#1090' '#1080#1089#1090#1086#1088#1080#1080' '#1079#1072#1074#1077#1088#1096#1077#1085'.' + Header.Subtitle.Anchors = [akLeft, akTop, akRight, akBottom] + Header.Subtitle.Font.Charset = DEFAULT_CHARSET + Header.Subtitle.Font.Color = clWindowText + Header.Subtitle.Font.Height = -11 + Header.Subtitle.Font.Name = 'Tahoma' + Header.Subtitle.Font.Style = [] + EnabledButtons = [bkBack, bkFinish, bkCancel] + VisibleButtons = [bkFinish] + ExplicitWidth = 0 + ExplicitHeight = 0 + object LExportDone: TLabel + Left = 16 + Top = 72 + Width = 529 + Height = 42 + AutoSize = False + Caption = + #1069#1082#1089#1087#1086#1088#1090' '#1080#1089#1090#1086#1088#1080#1080' '#1079#1072#1074#1077#1088#1096#1077#1085'. '#1058#1077#1087#1077#1088#1100' '#1042#1099' '#1084#1086#1078#1077#1090#1077' '#1086#1090#1087#1088#1072#1074#1080#1090#1100' '#1079#1072#1087#1088#1086#1089' '#1085#1072' '#1089 + + #1080#1085#1093#1088#1086#1085#1080#1079#1072#1094#1080#1102' '#1101#1082#1089#1087#1086#1088#1090#1080#1088#1086#1074#1072#1085#1085#1086#1081' '#1080#1089#1090#1086#1088#1080#1080' '#1089' '#1073#1072#1079#1086#1081' '#1076#1072#1085#1085#1099#1093'. '#1055#1088#1080' '#1073#1086#1083#1100#1096#1086 + + #1084' '#1086#1073#1098#1105#1084#1077' '#1101#1082#1089#1087#1086#1088#1090#1080#1088#1086#1074#1072#1085#1085#1086#1081' '#1080#1089#1090#1086#1088#1080#1080' '#1087#1088#1086#1094#1077#1076#1091#1088#1072' '#1089#1080#1085#1093#1088#1086#1085#1080#1079#1072#1094#1080#1080' '#1084#1086#1078#1077#1090' ' + + #1074#1099#1087#1086#1083#1085#1103#1090#1100#1089#1103' '#1079#1085#1072#1095#1080#1090#1077#1083#1100#1085#1086#1077' '#1074#1088#1077#1084#1103'.' + WordWrap = True + end + object CBSyncRequest: TCheckBox + Left = 16 + Top = 120 + Width = 529 + Height = 17 + Caption = #1054#1090#1087#1088#1072#1074#1080#1090#1100' '#1079#1072#1087#1088#1086#1089' '#1085#1072' '#1089#1080#1085#1093#1088#1086#1085#1080#1079#1072#1094#1080#1102 + TabOrder = 0 + end + end + end + object IMExportThread: TJvThread + Exclusive = True + MaxCount = 0 + RunOnCreate = True + FreeOnTerminate = True + OnExecute = IMExportThreadExecute + Left = 264 + Top = 216 + end +end diff --git a/plugins/MirandaNGHistoryToDB/MsgExport.pas b/plugins/MirandaNGHistoryToDB/MsgExport.pas new file mode 100644 index 0000000000..e36e3b1c8a --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/MsgExport.pas @@ -0,0 +1,452 @@ +{ ############################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.5 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ############################################################################ } + +unit MsgExport; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, JvWizard, JvExControls, JvWizardRouteMapNodes, ComCtrls, StdCtrls, + JvComponentBase, JvThread, JclStringConversions, Global, Contacts, m_api; + +type + TContactRecord = record + hContact: Cardinal; + ContactID: AnsiString; + ContactName: AnsiString; + ProtoName: AnsiString; + Selected: Boolean; + end; + TExportForm = class(TForm) + IMExportWizard: TJvWizard; + Page1: TJvWizardWelcomePage; + Page2: TJvWizardInteriorPage; + Page3: TJvWizardInteriorPage; + Page4: TJvWizardInteriorPage; + LExportDesc: TLabel; + IMExportThread: TJvThread; + CBSelectAll: TCheckBox; + ContactList: TListView; + PBTotalExport: TProgressBar; + LExportDesc2: TLabel; + CBSyncRequest: TCheckBox; + LExportDone: TLabel; + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure Page3Page(Sender: TObject); + procedure IMExportWizardCancelButtonClick(Sender: TObject); + procedure IMExportWizardFinishButtonClick(Sender: TObject); + procedure IMExportThreadExecute(Sender: TObject; Params: Pointer); + procedure CBSelectAllClick(Sender: TObject); + procedure ContactListChanging(Sender: TObject; Item: TListItem; Change: TItemChange; var AllowChange: Boolean); + procedure ContactListChange(Sender: TObject; Item: TListItem; Change: TItemChange); + procedure BringFormToFront(Form: TForm); + function CheckStopExportAndExit: Boolean; + private + { Private declarations } + StartExport: Boolean; + // + procedure OnLanguageChanged(var Msg: TMessage); message WM_LANGUAGECHANGED; + procedure LoadLanguageStrings; + public + { Public declarations } + end; + +var + ExportForm: TExportForm; + ExportContactRecords: Array of TContactRecord; + +implementation + +{$R *.dfm} +{$R icons.res} + +procedure TExportForm.FormCreate(Sender: TObject); +begin + StartExport := False; + ExportFormDestroy := False; + // + ExportFormHandle := Handle; + SetWindowLong(Handle, GWL_HWNDPARENT, 0); + SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW); + // + LoadLanguageStrings; +end; + +procedure TExportForm.FormShow(Sender: TObject); +var + ListItem: TListItem; + hContact: Cardinal; + ContactProto, ContactID, ContactName: AnsiString; + Count: Integer; +begin + IMExportWizard.ActivePage := Page1; + StartExport := False; + // + hContact := CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + ContactList.Columns[0].MaxWidth := 190; + ContactList.Columns[1].MaxWidth := 90; + ContactList.Columns[2].MaxWidth := 140; + ContactList.Items.BeginUpdate; + Count := 0; + while hContact <> 0 do + begin + ContactProto := GetContactProto(hContact); + ContactID := GetContactID(hContact, ContactProto); + ContactName := GetContactDisplayName(hContact, '', True); + // . + if ContactProto = MyAccount then + ContactProto := 'ICQ'; + if ContactName = '' then + ContactName := 'NoContactName'; + if ContactID = '' then + ContactID := 'NoContactID'; + SetLength(ExportContactRecords, Count + 1); + ExportContactRecords[Count].hContact := hContact; + ExportContactRecords[Count].ContactID := ContactID; + ExportContactRecords[Count].ContactName := ContactName; + ExportContactRecords[Count].ProtoName := ContactProto; + ExportContactRecords[Count].Selected := False; + Inc(Count); + ListItem := ContactList.Items.Add; + ListItem.Caption := ContactName; + ListItem.SubItems.Add(ContactProto); + ListItem.SubItems.Add(ContactID); + {if StrContactProtoToInt(ContactProto) = 15 then // 15 - Unknown Proto + ListItem.Checked := False + else + ListItem.Checked := True;} + hContact := CallService(MS_DB_CONTACT_FINDNEXT, hContact, 0); + end; + ContactList.Items.EndUpdate; +end; + +procedure TExportForm.FormClose(Sender: TObject; var Action: TCloseAction); +begin + ExportFormDestroy := True; + Action := caFree; +end; + +procedure TExportForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +begin + CanClose := CheckStopExportAndExit; +end; + +procedure TExportForm.IMExportWizardCancelButtonClick(Sender: TObject); +begin + Close; +end; + +procedure TExportForm.IMExportWizardFinishButtonClick(Sender: TObject); +begin + if IMExportWizard.ActivePage = Page4 then + begin + if CBSyncRequest.Checked then + OnSendMessageToAllComponent('002'); + Close; + end; +end; + +procedure TExportForm.Page3Page(Sender: TObject); +begin + StartExport := True; + Page3.EnabledButtons := [bkCancel]; + if not IMExportThread.Terminated then + begin + IMExportThread.Terminate; + while not (IMExportThread.Terminated) do + Sleep(1); + end; + IMExportThread.Execute(Self); +end; + +procedure TExportForm.IMExportThreadExecute(Sender: TObject; Params: Pointer); +var + I, J, K, ProtoType: Integer; + SelectedCount, BlobSize: Integer; + hDbEvent: Cardinal; + DBEventInfo: TDBEventInfo; + msgA: PAnsiChar; + msgW: PChar; + msgLen, LenW: Cardinal; + Msg_Date: TDateTime; + Msg_RcvrNick, Msg_RcvrAcc, Msg_SenderNick, Msg_SenderAcc, Msg_Text, MD5String: WideString; + Date_Str, MsgStatus: String; + ContactProto, ContactID, ContactName: AnsiString; + MyContactName, MyContactID: AnsiString; +begin + LExportDesc2.Caption := 'Export...'; + // + SelectedCount := 0; + for J := 0 to Length(ExportContactRecords) do + begin + if ExportContactRecords[J].Selected = True then + Inc(SelectedCount); + if IMExportThread.Terminated then // + Exit; + end; + LExportDesc.Caption := Format(GetLangStr('TotalSelect'), [IntToStr(SelectedCount), IntToStr(Length(ExportContactRecords))]); + // + PBTotalExport.Position := 0; + PBTotalExport.Max := SelectedCount; + SelectedCount := 0; + for I := 0 to Length(ExportContactRecords) do + begin + // , + if ExportContactRecords[I].Selected = True then + begin + LExportDesc2.Caption := Format(GetLangStr('ContactExport'), [ExportContactRecords[I].ContactName, ExportContactRecords[I].ContactID]); + Inc(SelectedCount); + PBTotalExport.Position := SelectedCount; + if IMExportThread.Terminated then // + Exit; + hDbEvent := CallService(MS_DB_EVENT_FINDFIRST, ExportContactRecords[I].hContact, 0); + while hDbEvent <> 0 do + begin + ZeroMemory(@DBEventInfo, SizeOf(DBEventInfo)); + DBEventInfo.cbSize := SizeOf(DBEventInfo); + DBEventInfo.pBlob := nil; + BlobSize := CallService(MS_DB_EVENT_GETBLOBSIZE, hDbEvent, 0); + GetMem(DBEventInfo.pBlob, BlobSize); + DBEventInfo.cbBlob := BlobSize; + if IMExportThread.Terminated then // + begin + if ImportLogOpened then + CloseLogFile(5); + Exit; + end; + if (CallService(MS_DB_EVENT_GET, hDbEvent, Integer(@DBEventInfo)) = 0) and (DBEventInfo.eventType = EVENTTYPE_MESSAGE and EVENTTYPE_URL) then + begin + // + msgA := PAnsiChar(DBEventInfo.pBlob); + msgW := nil; + msgLen := lstrlenA(PAnsiChar(DBEventInfo.pBlob)) + 1; + if msgLen > DBEventInfo.cbBlob then + msgLen := DBEventInfo.cbBlob; + if Boolean(DBEventInfo.flags and DBEF_UTF) then + begin + SetLength(Msg_Text, msgLen); + LenW := Utf8ToWideChar(PChar(Msg_Text), msgLen, msgA, msgLen - 1, CP_ACP); + if Integer(LenW) > 0 then + SetLength(Msg_Text, LenW - 1) + else + Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1); + end + else + begin + LenW := 0; + if DBEventInfo.cbBlob >= msgLen * SizeOf(Char) then + begin + msgW := PChar(msgA + msgLen); + for K := 0 to ((DBEventInfo.cbBlob - msgLen) div SizeOf(Char)) - 1 do + if msgW[K] = #0 then + begin + LenW := K; + Break; + end; + end; + if (LenW > 0) and (LenW < msgLen) then + SetString(Msg_Text, msgW, LenW) + else + Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1); + end; + // + ContactProto := GetContactProto(ExportContactRecords[I].hContact); + // + ContactID := GetContactID(ExportContactRecords[I].hContact, ContactProto); + ContactName := GetContactDisplayName(ExportContactRecords[I].hContact, '', True); + // + MyContactName := GetMyContactDisplayName(ContactProto); + MyContactID := GetMyContactID(ContactProto); + // . + if ContactProto = MyAccount then + ContactProto := 'ICQ'; + // + ProtoType := StrContactProtoToInt(ContactProto); + if ContactID = '' then + ContactID := 'NoContactID'; + if ContactName = '' then + ContactName := 'NoContactName'; + if MyContactID = '' then + MyContactID := 'NoMyContactID'; + if MyContactName = '' then + MyContactName := 'NoMyContactName'; + // , .. + Msg_SenderNick := PrepareString(pWideChar(AnsiToWideString(MyContactName, CP_ACP))); + Msg_SenderAcc := PrepareString(pWideChar(AnsiToWideString(MyContactID, CP_ACP))); + Msg_SenderNick := WideStringToUTF8(Msg_SenderNick); + Msg_SenderAcc := WideStringToUTF8(Msg_SenderAcc); + Msg_RcvrNick := PrepareString(pWideChar(AnsiToWideString(ContactName, CP_ACP))); + Msg_RcvrAcc := PrepareString(pWideChar(AnsiToWideString(ContactID, CP_ACP))); + Msg_RcvrNick := WideStringToUTF8(Msg_RcvrNick); + Msg_RcvrAcc := WideStringToUTF8(Msg_RcvrAcc); + Msg_Text := WideStringToUTF8(PrepareString(pWideChar(Msg_Text))); + MD5String := Msg_RcvrAcc + FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + Msg_Text; + if (DBType = 'oracle') or (DBType = 'oracle-9i') then + Date_Str := FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + else + Date_Str := FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)); + if MatchStrings(LowerCase(ContactProto), 'skype*') then + begin + // ( ) + if (DBEventInfo.flags and DBEF_SENT) = 0 then + MsgStatus := '0' // + else + MsgStatus := '1'; // + // + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2); + if (MatchStrings(DBType, 'oracle*')) then // Oracle, SQL- CHAT_MSG_LOG_ORACLE + WriteInLog(ProfilePath, Format(CHAT_MSG_LOG_ORACLE, [DBUserName, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]), 5) + else + WriteInLog(ProfilePath, Format(CHAT_MSG_LOG, [DBUserName, MsgStatus, Date_Str, Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]), 5); + end + else + begin + // ( ) + if (DBEventInfo.flags and DBEF_SENT) = 0 then + MsgStatus := '1' // + else + MsgStatus := '0'; // + // + if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2); + if (MatchStrings(DBType, 'oracle*')) then // Oracle, SQL- MSG_LOG_ORACLE + WriteInLog(ProfilePath, Format(MSG_LOG_ORACLE, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_Text, EncryptMD5(MD5String)]), 5) + else + WriteInLog(ProfilePath, Format(MSG_LOG, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, Date_Str, Msg_Text, EncryptMD5(MD5String)]), 5); + end; + end; + hDbEvent := CallService(MS_DB_EVENT_FINDNEXT, hDbEvent, 0); + end; + end; + if IMExportThread.Terminated then // + Exit; + end; + Page3.EnabledButtons := [bkCancel,bkNext]; + StartExport := False; + if ImportLogOpened then + CloseLogFile(5); + LExportDesc2.Caption := GetLangStr('ExportDone'); +end; + +procedure TExportForm.BringFormToFront(Form: TForm); +begin + if Form.WindowState = wsMaximized then + ShowWindow(Form.Handle, SW_SHOWMAXIMIZED) + else + ShowWindow(Form.Handle, SW_SHOWNORMAL); + Form.BringToFront; +end; + +function TExportForm.CheckStopExportAndExit: Boolean; +begin + if StartExport then + begin + case MessageBox(Handle, pWideChar(GetLangStr('ExportAbort')), pWideChar(htdPluginShortName + ' - ' +GetLangStr('ExportAbortCaption')),36) of + 6: + begin + if not IMExportThread.Terminated then + begin + IMExportThread.Terminate; + while not (IMExportThread.Terminated) do + begin + Sleep(1); + Forms.Application.ProcessMessages; + end; + end; + Result := True; + end; + 7: + begin + Result := False; + Exit; + end; + end; + end + else + Result := True; +end; + +procedure TExportForm.ContactListChange(Sender: TObject; Item: TListItem; Change: TItemChange); +begin + if Item.Checked <> ExportContactRecords[Item.Index].Selected then // Item.Checked + begin + ExportContactRecords[Item.Index].Selected := Item.Checked; // + { ....} + end; +end; + +procedure TExportForm.ContactListChanging(Sender: TObject; Item: TListItem; Change: TItemChange; var AllowChange: Boolean); +begin + ExportContactRecords[Item.Index].Selected := Item.Checked; // Item.Checked, + AllowChange := True; // :) +end; + +procedure TExportForm.CBSelectAllClick(Sender: TObject); +var + I: Integer; +begin + for I := 0 to ContactList.Items.Count-1 do + begin + ContactList.Items[I].Checked := CBSelectAll.Checked; + ExportContactRecords[I].Selected := CBSelectAll.Checked; + end; + //LExportDesc.Caption := IntToStr(Length(ExportContactRecords)) + ' - ' + IntToStr(ContactList.Items.Count); +end; + +// +procedure TExportForm.OnLanguageChanged(var Msg: TMessage); +begin + LoadLanguageStrings; +end; + +// +procedure TExportForm.LoadLanguageStrings; +var + ExportBitmap: TBitmap; +begin + Caption := htdPluginShortName + ' - ' + GetLangStr('ExortFormCaption'); + IMExportWizard.ButtonBack.Caption := '< ' + GetLangStr('ButtonBack'); + IMExportWizard.ButtonNext.Caption := GetLangStr('ButtonNext') + ' >'; + IMExportWizard.ButtonFinish.Caption := GetLangStr('ButtonFinish'); + IMExportWizard.ButtonCancel.Caption := GetLangStr('ButtonCancel'); + IMExportWizard.Pages.Items[0].Title.Text := GetLangStr('IMExportWizardPage0Title'); + IMExportWizard.Pages.Items[0].Subtitle.Text := Format(GetLangStr('IMExportWizardPage0SubTitle'), [htdIMClientName]); + IMExportWizard.Pages.Items[1].Title.Text := GetLangStr('IMExportWizardPage1Title'); + IMExportWizard.Pages.Items[1].Subtitle.Text := GetLangStr('IMExportWizardPage1SubTitle'); + IMExportWizard.Pages.Items[2].Title.Text := GetLangStr('IMExportWizardPage2Title'); + IMExportWizard.Pages.Items[2].Subtitle.Text := GetLangStr('IMExportWizardPage2SubTitle'); + IMExportWizard.Pages.Items[3].Title.Text := GetLangStr('IMExportWizardPage3Title'); + IMExportWizard.Pages.Items[3].Subtitle.Text := GetLangStr('IMExportWizardPage3SubTitle'); + CBSelectAll.Caption := GetLangStr('SelectAll'); + ContactList.Columns[0].Caption := GetLangStr('NickName'); + ContactList.Columns[1].Caption := GetLangStr('Protocol'); + ContactList.Columns[2].Caption := GetLangStr('Number'); + LExportDone.Caption := GetLangStr('ExportDoneDesc'); + CBSyncRequest.Caption := GetLangStr('SendSyncRequest'); + // + if IMExportWizard.ActivePage = Page1 then + begin + ExportBitmap := TBitmap.Create; + try + if DefaultLanguage = 'Russian' then + ExportBitmap.LoadFromResourceName(HInstance, 'Export_Ru') + else + ExportBitmap.LoadFromResourceName(HInstance, 'Export_En'); + Page1.WaterMark.Image.Picture.Assign(ExportBitmap); + finally + ExportBitmap.Free; + end; + end; +end; + +end. diff --git a/plugins/MirandaNGHistoryToDB/copy_langs.bat b/plugins/MirandaNGHistoryToDB/copy_langs.bat new file mode 100644 index 0000000000..b1487eba92 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/copy_langs.bat @@ -0,0 +1,14 @@ +@echo off + +if not exist .\..\..\bin10\Release\Plugins\langs ( + mkdir .\..\..\bin10\Release\Plugins\langs +) + +if not exist .\..\..\bin10\Release64\Plugins\langs ( + mkdir .\..\..\bin10\Release64\Plugins\langs +) + +copy /Y langs\Russian.xml .\..\..\bin10\Release\Plugins\langs +copy /Y langs\English.xml .\..\..\bin10\Release\Plugins\langs +copy /Y langs\Russian.xml .\..\..\bin10\Release64\Plugins\langs +copy /Y langs\English.xml .\..\..\bin10\Release64\Plugins\langs diff --git a/plugins/MirandaNGHistoryToDB/icons.res b/plugins/MirandaNGHistoryToDB/icons.res new file mode 100644 index 0000000000..88c819c734 Binary files /dev/null and b/plugins/MirandaNGHistoryToDB/icons.res differ diff --git a/plugins/MirandaNGHistoryToDB/jedi.inc b/plugins/MirandaNGHistoryToDB/jedi.inc new file mode 100644 index 0000000000..c31a08c04a --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/jedi.inc @@ -0,0 +1,1430 @@ +{$IFNDEF JEDI_INC} +{$DEFINE JEDI_INC} + +{**************************************************************************************************} +{ } +{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");} +{ you may not use this file except in compliance with the License. You may obtain a copy of the } +{ License at http://www.mozilla.org/MPL/ } +{ } +{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF } +{ ANY KIND, either express or implied. See the License for the specific language governing rights } +{ and limitations under the License. } +{ } +{ The Original Code is: jedi.inc. } +{ The Initial Developer of the Original Code is Project JEDI http://www.delphi-jedi.org } +{ } +{ Alternatively, the contents of this file may be used under the terms of the GNU Lesser General } +{ Public License (the "LGPL License"), in which case the provisions of the LGPL License are } +{ applicable instead of those above. If you wish to allow use of your version of this file only } +{ under the terms of the LGPL License and not to allow others to use your version of this file } +{ under the MPL, indicate your decision by deleting the provisions above and replace them with } +{ the notice and other provisions required by the LGPL License. If you do not delete the } +{ provisions above, a recipient may use your version of this file under either the MPL or the } +{ LGPL License. } +{ } +{ For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html } +{ } +{**************************************************************************************************} +{ } +{ This file defines various generic compiler directives used in different libraries, e.g. in the } +{ JEDI Code Library (JCL) and JEDI Visual Component Library Library (JVCL). The directives in } +{ this file are of generic nature and consist mostly of mappings from the VERXXX directives } +{ defined by Delphi, C++Builder and FPC to friendly names such as DELPHI5 and } +{ SUPPORTS_WIDESTRING. These friendly names are subsequently used in the libraries to test for } +{ compiler versions and/or whether the compiler supports certain features (such as widestrings or } +{ 64 bit integers. The libraries provide an additional, library specific, include file. For the } +{ JCL e.g. this is jcl.inc. These files should be included in source files instead of this file } +{ (which is pulled in automatically). } +{ } +{**************************************************************************************************} +{ } +{ Last modified: $Date:: 2012-09-04 16:01:38 +0200 (út, 04 9 2012) $ } +{ Revision: $Rev:: 161 $ } +{ Author: $Author:: outchy $ } +{ } +{**************************************************************************************************} + +(* + +- Development environment directives + + This file defines two directives to indicate which development environment the + library is being compiled with. Currently this can either be Delphi, Kylix, + C++Builder or FPC. + + Directive Description + ------------------------------------------------------------------------------ + DELPHI Defined if compiled with Delphi + KYLIX Defined if compiled with Kylix + DELPHICOMPILER Defined if compiled with Delphi or Kylix/Delphi + BCB Defined if compiled with C++Builder + CPPBUILDER Defined if compiled with C++Builder (alias for BCB) + BCBCOMPILER Defined if compiled with C++Builder or Kylix/C++ + DELPHILANGUAGE Defined if compiled with Delphi, Kylix or C++Builder + BORLAND Defined if compiled with Delphi, Kylix or C++Builder + FPC Defined if compiled with FPC + +- Platform Directives + + Platform directives are not all explicitly defined in this file, some are + defined by the compiler itself. They are listed here only for completeness. + + Directive Description + ------------------------------------------------------------------------------ + WIN32 Defined when target platform is 32 bit Windows + WIN64 Defined when target platform is 64 bit Windows + MSWINDOWS Defined when target platform is 32 bit Windows + LINUX Defined when target platform is Linux + UNIX Defined when target platform is Unix-like (including Linux) + CLR Defined when target platform is .NET + +- Architecture directives. These are auto-defined by FPC + CPU32 and CPU64 are mostly for generic pointer size dependant differences rather + than for a specific architecture. + + CPU386 Defined when target platform is native x86 (win32) + CPUx86_64 Defined when target platform is native x86_64 (win64) + CPU32 Defined when target is 32-bit + CPU64 Defined when target is 64-bit + CPUASM Defined when target assembler is available + +- Visual library Directives + + The following directives indicate for a visual library. In a Delphi/BCB + (Win32) application you need to define the VisualCLX symbol in the project + options, if you want to use the VisualCLX library. Alternatively you can use + the IDE expert, which is distributed with the JCL to do this automatically. + + Directive Description + ------------------------------------------------------------------------------ + VCL Defined for Delphi/BCB (Win32) exactly if VisualCLX is not defined + VisualCLX Defined for Kylix; needs to be defined for Delphi/BCB to + use JCL with VisualCLX applications. + + +- Other cross-platform related defines + + These symbols are intended to help in writing portable code. + + Directive Description + ------------------------------------------------------------------------------ + PUREPASCAL Code is machine-independent (as opposed to assembler code) + Win32API Code is specific for the Win32 API; + use instead of "{$IFNDEF CLR} {$IFDEF MSWINDOWS}" constructs + + +- Delphi Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. These directives are only defined if + the compiler is Delphi (ie DELPHI is defined). + + Directive Description + ------------------------------------------------------------------------------ + DELPHI1 Defined when compiling with Delphi 1 (Codename WASABI/MANGO) + DELPHI2 Defined when compiling with Delphi 2 (Codename POLARIS) + DELPHI3 Defined when compiling with Delphi 3 (Codename IVORY) + DELPHI4 Defined when compiling with Delphi 4 (Codename ALLEGRO) + DELPHI5 Defined when compiling with Delphi 5 (Codename ARGUS) + DELPHI6 Defined when compiling with Delphi 6 (Codename ILLIAD) + DELPHI7 Defined when compiling with Delphi 7 (Codename AURORA) + DELPHI8 Defined when compiling with Delphi 8 (Codename OCTANE) + DELPHI2005 Defined when compiling with Delphi 2005 (Codename DIAMONDBACK) + DELPHI9 Alias for DELPHI2005 + DELPHI10 Defined when compiling with Delphi 2006 (Codename DEXTER) + DELPHI2006 Alias for DELPHI10 + DELPHI11 Defined when compiling with Delphi 2007 for Win32 (Codename SPACELY) + DELPHI2007 Alias for DELPHI11 + DELPHI12 Defined when compiling with Delphi 2009 for Win32 (Codename TIBURON) + DELPHI2009 Alias for DELPHI12 + DELPHI14 Defined when compiling with Delphi 2010 for Win32 (Codename WEAVER) + DELPHI2010 Alias for DELPHI14 + DELPHI15 Defined when compiling with Delphi XE for Win32 (Codename FULCRUM) + DELPHIXE Alias for DELPHI15 + DELPHI16 Defined when compiling with Delphi XE2 for Win32 (Codename PULSAR) + DELPHIXE2 Alias for DELPHI16 + DELPHI17 Defined when compiling with Delphi XE3 for Win32 (Codename WATERDRAGON) + DELPHIXE3 Alias for DELPHI17 + DELPHI1_UP Defined when compiling with Delphi 1 or higher + DELPHI2_UP Defined when compiling with Delphi 2 or higher + DELPHI3_UP Defined when compiling with Delphi 3 or higher + DELPHI4_UP Defined when compiling with Delphi 4 or higher + DELPHI5_UP Defined when compiling with Delphi 5 or higher + DELPHI6_UP Defined when compiling with Delphi 6 or higher + DELPHI7_UP Defined when compiling with Delphi 7 or higher + DELPHI8_UP Defined when compiling with Delphi 8 or higher + DELPHI2005_UP Defined when compiling with Delphi 2005 or higher + DELPHI9_UP Alias for DELPHI2005_UP + DELPHI10_UP Defined when compiling with Delphi 2006 or higher + DELPHI2006_UP Alias for DELPHI10_UP + DELPHI11_UP Defined when compiling with Delphi 2007 for Win32 or higher + DELPHI2007_UP Alias for DELPHI11_UP + DELPHI12_UP Defined when compiling with Delphi 2009 for Win32 or higher + DELPHI2009_UP Alias for DELPHI12_UP + DELPHI14_UP Defined when compiling with Delphi 2010 for Win32 or higher + DELPHI2010_UP Alias for DELPHI14_UP + DELPHI15_UP Defined when compiling with Delphi XE for Win32 or higher + DELPHIXE_UP Alias for DELPHI15_UP + DELPHI16_UP Defined when compiling with Delphi XE2 for Win32 or higher + DELPHIXE2_UP Alias for DELPHI16_UP + DELPHI17_UP Defined when compiling with Delphi XE3 for Win32 or higher + DELPHIXE3_UP Alias for DELPHI17_UP + + +- Kylix Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. These directives are only defined if + the compiler is Kylix (ie KYLIX is defined). + + Directive Description + ------------------------------------------------------------------------------ + KYLIX1 Defined when compiling with Kylix 1 + KYLIX2 Defined when compiling with Kylix 2 + KYLIX3 Defined when compiling with Kylix 3 (Codename CORTEZ) + KYLIX1_UP Defined when compiling with Kylix 1 or higher + KYLIX2_UP Defined when compiling with Kylix 2 or higher + KYLIX3_UP Defined when compiling with Kylix 3 or higher + + +- Delphi Compiler Versions (Delphi / Kylix, not in BCB mode) + + Directive Description + ------------------------------------------------------------------------------ + DELPHICOMPILER1 Defined when compiling with Delphi 1 + DELPHICOMPILER2 Defined when compiling with Delphi 2 + DELPHICOMPILER3 Defined when compiling with Delphi 3 + DELPHICOMPILER4 Defined when compiling with Delphi 4 + DELPHICOMPILER5 Defined when compiling with Delphi 5 + DELPHICOMPILER6 Defined when compiling with Delphi 6 or Kylix 1, 2 or 3 + DELPHICOMPILER7 Defined when compiling with Delphi 7 + DELPHICOMPILER8 Defined when compiling with Delphi 8 + DELPHICOMPILER9 Defined when compiling with Delphi 2005 + DELPHICOMPILER10 Defined when compiling with Delphi Personality of BDS 4.0 + DELPHICOMPILER11 Defined when compiling with Delphi 2007 for Win32 + DELPHICOMPILER12 Defined when compiling with Delphi Personality of BDS 6.0 + DELPHICOMPILER14 Defined when compiling with Delphi Personality of BDS 7.0 + DELPHICOMPILER15 Defined when compiling with Delphi Personality of BDS 8.0 + DELPHICOMPILER16 Defined when compiling with Delphi Personality of BDS 9.0 + DELPHICOMPILER17 Defined when compiling with Delphi Personality of BDS 10.0 + DELPHICOMPILER1_UP Defined when compiling with Delphi 1 or higher + DELPHICOMPILER2_UP Defined when compiling with Delphi 2 or higher + DELPHICOMPILER3_UP Defined when compiling with Delphi 3 or higher + DELPHICOMPILER4_UP Defined when compiling with Delphi 4 or higher + DELPHICOMPILER5_UP Defined when compiling with Delphi 5 or higher + DELPHICOMPILER6_UP Defined when compiling with Delphi 6 or Kylix 1, 2 or 3 or higher + DELPHICOMPILER7_UP Defined when compiling with Delphi 7 or higher + DELPHICOMPILER8_UP Defined when compiling with Delphi 8 or higher + DELPHICOMPILER9_UP Defined when compiling with Delphi 2005 + DELPHICOMPILER10_UP Defined when compiling with Delphi 2006 or higher + DELPHICOMPILER11_UP Defined when compiling with Delphi 2007 for Win32 or higher + DELPHICOMPILER12_UP Defined when compiling with Delphi 2009 for Win32 or higher + DELPHICOMPILER14_UP Defined when compiling with Delphi 2010 for Win32 or higher + DELPHICOMPILER15_UP Defined when compiling with Delphi XE for Win32 or higher + DELPHICOMPILER16_UP Defined when compiling with Delphi XE2 for Win32 or higher + DELPHICOMPILER17_UP Defined when compiling with Delphi XE3 for Win32 or higher + + +- C++Builder Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. These directives are only defined if + the compiler is C++Builder (ie BCB is defined). + + Directive Description + ------------------------------------------------------------------------------ + BCB1 Defined when compiling with C++Builder 1 + BCB3 Defined when compiling with C++Builder 3 + BCB4 Defined when compiling with C++Builder 4 + BCB5 Defined when compiling with C++Builder 5 (Codename RAMPAGE) + BCB6 Defined when compiling with C++Builder 6 (Codename RIPTIDE) + BCB10 Defined when compiling with C++Builder Personality of BDS 4.0 (also known as C++Builder 2006) (Codename DEXTER) + BCB11 Defined when compiling with C++Builder Personality of RAD Studio 2007 (also known as C++Builder 2007) (Codename COGSWELL) + BCB12 Defined when compiling with C++Builder Personality of RAD Studio 2009 (also known as C++Builder 2009) (Codename TIBURON) + BCB14 Defined when compiling with C++Builder Personality of RAD Studio 2010 (also known as C++Builder 2010) (Codename WEAVER) + BCB15 Defined when compiling with C++Builder Personality of RAD Studio XE (also known as C++Builder XE) (Codename FULCRUM) + BCB16 Defined when compiling with C++Builder Personality of RAD Studio XE2 (also known as C++Builder XE2) (Codename PULSAR) + BCB17 Defined when compiling with C++Builder Personality of RAD Studio XE3 (also known as C++Builder XE3) (Codename WATERDRAGON) + BCB1_UP Defined when compiling with C++Builder 1 or higher + BCB3_UP Defined when compiling with C++Builder 3 or higher + BCB4_UP Defined when compiling with C++Builder 4 or higher + BCB5_UP Defined when compiling with C++Builder 5 or higher + BCB6_UP Defined when compiling with C++Builder 6 or higher + BCB10_UP Defined when compiling with C++Builder Personality of BDS 4.0 or higher + BCB11_UP Defined when compiling with C++Builder Personality of RAD Studio 2007 or higher + BCB12_UP Defined when compiling with C++Builder Personality of RAD Studio 2009 or higher + BCB14_UP Defined when compiling with C++Builder Personality of RAD Studio 2010 or higher + BCB15_UP Defined when compiling with C++Builder Personality of RAD Studio XE or higher + BCB16_UP Defined when compiling with C++Builder Personality of RAD Studio XE2 or higher + BCB17_UP Defined when compiling with C++Builder Personality of RAD Studio XE3 or higher + + +- RAD Studio / Borland Developer Studio Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated IDE. These directives are only defined if + the IDE is Borland Developer Studio Version 2 or above. + + Note: Borland Developer Studio 2006 is marketed as Delphi 2006 or C++Builder 2006, + but those provide only different labels for identical content. + + Directive Description + ------------------------------------------------------------------------------ + BDS Defined when compiling with BDS version of dcc32.exe (Codename SIDEWINDER) + BDS2 Defined when compiling with BDS 2.0 (Delphi 8) (Codename OCTANE) + BDS3 Defined when compiling with BDS 3.0 (Delphi 2005) (Codename DIAMONDBACK) + BDS4 Defined when compiling with BDS 4.0 (Borland Developer Studio 2006) (Codename DEXTER) + BDS5 Defined when compiling with BDS 5.0 (CodeGear RAD Studio 2007) (Codename HIGHLANDER) + BDS6 Defined when compiling with BDS 6.0 (CodeGear RAD Studio 2009) (Codename TIBURON) + BDS7 Defined when compiling with BDS 7.0 (Embarcadero RAD Studio 2010) (Codename WEAVER) + BDS8 Defined when compiling with BDS 8.0 (Embarcadero RAD Studio XE) (Codename FULCRUM) + BDS9 Defined when compiling with BDS 9.0 (Embarcadero RAD Studio XE2) (Codename PULSAR) + BDS10 Defined when compiling with BDS 10.0 (Embarcadero RAD Studio XE3) (Codename WATERDRAGON) + BDS2_UP Defined when compiling with BDS 2.0 or higher + BDS3_UP Defined when compiling with BDS 3.0 or higher + BDS4_UP Defined when compiling with BDS 4.0 or higher + BDS5_UP Defined when compiling with BDS 5.0 or higher + BDS6_UP Defined when compiling with BDS 6.0 or higher + BDS7_UP Defined when compiling with BDS 7.0 or higher + BDS8_UP Defined when compiling with BDS 8.0 or higher + BDS9_UP Defined when compiling with BDS 9.0 or higher + BDS10_UP Defined when compiling with BDS 10.0 or higher + +- Compiler Versions + + The following directives are direct mappings from the VERXXX directives to a + friendly name of the associated compiler. Unlike the DELPHI_X and BCB_X + directives, these directives are indepedent of the development environment. + That is, they are defined regardless of whether compilation takes place using + Delphi or C++Builder. + + Directive Description + ------------------------------------------------------------------------------ + COMPILER1 Defined when compiling with Delphi 1 + COMPILER2 Defined when compiling with Delphi 2 or C++Builder 1 + COMPILER3 Defined when compiling with Delphi 3 + COMPILER35 Defined when compiling with C++Builder 3 + COMPILER4 Defined when compiling with Delphi 4 or C++Builder 4 + COMPILER5 Defined when compiling with Delphi 5 or C++Builder 5 + COMPILER6 Defined when compiling with Delphi 6 or C++Builder 6 + COMPILER7 Defined when compiling with Delphi 7 + COMPILER8 Defined when compiling with Delphi 8 + COMPILER9 Defined when compiling with Delphi 9 + COMPILER10 Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 + COMPILER11 Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 + COMPILER12 Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 + COMPILER14 Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 + COMPILER15 Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 + COMPILER16 Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 + COMPILER17 Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 + COMPILER1_UP Defined when compiling with Delphi 1 or higher + COMPILER2_UP Defined when compiling with Delphi 2 or C++Builder 1 or higher + COMPILER3_UP Defined when compiling with Delphi 3 or higher + COMPILER35_UP Defined when compiling with C++Builder 3 or higher + COMPILER4_UP Defined when compiling with Delphi 4 or C++Builder 4 or higher + COMPILER5_UP Defined when compiling with Delphi 5 or C++Builder 5 or higher + COMPILER6_UP Defined when compiling with Delphi 6 or C++Builder 6 or higher + COMPILER7_UP Defined when compiling with Delphi 7 + COMPILER8_UP Defined when compiling with Delphi 8 + COMPILER9_UP Defined when compiling with Delphi Personalities of BDS 3.0 + COMPILER10_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 or higher + COMPILER11_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 or higher + COMPILER12_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 or higher + COMPILER14_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 or higher + COMPILER15_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 or higher + COMPILER16_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 or higher + COMPILER17_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 or higher + + +- RTL Versions + + Use e.g. following to determine the exact RTL version since version 14.0: + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF Declared(RTLVersion) and (RTLVersion >= 14.2)} + // code for Delphi 6.02 or higher, Kylix 2 or higher, C++Builder 6 or higher + ... + {$IFEND} + {$ENDIF} + + Directive Description + ------------------------------------------------------------------------------ + RTL80_UP Defined when compiling with Delphi 1 or higher + RTL90_UP Defined when compiling with Delphi 2 or higher + RTL93_UP Defined when compiling with C++Builder 1 or higher + RTL100_UP Defined when compiling with Delphi 3 or higher + RTL110_UP Defined when compiling with C++Builder 3 or higher + RTL120_UP Defined when compiling with Delphi 4 or higher + RTL125_UP Defined when compiling with C++Builder 4 or higher + RTL130_UP Defined when compiling with Delphi 5 or C++Builder 5 or higher + RTL140_UP Defined when compiling with Delphi 6, Kylix 1, 2 or 3 or C++Builder 6 or higher + RTL150_UP Defined when compiling with Delphi 7 or higher + RTL160_UP Defined when compiling with Delphi 8 or higher + RTL170_UP Defined when compiling with Delphi Personalities of BDS 3.0 or higher + RTL180_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 or higher + RTL185_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 or higher + RTL190_UP Defined when compiling with Delphi.NET of BDS 5.0 or higher + RTL200_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 or higher + RTL210_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 or higher + RTL220_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 or higher + RTL230_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 or higher + RTL240_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 or higher + + +- CLR Versions + + Directive Description + ------------------------------------------------------------------------------ + CLR Defined when compiling for .NET + CLR10 Defined when compiling for .NET 1.0 (may be overriden by FORCE_CLR10) + CLR10_UP Defined when compiling for .NET 1.0 or higher + CLR11 Defined when compiling for .NET 1.1 (may be overriden by FORCE_CLR11) + CLR11_UP Defined when compiling for .NET 1.1 or higher + CLR20 Defined when compiling for .NET 2.0 (may be overriden by FORCE_CLR20) + CLR20_UP Defined when compiling for .NET 2.0 or higher + + +- Feature Directives + + The features directives are used to test if the compiler supports specific + features, such as method overloading, and adjust the sources accordingly. Use + of these directives is preferred over the use of the DELPHI and COMPILER + directives. + + Directive Description + ------------------------------------------------------------------------------ + SUPPORTS_CONSTPARAMS Compiler supports const parameters (D1+) + SUPPORTS_SINGLE Compiler supports the Single type (D1+) + SUPPORTS_DOUBLE Compiler supports the Double type (D1+) + SUPPORTS_EXTENDED Compiler supports the Extended type (D1+) + SUPPORTS_CURRENCY Compiler supports the Currency type (D2+) + SUPPORTS_THREADVAR Compiler supports threadvar declarations (D2+) + SUPPORTS_OUTPARAMS Compiler supports out parameters (D3+) + SUPPORTS_VARIANT Compiler supports variant (D2+) + SUPPORTS_WIDECHAR Compiler supports the WideChar type (D2+) + SUPPORTS_WIDESTRING Compiler supports the WideString type (D3+/BCB3+) + SUPPORTS_INTERFACE Compiler supports interfaces (D3+/BCB3+) + SUPPORTS_DISPINTERFACE Compiler supports dispatch interfaces (D3+/BCB3+) + SUPPORTS_DISPID Compiler supports dispatch ids (D3+/BCB3+/FPC) + SUPPORTS_EXTSYM Compiler supports the $EXTERNALSYM directive (D4+/BCB3+) + SUPPORTS_NODEFINE Compiler supports the $NODEFINE directive (D4+/BCB3+) + SUPPORTS_LONGWORD Compiler supports the LongWord type (unsigned 32 bit) (D4+/BCB4+) + SUPPORTS_INT64 Compiler supports the Int64 type (D4+/BCB4+) + SUPPORTS_UINT64 Compiler supports the UInt64 type (D XE+ ?) + SUPPORTS_DYNAMICARRAYS Compiler supports dynamic arrays (D4+/BCB4+) + SUPPORTS_DEFAULTPARAMS Compiler supports default parameters (D4+/BCB4+) + SUPPORTS_OVERLOAD Compiler supports overloading (D4+/BCB4+) + SUPPORTS_IMPLEMENTS Compiler supports implements (D4+/BCB4+) + SUPPORTS_DEPRECATED Compiler supports the deprecated directive (D6+/BCB6+) + SUPPORTS_PLATFORM Compiler supports the platform directive (D6+/BCB6+) + SUPPORTS_LIBRARY Compiler supports the library directive (D6+/BCB6+/FPC) + SUPPORTS_LOCAL Compiler supports the local directive (D6+/BCB6+) + SUPPORTS_SETPEFLAGS Compiler supports the SetPEFlags directive (D6+/BCB6+) + SUPPORTS_EXPERIMENTAL_WARNINGS Compiler supports the WARN SYMBOL_EXPERIMENTAL and WARN UNIT_EXPERIMENTAL directives (D6+/BCB6+) + SUPPORTS_INLINE Compiler supports the inline directive (D9+/FPC) + SUPPORTS_FOR_IN Compiler supports for in loops (D9+) + SUPPORTS_NESTED_CONSTANTS Compiler supports nested constants (D9+) + SUPPORTS_NESTED_TYPES Compiler supports nested types (D9+) + SUPPORTS_REGION Compiler supports the REGION and ENDREGION directives (D9+) + SUPPORTS_ENHANCED_RECORDS Compiler supports class [operator|function|procedure] for record types (D9.NET, D10+) + SUPPORTS_CLASS_FIELDS Compiler supports class fields (D9.NET, D10+) + SUPPORTS_CLASS_HELPERS Compiler supports class helpers (D9.NET, D10+) + SUPPORTS_CLASS_OPERATORS Compiler supports class operators (D9.NET, D10+) + SUPPORTS_CLASS_CTORDTORS Compiler supports class contructors/destructors (D14+) + SUPPORTS_STRICT Compiler supports strict keyword (D9.NET, D10+) + SUPPORTS_STATIC Compiler supports static keyword (D9.NET, D10+) + SUPPORTS_FINAL Compiler supports final keyword (D9.NET, D10+) + SUPPORTS_METHODINFO Compiler supports the METHODINFO directives (D10+) + SUPPORTS_GENERICS Compiler supports generic implementations (D11.NET, D12+) + SUPPORTS_DEPRECATED_DETAILS Compiler supports additional text for the deprecated directive (D11.NET, D12+) + ACCEPT_DEPRECATED Compiler supports or ignores the deprecated directive (D6+/BCB6+/FPC) + ACCEPT_PLATFORM Compiler supports or ignores the platform directive (D6+/BCB6+/FPC) + ACCEPT_LIBRARY Compiler supports or ignores the library directive (D6+/BCB6+) + SUPPORTS_CUSTOMVARIANTS Compiler supports custom variants (D6+/BCB6+) + SUPPORTS_VARARGS Compiler supports varargs (D6+/BCB6+) + SUPPORTS_ENUMVALUE Compiler supports assigning ordinalities to values of enums (D6+/BCB6+) + SUPPORTS_DEPRECATED_WARNINGS Compiler supports deprecated warnings (D6+/BCB6+) + SUPPORTS_LIBRARY_WARNINGS Compiler supports library warnings (D6+/BCB6+) + SUPPORTS_PLATFORM_WARNINGS Compiler supports platform warnings (D6+/BCB6+) + SUPPORTS_UNSAFE_WARNINGS Compiler supports unsafe warnings (D7) + SUPPORTS_WEAKPACKAGEUNIT Compiler supports the WEAKPACKAGEUNIT directive + SUPPORTS_COMPILETIME_MESSAGES Compiler supports the MESSAGE directive + SUPPORTS_PACKAGES Compiler supports Packages + HAS_UNIT_LIBC Unit Libc exists (Kylix, FPC on Linux/x86) + HAS_UNIT_RTLCONSTS Unit RTLConsts exists (D6+/BCB6+/FPC) + HAS_UNIT_TYPES Unit Types exists (D6+/BCB6+/FPC) + HAS_UNIT_VARIANTS Unit Variants exists (D6+/BCB6+/FPC) + HAS_UNIT_STRUTILS Unit StrUtils exists (D6+/BCB6+/FPC) + HAS_UNIT_DATEUTILS Unit DateUtils exists (D6+/BCB6+/FPC) + HAS_UNIT_CONTNRS Unit contnrs exists (D6+/BCB6+/FPC) + HAS_UNIT_HTTPPROD Unit HTTPProd exists (D9+) + HAS_UNIT_GIFIMG Unit GifImg exists (D11+) + HAS_UNIT_ANSISTRINGS Unit AnsiStrings exists (D12+) + HAS_UNIT_PNGIMAGE Unit PngImage exists (D12+) + HAS_UNIT_CHARACTER Unit Character exists (D12+) + XPLATFORM_RTL The RTL supports crossplatform function names (e.g. RaiseLastOSError) (D6+/BCB6+/FPC) + SUPPORTS_UNICODE string type is aliased to an unicode string (WideString or UnicodeString) (DX.NET, D12+) + SUPPORTS_UNICODE_STRING Compiler supports UnicodeString (D12+) + SUPPORTS_INT_ALIASES Types Int8, Int16, Int32, UInt8, UInt16 and UInt32 are defined in the unit System (D12+) + HAS_UNIT_RTTI Unit RTTI is available (D14+) + SUPPORTS_CAST_INTERFACE_TO_OBJ The compiler supports casts from interfaces to objects (D14+) + SUPPORTS_DELAYED_LOADING The compiler generates stubs for delaying imported function loads (D14+) + HAS_UNIT_REGULAREXPRESSIONSAPI Unit RegularExpressionsAPI is available (D15+) + HAS_UNIT_SYSTEM_UITYPES Unit System.UITypes is available (D16+) + HAS_UNIT_SYSTEM_ACTIONS Unit System.Actions is available (D17+) + + +- Compiler Settings + + The compiler settings directives indicate whether a specific compiler setting + is in effect. This facilitates changing compiler settings locally in a more + compact and readible manner. + + Directive Description + ------------------------------------------------------------------------------ + ALIGN_ON Compiling in the A+ state (no alignment) + BOOLEVAL_ON Compiling in the B+ state (complete boolean evaluation) + ASSERTIONS_ON Compiling in the C+ state (assertions on) + DEBUGINFO_ON Compiling in the D+ state (debug info generation on) + IMPORTEDDATA_ON Compiling in the G+ state (creation of imported data references) + LONGSTRINGS_ON Compiling in the H+ state (string defined as AnsiString) + IOCHECKS_ON Compiling in the I+ state (I/O checking enabled) + WRITEABLECONST_ON Compiling in the J+ state (typed constants can be modified) + LOCALSYMBOLS Compiling in the L+ state (local symbol generation) + LOCALSYMBOLS_ON Alias of LOCALSYMBOLS + TYPEINFO_ON Compiling in the M+ state (RTTI generation on) + OPTIMIZATION_ON Compiling in the O+ state (code optimization on) + OPENSTRINGS_ON Compiling in the P+ state (variable string parameters are openstrings) + OVERFLOWCHECKS_ON Compiling in the Q+ state (overflow checing on) + RANGECHECKS_ON Compiling in the R+ state (range checking on) + TYPEDADDRESS_ON Compiling in the T+ state (pointers obtained using the @ operator are typed) + SAFEDIVIDE_ON Compiling in the U+ state (save FDIV instruction through RTL emulation) + VARSTRINGCHECKS_ON Compiling in the V+ state (type checking of shortstrings) + STACKFRAMES_ON Compiling in the W+ state (generation of stack frames) + EXTENDEDSYNTAX_ON Compiling in the X+ state (Delphi extended syntax enabled) +*) + +{$DEFINE BORLAND} + +{ Set FreePascal to Delphi mode } +{$IFDEF FPC} + {$MODE DELPHI} + {$ASMMODE Intel} + {$UNDEF BORLAND} + {$DEFINE CPUASM} + // FPC defines CPU32, CPU64 and Unix automatically +{$ENDIF} + +{$IFDEF BORLAND} + {$IFDEF LINUX} + {$DEFINE KYLIX} + {$ENDIF LINUX} + {$IFNDEF CLR} + {$IFNDEF CPUX86} + {$IFNDEF CPUX64} + {$DEFINE CPU386} // For Borland compilers select the x86 compat assembler by default + {$DEFINE CPU32} // Assume Borland compilers are 32-bit (rather than 64-bit) + {$DEFINE CPUASM} + {$ELSE ~CPUX64} + {$DEFINE CPU64} + {$DEFINE CPUASM} + {$DEFINE DELPHI64_TEMPORARY} + {$ENDIF ~CPUX64} + {$ELSE ~CPUX86} + {$DEFINE CPU386} + {$DEFINE CPU32} + {$DEFINE CPUASM} + {$ENDIF ~CPUX86} + {$ENDIF ~CLR} +{$ENDIF BORLAND} + +{------------------------------------------------------------------------------} +{ VERXXX to COMPILERX, DELPHIX and BCBX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BORLAND} + {$IFDEF KYLIX} + {$I kylix.inc} // FPC incompatible stuff + {$ELSE ~KYLIX} + + {$DEFINE UNKNOWN_COMPILER_VERSION} + + {$IFDEF VER80} + {$DEFINE COMPILER1} + {$DEFINE DELPHI1} + {$DEFINE DELPHICOMPILER1} + {$DEFINE RTL80_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER90} + {$DEFINE COMPILER2} + {$DEFINE DELPHI2} + {$DEFINE DELPHICOMPILER2} + {$DEFINE RTL90_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER93} + {$DEFINE COMPILER2} + {$DEFINE BCB1} + {$DEFINE BCB} + {$DEFINE RTL93_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER100} + {$DEFINE COMPILER3} + {$DEFINE DELPHI3} + {$DEFINE DELPHICOMPILER3} + {$DEFINE RTL100_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER110} + {$DEFINE COMPILER35} + {$DEFINE BCB3} + {$DEFINE BCB} + {$DEFINE RTL110_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER120} + {$DEFINE COMPILER4} + {$DEFINE DELPHI4} + {$DEFINE DELPHICOMPILER4} + {$DEFINE RTL120_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER125} + {$DEFINE COMPILER4} + {$DEFINE BCB4} + {$DEFINE BCB} + {$DEFINE RTL125_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER130} + {$DEFINE COMPILER5} + {$IFDEF BCB} + {$DEFINE BCB5} + {$ELSE} + {$DEFINE DELPHI5} + {$DEFINE DELPHICOMPILER5} + {$ENDIF} + {$DEFINE RTL130_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER140} + {$DEFINE COMPILER6} + {$IFDEF BCB} + {$DEFINE BCB6} + {$ELSE} + {$DEFINE DELPHI6} + {$DEFINE DELPHICOMPILER6} + {$ENDIF} + {$DEFINE RTL140_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER150} + {$DEFINE COMPILER7} + {$DEFINE DELPHI7} + {$DEFINE DELPHICOMPILER7} + {$DEFINE RTL150_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER160} + {$DEFINE BDS2} + {$DEFINE BDS} + {$IFDEF CLR} + {$DEFINE CLR10} + {$ENDIF CLR} + {$DEFINE COMPILER8} + {$DEFINE DELPHI8} + {$DEFINE DELPHICOMPILER8} + {$DEFINE RTL160_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER170} + {$DEFINE BDS3} + {$DEFINE BDS} + {$IFDEF CLR} + {$DEFINE CLR11} + {$ENDIF CLR} + {$DEFINE COMPILER9} + {$DEFINE DELPHI9} + {$DEFINE DELPHI2005} // synonym to DELPHI9 + {$DEFINE DELPHICOMPILER9} + {$DEFINE RTL170_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER180} + {$DEFINE BDS} + {$IFDEF CLR} + {$DEFINE CLR11} + {$ENDIF CLR} + {$IFDEF VER185} + {$DEFINE BDS5} + {$DEFINE COMPILER11} + {$IFDEF BCB} + {$DEFINE BCB11} + {$ELSE} + {$DEFINE DELPHI11} + {$DEFINE DELPHI2007} // synonym to DELPHI11 + {$DEFINE DELPHICOMPILER11} + {$ENDIF} + {$DEFINE RTL185_UP} + {$ELSE ~~VER185} + {$DEFINE BDS4} + {$DEFINE COMPILER10} + {$IFDEF BCB} + {$DEFINE BCB10} + {$ELSE} + {$DEFINE DELPHI10} + {$DEFINE DELPHI2006} // synonym to DELPHI10 + {$DEFINE DELPHICOMPILER10} + {$ENDIF} + {$DEFINE RTL180_UP} + {$ENDIF ~VER185} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$IFDEF VER190} // Delphi 2007 for .NET + {$DEFINE BDS} + {$DEFINE BDS5} + {$IFDEF CLR} + {$DEFINE CLR20} + {$ENDIF CLR} + {$DEFINE COMPILER11} + {$DEFINE DELPHI11} + {$DEFINE DELPHI2007} // synonym to DELPHI11 + {$DEFINE DELPHICOMPILER11} + {$DEFINE RTL190_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER190} + + {$IFDEF VER200} // RAD Studio 2009 + {$DEFINE BDS} + {$DEFINE BDS6} + {$IFDEF CLR} + {$DEFINE CLR20} + {$ENDIF CLR} + {$DEFINE COMPILER12} + {$IFDEF BCB} + {$DEFINE BCB12} + {$ELSE} + {$DEFINE DELPHI12} + {$DEFINE DELPHI2009} // synonym to DELPHI12 + {$DEFINE DELPHICOMPILER12} + {$ENDIF BCB} + {$IFDEF CLR} + {$DEFINE RTL190_UP} + {$ELSE} + {$DEFINE RTL200_UP} + {$ENDIF} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER200} + + {$IFDEF VER210} // RAD Studio 2010 + {$DEFINE BDS} + {$DEFINE BDS7} + {$DEFINE COMPILER14} + {$IFDEF BCB} + {$DEFINE BCB14} + {$ELSE} + {$DEFINE DELPHI14} + {$DEFINE DELPHI2010} // synonym to DELPHI14 + {$DEFINE DELPHICOMPILER14} + {$ENDIF BCB} + {$DEFINE RTL210_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER210} + + {$IFDEF VER220} // RAD Studio XE + {$DEFINE BDS} + {$DEFINE BDS8} + {$DEFINE COMPILER15} + {$IFDEF BCB} + {$DEFINE BCB15} + {$ELSE} + {$DEFINE DELPHI15} + {$DEFINE DELPHIXE} // synonym to DELPHI15 + {$DEFINE DELPHICOMPILER15} + {$ENDIF BCB} + {$DEFINE RTL220_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER220} + + {$IFDEF VER230} // RAD Studio XE2 + {$DEFINE BDS} + {$DEFINE BDS9} + {$DEFINE COMPILER16} + {$IFDEF BCB} + {$DEFINE BCB16} + {$ELSE} + {$DEFINE DELPHI16} + {$DEFINE DELPHIXE2} // synonym to DELPHI16 + {$DEFINE DELPHICOMPILER16} + {$ENDIF BCB} + {$DEFINE RTL230_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER230} + + {$IFDEF VER240} // RAD Studio XE3 + {$DEFINE BDS} + {$DEFINE BDS10} + {$DEFINE COMPILER17} + {$IFDEF BCB} + {$DEFINE BCB17} + {$ELSE} + {$DEFINE DELPHI17} + {$DEFINE DELPHIXE3} // synonym to DELPHI17 + {$DEFINE DELPHICOMPILER17} + {$ENDIF BCB} + {$DEFINE RTL240_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF VER240} + + {$IFDEF UNKNOWN_COMPILER_VERSION} // adjust for newer version (always use latest version) + {$DEFINE BDS} + {$DEFINE BDS10} + {$DEFINE COMPILER17} + {$IFDEF BCB} + {$DEFINE BCB17} + {$ELSE} + {$DEFINE DELPHI17} + {$DEFINE DELPHIXE3} // synonym to DELPHI17 + {$DEFINE DELPHICOMPILER17} + {$ENDIF BCB} + {$DEFINE RTL240_UP} + {$UNDEF UNKNOWN_COMPILER_VERSION} + {$ENDIF} + + {$ENDIF ~KYLIX} + + {$IFDEF BCB} + {$DEFINE CPPBUILDER} + {$DEFINE BCBCOMPILER} + {$ELSE ~BCB} + {$DEFINE DELPHI} + {$DEFINE DELPHICOMPILER} + {$ENDIF ~BCB} + +{$ENDIF BORLAND} + +{------------------------------------------------------------------------------} +{ DELPHIX_UP from DELPHIX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHI17} {$DEFINE DELPHI17_UP} {$ENDIF} +{$IFDEF DELPHI16} {$DEFINE DELPHI16_UP} {$ENDIF} +{$IFDEF DELPHI15} {$DEFINE DELPHI15_UP} {$ENDIF} +{$IFDEF DELPHI14} {$DEFINE DELPHI14_UP} {$ENDIF} +{$IFDEF DELPHI12} {$DEFINE DELPHI12_UP} {$ENDIF} +{$IFDEF DELPHI11} {$DEFINE DELPHI11_UP} {$ENDIF} +{$IFDEF DELPHI10} {$DEFINE DELPHI10_UP} {$ENDIF} +{$IFDEF DELPHI9} {$DEFINE DELPHI9_UP} {$ENDIF} +{$IFDEF DELPHI8} {$DEFINE DELPHI8_UP} {$ENDIF} +{$IFDEF DELPHI7} {$DEFINE DELPHI7_UP} {$ENDIF} +{$IFDEF DELPHI6} {$DEFINE DELPHI6_UP} {$ENDIF} +{$IFDEF DELPHI5} {$DEFINE DELPHI5_UP} {$ENDIF} +{$IFDEF DELPHI4} {$DEFINE DELPHI4_UP} {$ENDIF} +{$IFDEF DELPHI3} {$DEFINE DELPHI3_UP} {$ENDIF} +{$IFDEF DELPHI2} {$DEFINE DELPHI2_UP} {$ENDIF} +{$IFDEF DELPHI1} {$DEFINE DELPHI1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ DELPHIX_UP from DELPHIX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHI17_UP} + {$DEFINE DELPHIXE3_UP} // synonym to DELPHI17_UP + {$DEFINE DELPHI16_UP} +{$ENDIF} + +{$IFDEF DELPHI16_UP} + {$DEFINE DELPHIXE2_UP} // synonym to DELPHI16_UP + {$DEFINE DELPHI15_UP} +{$ENDIF} + +{$IFDEF DELPHI15_UP} + {$DEFINE DELPHIXE_UP} // synonym to DELPHI15_UP + {$DEFINE DELPHI14_UP} +{$ENDIF} + +{$IFDEF DELPHI14_UP} + {$DEFINE DELPHI2010_UP} // synonym to DELPHI14_UP + {$DEFINE DELPHI12_UP} +{$ENDIF} + +{$IFDEF DELPHI12_UP} + {$DEFINE DELPHI2009_UP} // synonym to DELPHI12_UP + {$DEFINE DELPHI11_UP} +{$ENDIF} + +{$IFDEF DELPHI11_UP} + {$DEFINE DELPHI2007_UP} // synonym to DELPHI11_UP + {$DEFINE DELPHI10_UP} +{$ENDIF} + +{$IFDEF DELPHI10_UP} + {$DEFINE DELPHI2006_UP} // synonym to DELPHI10_UP + {$DEFINE DELPHI9_UP} +{$ENDIF} + +{$IFDEF DELPHI9_UP} + {$DEFINE DELPHI2005_UP} // synonym to DELPHI9_UP + {$DEFINE DELPHI8_UP} +{$ENDIF} + +{$IFDEF DELPHI8_UP} {$DEFINE DELPHI7_UP} {$ENDIF} +{$IFDEF DELPHI7_UP} {$DEFINE DELPHI6_UP} {$ENDIF} +{$IFDEF DELPHI6_UP} {$DEFINE DELPHI5_UP} {$ENDIF} +{$IFDEF DELPHI5_UP} {$DEFINE DELPHI4_UP} {$ENDIF} +{$IFDEF DELPHI4_UP} {$DEFINE DELPHI3_UP} {$ENDIF} +{$IFDEF DELPHI3_UP} {$DEFINE DELPHI2_UP} {$ENDIF} +{$IFDEF DELPHI2_UP} {$DEFINE DELPHI1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BCBX_UP from BCBX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BCB17} {$DEFINE BCB17_UP} {$ENDIF} +{$IFDEF BCB16} {$DEFINE BCB16_UP} {$ENDIF} +{$IFDEF BCB15} {$DEFINE BCB15_UP} {$ENDIF} +{$IFDEF BCB14} {$DEFINE BCB14_UP} {$ENDIF} +{$IFDEF BCB12} {$DEFINE BCB12_UP} {$ENDIF} +{$IFDEF BCB11} {$DEFINE BCB11_UP} {$ENDIF} +{$IFDEF BCB10} {$DEFINE BCB10_UP} {$ENDIF} +{$IFDEF BCB6} {$DEFINE BCB6_UP} {$ENDIF} +{$IFDEF BCB5} {$DEFINE BCB5_UP} {$ENDIF} +{$IFDEF BCB4} {$DEFINE BCB4_UP} {$ENDIF} +{$IFDEF BCB3} {$DEFINE BCB3_UP} {$ENDIF} +{$IFDEF BCB1} {$DEFINE BCB1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BCBX_UP from BCBX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BCB17_UP} {$DEFINE BCB16_UP} {$ENDIF} +{$IFDEF BCB16_UP} {$DEFINE BCB15_UP} {$ENDIF} +{$IFDEF BCB15_UP} {$DEFINE BCB14_UP} {$ENDIF} +{$IFDEF BCB14_UP} {$DEFINE BCB12_UP} {$ENDIF} +{$IFDEF BCB12_UP} {$DEFINE BCB11_UP} {$ENDIF} +{$IFDEF BCB11_UP} {$DEFINE BCB10_UP} {$ENDIF} +{$IFDEF BCB10_UP} {$DEFINE BCB6_UP} {$ENDIF} +{$IFDEF BCB6_UP} {$DEFINE BCB5_UP} {$ENDIF} +{$IFDEF BCB5_UP} {$DEFINE BCB4_UP} {$ENDIF} +{$IFDEF BCB4_UP} {$DEFINE BCB3_UP} {$ENDIF} +{$IFDEF BCB3_UP} {$DEFINE BCB1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BDSX_UP from BDSX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BDS10} {$DEFINE BDS10_UP} {$ENDIF} +{$IFDEF BDS9} {$DEFINE BDS9_UP} {$ENDIF} +{$IFDEF BDS8} {$DEFINE BDS8_UP} {$ENDIF} +{$IFDEF BDS7} {$DEFINE BDS7_UP} {$ENDIF} +{$IFDEF BDS6} {$DEFINE BDS6_UP} {$ENDIF} +{$IFDEF BDS5} {$DEFINE BDS5_UP} {$ENDIF} +{$IFDEF BDS4} {$DEFINE BDS4_UP} {$ENDIF} +{$IFDEF BDS3} {$DEFINE BDS3_UP} {$ENDIF} +{$IFDEF BDS2} {$DEFINE BDS2_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ BDSX_UP from BDSX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF BDS10_UP} {$DEFINE BDS9_UP} {$ENDIF} +{$IFDEF BDS9_UP} {$DEFINE BDS8_UP} {$ENDIF} +{$IFDEF BDS8_UP} {$DEFINE BDS7_UP} {$ENDIF} +{$IFDEF BDS7_UP} {$DEFINE BDS6_UP} {$ENDIF} +{$IFDEF BDS6_UP} {$DEFINE BDS5_UP} {$ENDIF} +{$IFDEF BDS5_UP} {$DEFINE BDS4_UP} {$ENDIF} +{$IFDEF BDS4_UP} {$DEFINE BDS3_UP} {$ENDIF} +{$IFDEF BDS3_UP} {$DEFINE BDS2_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ DELPHICOMPILERX_UP from DELPHICOMPILERX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHICOMPILER17} {$DEFINE DELPHICOMPILER17_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER16} {$DEFINE DELPHICOMPILER16_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER15} {$DEFINE DELPHICOMPILER15_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER14} {$DEFINE DELPHICOMPILER14_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER12} {$DEFINE DELPHICOMPILER12_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER11} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER10} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER9} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER8} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER7} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER6} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER5} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER4} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER3} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER2} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER1} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ DELPHICOMPILERX_UP from DELPHICOMPILERX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF DELPHICOMPILER17_UP} {$DEFINE DELPHICOMPILER16_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER16_UP} {$DEFINE DELPHICOMPILER15_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER15_UP} {$DEFINE DELPHICOMPILER14_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER14_UP} {$DEFINE DELPHICOMPILER12_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER12_UP} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER11_UP} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER10_UP} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER9_UP} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER7_UP} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER6_UP} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER5_UP} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER4_UP} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER3_UP} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF} +{$IFDEF DELPHICOMPILER2_UP} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ COMPILERX_UP from COMPILERX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF COMPILER17} {$DEFINE COMPILER17_UP} {$ENDIF} +{$IFDEF COMPILER16} {$DEFINE COMPILER16_UP} {$ENDIF} +{$IFDEF COMPILER15} {$DEFINE COMPILER15_UP} {$ENDIF} +{$IFDEF COMPILER14} {$DEFINE COMPILER14_UP} {$ENDIF} +{$IFDEF COMPILER12} {$DEFINE COMPILER12_UP} {$ENDIF} +{$IFDEF COMPILER11} {$DEFINE COMPILER11_UP} {$ENDIF} +{$IFDEF COMPILER10} {$DEFINE COMPILER10_UP} {$ENDIF} +{$IFDEF COMPILER9} {$DEFINE COMPILER9_UP} {$ENDIF} +{$IFDEF COMPILER8} {$DEFINE COMPILER8_UP} {$ENDIF} +{$IFDEF COMPILER7} {$DEFINE COMPILER7_UP} {$ENDIF} +{$IFDEF COMPILER6} {$DEFINE COMPILER6_UP} {$ENDIF} +{$IFDEF COMPILER5} {$DEFINE COMPILER5_UP} {$ENDIF} +{$IFDEF COMPILER4} {$DEFINE COMPILER4_UP} {$ENDIF} +{$IFDEF COMPILER35} {$DEFINE COMPILER35_UP} {$ENDIF} +{$IFDEF COMPILER3} {$DEFINE COMPILER3_UP} {$ENDIF} +{$IFDEF COMPILER2} {$DEFINE COMPILER2_UP} {$ENDIF} +{$IFDEF COMPILER1} {$DEFINE COMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ COMPILERX_UP from COMPILERX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF COMPILER17_UP} {$DEFINE COMPILER16_UP} {$ENDIF} +{$IFDEF COMPILER16_UP} {$DEFINE COMPILER15_UP} {$ENDIF} +{$IFDEF COMPILER15_UP} {$DEFINE COMPILER14_UP} {$ENDIF} +{$IFDEF COMPILER14_UP} {$DEFINE COMPILER12_UP} {$ENDIF} +{$IFDEF COMPILER12_UP} {$DEFINE COMPILER11_UP} {$ENDIF} +{$IFDEF COMPILER11_UP} {$DEFINE COMPILER10_UP} {$ENDIF} +{$IFDEF COMPILER10_UP} {$DEFINE COMPILER9_UP} {$ENDIF} +{$IFDEF COMPILER9_UP} {$DEFINE COMPILER8_UP} {$ENDIF} +{$IFDEF COMPILER8_UP} {$DEFINE COMPILER7_UP} {$ENDIF} +{$IFDEF COMPILER7_UP} {$DEFINE COMPILER6_UP} {$ENDIF} +{$IFDEF COMPILER6_UP} {$DEFINE COMPILER5_UP} {$ENDIF} +{$IFDEF COMPILER5_UP} {$DEFINE COMPILER4_UP} {$ENDIF} +{$IFDEF COMPILER4_UP} {$DEFINE COMPILER35_UP} {$ENDIF} +{$IFDEF COMPILER35_UP} {$DEFINE COMPILER3_UP} {$ENDIF} +{$IFDEF COMPILER3_UP} {$DEFINE COMPILER2_UP} {$ENDIF} +{$IFDEF COMPILER2_UP} {$DEFINE COMPILER1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ RTLX_UP from RTLX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF RTL240_UP} {$DEFINE RTL230_UP} {$ENDIF} +{$IFDEF RTL230_UP} {$DEFINE RTL220_UP} {$ENDIF} +{$IFDEF RTL220_UP} {$DEFINE RTL210_UP} {$ENDIF} +{$IFDEF RTL210_UP} {$DEFINE RTL200_UP} {$ENDIF} +{$IFDEF RTL200_UP} {$DEFINE RTL190_UP} {$ENDIF} +{$IFDEF RTL190_UP} {$DEFINE RTL185_UP} {$ENDIF} +{$IFDEF RTL185_UP} {$DEFINE RTL180_UP} {$ENDIF} +{$IFDEF RTL180_UP} {$DEFINE RTL170_UP} {$ENDIF} +{$IFDEF RTL170_UP} {$DEFINE RTL160_UP} {$ENDIF} +{$IFDEF RTL160_UP} {$DEFINE RTL150_UP} {$ENDIF} +{$IFDEF RTL150_UP} {$DEFINE RTL145_UP} {$ENDIF} +{$IFDEF RTL145_UP} {$DEFINE RTL142_UP} {$ENDIF} +{$IFDEF RTL142_UP} {$DEFINE RTL140_UP} {$ENDIF} +{$IFDEF RTL140_UP} {$DEFINE RTL130_UP} {$ENDIF} +{$IFDEF RTL130_UP} {$DEFINE RTL125_UP} {$ENDIF} +{$IFDEF RTL125_UP} {$DEFINE RTL120_UP} {$ENDIF} +{$IFDEF RTL120_UP} {$DEFINE RTL110_UP} {$ENDIF} +{$IFDEF RTL110_UP} {$DEFINE RTL100_UP} {$ENDIF} +{$IFDEF RTL100_UP} {$DEFINE RTL93_UP} {$ENDIF} +{$IFDEF RTL93_UP} {$DEFINE RTL90_UP} {$ENDIF} +{$IFDEF RTL90_UP} {$DEFINE RTL80_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ Check for CLR overrides of default detection } +{------------------------------------------------------------------------------} + +{$IFDEF CLR} + {$IFDEF FORCE_CLR10} + {$DEFINE CLR10} + {$UNDEF CLR11} + {$UNDEF CLR20} + {$ENDIF FORCE_CLR10} + + {$IFDEF FORCE_CLR11} + {$UNDEF CLR10} + {$DEFINE CLR11} + {$UNDEF CLR20} + {$ENDIF FORCE_CLR11} + + {$IFDEF FORCE_CLR20} + {$UNDEF CLR10} + {$UNDEF CLR11} + {$DEFINE CLR20} + {$ENDIF FORCE_CLR20} +{$ENDIF CLR} + +{------------------------------------------------------------------------------} +{ CLRX from CLRX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF CLR10} {$DEFINE CLR10_UP} {$ENDIF} +{$IFDEF CLR11} {$DEFINE CLR11_UP} {$ENDIF} +{$IFDEF CLR20} {$DEFINE CLR20_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ CLRX_UP from CLRX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF CLR20_UP} {$DEFINE CLR11_UP} {$ENDIF} +{$IFDEF CLR11_UP} {$DEFINE CLR10_UP} {$ENDIF} + +{------------------------------------------------------------------------------} + +{$IFDEF DELPHICOMPILER} + {$DEFINE DELPHILANGUAGE} +{$ENDIF} + +{$IFDEF BCBCOMPILER} + {$DEFINE DELPHILANGUAGE} +{$ENDIF} + +{------------------------------------------------------------------------------} +{ KYLIXX_UP from KYLIXX mappings } +{------------------------------------------------------------------------------} + +{$IFDEF KYLIX3} {$DEFINE KYLIX3_UP} {$ENDIF} +{$IFDEF KYLIX2} {$DEFINE KYLIX2_UP} {$ENDIF} +{$IFDEF KYLIX1} {$DEFINE KYLIX1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ KYLIXX_UP from KYLIXX_UP mappings } +{------------------------------------------------------------------------------} + +{$IFDEF KYLIX3_UP} {$DEFINE KYLIX2_UP} {$ENDIF} +{$IFDEF KYLIX2_UP} {$DEFINE KYLIX1_UP} {$ENDIF} + +{------------------------------------------------------------------------------} +{ Map COMPILERX_UP to friendly feature names } +{------------------------------------------------------------------------------} + +{$IFDEF FPC} + {$IFDEF VER1_0} + Please use FPC 2.0 or higher to compile this. + {$ELSE} + {$DEFINE SUPPORTS_OUTPARAMS} + {$DEFINE SUPPORTS_WIDECHAR} + {$DEFINE SUPPORTS_WIDESTRING} + {$IFDEF HASINTF} + {$DEFINE SUPPORTS_INTERFACE} + {$ENDIF} + {$IFDEF HASVARIANT} + {$DEFINE SUPPORTS_VARIANT} + {$ENDIF} + {$IFDEF FPC_HAS_TYPE_SINGLE} + {$DEFINE SUPPORTS_SINGLE} + {$ENDIF} + {$IFDEF FPC_HAS_TYPE_DOUBLE} + {$DEFINE SUPPORTS_DOUBLE} + {$ENDIF} + {$IFDEF FPC_HAS_TYPE_EXTENDED} + {$DEFINE SUPPORTS_EXTENDED} + {$ENDIF} + {$IFDEF HASCURRENCY} + {$DEFINE SUPPORTS_CURRENCY} + {$ENDIF} + {$DEFINE SUPPORTS_THREADVAR} + {$DEFINE SUPPORTS_CONSTPARAMS} + {$DEFINE SUPPORTS_LONGWORD} + {$DEFINE SUPPORTS_INT64} + {$DEFINE SUPPORTS_DYNAMICARRAYS} + {$DEFINE SUPPORTS_DEFAULTPARAMS} + {$DEFINE SUPPORTS_OVERLOAD} + {$DEFINE ACCEPT_DEPRECATED} // 2.2 also gives warnings + {$DEFINE ACCEPT_PLATFORM} // 2.2 also gives warnings + {$DEFINE ACCEPT_LIBRARY} + {$DEFINE SUPPORTS_EXTSYM} + {$DEFINE SUPPORTS_NODEFINE} + + {$DEFINE SUPPORTS_CUSTOMVARIANTS} + {$DEFINE SUPPORTS_VARARGS} + {$DEFINE SUPPORTS_ENUMVALUE} + {$IFDEF LINUX} + {$DEFINE HAS_UNIT_LIBC} + {$ENDIF LINUX} + {$DEFINE HAS_UNIT_CONTNRS} + {$DEFINE HAS_UNIT_TYPES} + {$DEFINE HAS_UNIT_VARIANTS} + {$DEFINE HAS_UNIT_STRUTILS} + {$DEFINE HAS_UNIT_DATEUTILS} + {$DEFINE HAS_UNIT_RTLCONSTS} + + {$DEFINE XPLATFORM_RTL} + + {$IFDEF VER2_2} + {$DEFINE SUPPORTS_DISPINTERFACE} + {$DEFINE SUPPORTS_IMPLEMENTS} + {$DEFINE SUPPORTS_DISPID} + {$ELSE} + {$UNDEF SUPPORTS_DISPINTERFACE} + {$UNDEF SUPPORTS_IMPLEMENTS} + {$endif} + {$UNDEF SUPPORTS_UNSAFE_WARNINGS} + {$ENDIF} +{$ENDIF FPC} + +{$IFDEF CLR} + {$DEFINE SUPPORTS_UNICODE} +{$ENDIF CLR} + +{$IFDEF COMPILER1_UP} + {$DEFINE SUPPORTS_CONSTPARAMS} + {$DEFINE SUPPORTS_SINGLE} + {$DEFINE SUPPORTS_DOUBLE} + {$DEFINE SUPPORTS_EXTENDED} + {$DEFINE SUPPORTS_PACKAGES} +{$ENDIF COMPILER1_UP} + +{$IFDEF COMPILER2_UP} + {$DEFINE SUPPORTS_CURRENCY} + {$DEFINE SUPPORTS_THREADVAR} + {$DEFINE SUPPORTS_VARIANT} + {$DEFINE SUPPORTS_WIDECHAR} +{$ENDIF COMPILER2_UP} + +{$IFDEF COMPILER3_UP} + {$DEFINE SUPPORTS_OUTPARAMS} + {$DEFINE SUPPORTS_WIDESTRING} + {$DEFINE SUPPORTS_INTERFACE} + {$DEFINE SUPPORTS_DISPINTERFACE} + {$DEFINE SUPPORTS_DISPID} + {$DEFINE SUPPORTS_WEAKPACKAGEUNIT} +{$ENDIF COMPILER3_UP} + +{$IFDEF COMPILER35_UP} + {$DEFINE SUPPORTS_EXTSYM} + {$DEFINE SUPPORTS_NODEFINE} +{$ENDIF COMPILER35_UP} + +{$IFDEF COMPILER4_UP} + {$DEFINE SUPPORTS_LONGWORD} + {$DEFINE SUPPORTS_INT64} + {$DEFINE SUPPORTS_DYNAMICARRAYS} + {$DEFINE SUPPORTS_DEFAULTPARAMS} + {$DEFINE SUPPORTS_OVERLOAD} + {$DEFINE SUPPORTS_IMPLEMENTS} +{$ENDIF COMPILER4_UP} + +{$IFDEF COMPILER6_UP} + {$DEFINE SUPPORTS_DEPRECATED} + {$DEFINE SUPPORTS_LIBRARY} + {$DEFINE SUPPORTS_PLATFORM} + {$DEFINE SUPPORTS_LOCAL} + {$DEFINE SUPPORTS_SETPEFLAGS} + {$DEFINE SUPPORTS_EXPERIMENTAL_WARNINGS} + {$DEFINE ACCEPT_DEPRECATED} + {$DEFINE ACCEPT_PLATFORM} + {$DEFINE ACCEPT_LIBRARY} + {$DEFINE SUPPORTS_DEPRECATED_WARNINGS} + {$DEFINE SUPPORTS_LIBRARY_WARNINGS} + {$DEFINE SUPPORTS_PLATFORM_WARNINGS} + {$DEFINE SUPPORTS_CUSTOMVARIANTS} + {$DEFINE SUPPORTS_VARARGS} + {$DEFINE SUPPORTS_ENUMVALUE} + {$DEFINE SUPPORTS_COMPILETIME_MESSAGES} +{$ENDIF COMPILER6_UP} + +{$IFDEF COMPILER7_UP} + {$DEFINE SUPPORTS_UNSAFE_WARNINGS} +{$ENDIF COMPILER7_UP} + +{$IFDEF COMPILER9_UP} + {$DEFINE SUPPORTS_FOR_IN} + {$DEFINE SUPPORTS_INLINE} + {$DEFINE SUPPORTS_NESTED_CONSTANTS} + {$DEFINE SUPPORTS_NESTED_TYPES} + {$DEFINE SUPPORTS_REGION} + {$IFDEF CLR} + {$DEFINE SUPPORTS_ENHANCED_RECORDS} + {$DEFINE SUPPORTS_CLASS_FIELDS} + {$DEFINE SUPPORTS_CLASS_HELPERS} + {$DEFINE SUPPORTS_CLASS_OPERATORS} + {$DEFINE SUPPORTS_STRICT} + {$DEFINE SUPPORTS_STATIC} + {$DEFINE SUPPORTS_FINAL} + {$ENDIF CLR} +{$ENDIF COMPILER9_UP} + +{$IFDEF COMPILER10_UP} + {$DEFINE SUPPORTS_ENHANCED_RECORDS} + {$DEFINE SUPPORTS_CLASS_FIELDS} + {$DEFINE SUPPORTS_CLASS_HELPERS} + {$DEFINE SUPPORTS_CLASS_OPERATORS} + {$DEFINE SUPPORTS_STRICT} + {$DEFINE SUPPORTS_STATIC} + {$DEFINE SUPPORTS_FINAL} + {$DEFINE SUPPORTS_METHODINFO} +{$ENDIF COMPILER10_UP} + +{$IFDEF COMPILER11_UP} + {$IFDEF CLR} + {$DEFINE SUPPORTS_GENERICS} + {$DEFINE SUPPORTS_DEPRECATED_DETAILS} + {$ENDIF CLR} +{$ENDIF COMPILER11_UP} + +{$IFDEF COMPILER12_UP} + {$DEFINE SUPPORTS_GENERICS} + {$DEFINE SUPPORTS_DEPRECATED_DETAILS} + {$DEFINE SUPPORTS_INT_ALIASES} + {$IFNDEF CLR} + {$DEFINE SUPPORTS_UNICODE} + {$DEFINE SUPPORTS_UNICODE_STRING} + {$ENDIF CLR} +{$ENDIF COMPILER12_UP} + +{$IFDEF COMPILER14_UP} + {$DEFINE SUPPORTS_CLASS_CTORDTORS} + {$DEFINE HAS_UNIT_RTTI} + {$DEFINE SUPPORTS_CAST_INTERFACE_TO_OBJ} + {$DEFINE SUPPORTS_DELAYED_LOADING} +{$ENDIF COMPILER14_UP} + +{$IFDEF COMPILER16_UP} + {$DEFINE USE_64BIT_TYPES} +{$ENDIF COMPILER16_UP} + +{$IFDEF RTL130_UP} + {$DEFINE HAS_UNIT_CONTNRS} +{$ENDIF RTL130_UP} + +{$IFDEF RTL140_UP} + {$IFDEF LINUX} + {$DEFINE HAS_UNIT_LIBC} + {$ENDIF LINUX} + {$DEFINE HAS_UNIT_RTLCONSTS} + {$DEFINE HAS_UNIT_TYPES} + {$DEFINE HAS_UNIT_VARIANTS} + {$DEFINE HAS_UNIT_STRUTILS} + {$DEFINE HAS_UNIT_DATEUTILS} + {$DEFINE XPLATFORM_RTL} +{$ENDIF RTL140_UP} + +{$IFDEF RTL170_UP} + {$DEFINE HAS_UNIT_HTTPPROD} +{$ENDIF RTL170_UP} + +{$IFDEF RTL185_UP} + {$DEFINE HAS_UNIT_GIFIMG} +{$ENDIF RTL185_UP} + +{$IFDEF RTL200_UP} + {$DEFINE HAS_UNIT_ANSISTRINGS} + {$DEFINE HAS_UNIT_PNGIMAGE} + {$DEFINE HAS_UNIT_CHARACTER} +{$ENDIF RTL200_UP} + +{$IFDEF RTL220_UP} + {$DEFINE SUPPORTS_UINT64} + {$DEFINE HAS_UNIT_REGULAREXPRESSIONSAPI} +{$ENDIF RTL220_UP} + +{$IFDEF RTL230_UP} + {$DEFINE HAS_UNITSCOPE} + {$DEFINE HAS_UNIT_SYSTEM_UITYPES} +{$ENDIF RTL230_UP} + +{$IFDEF RTL240_UP} + {$DEFINE HAS_UNIT_SYSTEM_ACTIONS} +{$ENDIF RTL240_UP} + +{------------------------------------------------------------------------------} +{ Cross-platform related defines } +{------------------------------------------------------------------------------} + +{$IFNDEF CPUASM} + {$DEFINE PUREPASCAL} +{$ENDIF ~CPUASM} + +{$IFDEF WIN32} + {$DEFINE MSWINDOWS} // predefined for D6+/BCB6+ + {$DEFINE Win32API} +{$ENDIF} + +{$IFDEF DELPHILANGUAGE} + {$IFDEF LINUX} + {$DEFINE UNIX} + {$ENDIF} + + {$IFNDEF CONSOLE} + {$IFDEF LINUX} + {$DEFINE VisualCLX} + {$ENDIF} + {$IFNDEF VisualCLX} + {$DEFINE VCL} + {$ENDIF} + {$ENDIF ~CONSOLE} +{$ENDIF DELPHILANGUAGE} + +{------------------------------------------------------------------------------} +{ Compiler settings } +{------------------------------------------------------------------------------} + +{$IFOPT A+} {$DEFINE ALIGN_ON} {$ENDIF} +{$IFOPT B+} {$DEFINE BOOLEVAL_ON} {$ENDIF} +{$IFDEF COMPILER2_UP} + {$IFOPT C+} {$DEFINE ASSERTIONS_ON} {$ENDIF} +{$ENDIF} +{$IFOPT D+} {$DEFINE DEBUGINFO_ON} {$ENDIF} +{$IFOPT G+} {$DEFINE IMPORTEDDATA_ON} {$ENDIF} +{$IFDEF COMPILER2_UP} + {$IFOPT H+} {$DEFINE LONGSTRINGS_ON} {$ENDIF} +{$ENDIF} + +// Hints +{$IFOPT I+} {$DEFINE IOCHECKS_ON} {$ENDIF} +{$IFDEF COMPILER2_UP} + {$IFOPT J+} {$DEFINE WRITEABLECONST_ON} {$ENDIF} +{$ENDIF} +{$IFOPT L+} {$DEFINE LOCALSYMBOLS} {$DEFINE LOCALSYMBOLS_ON} {$ENDIF} +{$IFOPT M+} {$DEFINE TYPEINFO_ON} {$ENDIF} +{$IFOPT O+} {$DEFINE OPTIMIZATION_ON} {$ENDIF} +{$IFOPT P+} {$DEFINE OPENSTRINGS_ON} {$ENDIF} +{$IFOPT Q+} {$DEFINE OVERFLOWCHECKS_ON} {$ENDIF} +{$IFOPT R+} {$DEFINE RANGECHECKS_ON} {$ENDIF} + +// Real compatibility +{$IFOPT T+} {$DEFINE TYPEDADDRESS_ON} {$ENDIF} +{$IFOPT U+} {$DEFINE SAFEDIVIDE_ON} {$ENDIF} +{$IFOPT V+} {$DEFINE VARSTRINGCHECKS_ON} {$ENDIF} +{$IFOPT W+} {$DEFINE STACKFRAMES_ON} {$ENDIF} + +// Warnings +{$IFOPT X+} {$DEFINE EXTENDEDSYNTAX_ON} {$ENDIF} + +// for Delphi/BCB trial versions remove the point from the line below +{.$UNDEF SUPPORTS_WEAKPACKAGEUNIT} + +{$ENDIF ~JEDI_INC} diff --git a/plugins/MirandaNGHistoryToDB/langs/English.xml b/plugins/MirandaNGHistoryToDB/langs/English.xml new file mode 100644 index 0000000000..b5fdedbc2b --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/langs/English.xml @@ -0,0 +1,505 @@ + + + HistoryToDB + Search in the message window + Clear the message + Sync history + Import history + From the history of ICQ 7 and above + From the history of RnQ + From the history of QIP 2005 + From the history of QIP 2010/Infium/2012 + From the history of Miranda + From the history of qutIM + Settings + History of %s (%s) + History of chat "%s" (%s) + History of %s + History with + to + Show + Search + Search + No matches found. + Message history in %s + History of the chat messages in %s + Information + There is not one open tab. + There is no open tabs chat. + Message history + Chat history + Search contact + Refresh history + Save history + Delete history + Delete history of the current contact + Delete history + Not selected for removal of contact history + Select a contact search history + Select the contact to refresh history + Delete + History of the selected contact will be deleted. Are you sure? + History of all contacts and chat rooms will be deleted. Are you sure? + Copy + Select all + Unselect all + [%s] HistoryToDBSync sent a request to synchronize history + Show history for the day + Show history for the month + Show history for the year + Show history for the entire period + Loading, please wait... + Settings + Database + Synchronization + Interface + Events + Fonts and more + Encryption history + Hot keys + About + Database + Synchronization history + Events + Connecting method: + DB type: + DB address: + Schema: + DB port: + DB name: + TNS Name: + Login: + Password: + Check database connection + Directly + Synchronization method: + Synchronization interval: + Automatic + Manually + On schedule + Every 5 minutes + Every 10 minutes + Every 20 minutes + Every 30 minutes + When you exit the program + After 10 messages + After 20 messages + After 30 messages + Every N minutes + After N messages + User intervals + Interval of time (min.): + Interval of count message: + Enable encryption message history + Show pop-up messages + Write errors to a log file + Hide HistoryToDBSync icon from the tray + Number of recent messages to display in the window history of correspondence + Add the button plug-in to modules panel (for only IM-client QIP 2012 and RnQ) + Save settings + Close + Encryption keys + Key number + Key status + Encryption method + Get encryption keys + Create a new key + Update + Attention! + A new version of the program. + Please visit the official website for updates. + The structure of your database is outdated. + Program version: %s + Database version: %s + Table configuration is successfully read. + Connecting to the database is successfully established. + Error + Unable to verify the version of the plugin. + Unable to connect to the database. + Error SQL query. + Error SQLExec query. + Please enter "DB address" + Please enter "DB port" + Please enter "Password" + Please enter "Login" + Please enter "DB name" + Please enter "Schema" + Please enter "TNS Name" + Settings have been saved. + Unable to save the settings. + Unable to read the settings. + [%s] HistoryToDBSync sent a request to recalculate the MD5-hashes + [%s] HistoryToDBSync sent a request to recalculate the MD5-hashes and remove duplicate messages + Database service + Recalculate of all the MD5-hashes in the database + Recalculate of all the MD5-hashes in the database and remove duplicate messages + Add special-contact (for only IM-client QIP 2012) + Fonts + Spacing for the header + Spacing for text + Font header for incomming: + Font header for outgoing: + Font for incoming messages: + Font for outgoing messages: + Font for service messages: + Spacing before: + Spacing after: + Find + Find more... + Activate global keyboard shortcuts + Assign + Remove + Shortcuts + Failed to open file + Failed to open file %s + Try again? + File to take another program. + WARNING! This message is encrypted. Perhaps you entered an incorrect password or encryption key in the database is not found the right key to decrypt the message. + The maximum size of log file errors (Kbyte) + Rename + Merge + Delete + Save contact list + Update contact information in the DB + Check for updates + A list of contacts and protocols stored. + Error! Contact list and protocols are not saved or stored properly. + Sent a request to update the list of contacts in the database. + The file %s to update your contact list can not be found. Request for update is not sent. + Not in the list + Update contact information in the DB (Nickname и UserID) + Please wait, is removal of the history... + [%s] HistoryToDBSync sent a request to update the contact list from a file %s + [%s] File %s to update your contact list can not be found. Please, select 'Save contact list' in the context menu, Other contacts QIPHistoryToDB. + [%s] The file %s to update your contact list can not be found. Select 'Save contact list' in the context menu RnQHistoryToDB in the chat window. + [%s] The file %s to update your contact list can not be found. Select 'Save contact list' in the context menu plugin. + [%s] HistoryToDBSync sent a request to disable synchronization of the history of the file %s. + [%s] HistoryToDBSync sent a request to enable synchronization of the history of the file %s. + Message history %s (%s) in HistoryToDBViewer + History in HistoryToDBViewer + Do not write messages in the DB marked as spam (for only IM-client QIP 2012) + Error: Invalid password encryption key. Enter the correct password or reading encrypted messages will be impossible. + Transparency + Enable transparency windows + Thank you + Use the expanded name for private chat (ChatName / Nickname) + Total lines: + Time to all lines: + ms + Failed to delete file + Failed to delete file %s + Try again? + Additionally + Synchronize history when you close the IM-client + Enable support for Skype + Language + Language: + Enable debug logging + Export history + Export history + Back + Next + Exit + Cancel + Welcome to the export wizard history + This wizard helps you export the story of %s to the external database. Exports will be made to a file in sql-insert. When you synchronize the data will be transmitted to the database. + Export Wizard history + Select the contacts whose history you want to export. + Export Wizard history + There is a history of exporting, please wait... + Export Wizard history + Export of finished history. + Nickname + Protocol + UserID + Total selected %s contacts from %s + Export history of contact %s (%s) ... + Export of finished history. + Are you sure you want to cancel the export and exit the wizard? + Out of the Export Wizard + Export of finished histori. Now you can send a request to synchronize the history of the exported database. A high volume of exported history synchronization procedure can be done a long time. + Send a request to synchronize + Import messages from the database directly from the Miranda of the IM-client. + During the upgrade, contact list error. + During recalculation of MD5-hash error. + For additional information, see the log files. + Running the synchronization of messages... + [%s] We make %s attempts to reconnect to the database. + [%s] Failed to reconnect to the database. + Number of reconnection attempts: + Reconnect interval (ms): + Auto scrolling messages + HistoryToDBSync run at Windows startup + Start Skype with HistoryToDBSync + Shutdown Skype when you close HistoryToDBSync + Update server is down for maintenance.%sTry to start the procedure to check for updates later. + + About + About + Version: + License: + + [%s] Error: Unable to connect to the database. Error: %s + [%s] Error: Database on service mode. Saving messages in the database is impossible. + [%s] Error: Database on service mode. Saving of pending messages in the database is impossible. + [%s] Error: Unable to connect to the database. Error: %s + [%s] Error: Unable to perform operation. Database on service mode. + [%s] Write error messages from the log file to the database: %s + [%s] Error in query update: %s + [%s] The file %s found %s messages; Loaded in DB: %s; Bad: %s; Duplicate: %s; Encrypted: %s + Found %s messages; Loaded in DB: %s; Bad: %s; Duplicate: %s; Encrypted: %s + [%s] File pending message %s not found. + Message file %s not found. + [%s] Database connection is not established. + History viewer %s not found. + The history synchronization program %s not found. + Update program %s not found. + Wrong SDK version. To work needed QIP 2012 and above. + The history import program %s not found. + Unable to perform operation. Database on service mode. + + Show + Hide + Synchronization + Settings + About + Exit + Synchronization history + Synchronization status: + Synchronization is done + Start synchronization + Stop synchronization + Synchronization running + Synchronization stopped + File synchronization can not be found + Running time of report... (%s sec.) + Waiting for a synchronization request + Not specified + Unknown type IM-client. Updating the database is impossible. + Database successfully updated. + An error occurred when update the database. Look in the log file. + Total messages: + Added to database: + Total error adding: + Up time: + Time left: + Found dublicates: + Log-file + View the log file + Log-file name: + Delete the log file + Update + Total messages for the analysis: + MD5-hash error: + Fixed MD5-hash: + Found duplicates: + Removed duplicate: + Entering a password + Enter the encryption key password + Entering a password + Error: Wrong key password. Enter the correct password or encryption of messages is not available. + Error: Could not find the active key + Error: There is more than one active key + Key number: + Key password: + Enter + Cancel + Remember the password for this session + Save all passwords + Unknown error decrypting the encryption key. + Check the encryption key + Encrypt message: + Error: Not found the right encryption key. + Started updating the contact list... + Not found a file with a list of protocols and contacts. + List for contacts updated. + Launched recalculate MD5-hash... + Recalculation of the MD5-hash done. + View log-file + Skype status: + Disable + Request for authorization... + Connection is allowed + Connection rejected + Connection is broken + Skype API is available + Error creating an instance of Skype + Error deleting an instance of Skype + Error connecting to an instance of Skype + We are trying to run Skype... + Error when starting Skype + Error creating interface Skype + Most likely you have not installed Skype and its version below 5.0 + + Import history of QIP 2010/Infium/2012 + Import history of QIP 2005 + Import options + Load from directory + Upload a single file + Open history file + Select: + Select a directory: + Select file: + Unknown + Select + Choose a directory + Select file + Generate SQL-file + Preview history + Recipient: + Total messages: + My Nickname: + My UserID: + Status: + Processed messages: + Choose a directory + All QIP 2010/Infium/2012 history files (*.qhf;*.ahf) + QIP 2010/Infium/2012 history files (*.qhf) + QIP 2010/Infium/2012 archive history files (*.ahf) + QIP 2005 history files (*.txt) + Selected file %s + History file + Error reading file + Stop + Stopped (%s) + Done! + Select the file(s) to import + Proceed + Wait... + There is a record in SQL-file... + Import finished. After the next synchronization session, all information will be added to the database. + RnQ history files (*.*) + Import history of RnQ + Running import history from RnQ + Running import history from QIP 2005 + Running import history from QIP 2010/Infium/2012 + Total %s history files selected. + Processing the file %s + File %s processed. + Imported %s records. + Found %s records. + Import history of ICQ 7 + ICQ 7 history files (Messages.qdb) + Running import history from ICQ 7 + You are connected to the database %s + The database is locked. Close the client ICQ 7 and try again. + Found the history of the correspondence with the user %s + Imported %s entries. + + Creating an encryption key + Creating an encryption key + Status key: + Encryption algorithm: + Key length (characters): + Key password: + Encryption key: + (Encoded in BASE64) + Storage location key: + Generate and save + Enter a password for the encryption key. + Do you already have an active key, change the status of the old key and repeat the operation to generate a new key. + Your new key is generated and stored in No. %s + Your new key is generated and stored in the database as No. %s + Please remember the password and the key No. + An error occurred when saving the key in the database. Check the settings of the database and try again. + Active + Inactive + Locally + On the server DB + Change key status + Change key password + Delete key + The database already has an active key. Change the status of the active key, and then return to this operation. + Status key is changed. + Removing the encryption key + The database found messages encrypted with that key. Are you sure you want to delete this key? + The encryption key is deleted. + WARNING! You are about to delete the active key. Without the active key encryption of messages is impossible. + Changing the password encryption key + Entered an incorrect current password encryption key. + The new password and confirmation do not match, or blank. Please try again. + Password for the encryption key is changed. + Changing the password encryption key + Current password: + New password: + Repeat new password: + Change password + Other Colors... + Automatic + General settings + Connection settings + Logs + First, select the "DB type" and "IM-client." + Update + Stop + Settings + IM-client: + Use a proxy server + Proxy server: + Port: + Proxy server requires a password + User: + Password: + Update + Click the "Update" button to start the update process. + Amount: + Speed: + Filename: + Description: + File size: + Unknown + Language file is not found + Initializing download... + KB + Kbytes/sec + Initializing download from the URL + Invalid response header from the server. + Check the settings for connecting to the Internet. Maybe your proxy server blocks access to the site updates. + Header data: + Parse the header... + Error opening session. + Error when requesting the file. + An error occurred while reading the file. + Failed to query the data through a proxy server. + Loading... + Download stopped. + Close all the components plugin, IM clients and try to repeat the update. + Download successful. + Is the checksum file... + MD5 file in memory: + Filesize in memory: + Checksum and file size are confirmed. + Checksum file to disk and server are the same. + Not correct the checksum of the received data. + File is saved as + Can not save file + Not true size of the received data. + All updates are downloaded successfully. + All updates have been installed. + Step + The number of files to update + File to update + Update settings file not found + Start update localization file %s... + Update localization file %s completed. + Start update sql-file %s... + Update sql-file %s completed. + Start update file %s... + Update file %s completed. + File %s is not updated. + In the memory of the process found %s (PID: %s) + Send the command to the end of the program... + Re looking for process %s in the memory... + Trying to force terminated the process %s + Process %s forcibly terminated. + Process %s can not be forcibly terminated. + Set SeDebugPrivilege and try again to terminate the process %s + Process %s forcibly terminated when SeDebugPrivilege. + Process %s can not be forced to terminated in SeDebugPrivilege. + Process %s not found in memory. + We are trying to close the process %s + Запускаем программу %s + Программа %s запущена. + Программа %s не запущена. + + \ No newline at end of file diff --git a/plugins/MirandaNGHistoryToDB/langs/Russian.xml b/plugins/MirandaNGHistoryToDB/langs/Russian.xml new file mode 100644 index 0000000000..a7933c774c --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/langs/Russian.xml @@ -0,0 +1,506 @@ + + + HistoryToDB + Поиск в окне сообщений + Очистить окно сообщений + Синхронизировать историю + Импорт истории + Из истории ICQ 7 и выше + Из истории RnQ + Из истории QIP 2005 + Из истории QIP 2010/Infium/2012 + Из истории Miranda + Из истории qutIM + Настройки + Переписка с %s (%s) + Переписка чата "%s" (%s) + Переписка с %s + История переписки с + по + Показать + Поиск + Поиск + Поиск закончен. Совпадений не найдено. + История сообщений в %s + История чат-сообщений в %s + Информация + Нет ни одной открытой вкладки сообщений. + Нет ни одной открытой вкладки чата. + История сообщений + История чатов + Найти контакт + Перечитать историю контакта + Сохранить историю контакта + Удалить историю контакта + Удалить историю текущего контакта + Удалить всю историю + Не выбран контакт для удаления истории + Выберите контакт для поиска истории + Выберите контакт для перезагрузки истории + Удалить + История выбранного контакта будет полностью удалена из базы. Вы уверены? + История всех контактов и чатов будет полностью удалена из базы. Вы уверены? + Копировать + Выбрать все + Снять выбор со всех + [%s] HistoryToDBSync отправлен запрос на синхронизацию истории + Показать за день + Показать за месяц + Показать за год + Показать за весь период + Подождите, идет загрузка... + Настройки + База данных + Синхронизация + Интерфейс + События + Шрифты и пр. + Горячие клавиши + Шифрование истории + О программе + База данных + Синхронизация истории + События + Метод подкл-я к БД: + Тип БД: + Адрес сервера БД: + Схема: + Порт сервера БД: + Имя БД: + TNS: + Логин: + Пароль: + Проверить соединение с БД + Напрямую + Метод синхронизации: + Интервал синхронизации: + Автоматический + Вручную + По расписанию + Каждые 5 минут + Каждые 10 минут + Каждые 20 минут + Каждые 30 минут + При выходе из программы + После кажд. 10-го сооб-я + После кажд. 20-го сооб-я + После кажд. 30-го сооб-я + Каждые N минут + После кажд. N сооб-я + Интервалы пользователя + Интервал по времени (мин.): + Интервал по кол. сообщений: + Включить шифрование истории сообщений + Показывать всплывающие сообщения + Писать ошибки в лог-файл + Скрыть иконку HistoryToDBSync из трея + Количество последних сообщений для показа в окне истории переписки + Добавить кнопку плагина в панель модулей (только для IM-клиента QIP 2012 и RnQ) + Сохранить настройки + Закрыть + Ключи шифрования на сервере + Номер ключа + Статус ключа + Метод шифрования + Получить ключи из БД + Создать новый ключ + Обновление + Внимание! + Вышла новая версия программы. + Пожалуйста, посетите официальный сайт для обновления. + Структура Вашей БД устарела. + Версия программы: %s + Версия БД: %s + Новая версия программы: %s + Таблица конфигурации успешно прочитана. + Подключение к БД успешно установлено. + Ошибка + Не удается проверить версию плагина. + Не удается установить подключение к БД. + Ошибка выполнения SQL запроса. + Ошибка выполнения SQLExec запроса. + Не заполнено поле "Адрес сервера БД" + Не заполнено поле "Порт сервера БД" + Не заполнено поле "Пароль" + Не заполнено поле "Логин" + Не заполнено поле "Имя БД" + Не заполнено поле "Схема" + Не заполнено поле "TNS" + Настройки сохранены. + Невозможно сохранить настройки. + Невозможно прочитать настройки. + [%s] HistoryToDBSync отправлен запрос на перерасчет MD5-хешей + [%s] HistoryToDBSync отправлен запрос на перерасчет MD5-хешей и удаление дубликатов сообщений + Обслуживание БД + Пересчитать все MD5-хэши в БД + Пересчитать все MD5-хэши в БД и удалить дубликаты + Добавить спец-контакт (только для IM-клиента QIP 2012) + Шрифты + Расстояние для заголовка + Расстояние для текста + Шрифт заголовка для входящих: + Шрифт заголовка для исходящих: + Шрифт для входящих сообщений: + Шрифт для исходящих сообщений: + Шрифт для сервисных сообщений: + Расстояние перед: + Расстояние после: + Найти + Найти далее... + Включить поддержку глобальных горячих клавиш + Назначить + Удалить + Горячие клавиши + Ошибка открытия файла + Ошибка открытия файла %s + Возможно файл занять программой. Повторить попытку? + Возможно файл занять программой. + ВНИМАНИЕ! Это сообщение зашифровано. Возможно Вы ввели неправильный пароль ключа шифрования или в БД не найдено нужного ключа для расшифровки сообщения. + Максимальный размер лог-файла ошибок (Кбайт) + Переименовать + Объединить + Удалить + Сохранить список контактов + Обновить данные контактов в БД + Проверить наличие обновлений + Список контактов и протоколов сохранен. + Ошибка! Список контактов и протоколов не сохранен или сохранен частично. + Отправлен запрос на обновление списка контактов в БД. + Файл %s для обновления списка контактов не найден. Запрос на обновление не отправлен. + Не в списке + Обновить данные контактов в БД (Nickname и UserID) + Подождите, идет удаление истории... + [%s] HistoryToDBSync отправлен запрос на обновление списка контактов из файла %s + [%s] Файл %s для обновления списка контактов не найден. Выберите пункт 'Сохранить список контактов' в контекстном меню спец-контакта QIPHistoryToDB. + [%s] Файл %s для обновления списка контактов не найден. Выберите пункт 'Сохранить список контактов' в контекстном меню RnQHistoryToDB в окне чата. + [%s] Файл %s для обновления списка контактов не найден. Выберите пункт 'Сохранить список контактов' в контекстном меню плагина. + [%s] HistoryToDBSync отправлен запрос на запрет синхронизации истории из файла %s. + [%s] HistoryToDBSync отправлен запрос на разрешение синхронизации истории из файла %s. + История сообщений %s (%s) в HistoryToDBViewer + История в HistoryToDBViewer + Не записывать в БД сообщения помеченые как спам (только для IM-клиента QIP 2012) + Ошибка: Неверный пароль ключа шифрования. Введите правильный пароль или чтение зашифрованных сообщений будет невозможно. + Прозрачность окон + Включить прозрачность окон + Благодарности + Использовать расширенное имя для приватных чатов (Имя чата / Ник собеседника) + Всего строк: + Время загрузки: + мс + Ошибка удаления файла + Ошибка удаления файла %s + Возможно файл занят другой программой. Повторить попытку? + Дополнительно + Дополнительная синхронизация истории при выходе из IM-клиента + Включить поддержку Skype + Язык программы + Язык программы: + Вести расширенный лог работы программы (Debug-режим) + Экспортировать историю + Экспорт истории + Назад + Далее + Выйти + Отмена + Добро пожаловать в мастер экспорта истории + Данный мастер поможет Вам экспортировать историю %s во внешнюю базу данных. Экспорт будет произведен в файл формата sql-insert. При синхронизации эти данные будут переданы в базу данных. + Мастер экспорта истории + Выберите контакты, историю которых Вы хотите экспортировать. + Мастер экспорта истории + Идет экспорт истории, подождите... + Мастер экспорта истории + Экспорт истории завершен. + Ник + Протокол + Номер + Всего выбрано %s контактов из %s + Экспорт истории контакта %s (%s) ... + Экспорт истории завершен. + Вы действительно хотите прервать экспорт и выйти из мастера? + Выход из мастера экспорта + Экспорт истории завершен. Теперь Вы можете отправить запрос на синхронизацию экспортированной истории с базой данных. При большом объёме экспортированной истории процедура синхронизации может выполняться значительное время. + Отправить запрос на синхронизацию + Импорт сообщений из базы Miranda осуществляется непосредственно из самого IM-клиента. + Во время обновления списка контактов произошла ошибка. + Во время перерасчета MD5-хэшей произошла ошибка. + Для получения доп. информации смотрите лог-файлы. + Запущена синхронизация сообщений... + [%s] Выполняем %s попытку переподключения к БД. + [%s] Ошибка переподключения к БД. + Кол. попыток переподключения: + Интервал переподключения (мсек): + Автоскроллинг сообщений + Запускать HistoryToDBSync при загрузке Windows + Запускать Skype при запуске HistoryToDBSync + Выходить из Skype при закрытии HistoryToDBSync + Сервер обновлений находится на сервисном обслуживании.%sПопробуйте запустить процедуру проверки обновлений позже. + + О плагине + О плагине + Версия: + Лицензия: + + [%s] Ошибка: Не удаётся подключиться к БД. Ошибка: %s + [%s] Ошибка: БД на сервисном обслуживании. Сохранение сообщений в БД невозможно. + [%s] Ошибка: БД на сервисном обслуживании. Сохранение отложенных сообщений в БД невозможно. + [%s] Ошибка: Не удаётся подключиться к БД. Ошибка: %s + [%s] Ошибка: Невозможно выполнить операцию. БД на сервисном обслуживании. + [%s] Ошибка записи сообщений из лог-файла в БД: %s + [%s] Ошибка при запросе обновления: %s + [%s] В файле %s найдено %s сообщений; Добавлено в базу %s; Всего отбраковано %s; Найдено дубликатов %s; Зашифровано %s + Всего сообщений %s; Добавлено в базу %s; Всего отбраковано %s; Найдено дубликатов %s; Зашифровано %s + [%s] Файл отложенных сообщений %s не найден. + Файл сообщений %s не найден. + [%s] Соединение с БД не установлено. + Просмотрщик истории %s не найден. + Программа синхронизации истории %s не найден. + Программа проверки обновлений %s не найдена. + Неверная версия SDK. Для работы необходим QIP 2012 и выше. + Программа импорта истории %s не найдена. + Невозможно выполнить операцию. База данных на сервисном обслуживании. + + Показать + Скрыть + Синхронизировать историю + Настройки + О программе + Выйти + Синхронизация истории + Состояние синхронизации: + Синхронизация выполнена + Запустить синхронизацию + Остановить синхронизацию + Идет синхронизация... + Cинхронизация остановлена + Файл для синхронизации не найден + Запущен отчет времени... (%s сек.) + Ожидание запроса на синхронизацию + Не задан + Неизвестный тип IM-клиента. Обновление БД невозможно. + Произведено успешное обновление БД. + Произошла ошибка при обновлений БД. Смотрите в лог-файл. + Всего сообщений: + Добавлено в базу: + Всего отбраковано: + С начала имп-а прошло: + До окончания осталось: + Найдено дубликатов: + Лог-файл + Просмотр лог-файла + Имя лог-файла: + Удалить лог-файл + Обновить + Всего сообщений для анализа: + Ошибочных MD5-хэшей: + Исправлено MD5-хэшей: + Найдено дубликатов: + Удалено дубликатов: + Ввод пароля + Ввод пароля ключа шифрования + Ввод пароля ключа шифрования + Ошибка: Неверный пароль ключа шифрования. Введите правильный пароль или шифрование сообщений будет недоступно. + Ошибка: Не найден активный ключ. + Ошибка: Найдено более 1 активного ключа. + Номер ключа: + Пароль ключа: + Ввод + Отмена + Запомнить пароль до выхода из программы + Сохранить все пароли + Неизвестная ошибка расшифровки ключа шифрования. + Проверка ключа шифрования + Зашифровано сооб-й: + Ошибка: В БД не найдено нужного ключа шифрования. + Запущено обновление списка контактов... + Не найдены файл со списком протоколов и контактов. + Cписк контактов обновлен. + Запущен перерасчет MD5-хэшей... + Перерасчет MD5-хэшей завершен. + Посмотреть лог-файлы + Статус Skype: + Отключено + Запрос авторизации... + Подключение разрешено + Подключение отклонено + Подключение отключено + Skype API доступно + Ошибка создания экземпляра Skype + Ошибка при удалении экземпляра Skype + Ошибка при подключении к экземпляру Skype + Пытаемся запустить Skype... + Ошибка при запуске Skype + Ошибка при создании интерфейса Skype + Возможно на компьютере не установлен Skype или его версия ниже 5.0 + + Импорт истории из QIP 2010/Infium/2012 + Импорт истории из QIP 2005 + Параметры импорта истории + Загрузить из директории + Загрузить из одного файла + Открыть файл истории + Выберите: + Выберите директорию: + Выберите файл: + Неизвестно + Выбрать + Выбрать директорию + Выбрать файл + Сформировать SQL-файл + Предпросмотр истории + Получатель: + Всего сообщений: + Мои Nickname: + Мой UserID: + Статус: + Обработано сообщений: + Выберите каталог + Все файлы истории QIP 2010/Infium/2012 (*.qhf;*.ahf) + Файлы истории QIP 2010/Infium/2012 (*.qhf) + Архивные файлы истории QIP 2010/Infium/2012 (*.ahf) + Файлы истории QIP 2005 (*.txt) + Выбран файл %s + Файл истории + Ошибка чтения файла + Остановить + Остановлено (%s) + Готово! + Выберите файл(ы) для импорта + Продолжить + Ждите... + Идет запись в SQL-файл... + Импорт закончен. После очередного сеанса синхронизации вся информация будет добавлена в БД. + Файлы истории RnQ (*.*) + Импорт истории из RnQ + Запущен импорт истории из RnQ + Запущен импорт истории из QIP 2005 + Запущен импорт истории из QIP 2010/Infium/2012 + Всего выбрано %s файлов истории. + Идет обработка файла %s + Импортировано %s записей. + Файл %s обработан. + Всего найдено %s записей. + Импорт истории из ICQ 7 + Файлы истории ICQ 7 (Messages.qdb) + Запущен импорт истории из ICQ 7 + Вы подключены к БД %s + База данных заблокирована. Закройте клиента ICQ 7 и повторите попытку. + Найдена история переписки с пользователем %s + Импортировано %s записей. + + Создание ключа шифрования + Создание ключа шифрования + Статус ключа: + Алгоритм шифрования: + Длина ключа (символов): + Пароль ключа: + Ключ шифрования: + (Закодирован в BASE64) + Место хранения ключа: + Сгенерировать и сохранить + Введите пароль для защиты ключа шифрования. + У Вас уже есть один активный ключ, поменяйте статус старого ключа и повторите операцию генерации нового ключа. + Ваш новый ключ сгенерирован и сохранен под номером %s + Ваш новый ключ сгенерирован и сохранен в БД под номером %s + Пожалуйста, запомните введенный пароль и номер ключа. + Произошла ошибка при сохранении ключа в БД. Проверьте настройки БД и попробуйте еще раз. + Активный + Неактивный + Локально + На сервере в БД + Изменить статус ключа + Изменить пароль ключа + Удалить ключ + В базе данных уже есть один активный ключ. Измените статус активного ключа, а потом вернитесь к этой операции. + Статус ключа изменен. + Удаление ключа шифрования + В базе данных найдены сообщения зашифрованные этим ключом. Вы действительно хотите удалить этот ключ? + Ключ шифрования удален. + ВНИМАНИЕ! Вы собираетесь удалить активный ключ. Без активного ключа шифрование сообщений будет невозможно. + Смена пароля ключа шифрования + Введен неправильный текущий пароль ключа шифрования. + Введенные новые пароли и подтверждение не совпадают или пустые. Повторите попытку. + Пароль на ключ шифрования изменен. + Смена пароля ключа шифрования + Текущий пароль: + Новый пароль: + Повторите новый пароль: + Сменить пароль + Другой цвет... + Авто + Общие настройки + Настройки соединения + Лог работы + Вначале выберите "Тип БД" и "IM-клиент". + Обновить + Остановить + Настройки + IM-клиент: + Использовать прокси-сервер + Адрес прокси-сервера: + Порт: + Прокси-сервер требует авторизацию + Пользователь: + Пароль: + Обновление + Нажмите кнопку "Обновить" для начала процесса обновления. + Объем: + Скорость: + Имя файла: + Описание: + Размер файла: + Не известно + Не найден файл локализации + Инициализация скачивания... + Кбайт + Кбайт/сек + Инициализация скачивания c URL + Неправильный заголовок ответа с сервера. + Проверьте настройки подключения к Интернет. Возможно Ваш прокси-сервер блокирует доступ к сайту обновления. + Данные заголовка: + Парсим заголовок... + Ошибка при открытии сессии. + Ошибка при запрашивании файла. + Ошибка при чтении файла. + Ошибка при запросе данных через прокси-сервер. + Идет загрузка... + Скачивание остановлено. + Завершите работу всех компонентов плагина вручную и попробуйте повторить обновление. + Скачивание успешно завершено. + Идет подсчёт контрольной суммы файла... + MD5 файла в памяти: + Размер файла в памяти: + Контрольная сумма и размер файла подтверждены. + Контрольная сумма файла на диске и на сервере совпадают. + Не сходится контрольная сумма принятых данных. + Файл сохранен под именем + Ошибка сохранения файла + Не сходится размер принятых данных. + Все обновления успешно загружены. + Все обновления успешно установлены. + Шаг + Число файлов для обновления + Очередной файл для обновления + Не найден файл настроек обновления + Начинаем обновление файла локализации %s... + Обновление файла локализации %s выполнено. + Начинаем обновление sql-файла %s... + Обновление sql-файла %s выполнено. + Начинаем обновление файла %s... + Обновление файла %s выполнено. + Файл %s не обновлен. + В памяти найден процесс %s (PID: %s) + Отправляем команду завершения... + Повторно ищем процесс %s в памяти... + Пытаемся принудительно завершить процесс %s + Процесс %s принудительно завершен. + Процесс %s не может быть принудительно завершен. + Повышаем свои привилегии до SeDebugPrivilege и пробуем еще раз завершить процесс %s + Процесс %s принудительно завершен при SeDebugPrivilege. + Процесс %s не может быть принудительно завершен даже при SeDebugPrivilege. + Процесс %s не найден в памяти. + Пытаемся завершить процесс %s + Запускаем программу %s + Программа %s запущена. + Программа %s не запущена. + + \ No newline at end of file diff --git a/plugins/MirandaNGHistoryToDB/m_historytodb.inc b/plugins/MirandaNGHistoryToDB/m_historytodb.inc new file mode 100644 index 0000000000..07aa224029 --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/m_historytodb.inc @@ -0,0 +1,40 @@ +{ ############################################################################ } +{ # # } +{ # MirandaNG HistoryToDB Plugin v2.4 # } +{ # # } +{ # License: GPLv3 # } +{ # # } +{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } +{ # # } +{ ############################################################################ } + +{$IFNDEF M_HISTORYTODB} +{$DEFINE M_HISTORYTODB} + +const + + // MS_MHTD_SHOWHISTORY + // (supported from 2.4.0) + // Open history + // wParam - zero + // lParam - zero + // Return - 0 + MS_MHTD_SHOWHISTORY = 'MirandaNGHistoryToDB/ShowHistory'; + + // MS_MHTD_SHOWCONTACTHISTORY + // (supported from 2.4.0) + // Open contact history + // wParam - hContact + // lParam - zero + // Return - 0 + MS_MHTD_SHOWCONTACTHISTORY = 'MirandaNGHistoryToDB/ShowContactHistory'; + + // MS_MHTD_GETVERSION + // (supported from 2.4.0) + // Get current MirandaNGHistoryToDB version + // wParam - zero + // lParam - zero + // Return - current version, via PLUGIN_MAKE_VERSION macro + MS_MHTD_GETVERSION = 'MirandaNGHistoryToDB/GetVersion'; + +{$ENDIF} -- cgit v1.2.3