diff --git a/components/jvcllaz/design/JvMM/images/tjvanimatedimage.bmp b/components/jvcllaz/design/JvMM/images/tjvanimatedimage.bmp new file mode 100644 index 000000000..a412acfe8 Binary files /dev/null and b/components/jvcllaz/design/JvMM/images/tjvanimatedimage.bmp differ diff --git a/components/jvcllaz/design/JvWizard/images/images.txt b/components/jvcllaz/design/JvWizard/images/images.txt new file mode 100644 index 000000000..06eb2dc69 --- /dev/null +++ b/components/jvcllaz/design/JvWizard/images/images.txt @@ -0,0 +1,4 @@ +tjvwizard.bmp +tjvwizardroutemaplist.bmp +tjvwizardroutemapnodes.bmp +tjvwizardroutemapsteps.bmp diff --git a/components/jvcllaz/design/JvWizard/images/make_res.bat b/components/jvcllaz/design/JvWizard/images/make_res.bat new file mode 100644 index 000000000..cf0fc66e8 --- /dev/null +++ b/components/jvcllaz/design/JvWizard/images/make_res.bat @@ -0,0 +1 @@ +lazres ../../../resource/jvwizardsreg.res @images.txt diff --git a/components/jvcllaz/design/JvWizard/images/tjvwizard.bmp b/components/jvcllaz/design/JvWizard/images/tjvwizard.bmp new file mode 100644 index 000000000..6bbfe8db3 Binary files /dev/null and b/components/jvcllaz/design/JvWizard/images/tjvwizard.bmp differ diff --git a/components/jvcllaz/design/JvWizard/images/tjvwizardroutemaplist.bmp b/components/jvcllaz/design/JvWizard/images/tjvwizardroutemaplist.bmp new file mode 100644 index 000000000..7da3811c6 Binary files /dev/null and b/components/jvcllaz/design/JvWizard/images/tjvwizardroutemaplist.bmp differ diff --git a/components/jvcllaz/design/JvWizard/images/tjvwizardroutemapnodes.bmp b/components/jvcllaz/design/JvWizard/images/tjvwizardroutemapnodes.bmp new file mode 100644 index 000000000..6c9be51ca Binary files /dev/null and b/components/jvcllaz/design/JvWizard/images/tjvwizardroutemapnodes.bmp differ diff --git a/components/jvcllaz/design/JvWizard/images/tjvwizardroutemapsteps.bmp b/components/jvcllaz/design/JvWizard/images/tjvwizardroutemapsteps.bmp new file mode 100644 index 000000000..2b22c39ba Binary files /dev/null and b/components/jvcllaz/design/JvWizard/images/tjvwizardroutemapsteps.bmp differ diff --git a/components/jvcllaz/design/JvWizard/jvwizardeditorform.lfm b/components/jvcllaz/design/JvWizard/jvwizardeditorform.lfm new file mode 100644 index 000000000..864f3d4ce --- /dev/null +++ b/components/jvcllaz/design/JvWizard/jvwizardeditorform.lfm @@ -0,0 +1,260 @@ +object JvWizardPageListEditor: TJvWizardPageListEditor + Left = 192 + Height = 304 + Top = 107 + Width = 192 + Caption = 'K Wizard Page Editor' + ClientHeight = 304 + ClientWidth = 192 + Color = clBtnFace + OnClose = FormClose + OnShow = FormShow + LCLVersion = '2.1.0.0' + object tbrWizardPages: TToolBar + Left = 0 + Height = 23 + Top = 0 + Width = 192 + AutoSize = True + ButtonHeight = 23 + ButtonWidth = 23 + Caption = 'tbrWizardPages' + EdgeInner = esNone + EdgeOuter = esNone + Images = imgWizardPages + ParentShowHint = False + ShowHint = True + TabOrder = 0 + object btnAddWelcomePage: TToolButton + Left = 1 + Top = 0 + Action = actAddInteriorPage + DropdownMenu = popWizard + Style = tbsDropDown + end + object btnDeletePages: TToolButton + Left = 36 + Top = 0 + Action = actDeletePages + end + object ToolButton1: TToolButton + Left = 59 + Height = 23 + Top = 0 + Caption = 'ToolButton1' + ImageIndex = 3 + Style = tbsSeparator + end + object tbMoveUp: TToolButton + Left = 67 + Top = 0 + Action = acMoveUp + end + object tbMoveDown: TToolButton + Left = 90 + Top = 0 + Action = acMoveDown + end + end + object lbxWizardPages: TListBox + Left = 0 + Height = 281 + Top = 23 + Width = 192 + Align = alClient + ItemHeight = 0 + OnClick = lbxWizardPagesClick + OnDragDrop = lbxWizardPagesDragDrop + OnDragOver = lbxWizardPagesDragOver + OnMouseDown = lbxWizardPagesMouseDown + TabOrder = 1 + end + object imgWizardPages: TImageList + Left = 20 + Top = 30 + Bitmap = { + 4C69040000001000000010000000000000000000000000000000848484FFFFFF + FFFF000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000FFFFFF0000000000000000848484FF00FF + FFFF0000000000000000848484FF000000000000000000000000000000000000 + 0000000000000000000000000000848484FF00FFFFFF00000000848484FFFFFF + FFFF00000000848484FF00FFFFFF000000000000000000000000000000000000 + 000000000000000000000000000000000000848484FF00FFFFFF848484FF00FF + FFFF848484FF00FFFFFF00000000000000000000000000000000000000000000 + 0000000000000000000000000000FFFFFFFF00FFFFFF848484FF00FFFFFFFFFF + FFFF848484FF848484FF848484FF848484FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF00000000848484FF848484FF848484FFFFFFFFFF8484 + 84FFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF + FFFFFFFFFFFF000000FF848484FF00000000848484FFFFFFFFFF848484FF00FF + FFFF848484FF00FFFFFFFFFFFFFF00FFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF + FFFF00FFFFFF000000FF848484FF848484FF00FFFFFF00FFFFFF848484FFFFFF + FFFF00FFFFFF848484FF00FFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF + FFFFFFFFFFFF000000FF848484FFFFFFFFFF000000FFFFFFFFFF848484FF00FF + FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF + FFFF00FFFFFF000000FF848484FF00000000000000FF00FFFFFFFFFFFFFF00FF + FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF000000FF000000FF0000 + 00FF000000FF000000FF848484FF00000000000000FFFFFFFFFF00FFFFFFFFFF + FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFF000000FF00FFFFFFC6C6 + C6FF000000FF000000FF848484FF00000000000000FF00FFFFFFFFFFFFFF00FF + FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF000000FFC6C6C6FF0000 + 00FFFFFFFFFF000000FF848484FF00000000000000FFFFFFFFFF00FFFFFFFFFF + FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFF000000FF000000FFFFFF + FFFF00FFFFFF000000FF848484FF00000000000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF848484FF0000000000000000848484FF848484FF8484 + 84FF848484FF848484FF848484FF848484FF848484FF848484FF848484FF8484 + 84FF848484FF848484FF848484FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000084FF000084FF848484FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000084FF000084FF848484FF000000000000000000000000000000000000 + 0000000000000000000000000000000084FF000084FF848484FF000000000000 + 84FF000084FF848484FF00000000000000000000000000000000000000000000 + 0000000000000000000000000000848484FF000084FF000084FF000084FF0000 + 84FF848484FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF0000000000000000848484FF000084FF000084FF0000 + 84FFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF + FFFFFFFFFFFF000000FF848484FF00000000848484FF000084FF000084FF0000 + 84FF000084FFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF + FFFF00FFFFFF000000FF848484FF00000000000084FF000084FF848484FF00FF + FFFF000084FF000084FFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FF + FFFFFFFFFFFF000000FF848484FF848484FF000084FF848484FF00FFFFFFFFFF + FFFF848484FF000084FF848484FFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF + FFFF00FFFFFF000000FF848484FF000084FF000084FF00FFFFFFFFFFFFFF00FF + FFFFFFFFFFFF848484FF000084FF00FFFFFFFFFFFFFF000000FF000000FF0000 + 00FF000000FF000000FF848484FF000084FF000000FFFFFFFFFF00FFFFFFFFFF + FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFF000000FF00FFFFFFC6C6 + C6FF000000FF000000FF848484FF848484FF000000FF00FFFFFFFFFFFFFF00FF + FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF000000FFC6C6C6FF0000 + 00FFFFFFFFFF000000FF848484FF00000000000000FFFFFFFFFF00FFFFFFFFFF + FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFF000000FF000000FFFFFF + FFFF00FFFFFF000000FF848484FF00000000000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF848484FF0000000000000000848484FF848484FF8484 + 84FF848484FF848484FF848484FF848484FF848484FF848484FF848484FF8484 + 84FF848484FF848484FF848484FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000FF848400FF000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF848400FF848400FF848400FF000000FF00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FF848400FF848400FF848400FF848400FF848400FF000000FF000000000000 + 0000000000000000000000000000000000000000000000000000000000FF8484 + 00FF848400FF848400FF848400FF848400FF848400FF848400FF000000FF0000 + 00000000000000000000000000000000000000000000000000FF000000FF0000 + 00FF000000FF848400FF848400FF848400FF000000FF000000FF000000FF0000 + 00FF000000000000000000000000000000000000000000000000000000000000 + 0000000000FF848400FF848400FF848400FF000000FF00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF848400FF848400FF848400FF000000FF00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF848400FF848400FF848400FF000000FF00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FF000000FF000000FF000000FF00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FF000000FF000000FF000000FF00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF848400FF848400FF848400FF000000FF00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF848400FF848400FF848400FF000000FF00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF848400FF848400FF848400FF000000FF00000000000000000000 + 00000000000000000000000000000000000000000000000000FF000000FF0000 + 00FF000000FF848400FF848400FF848400FF000000FF000000FF000000FF0000 + 00FF000000000000000000000000000000000000000000000000000000FF8484 + 00FF848400FF848400FF848400FF848400FF848400FF848400FF000000FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FF848400FF848400FF848400FF848400FF848400FF000000FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF848400FF848400FF848400FF000000FF00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000FF848400FF000000FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000 + } + end + object actWizardPages: TActionList + Images = imgWizardPages + OnUpdate = actWizardPagesUpdate + Left = 86 + Top = 34 + object actAddWelcomePage: TAction + Caption = 'Add Welcome Page' + Hint = 'Add Welcome page' + ImageIndex = 0 + OnExecute = actAddWelcomePageExecute + ShortCut = 16429 + end + object actAddInteriorPage: TAction + Caption = 'Add Interior Page' + Hint = 'Add Interior page' + ImageIndex = 0 + OnExecute = actAddInteriorPageExecute + ShortCut = 45 + end + object actDeletePages: TAction + Caption = 'actDeletePages' + Hint = 'Delete selected page(s)' + ImageIndex = 1 + OnExecute = actDeletePagesExecute + OnUpdate = actDeletePagesUpdate + end + object acMoveUp: TAction + Caption = 'Move Up' + Hint = 'Move Up' + ImageIndex = 2 + OnExecute = acMoveUpExecute + ShortCut = 16422 + end + object acMoveDown: TAction + Caption = 'Move Down' + Hint = 'Move Down' + ImageIndex = 3 + OnExecute = acMoveDownExecute + ShortCut = 16424 + end + end + object popWizard: TPopupMenu + Images = imgWizardPages + Left = 66 + Top = 78 + object AddInteriorPage1: TMenuItem + Action = actAddInteriorPage + Default = True + end + object AddWelcomePage1: TMenuItem + Action = actAddWelcomePage + end + end +end diff --git a/components/jvcllaz/design/JvWizard/jvwizardeditorform.pas b/components/jvcllaz/design/JvWizard/jvwizardeditorform.pas new file mode 100644 index 000000000..717dd9921 --- /dev/null +++ b/components/jvcllaz/design/JvWizard/jvwizardeditorform.pas @@ -0,0 +1,636 @@ +{----------------------------------------------------------------------------- +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/MPL-1.1.html + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: JvWizardEditorForm.PAS, released on 2002-01-29. + +The Initial Developer of the Original Code is William Yu Wei. +Portions created by William Yu Wei are Copyright (C) 2002 William Yu Wei. +All Rights Reserved. + +Contributor(s): +Peter Thörnqvist - converted to JVCL naming conventions on 2003-07-11 +Micha³ Gawrycki - Lazarus port (2019) + +You may retrieve the latest version of this file at the Project JEDI's JVCL home page, +located at http://jvcl.delphi-jedi.org + +Known Issues: +-----------------------------------------------------------------------------} +// $Id$ + +{***************************************************************************** + Purpose: Jv Wizard Component Editor + + History: + --------------------------------------------------------------------------- + Date(mm/dd/yy) Comments + --------------------------------------------------------------------------- + 01/29/2002 Initial create + 1) Move TJvWizardActivePageProperty, TJvWizardEditor + class from JvWizardReg to here + 2) TJvWizardPageListProperty added + TJvWizardPageList dialog form added +******************************************************************************} + +unit JvWizardEditorForm; + +{$mode objfpc} +{$H+} + +interface + +uses + SysUtils, Classes, + Graphics, Controls, Forms, Dialogs, ActnList, ImgList, ComCtrls, StdCtrls, + ToolWin, Menus, PropEdits, ComponentEditors, FormEditingIntf, + JvWizard; + +type + TJvWizardActivePageProperty = class(TComponentPropertyEditor) + public + function GetAttributes: TPropertyAttributes; override; + procedure GetValues(Proc: TGetStrProc); override; + end; + + // JvWizard Component Local Menu Editor + + { TJvWizardEditor } + + TJvWizardEditor = class(TComponentEditor) + protected + function GetWizard: TJvWizard; virtual; + function GetPageOwner: TComponent; + procedure AddPage(Page: TJvWizardCustomPage); + procedure AddWelcomePage; + procedure AddInteriorPage; + procedure NextPage(Step: Integer); + property Wizard: TJvWizard read GetWizard; + public + constructor Create(AComponent: TComponent; + ADesigner: TComponentEditorDesigner); override; + destructor Destroy; override; + procedure ExecuteVerb(Index: Integer); override; + function GetVerb(Index: Integer): string; override; + function GetVerbCount: Integer; override; + end; + + TJvWizardPageListProperty = class(TPropertyEditor) + function GetAttributes: TPropertyAttributes; override; + function GetValue: string; override; + procedure Edit; override; + end; + + { TJvWizardLazIDEHelper } + + TJvWizardLazIDEHelper = class + private + procedure SetSelection(const ASelection: TPersistentSelectionList); + public + constructor Create; + destructor Destroy; override; + end; + + { TJvWizardPageListEditor } + + TJvWizardPageListEditor = class({TDesignWindow}TForm) + tbrWizardPages: TToolBar; + lbxWizardPages: TListBox; + btnAddWelcomePage: TToolButton; + btnDeletePages: TToolButton; + ToolButton1: TToolButton; + imgWizardPages: TImageList; + actWizardPages: TActionList; + actAddWelcomePage: TAction; + actAddInteriorPage: TAction; + actDeletePages: TAction; + popWizard: TPopupMenu; + AddWelcomePage1: TMenuItem; + AddInteriorPage1: TMenuItem; + tbMoveUp: TToolButton; + tbMoveDown: TToolButton; + acMoveUp: TAction; + acMoveDown: TAction; + procedure FormClose(Sender: TObject; var AAction: TCloseAction); + procedure actAddWelcomePageExecute(Sender: TObject); + procedure actAddInteriorPageExecute(Sender: TObject); + procedure actDeletePagesExecute(Sender: TObject); + procedure actDeletePagesUpdate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure lbxWizardPagesClick(Sender: TObject); + procedure lbxWizardPagesMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure lbxWizardPagesDragOver(Sender, Source: TObject; X, Y: Integer; + State: TDragState; var Accept: Boolean); + procedure lbxWizardPagesDragDrop(Sender, Source: TObject; X, Y: Integer); + procedure actWizardPagesUpdate(AAction: TBasicAction; + var Handled: Boolean); + procedure acMoveUpExecute(Sender: TObject); + procedure acMoveDownExecute(Sender: TObject); + private + FDesigner: TComponentEditorDesigner; + FWizard: TJvWizard; + procedure SetWizard(const Value: TJvWizard); + procedure UpdatePageList(const CurrItemIndex: Integer); + procedure SelectWizardPage(const Index: Integer); + function GetPageOwner: TComponent; + + procedure DeletePersist(APersistent: TPersistent); + procedure ItemModified(Sender: TObject); + protected + procedure AddPage(Page: TJvWizardCustomPage); + procedure AddWelcomePage; + procedure AddInteriorPage; + property Wizard: TJvWizard read FWizard write SetWizard; + public + property CompDesigner: TComponentEditorDesigner read FDesigner write FDesigner; + end; + +implementation + +uses + JvDsgnConsts; + +{$R *.lfm} + +procedure ShowWizardPageListEditor(Designer: TComponentEditorDesigner; AWizard: TJvWizard); +var + I: Integer; + AWizardPageListEditor: TJvWizardPageListEditor; +begin + // because the page list editor is not show modal, so + // we need to find it rather than create a new instance. + AWizardPageListEditor := nil; + for I := 0 to Screen.FormCount - 1 do + if Screen.Forms[I] is TJvWizardPageListEditor then + if TJvWizardPageListEditor(Screen.Forms[I]).Wizard = AWizard then + begin + AWizardPageListEditor := TJvWizardPageListEditor(Screen.Forms[I]); + Break; + end; + // Show the wizard editor + if Assigned(AWizardPageListEditor) then + begin + AWizardPageListEditor.Show; + if AWizardPageListEditor.WindowState = wsMinimized then + AWizardPageListEditor.WindowState := wsNormal; + end + else + begin + AWizardPageListEditor := TJvWizardPageListEditor.Create(Application); + try + AWizardPageListEditor.CompDesigner := Designer; + AWizardPageListEditor.Wizard := AWizard; + AWizardPageListEditor.Show; + except + AWizardPageListEditor.Free; + raise; + end; + end; +end; + +{ TJvWizardLazIDEHelper } + +procedure TJvWizardLazIDEHelper.SetSelection( + const ASelection: TPersistentSelectionList); +begin + if (ASelection.Count = 1) and (ASelection.Items[0] is TJvWizardCustomPage) and + Assigned(TJvWizardCustomPage(ASelection.Items[0]).Wizard) then + TJvWizardCustomPage(ASelection.Items[0]).Wizard.ActivePage := TJvWizardCustomPage(ASelection.Items[0]); +end; + +constructor TJvWizardLazIDEHelper.Create; +begin + if GlobalDesignHook <> nil then + GlobalDesignHook.AddHandlerSetSelection(@SetSelection); +end; + +destructor TJvWizardLazIDEHelper.Destroy; +begin + if GlobalDesignHook <> nil then + GlobalDesignHook.RemoveAllHandlersForObject(Self); + inherited Destroy; +end; + +//=== { TJvWizardActivePageProperty } ======================================== + +function TJvWizardActivePageProperty.GetAttributes: TPropertyAttributes; +begin + Result := [paValueList]; +end; + +procedure TJvWizardActivePageProperty.GetValues(Proc: TGetStrProc); +var + I: Integer; + Component: TComponent; + Root: TPersistent; +begin + Root := PropertyHook.LookupRoot; + if not (Root is TComponent) then + Root := GetComponent(0); + for I := 0 to TComponent(Root).ComponentCount - 1 do + begin + Component := TComponent(Root).Components[I]; + if (Component.Name <> '') and (Component is TJvWizardCustomPage) and + (TJvWizardCustomPage(Component).Wizard = GetComponent(0)) then + Proc(Component.Name); + end; +end; + +//=== { TJvWizardEditor } ==================================================== + +procedure TJvWizardEditor.AddPage(Page: TJvWizardCustomPage); +begin + Page.Parent := Wizard; + Page.Wizard := Wizard; + Wizard.ActivePage := Page; + Designer.PropertyEditorHook.PersistentAdded(Page, True); + Designer.PropertyEditorHook.RefreshPropertyValues; + Designer.Modified; + if GlobalDesignHook <> nil then + GlobalDesignHook.Modified(Self); +end; + +procedure TJvWizardEditor.AddInteriorPage; +var + Page: TJvWizardInteriorPage; +begin + Page := TJvWizardInteriorPage.Create(GetPageOwner); + try + Page.Name := Designer.UniqueName(TJvWizardInteriorPage.ClassName); + AddPage(Page); + except + Page.Free; + raise; + end; +end; + +procedure TJvWizardEditor.AddWelcomePage; +var + Page: TJvWizardWelcomePage; +begin + Page := TJvWizardWelcomePage.Create(GetPageOwner); + try + Page.Name := Designer.UniqueName(TJvWizardWelcomePage.ClassName); + AddPage(Page); + except + Page.Free; + raise; + end; +end; + +procedure TJvWizardEditor.ExecuteVerb(Index: Integer); +var + Page: TPersistent; +begin + case Index of + 0: + ShowWizardPageListEditor(Designer, GetWizard); + 1: + AddWelcomePage; + 2: + AddInteriorPage; + 3: + NextPage(1); + 4: + NextPage(-1); + 5: + if Assigned(Wizard.ActivePage) then + begin + GlobalDesignHook.SelectOnlyThis(Wizard); + Page := Wizard.ActivePage; + GlobalDesignHook.DeletePersistent(Page); + end; + end; +end; + +function TJvWizardEditor.GetWizard: TJvWizard; +begin + if Component is TJvWizard then + Result := TJvWizard(Component) + else + Result := TJvWizard(TJvWizardCustomPage(Component).Wizard); +end; + +function TJvWizardEditor.GetPageOwner: TComponent; +begin + if Wizard <> nil then + begin + Result := Wizard.Owner; + if Result = nil then + Result := Wizard; + end + else + Result := nil; +end; + +function TJvWizardEditor.GetVerb(Index: Integer): string; +begin + case Index of + 0: + Result := RsPageListEllipsis; + 1: + Result := RsNewWelcomePage; + 2: + Result := RsNewInteriorPage; + 3: + Result := RsNextPage; + 4: + Result := RsPreviousPage; + 5: + Result := RsDeletePage; + end; +end; + +function TJvWizardEditor.GetVerbCount: Integer; +begin + Result := 6; +end; + +procedure TJvWizardEditor.NextPage(Step: Integer); +var + Page: TJvWizardCustomPage; +begin + Page := Wizard.FindNextPage(Wizard.ActivePageIndex, Step, False); + if Assigned(Page) and (Page <> Wizard.ActivePage) then + begin + if Component is TJvWizardCustomPage then + Designer.SelectOnlyThisComponent(Page); + Wizard.ActivePage := Page; + Designer.Modified; + end; +end; + +constructor TJvWizardEditor.Create(AComponent: TComponent; + ADesigner: TComponentEditorDesigner); +begin + inherited Create(AComponent, ADesigner); +end; + +destructor TJvWizardEditor.Destroy; +begin + inherited Destroy; +end; + +//=== { TJvWizardPageListEditor } ============================================ + +procedure TJvWizardPageListProperty.Edit; +begin + //ShowWizardPageListEditor(Designer, TJvWizard(GetComponent(0))); +end; + +function TJvWizardPageListProperty.GetAttributes: TPropertyAttributes; +begin + Result := [paDialog, paReadOnly]; +end; + +function TJvWizardPageListProperty.GetValue: string; +var + APageList: TList; +begin + APageList := TList(GetObjectValue); + if not Assigned(APageList) or (APageList.Count <= 0) then + Result := RsNone + else + Result := Format('(%s)', [GetPropType^.Name]); +end; + +//=== { TJvWizardPageList Dialog Form } ====================================== + +procedure TJvWizardPageListEditor.UpdatePageList(const CurrItemIndex: Integer); +var + I: Integer; +begin + if Assigned(FWizard) then + begin + lbxWizardPages.Items.BeginUpdate; + try + lbxWizardPages.Items.Clear; + for I := 0 to FWizard.PageCount - 1 do + lbxWizardPages.Items.Add(TJvWizardCustomPage(FWizard.Pages[I]).Name); + if (CurrItemIndex >= 0) and (CurrItemIndex < lbxWizardPages.Items.Count) then + lbxWizardPages.ItemIndex := CurrItemIndex + else + lbxWizardPages.ItemIndex := -1; + finally + lbxWizardPages.Items.EndUpdate; + end; + end; +end; + +procedure TJvWizardPageListEditor.SelectWizardPage(const Index: Integer); +var + Page: TJvWizardCustomPage; +begin + if Assigned(FWizard) and Active then + begin + Page := nil; + if (Index >= 0) and (Index < FWizard.PageCount) then + Page := TJvWizardCustomPage(FWizard.Pages[Index]); + if Assigned(Page) then + CompDesigner.SelectOnlyThisComponent(Page) + else + if Assigned(Wizard) then + CompDesigner.SelectOnlyThisComponent(Wizard); + Wizard.ActivePage := Page; + CompDesigner.Modified; + end; +end; + +function TJvWizardPageListEditor.GetPageOwner: TComponent; +begin + if Wizard <> nil then + begin + Result := Wizard.Owner; + if Result = nil then + Result := Wizard; + end + else + Result := nil; +end; + +procedure TJvWizardPageListEditor.DeletePersist(APersistent: TPersistent); +begin + if APersistent = FWizard then + begin + FWizard := nil; + Close; + end + else if APersistent is TJvWizardCustomPage then + ItemModified(nil); +end; + +procedure TJvWizardPageListEditor.ItemModified(Sender: TObject); +begin + if not (csDestroying in ComponentState) then + UpdatePageList(lbxWizardPages.ItemIndex); +end; + +procedure TJvWizardPageListEditor.SetWizard(const Value: TJvWizard); +begin + if FWizard <> Value then + begin + FWizard := Value; + UpdatePageList(0); + end; +end; + +procedure TJvWizardPageListEditor.AddPage(Page: TJvWizardCustomPage); +begin + Page.Parent := Wizard; + Page.Wizard := Wizard; + Wizard.ActivePage := Page; + //list box will show twice when adding either welcome page or interior page. + lbxWizardPages.ItemIndex := lbxWizardPages.Items.Add(Page.Name); + CompDesigner.PropertyEditorHook.PersistentAdded(Page, True); + CompDesigner.PropertyEditorHook.RefreshPropertyValues; + CompDesigner.PropertyEditorHook.Modified(Self); + if GlobalDesignHook <> nil then + GlobalDesignHook.Modified(Self); +end; + +procedure TJvWizardPageListEditor.AddInteriorPage; +var + APage: TJvWizardCustomPage; +begin + APage := TJvWizardInteriorPage.Create(GetPageOwner); + try + APage.Name := CompDesigner.UniqueName(APage.ClassName); + AddPage(APage); + except + APage.Free; + raise; + end; +end; + +procedure TJvWizardPageListEditor.AddWelcomePage; +var + APage: TJvWizardCustomPage; +begin + APage := TJvWizardWelcomePage.Create(GetPageOwner); + try + APage.Name := CompDesigner.UniqueName(APage.ClassName); + AddPage(APage); + except + APage.Free; + raise; + end; +end; + +procedure TJvWizardPageListEditor.FormClose(Sender: TObject; var AAction: TCloseAction); +begin + AAction := caFree; + GlobalDesignHook.RemoveAllHandlersForObject(Self); +end; + +procedure TJvWizardPageListEditor.actAddWelcomePageExecute(Sender: TObject); +begin + AddWelcomePage; +end; + +procedure TJvWizardPageListEditor.actAddInteriorPageExecute(Sender: TObject); +begin + AddInteriorPage; +end; + +procedure TJvWizardPageListEditor.actDeletePagesExecute(Sender: TObject); +begin + if Assigned(Wizard.ActivePage) then + begin + if lbxWizardPages.ItemIndex >= 0 then + lbxWizardPages.Items.Delete(Wizard.ActivePage.PageIndex); + CompDesigner.SelectOnlyThisComponent(Wizard); + Wizard.ActivePage.Free; + CompDesigner.Modified; + end; +end; + +procedure TJvWizardPageListEditor.actDeletePagesUpdate(Sender: TObject); +begin + (Sender as TAction).Enabled := + (lbxWizardPages.Items.Count > 0) and (lbxWizardPages.ItemIndex >= 0); +end; + +procedure TJvWizardPageListEditor.FormShow(Sender: TObject); +begin + GlobalDesignHook.AddHandlerPersistentDeleting(@DeletePersist); + GlobalDesignHook.AddHandlerModified(@ItemModified); +end; + +procedure TJvWizardPageListEditor.lbxWizardPagesClick(Sender: TObject); +begin + SelectWizardPage(lbxWizardPages.ItemIndex); +end; + +procedure TJvWizardPageListEditor.lbxWizardPagesMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + lbxWizardPages.BeginDrag(False); +end; + +procedure TJvWizardPageListEditor.lbxWizardPagesDragOver(Sender, Source: TObject; + X, Y: Integer; State: TDragState; var Accept: Boolean); +begin + Accept := + (Source is TListBox) and + (lbxWizardPages.ItemAtPos(Point(X, Y), True) <> -1) and + (lbxWizardPages.ItemAtPos(Point(X, Y), True) <> lbxWizardPages.ItemIndex); +end; + +procedure TJvWizardPageListEditor.lbxWizardPagesDragDrop(Sender, Source: TObject; + X, Y: Integer); +var + OldIndex, NewIndex: Integer; +begin + OldIndex := lbxWizardPages.ItemIndex; + NewIndex := lbxWizardPages.ItemAtPos(Point(X,Y), True); + lbxWizardPages.Items.Move(OldIndex, NewIndex); + if Assigned(FWizard) then + begin + TJvWizardCustomPage(FWizard.Pages[OldIndex]).PageIndex := NewIndex; + lbxWizardPages.ItemIndex := NewIndex; + end; +end; + +procedure TJvWizardPageListEditor.actWizardPagesUpdate(AAction: TBasicAction; + var Handled: Boolean); +begin + acMoveUp.Enabled := lbxWizardPages.ItemIndex > 0; + acMoveDown.Enabled := + (lbxWizardPages.ItemIndex <> -1) and + (lbxWizardPages.ItemIndex < lbxWizardPages.Items.Count - 1); +end; + +procedure TJvWizardPageListEditor.acMoveUpExecute(Sender: TObject); +var + I: Integer; +begin + I := lbxWizardPages.ItemIndex; + lbxWizardPages.Items.Move(I, I-1); + if Assigned(FWizard) then + begin + TJvWizardCustomPage(FWizard.Pages[I]).PageIndex := I - 1; + lbxWizardPages.ItemIndex := I - 1; + end; +end; + +procedure TJvWizardPageListEditor.acMoveDownExecute(Sender: TObject); +var + I: Integer; +begin + I := lbxWizardPages.ItemIndex; + lbxWizardPages.Items.Move(I, I+1); + if Assigned(FWizard) then + begin + TJvWizardCustomPage(FWizard.Pages[I]).PageIndex := I + 1; + lbxWizardPages.ItemIndex := I + 1; + end; +end; + +end. diff --git a/components/jvcllaz/design/JvWizard/jvwizardreg.pas b/components/jvcllaz/design/JvWizard/jvwizardreg.pas new file mode 100644 index 000000000..9dac22039 --- /dev/null +++ b/components/jvcllaz/design/JvWizard/jvwizardreg.pas @@ -0,0 +1,55 @@ +unit JvWizardReg; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils; + +procedure Register; + +implementation + +uses + JvWizard, JvWizardRouteMapNodes, JvWizardRouteMapSteps, JvWizardRouteMapList, + JvWizardEditorForm, JvDsgnConsts, PropEdits, ComponentEditors, FormEditingIntf; + +{$R ../../resource/jvwizardsreg.res} + +var + JvWizardIdeHelper: TJvWizardLazIDEHelper = nil; + +procedure Register; +const + cActivePage = 'ActivePage'; + cPages = 'Pages'; +begin + RegisterComponents({RsPaletteWizard}RsPaletteJvcl, [TJvWizard, TJvWizardRouteMapSteps, + TJvWizardRouteMapNodes, TJvWizardRouteMapList]); + RegisterNoIcon([TJvWizardCustomPage, TJvWizardWelcomePage, + TJvWizardInteriorPage]); + RegisterComponentEditor(TJvWizard, TJvWizardEditor); + RegisterComponentEditor(TJvWizardCustomPage, TJvWizardEditor); + RegisterComponentEditor(TJvWizardWelcomePage, TJvWizardEditor); + RegisterComponentEditor(TJvWizardInteriorPage, TJvWizardEditor); + RegisterPropertyEditor(TypeInfo(TJvWizardCustomPage), TJvWizard, cActivePage, + TJvWizardActivePageProperty); + RegisterPropertyEditor(TypeInfo(TJvWizardWelcomePage), TJvWizard, cActivePage, + TJvWizardActivePageProperty); + RegisterPropertyEditor(TypeInfo(TJvWizardInteriorPage), TJvWizard, cActivePage, + TJvWizardActivePageProperty); + // JvWizard Page List Editor + RegisterPropertyEditor(TypeInfo(TJvWizardPageList), TJvWizard, cPages, + TJvWizardPageListProperty); + + if Assigned(GlobalDesignHook) and (not Assigned(JvWizardIdeHelper)) then + JvWizardIdeHelper := TJvWizardLazIDEHelper.Create; +end; + +finalization + if Assigned(JvWizardIdeHelper) then + JvWizardIdeHelper.Free; + +end. + diff --git a/components/jvcllaz/examples/JvWizard/JvWizardDemo.lpi b/components/jvcllaz/examples/JvWizard/JvWizardDemo.lpi new file mode 100644 index 000000000..cf539042c --- /dev/null +++ b/components/jvcllaz/examples/JvWizard/JvWizardDemo.lpi @@ -0,0 +1,82 @@ + + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + <Icon Value="0"/> + </General> + <BuildModes> + <Item Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="0"/> + </RunParams> + <RequiredPackages Count="2"> + <Item1> + <PackageName Value="JvWizardLazR"/> + </Item1> + <Item2> + <PackageName Value="LCL"/> + </Item2> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="JvWizardDemo.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="uformmain.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Form1"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="uFormMain"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="..\..\bin\JvWizardDemo"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/components/jvcllaz/examples/JvWizard/JvWizardDemo.lpr b/components/jvcllaz/examples/JvWizard/JvWizardDemo.lpr new file mode 100644 index 000000000..ce8edb26f --- /dev/null +++ b/components/jvcllaz/examples/JvWizard/JvWizardDemo.lpr @@ -0,0 +1,22 @@ +program JvWizardDemo; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX}{$IFDEF UseCThreads} + cthreads, + {$ENDIF}{$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, uFormMain + { you can add units after this }; + +{$R *.res} + +begin + RequireDerivedFormResource := True; + Application.Scaled := True; + Application.Initialize; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. + diff --git a/components/jvcllaz/examples/JvWizard/uformmain.lfm b/components/jvcllaz/examples/JvWizard/uformmain.lfm new file mode 100644 index 000000000..2162e0860 --- /dev/null +++ b/components/jvcllaz/examples/JvWizard/uformmain.lfm @@ -0,0 +1,3703 @@ +object Form1: TForm1 + Left = 366 + Height = 336 + Top = 212 + Width = 477 + ActiveControl = JvWizardWelcomePage1 + Caption = 'JvWizard demo' + ClientHeight = 336 + ClientWidth = 477 + LCLVersion = '2.1.0.0' + object JvWizard1: TJvWizard + Left = 0 + Height = 336 + Top = 0 + Width = 477 + ActivePage = JvWizardWelcomePage1 + ButtonBarHeight = 42 + ButtonStart.Caption = 'To &Start Page' + ButtonStart.NumGlyphs = 1 + ButtonStart.Width = 85 + ButtonLast.Caption = 'To &Last Page' + ButtonLast.NumGlyphs = 1 + ButtonLast.Width = 85 + ButtonBack.Caption = '< &Back' + ButtonBack.NumGlyphs = 1 + ButtonBack.Width = 75 + ButtonNext.Caption = '&Next >' + ButtonNext.NumGlyphs = 1 + ButtonNext.Width = 75 + ButtonFinish.Caption = '&Finish' + ButtonFinish.NumGlyphs = 1 + ButtonFinish.Width = 75 + ButtonCancel.Caption = 'Cancel' + ButtonCancel.NumGlyphs = 1 + ButtonCancel.ModalResult = 2 + ButtonCancel.Width = 75 + ButtonHelp.Caption = '&Help' + ButtonHelp.NumGlyphs = 1 + ButtonHelp.Width = 75 + ShowRouteMap = True + HeaderImages = ImageList1 + OnFinishButtonClick = JvWizard1FinishButtonClick + OnCancelButtonClick = JvWizard1CancelButtonClick + OnActivePageChanged = JvWizard1ActivePageChanged + object JvWizardWelcomePage1: TJvWizardWelcomePage + Header.ImageIndex = 0 + Header.Title.Color = clNone + Header.Title.Text = 'Welcome' + Header.Title.Anchors = [akTop, akLeft, akRight] + Header.Title.Font.Height = -16 + Header.Title.Font.Style = [fsBold] + Header.Subtitle.Color = clNone + Header.Subtitle.Text = 'Subtitle of welcome page' + Header.Subtitle.Anchors = [akTop, akLeft, akRight, akBottom] + VisibleButtons = [bkNext, bkCancel] + Caption = 'JvWizardWelcomePage1' + WaterMark.Image.Picture.Data = { + 1754506F727461626C654E6574776F726B47726170686963EB66010089504E47 + 0D0A1A0A0000000D49484452000001C20000012C0802000000DF3424E0000000 + 0774494D4507D70C031726035714A3B3000000097048597300000E7400000E74 + 016B24B3D60000000467414D410000B18F0BFC61050001667A4944415478DAEC + 9D7B901CC57DC7BB6766774FF71008DD497742D69D6224103244E881710C92EC + 94634B22548A12C249B08B87CB855D814052E5580887988088CBC156841F24E6 + 6548525684F01F060449CC43526C5ED2296524E1130F09249DB83B3DEF4E7BFB + 98E9FC7A7A776E66FA313DB3B377E714ADD5DE6C4FF76F7A7A663EF3FD75F7F4 + 604403461F858FC247E1A3102B306C90F12EC6F80782313616ACB8BB362B38F8 + E58BE416D90F1C5E85053631BF02237172ACD842C826E623236D4A0BC9D249B6 + 25A806C1DE641A72679FDB5A1E299DEE3B6197CA4A9B825A0E9BC582A560C568 + 5956D4BDA0A690A2CE65058C631C298F29D238ED245651F8D8F26747E834C0E1 + D3D7DB391CB2E44BE4CFE33FAF71C82E9F3AB0E338B85DC41DAEE05580B945E1 + D10D55A0E41CC1DC01707F9819D36C309C92531E714419D5176AE46152AEC1F2 + D4E90612BE51F87FE74FF73FBBF14BD61815455E1B8ACAD3AB279C309FD2A6AE + 096D860A93344E99DCD27AD6F089C1E1E383C471B4F654C1D0C8CC71E83C1182 + 1643C5BF133094375F378662E13682A98590151093131C215111AA3D9C0E40D9 + 1FBBE43836B126199926B39CB7AB8089A467043A75E83B764158FA205B53C2A8 + E2328C42897845925CD13693005B2D4563D45038EDD9335A339372278F0C1486 + 470229F519AEADE9A2AB0CCB7F2B2DD74F8A4631546134194343A54A95A1FE2F + 3943638A50143EAB05000D5790C8734C02D0D12484D8238E9933B2CD99D2199B + D824B8F5884325AEFDF8DC4C91B444A799C2DB9EBB503B46E309CC8875893654 + 43058A6DD65B8A1AA631B5AB1D8ED6C94303A5423146516BA9BBC427DA383254 + BB42B43C43D57D26CC5041DD4D0086F2373B2D111A1FA0D1F4F405E22070EACD + 2CCA349AB040CA21BF4A7A45482D4A822455CA5AD5DD8A00A50ABCA6E6D4EB9E + F7E15FD21B53921A53787FC9A4A8FECE45E41FB59069C89E3DB3AD942F0EF69F + F41A4347534E40293A8E41EDCE47DEB022C92C3F09C32EF57832349E23CF8B50 + 7E495006615C04407D3F08728A0E90C6CA198E69D80547762AE9A333B2A53546 + F067D5EA13139D121C5E3DB0A681D1380E786CDA46E54B5B8A6A8B2235F024EB + 264D6E9ADC7ECEE0C0C9FCA961E2E8F771EAC34D4204CDBB3D6F6122BAF37AB7 + 59F981C4A23FBED57E10D5CA500E61C1A3A1D318CADF32EA2142055D5BC10849 + 7DFAE39D1281B3DA6A30B081CB40521295810B587ED4B8A408255B1D5EA3BC0C + 892A33949615B8468CEA232F1EEEF45263FD7CDA9B8F6153733BDE39DF38A565 + F2F429A7FB4E9C393128B9DDD52E4585A9E5A48BBB7FFE9CE3C350E13EA816C5 + E92722436B72E4F54468BD00EAC503464B79DBCC199949262C602248CA6D3CEA + B061ADA88815282207D15F49C229D271EA633BE05267AA5E9D4BD2D4C936175F + 8A9E3DA3D56AC81E7FFFC362BE50A3DF1D6BC3FAF7EC585274FC82CC9D573054 + 86080D86FA8DD4CCD0341DF94422B48E000D7ACD4EC1C15923D368DA230E118D + 40C1EA534BE9CEC7A68D5E50D3942327F167AB19A3714A9F744FA5F236ED8BBB + C6EE3E69EE291F9B666533270EF5958B25F9B6D397A24A775E7F5F27A83BAF25 + 3E55940825C482AD7B511380A1A98B50AEEA23002A6EAC94DCCAEC2231103227 + 1976BE42D238E89427ADF70D5D21888328F573B4168CD6E8D1C794E5D15254B2 + 95D4C739E9030F4E23D39C3ABBA33C52021D4A3B94629F043549517DB34A291A + B3C0756568BC6AC0C225F70062FACD761BFBA20C1F32E03FED44A89C428486CA + A5C4AEA1CA8544E82A8EA141E918C5D0648DA18945686D00959F2CC1744E91D6 + 9735C98005A74C44F25FB984748E79FDB0CAE9527E9749252E05A73EA9472F5A + 51DF461075D694A4A8CF8A611AADB36714F323837D277D0C15EDE4584B51FD1A + 8A2B45EB1CB4DD792022AD2C033338BA7FDD0AA1FF0C5631065BCB02CB6654F6 + AD1A01C0246CC97F5511DA9542BFD97235D2CDE9C03AC478EB723736439339F2 + 5A2254E9C52700A84CA67A71A44C07929A395AA32E49A3D0A93AADB07013750B + 2E2745039FC225C2C931AAAF9234EA27D9D6F5CCA74D5BDD9069C84E9DD59E3F + 3574FAC3133515605CA4A822E7C474E729310D8A45931293F5A11A2E404DA342 + 4BC3A888CEA0611CDABA54A905528676837EB9F074F1EAB8FF08252A5D09910E + 93B278F4BAAC81A121DF9FFFAAA45288D0FA03D44B426C64179191A5372DA744 + C2DB961DF0D0E9315E776DD1FEF16C4DF761D0DA3C7AC5D51CEDD14B5628E46D + 12BD2CD38D619BC0D0D6AE8EE1E3A787064E0757D5743A8CBB148D6FA36E0C75 + 1D71C33441F233F79C1113220C4A4C43645C6C5FC9506F3982A1F065BA853051 + E0AA224CBA3A14A4EE7FC2542C2C2307F9A48D80A13A8E7C52112AB6CDC520FE + B29401140B6B9869529B38056C64E10061A740F8547C8D2739795361ADC6334C + 81873352798A294D8F3E4E64DA37A734EF769949B9D6CE7610A1EEC0269D6D47 + B3436D20D69E8672D4498AD6258037EE4A4E8A4EF71F8526A0934629CF446991 + 155DF38164288AA1FC0D02E351C3A661796B194F6DDB715B06DCFF8EDB304024 + 488D31CB09420945A89CAAB50174F48C01AD5E24460EC387B699465B551D8B3A + 06997D255E9361747C3D7ADEB4044363DCB9E4AEA33AB4B363E8F8A9FCC9212D + 9B3176347D292A389009A5681DDD79CA4BCB60E804625AA64917A9DED4702C14 + 55A666281E4D26DC8288A138C450617DD0B29B286351D9CA64296835C77698E3 + CFBE47C7D7E01065148E7C0C111AE5C56B0154DCF38EA57F6067ED02014D0A1F + A788442685072D22459DD8C28DBBE7B6E3036B8A4EFD3879F46914B2B62D8CE6 + 061D3AF563D34F7D786CE4E430D19AE1609CA5A8BED92829AA6F4F8BA1957E21 + ABA236019C96EBBE5793C5D907B156124BA87019C32412C02C164383B0A38530 + 2D6C21036518529D32E5A95355A995FE2B29435312A149012AB8730669CD552B + 7D66149939FA71649349E83F399F0260892A3351A61E75376AC3E8FF178F3E85 + 3D83759986DCD459ED430327C19717E9E0DF2D299ABC74712562C01076FB8840 + 6F9A546F5A96C5DA3A2377431A2D612852FCC692641298856A40CE504E57E2F0 + D6D8DD02966D106E14A9B6EBEFBB3C7548683B52866A8950892C4D0E507EA352 + 4B005023433B9D4649AA9A0F4AF777A2A0736A91408408BC49315A078F3ED165 + 27CB176B8666BD4228E77302869E336BDAE90F8FE54F0DEBDB543512FC6E4AD1 + 84EE3CED2C32587F1148CE4CC672E1892336222F918AA1E135118F234A9D6AFF + CF9A191ADA96094835CCAC65124480A525D0A86EE714F0B5E2E4C81DF9DA4568 + 72800A4F1CBEFA419396AA242D49AA3F3E346BC7AA449AF2273309AD4B80D1DA + 9C77A14C8BC33561DA2B3F3BFFCACF7E4266E39917F73CFDC21ED9066AAF7DEA + CB774EA70FCBBBEDA1B03FAB96CF5BB9FC02BEE0BBF61EDEF6FABBFB0F0C28ED + 4595286D293AA773EA2DD75D06BFB66EDBBF757B4FCCAD26EC59629968A32775 + D7697B27C09369B188CD69D793C480BC4954A6E9840CC56932946F37A8260449 + 8E4094C352B96C97CB0E1B4C453BFA49A4233F5E00559E86D5154E19484AE043 + 4AA1CD0B7E44AF48439B72EA73341051426F77923BF5E979F4FAA9A5263ADA26 + 2F9C3F53B676E79B1FC429A128855C1A31860EF69DF4F729B5B7B55C72E1B97C + E24B2E9C71D3EA25F7FEF897CFBCF456F221F7D17B22492CC9D1D4985D30AF03 + 16BAF7F6CAA5A8E636B8D42281417D77CB3033B4E913B427B8EE2976C0AADD79 + 294383C910123274741B218646D644028686DA0FA09E32B409958A53DBAEC0B4 + EAECF344D3636878837503287F93811B4109E30CC1598FA4095C7B14F342D008 + 229AF2EEBCFF57228C4E608F1E54676FDFE950F42E8AD17ADCC33065E8ACE9A7 + 7A8FE54F0F570D064C82FCECDE73B8BD6D72C7B416607D475B0B44AEFBDA1FF6 + F60D76EF3B222D51A2BB513229AA57C7B54BD1EA4567507A82EAB42C0A50FF00 + 4F8D9DACCD9DD79C504632BCC95F733C4305DDD60260EB3194D3BE81AD629CCD + 582843BBF8CB2E4F9DCA3355A35B9315495F842A002AA327129E7DD2D94D2A7F + 49D9A024CD2052C28A64B2DF11213239899339E4CEFBC6BFC6C5E844F4E8FDE1 + E917DEDCB5E730C2D1595B9A7283C3E1CEC28E6967510ACB0BD2DC9483EFA1E1 + 0262CF7A76750C0D9CF418CA87EEBD871F7EF275EFE70FEEFA9385AE4A0559CA + 6314046CF7DE23DCA6474B3EA7B3B5776070E84C41510320848FF60F866DF8F6 + 015CF8B70F1E8BAA489D10639093DB77645819DAF699A53D4706FF3C11125A10 + C6E3C8141105975EDFBAC39BC688A1A116047F12A842336B118481A565B783DF + ED8F8A2742E55E7C0C8046CA4FD512D3A416C126413616DA1787246BA449A538 + 55CC37CAA8EA462474EA2786472FBD98645B7BF5A9DBE1FB279B7EDD316DF295 + 9F990FCB3F7BBA7BC3A32F03526FBB71D9AAE517B26440D20D8F6D7BF9B577AA + 06A9BD6B572D800F284AE46274FB1BEF3DF1D2FE81BE5343C74F23ED00946418 + 85027891D7AEFCFD6B565CCC842A357E068C1FD8F0D3FFF17079C5E2D9B77EF9 + 0FBC0410B66EEBF9A7C721C1E86D00E078D3EAC5972FEAAA1A296E7EEE378F6C + D9E925B86251D70D572F84645ECC8E9D0737FEEB2B1C7383F5ABEFD24B8E181D + B9044EBB65023BDDBE23D1444AE986B8EE7C542B9E80A18254BCA13A32D4CB08 + 623E6BD1CEA8B2E3944AEEA07EF769FF80398508557BF1A143A50350F1905449 + F1D91FDA7546494A87CBDA42EF4476778E4AA71DA438C55C54D8D7A759E36374 + 0279F4FA2B02915F5C75494B73035BDEB5E71030F487DF5E3D77769B970018F7 + 9D6F5C092405C8B298DBAE5F0A0CF51280265DB1EC82B9E74DBF79DD66FF1B3D + 23C739CDED6A650BBD5578AD5971F1AD5FFEB43F4D73636EC5D2F34157DCFBE0 + 8B6010187ADF5F7F1EB978DD7FE018884DE0E98AA573CFEB9C7AC3DA27591680 + E303DFBAAAB931EB3392BDE1EA45EDAD2DEBFFF96544756EC7FADB3F172AD9E5 + 8B3AA7B736DFB4EEE709AA5F538A5A593A58DEA28D7AA6216CF8D33DAE29B9F3 + EA860F75B792FC51255109933134444E91EB2D282AFD726F552628D26289B59C + 56C648698AD07401AA454FFF1210D44694A474F46CB8B2B49CD274EEC8AE15A2 + 8CC202E91A0BA3A97BF4F104AC4E453D78CF9A500C68CF8736BDE28F018682D2 + 04442E9A3F73DB6BEF7CEB2FFE8831F4FB8FBEBCE999DD405560E8C2F933019D + 900C7837B7AB8D3174FF81FEAFFFDD532045AF5DFDA9DBAE5DF2F173A7AC5A7E + C1A667FF57511EAA3DAFB9D45B065F9E2D6F7BFD3DB6C07AA2602BD7FFCDA6A1 + 33A5E6A6EC9607AE03922E5D321B308A28672F6209AEF9CB7F6359EEB8F933E0 + DD838A044A1E1DA0385EFF579F670C5DFBBDFFDCB1F3405363F6813BFF18D80A + B4DDFCDC9BFB0F1E633D4820516FBDE7E9B7DF3F0E0936AE5B0509A838555029 + 9E60F45F93E06FD2CB1AE467C6B2B0EA928867390943356D4776CD7B19E23294 + 2B53ED0CC5DCE6D8B2818D869C010C2DD27653B713CA11998AF6E2C398966495 + 5484CCFF571C26A74AD232F626A093546F9D03164585E7750ABC00754CDE535F + 83729447C6AF4E5F8EBB1F781E98D2BDE7102C2FBDF4E3F0DD73A01F180A0B83 + C38587FEE3D51F7D9BF6FB2F5DF27B40C955CBE7B15C1B1EDB0E0C9D3273DA2F + 771E5CF5C9D973BA5A61958751615B0270D343A7171E7EF2F5B70F56C63CADBD + 7F2B7C9FD7D9DADCD80018ED689B0CC49CD39903923283CCB50705FAC09D576D + DF79A07BEF91F50FBEE4B7062864FEFEF6370E00436161F84C71E313BFEA686D + E91D1802868299479FDA059FF6D6E69646DAB60BB78AA30343CCC15F70414792 + 232A39B1294033267C5C809AF237A4C592A2B5051D775ED5ADE4DF63D9F026BF + 418EA1381143E58EBC8CA1A351066AC8661CDAA75FB6CB6C84943F49B4084D11 + A011F4F46FDC71877B5B0E2A1BD5E909234E8A883346DDE3AA7CCE50F91226E4 + 036B32A75E56F444E2513F99669EEF3DF2D2FEF7FAFC3147FAC26D7F3DEFF503 + 43990D004A8BDB6B3463DAE41FDFBD3A9492AD9A53F5C4419FE64BB66118E562 + 89356ECEE96A431A01E0DBE372B3B76F70EBB6B742FD48607FE9E2D997F8B4AA + 3F6C7AF637E0D7231F91A1F040CC47B6BCC15A069AAABEFC7E5FC7D1EE7DBDBB + 5160F4527B5BCBD2459D97CC9B01CAD4EFFE4B2B38A614656DA056D674C7E598 + FAC3B9FCDB8C884FD79D0F325462D6CF34DD21A2C1F1F063CD50EF8F81712E93 + 7532B4CD14A429F27540F98A10E9C54700345A7E8A8F0BBF77EE22ED65228892 + D4941C11411912069D811B41D4123E454C352AF26F2698478F2822FB98C65464 + F5F77437B9EA0CB92D92FC484FA0240EFC6CD5AEAE4A7878F36BFE9E7A14BC10 + 20DCB47AC98DAB97B065C0EBAEBD87C19D079FDD4BB07BDF91EBBFB979CDCA8B + 972EEE6A764B0B10046F1D3EB7DCF30BC8127543A65F90F88EAF2EAB6C655F2F + EBA9BF625167BBAFDB4A3B887A8DA902A5F2938E61C25875B4E3D159A734823F + 5E5DC7B7C3B9F33186888688137E942E35868A9B1C44C212DC7C64E4B2469698 + B4CDD4711C9B0E8D128950E1AD132700A8428F4AE9E98F72DCE9622D1B48CA53 + 7FAC8360B8EB284BBDA5FA3BF563EBD16BAEF07E1DEDAFF4B3EFDA73E8EB776D + E172D15AF4BA83D63DB4E3D7AFF6E44F0EF336933DCA03CE386328D0F09BF73F + C7F8BE707E98E640BDF50FBEB8DEF5FD414EAE5C763EF3C7018E7E61EBEF8587 + 642B96CD3DDA3FF4ECF69EA3FD83B75EF7297767076F5CF773D6BF7FEB972E93 + 31545F8A6277D4979503881A0DD92CC6A10B5B3F2497A25A761552145C493691 + 3DEDDDC0EE104CA792823E28440453FD54FD393A790A3BF22E30D97CD16C7268 + B79592B86B7945502F860ACFC78A6632689B2970B458191A8590B0335F2D42E3 + 015470C961F9EFC00ADB20A64335A92DD0A4E29016642367140AFA03EC476C8C + A6EBD12709F14C47A706802E9C3F133E73BBDA7A0EF443CC57D67CF22B6B2EEB + DE7BF867CFECDEF6DA3B9080358FAE5C3CEB85E777814D50A98F7FF78BFB0FF4 + EFDA7B64C363DBF4B719BAB97B20DB7F70C06B03F54B51083FF8DBAB16CC9B01 + 28BF61ED93C053F874EF3BF2D87DABBD4DED7EEB28ED6E6A6BB9627117D0930D + 47BDE60B9F809FB0D0737000D6322F7E285F620C859FDED0A8D8B5EF5D9F06CE + 64E9F39BB96CD637F792F230C46C2888ACD258EE3C7D3EDD9DD993B615DA8478 + D37D549F537779EA7BB1129DA99D042DFB0E60F5C523D5773A3194329E5626E0 + 67971C9B7C9F4DC23F3A4B557286F28A4EC950DF0ACBA2F316D8362996CAEE34 + 52882F4BCA00D5A327AFD3B16312D34686831C6E08947C52C314826B5CF4EA10 + A2481F07A3E9A251215CC616CA3FD9F40A6B157DFC1FFF0CD089AABDE70026F7 + F127F4DCF6DF5E77F5A5B33BCEFAF482598F7FF74F81448C7400D38736BF8692 + 4A5144BBFE0786860BCD4DB9352B2E761F0728AC5C7641A8E1B2E7C0006014F0 + FAE87DAB590F9247C0675FFE2D5B7864CBCE3B6E5E0E0B1BEFBC9242B329C78C + EC3F786CC7CE83C8D5A1B03BE7CD3A67FDED9F834890B1EDADCDD2BA8F841DB8 + 5C193A863E9BA50F72620DDE2195D93A1C5E973BC00977DA3952997A9EA1B4F2 + 403A414422C8E89B3E301B598D1968B0CFA83F71E5C576EC754D84A9541AE7D8 + 7E40B2373D953055EECC069D66DA9D76944D9CAA6268786093A02913E9319459 + A2EEB2854D2B033E7EB9EC541E7FF26F4F02D0A0C1B8001538F37CCD878FA103 + 7ADEC1F41870EF32887126C85791389970F01DCB41AA1A482B2475C0B12C65EA + 1E7DC465AF08DD7B0F7DE33BBF600F2FB9FD3C94A1A040BF76D716A6DDCE9ED1 + B6F6472F6E7BE35DE4A2131200A7007F7FFFC3FFDEF6FABB7A15E896823B5DC0 + FE86C777B067A2562C3D1F600A60DDF0D31D6C2D93931B9FF8D5235BDE00AD0A + 24BDE60B17C10716409CAEBDFFF9DDFB7AD929B8757BCFFA075F62A5055C3286 + 76EFEBBDE5DEA799A93BBEFF5F6CEDE58B3A6FB87A219C046C3C29DDE579FA3D + F5EE5419A6919D94CD35641B27E532218626A97E8D4C71A42820B254B6470AC5 + E17C219F2F14468A23F96269A4542A944BF95269A45C2ED9A43A5F12123154D2 + 241A3E7A21B4F9878886CB5B9D3CD42E3976D1B64B76A9582E16ECC248295F28 + E5470A79281E1B9FE4E9C3706974188A7D851633D457782397C9343664AD8C61 + 5855352D676850417391FE783C5A10EC2F150E1594A9782C666825DEC0C44026 + 2569D0000A1A127E3CE3F28F97469644B135ECCBEEFE3416ACB85BEB9C16EA73 + 14DA5E84F81F4D2650A3528352F7256850AA62430E92C4FC9CAE56D6874307BA + 1F3CC6629BA64C6E9CD272FC03FA7A6477E8FB592C17D3AD819D89D865D923DD + 18A8C73AAF008E6C1C286F10D29C17E877EAAD963D607341858918E4E7D16343 + 411BB8327A74B8F0F607C7C35514A81D893A009734675919F0E2E9C3F082EC0A + DEC596A21118F5573361B37396E914F2EEFBE3501594248CA2E0EBE6A318EA5F + 0ABAF3A11DF397269897175C3CA9E9A348AC25802AD4EA1BA5FC0D253A0C5589 + D05025FA9392B24DBBF22B2F329165E3AF425111643F82C9E5775551594190D2 + 9150B62582A8C8064A18884E3497E8CCA9BEA7FE61B5364693534FB86B72EA09 + AF6B89792D835C09358A57B954E85B95BA3A8E1D3C5A3C332233289950390646 + 931B44B29352F38C46928327B0E90E66B2C08B67A3418515210CC2EB30228F9E + 594065756E633A6FBC53A6AFE20854B4574109311A8BA141FBDA0C0D88CF8A48 + AABC6CCA64F36099BE07C0D26268F804A0CF3ED1494D6D220268C41FF5E916DA + 79EE402A2EC2EA6DD2B0E9A263096C72896B0D244E04A96054A76D545F446846 + EABF8F5EBB62B45FBBA45FD56CE691C1FE135586EA57557286EA578026439536 + 75EB3CD3409B42B3393AB11D0A5D30BAF591E81C1765A242D3B6D9CB366CB775 + AFD25554C932660CE5CA9A80A17CB95D090DFB05BF1C834E3B820D1B306AD149 + 090CCF5716DE76450C9589D0D0FED04151966D174A65F7CD2528506FF23F5A00 + 8D4B4F5EE6381631CA549312439227BD20D462C1F1A2844B9CC280A74517CD0A + EFB6FBDDF35EDFE0B0368074F7B00E4C17A4A207796A6747FEF4F0303FF3483D + 8F62EA6FD78C626A302597908D67020D9ACD5A519913154D379EBAEAEE5446B4 + 870820CADEAEC1DD24EBC9506185F1F6C58E9184A122527BD1740F6D4C1B2C30 + 95DBC512ED8FCAB83CAD264985A19578D3322799661174A9FF11D2B0F17400CA + F99C114B98980E2E23241C93AC3CF9642BA3DF9446644630370A3F06466542FA + 5FD6FFB970CD57EFF8F75D6FBE1FD7DAD805E5B6264F3B073CC4C10F8FFB948E + 4481D46F1FE4B2512E45A38A807512B9ABDDC73A81A0B95C868E8F8CBF9B89A4 + 68F85A0492003D4B25AA39DDDEA1EAF4456379AA783512DC23314383597C7F79 + 273E6457556F74D83C1D994EDF225A2C21933EEE40DF198038BE21246168888A + 22C682DC6D68C880D22F166D36FC4B7C10717C80EAD15371CA03E7092E639295 + 58D08916A790BE3B4436B91357757A184D7ECA62CD38595E4D1D95AE479F6B9A + D438A5E5D8FF317725407254E7B9EFEEB9F69C9D9DBDB4F7EA46D24A4842081D + 14E6A65C2118482A81D818C7E6F2514E998003065C7195930A7101B903B19310 + 28AE10636484121042C208B492D0B58724B4BBD29EB3BBDAB9FBCEEB9E3D7ABA + 5F77BF9E1D2DFC353B3BFDFABDFF1DDDFDF5FFFFEFBDFFEF1F0652CF02FB3A73 + A630EDBB102A901D8EE58DB7B62694A5695A33869A84AB22B5D79D8D2CCBDA5A + 7159B378E69477CCFCB42DA228EA3CAD94DF3307FE904C30CD1E833533F797C3 + 5355F7D78CE312AD39D022E6BC5FA31843A1006AAC44C3678EE0F9B9B5A5E67C + 3884ADFDABDD0AA0503117B3BB29669BA692E04F214442A59DB27B2707F4509D + 8E3D045846D79717D26604868BA5D1131459B9440BAC246605241EC5A362040B + B196F4CC53F30DCAD2DCAC25D4BDB8C3BBD2BB280A44204992453DEA902CCAFA + AC11B25102333CCD970A43211543D4791C52A7A926CF186A60A32D5095541C57 + 05DDD641E891ACF4EBE54D91B75698FB47E038104BF57558E035666C3A66BDAD + E000EA247E3ABD0D6D5AAEFD040229E8AEBEF11EB6BB69E11B9954178724793E + 09547C2ECBA27878FA1292FD8057D45767E2A9F454DCB54011347A24ED1B76A6 + A81356F30296E6E08E024228C0502FB3F15E09CE06A8EDA206A0B222E9D64FD5 + B483C845142D4ED3D01AEF621245F2115538861AC14CDB90A568923B78DF6860 + AA391D256C7D8E3861A8795841350C0D845D8517802EA0E26A5EEDF9BC21D702 + 267EA2A1A7D3FD065E1C94828B0486B460D933D9DD4566997CE6604E3F428551 + DC436AD1B821B247D4E85128182E032FE2C4D854DEE42F0AC3C234FABCE34BA1 + DE7BE009DA49713433A3C8A3F419654C901A00347651DF5423EB18AA22D8FFCD + 4D37D4B878EA7C01D34A08E608531B31CC0643F357EE0199515BBA208B4024D5 + 965550146664E6A6C85B9A35F31380B29FA3B382A8ADC655AC653D00A80D7AE2 + 36FF214399EB3FA16DB617498C71CABF30B2FA51C83F3D8FAAB91308305ACC66 + 2E64A9938B42E59AD315A529860E864BA706B495F645ECF3C2C8D6D8849EDD72 + 0A32120449020CE5184D357463E07E43E0C827356FED82B68147CAE9EF360228 + 667E08D16ECAC53489CE57EACADF98AB18183A5750DFEA2A03C1519180369E73 + F98AAEC843F14CCF46702C23E80A3E40D22203A8C35D05BBCF73AABDE6174173 + 4A6A0F5FE8DA096CB3BCB570FEE4BC053A1C6B4004B84B4FC5ADD3865B65534D + 7A2A2164789402881A3DBE50C85BC819A451C375377734CB80478530B7D64D44 + 5E80283A1BEE42967829376D82DC6A2751CEE1A92D32219A4461BB429CADAE05 + 62E8DC395D9807682AA8393025F5F8D516CC7214422DBDC35986266519BCF34C + 4E4BBD03A8237ADA40A7897202A9AA6D1245DCCE6E4F0E4FA86A5D213A7B26FF + C4026CA39758A35F287964581AAD5424393931BD2843B1381A3DD2198AA56996 + 9A7773E752AC08A2680E40B54DE440029564FB4276A2A82DF32F589DB79956C2 + 5CF91B7A592086C26AD63677A93A98128ABEDAD4B43ACA0643615F39D2CCAE1C + 91E50575265C922D80BA8A9FAEE889A4DAAB2289B3EEA590C94597C720465264 + A5BE881087CAC84D9231647455D56DC6238F688EF5950527CE8DA8B2629B69D1 + A4707BEDDBF41499CB78146FB588E79CA6F80139145EA6D8A2A816D64277C221 + 0ADA0678DC6AB877EF8283288A4AC5C550E72172E06F1DAE2262E85C5D9A4B14 + DDC51510FD75875C040C432D8ABCB56BFA21D0577C2CCB8BE005A8E6AD427702 + 5054F444D4EBB139D55E73152B90386353D833693C9C37831ADBA3A22F782A26 + 76146A22803D93A100DBD15CDDB9AABE36526A0C560CA8EFF3F1448AEF3D37D6 + 75E27C22C53B30ED68AACAC59D2FAF8BF0A94C2D154191C730CB2DD6DB1F4BA6 + 20ABA38CD2467B53B873455D74CE9DE8EC9991F184E691643C71F8E4D0B07DAC + 6323691E52C2668FCBC9B4D037301344440B1D7A55C7BAD930767DFD13BBF6F5 + E94E4F666A6D6FAC041DD7027ECC9ACF72E9C74F8F3B761D5FD51AB6A68E4DA5 + C726D3AE9793A68815CD95CDB5A57E8E6A6B28379E3AD23D0ADA79B467F4F4E0 + 9475B8D104600FA26871A9103937AF20865930342F97670CCDCFABFFCA49A6BC + 2A4A24C1D03441B82BF2D6F33347040EDEBBBCEE4C5F5BF463EE86A58B5600F5 + 8E9ED0634273912F80D70481176FC5D14C4DF95A7BDE36FAFC46EADF942B3F84 + C445A5F5AB1AEEBCA573FBC636BB0C9D2BEBE77E7F70F0CC7FBDD5D57562DE1B + 93B107DFFBFA3663E682E9FE27DE3085579A238068F7DCB6F1AA0D4D39BC86D0 + F2F99F7DFDB157761D7BFB831E7343F30940E4377E7FBD29F1F0A9E18774B778 + 0FFDF1155FBB6E95F154CE391EC8F0B37FFA6024A6B97D7AF08F36AF5D16B572 + FEBD1F18FCFFC3EA7FF2BEABAC892FEF3EF5F2EEEEFCB4BCC21B56446FDADA72 + 597BC4AE476B9656E77E0030DD7FE4FC2FDFFC6C249682F1B31145EDE80B54E7 + 9D438F38F937C14CD5610BC6D0B993401997340F58224D12B3F1B25C14793B01 + 92636841924449C6D459370B0B075087B350DB01860351545605022321F72B22 + 56C1578558DF78AAE5E7C28388140AA7385AAA1DFB1FDCB3F3CE9B3BD1ABDBB6 + B1157CF61E3CF3D36777DB4BA6978A6EDCBEECBB775D690BA0160282EA23DFDE + F9B51B56FFE53FBC6F8C4F373F266EB8F1C8B7B6DFB0ADC38679650E4373DE83 + DCDA8223A4D8E43064F4B1D48FEEDEB4BA1D29F01FA6FB03BC6E4B0BF83CF7D2 + A1D7DEED76AA156591130A150F439DAB41F51105C5D03C4618560086EABEA871 + FD1B48A6A22C282AAD23A9EE941FCBABD13238B07EE218906A417149F36F6051 + 1E1C0114153D1114122D728BE6004A2271DA3D379C85F605C7524804BBDC4FEF + 0B9E8A267FE248490E0FF0630F5E7FF3D52B0BA879FBC6D69A276EBBEB87FF59 + F43E39D04D3B963FFA9DAB0B2808C0F499BFB8E5EB7FFE1AA28E3F4740E4B4C3 + 5040BB3EE8C3F43D5A0C4B138487F9CDC2064B553196219EF8F6D6D6FAB2028A + DF7FE7FAD686F29F3FFF91A105680DF13AB3543C2A828F280B861A59630561A8 + B64D1EE303AA84C9D9642AAE485290227C1491927959917045F585CA0225158A + 828B1951E12AB224A350002764553384E698E08A2C13922803E98F658D553394 + B6738A17244CC53D03A80B7AC22E0DCC2A02046B4901121299F3DB5AE0B59BF9 + 8FB8F9D36C1159B8DB1EC4762F547CFDFE37761486A139EA68AEFAE6ED9BFFE5 + 95DF191349EA526DE2DA76794B61189AA3A09F7DE44F773CF8D35FE70F85D318 + D68483EB6E5DEF9061D7BE5E80A13447FB38D6ED6214B270C0F82C6B66385E7C + FC5B3B0AC3D01C5D7F65CB9981A9D7F77443CE15BEC869F1D5799B6925CCC21F + 86A138B40ACC9A00C150055303723C84A72B49A126C0540489D8C8988FF1318A + 4A11F8E0E408EB63EAAAA3013FD1B6AC64EAE285D3DD6793697C3C85D35C2896 + C84C2A7EB5AA9564384EC89490981F13D33C3F8C57E06C896178B4E97B8CC1B5 + 8550D60B603B63EF20713A69A63014CDA9F6B4A48A34C1B95D7D57B2EEA2C78C + 1E492041413127DBE897CB305A1329F9835B9C30A2EBF8608D65AEC94437ED5C + 618451A0DB92CCA582D1EFDEBDD5E16C9F1EB3DE14BACE44EB56D4E68285E40E + 5D87DE3954F2482CF1F9D034033094653C4DB4E0A6FF6E048450495F5D78F586 + 256B3AE0C6D023DDA32313C951DDFA09B4F8354BABDB96944373DEFDD5D5BB3F + 3AAB873F41529C114451F46E2F0C439DC7D3CA1FD63C5B0C85BD3C8C18AAB911 + 14A658355B2127B1F828E3974AD86035E9AB28C904FC249F48872B2A4A6836CB + F3D76D683D74F0E099BD479677D49654657EBDE7B7DD3DE7DAAB9A5B1A3AAA83 + 75C323C3125DC1D1A5D555E5CB9B6B398AECEE4F1FE60581658CF847E99EBC79 + 419CDF730E9FB12F043DE1289A9F9DC0496D03972202C9D469D867C969939CF5 + D2A9A6C6CE3818332E3329084716DD307AEF1D5BA045F77E7CFA6F9E7F7F2E48 + 32281AAD0280BB0E6A3F05209B0B1B973B2CA9AE50F2973725B5F97DE354F57C + 43AC418FE7A8EBE405D3FCD28DDB97D5C040ADEF5CEC17BFDA9F8BDC99230022 + 20F33DB76DC8052F31D1DAE5355EF5FA39D21600C492DA8CBC1E97E9D5774FD1 + AC2E87A258380BBDBE40FC1104595BD2C44B5BD640E6EE7EBBFFCC732F7E92CA + 88A6E1AD0E079E7A6087154C41E3AFDDD26216486D4551C75E79D2B8174E9EE4 + 5C53C93924F68AA1E01F9E95F8B14A7CA225A0AE8C44AAB992C9B164D04F5F9C + 189D1C1A675896E7A7688AC27DCCF991F1CA70D5C544EAFCF0D0A707F689C90D + B535357E31B084A96483A19ADA2A5F28D0984E639C38953A3FD4B3BF77B4BDA5 + B9F67286A324EE8054A9D2AC713C81728F3334405275763DBC0B8042FBEE053A + F39375815411488C32BCEFDC5E66986DBC4F3BA3A87E6EAEE9F32EC75C60F4CB + 601805D8B77D13645EFEADFF3BF1D4B3EF98CA02487DFA85BDC1007BF34E8805 + A0ADB12A174389E6582E14B8EFF157255E7FA4E1CFCF4CDA8FEFBF06C3E0300A + 90F1E1BF7ADB9478E38E65D09C0F3CF9A62658196A4AA5C557761D4BA68447BF + B3D35A240F8B911FF07D87FA9FF9F78F72B349A0AEAD9D8DB7DFB0FAE3E3433E + 1F0A864209057A8110AAF00041F5906D20656B678335DBB32F7E929EC1D0BCC2 + A313A9EFFF7CF73FFFE42653BCD2D38353D1CA40514451BB528BA6CE9B985BDA + 31CF1F8360A8F15240309420495C916835434D9EA5C67A2EEFA8DA5A1789D0D9 + E1E991AA68697945753F830F8F8FD537344C4CC4AAC261CEEFAB89D6F87DFEE7 + 5F78215A1D79ECC9C747067B7ABACFFA4BC36DA1709AA04EF59D95240928ECE1 + EAEAA6E6EA8040BEFBFEDB870EFBAEDEB0128FAEF28B64828A12F9AEE8499264 + 595CD0FDE75B3B8621002804325D0DA4F3266092C44820905224EA8CAEC3EDA1 + A5AAAE76D1792075D8948AD40AC4C67AE898A51CE8CE9FFDECBFD7AF6AE8688E + 0089127C834420543EFDFCFB76E57EF3DE49288CCE51595D5572627A06431D09 + 60682E48BD950032DEFFC4EBC9B499C9BFBE72705F53557B5318E0602ECE28A0 + 5FFCEAC35C6C4E2BEDFAA0070AA373222AFAF0F5F54F3CFAF4BBC6948F8E5DF8 + B4774CD3E5DD67E7A1C3EF4EE002F1A2240ADA07EED265963A1A2B80460FE50D + 44D45FBE79ECBAAD2D4781CA1F4B8D4E248FF68C411E394FA2A8D77548AEE351 + 18863A360D73C4D0BC4B01EB32380610CA61D3158C504563F864BCD22F758619 + 3C3E98C0E5F2809FC0F8A181D3341B6CAC8D06589C2A0F9605D8542A591F2951 + 5535C051B1B191738317264713C393898C2071BE004630A96C323639994A0BF4 + E0F9A39F656FBEE69A2B36B6BEB6FB77AFEC1D5AB19E0F5477665546E14A017C + 1BDDC09204C1D2548617B43D9A28008ABB1C5B0A38BD17098296E4ACA2CA0052 + 0BB8BA765768BE0DB3C09A07A91E95FA2FCC309A4CF35D27CE83CF5C4A7B5304 + 3407A4DB35B3F773F832F2F5ABEA81341AA8282148C2E80ACFAE6F0E189A4CF1 + 3FFAEBDF40CD7640C7CF45EECC51341CAA898474C5DFF6E9EDEB8F594DA54025 + F73A56CFFC87610E0DD7E6E5699632E9F2CE4F7701D75906726856948118E2E6 + 98E9C90776BCF66EF7FEC383A7076697D91BAA7BE7C059F0994FB6B39AD934DB + 6E22069A7D26AB3751B4507254E7BD2C6F82EC5302477E35E3C3A63BCAF0E0E8 + 053ED5DFDE580A34F7EEFEBEFA9AFAF6480D4551E2545CE2534D8D2DC964D24F + E284CC2B99447CEA22EDF3AD5CB1ECE0A75D870F1F0F05836706875592686AAD + 5488D2BAF6862696496785CFBA8F0F8D0E9CEC1E58BBAE6343E7655D27CF0AE3 + 93ADE55395A18A532343B184C056447D155162D6A30D41103E8EC96A73F7C691 + B65CCABCCEBAA1279A1AA52FDEA281404A2C64EAD8E126365EB6FC6CD0FA2E09 + 62166C18B5525FFFB873B91D9B6C17E703000D45CAA78762F386519BED95CE18 + 7ADF4FDE18194F40DB6B9243466209E30E22438B6752D6ADA885DA468D1C1146 + 45B3871AE15B0B28CF31BAE75094D27603EA5E18687F9A5C9FFF888FC492260D + 1DD36D9D777FF532F0016781B00904CF23BDA333F60748D5F623BB4051D4ADDF + 97549D779E56B2E36FC93BC7579593B1F67ABC243D1890136DADF55C004B67E2 + 5565D555D58D199150B2BCDF172430C9CF90B8DF373939A1885945E6453E2ECB + 194C05AF5A299B4952343D114F4C2653F54B57D35C39C505550AD4906D685BCE + F94B53626C3A7E9190F8AA50D9B2258DF5E5FEFFFD64774FEF40494DA33415F1 + 136BF1D2A84ACDCC3B1138C13294905B0565169E31E7E3F923D7BB16B65E8A24 + 283D42ACED5C933BE1B81947A1C09A6FD876826D44E0436859C1F910EDA7DADE + D0CE55F51D4D11F0EDBC3129182E133342269EC21CE97B7F729533869E1E8879 + 1F887902D0D9B9A20E48A0EB56D43863A8078D7E602EFABC86A134C778D6E5DD + 1106429A226F81B40FBB066FBB76B91D2780B0E073DD952D98BE73E968CFE811 + 80AA3DA3F352AA87DEA38AA26848873C549E3014A10B18C4243A9F9A3F1EF37C + 658CC866F840E2624D4859B3F3DA13DD27FB27CE6E59D9110EF915518E4F4F0B + 929AC864688ACA64449663FD7E7F3C31250A024D4882C88BA2521B29CD08C2E7 + E74EAB3811A96FC17C150D4DAD2343C3FFF3C6EB6921B96DF39630CD6B3B87A9 + 109638F3F9D18FDAA2C1CA325FEA5CD715D18A40141B981EAD65C4C9F8589C09 + B1A1D25C1B2982C000928A526E8F13869900B320F47458C06F18478A64449907 + 788AA45AA178153602AB1552DD3683168B50A1D06B96CE550DEB57D6773447DA + 9BAA9C973A19BA8CFBCB42930323CED90080DE71D35ABBB37FFB6FFB4EF7C7BC + BE4EF43DF5B5E0BBADB1D279A953C1747A76E3938EA134D0ADAC18EAB1D585EB + 25AFEE3E79FDD6D6DC3A01670279AE5CD7003E9826C3A60E1C19048AFFC804E4 + 3DB74051D4A5934EEABCD73D4BD03A10D4797B1F51462B8711A6090CAF2B2D19 + 3CF57157EFC717AECE9C991CED193C16AD2EAB89AE4C8D8F5FBC38C1716C30C8 + 4D4D5D9CE88E29B8DADCD21489442E5E9C12A40CC1F382C0FB594692C44C269B + 88C75B9ADA0F1F3E74B2BB776C6C9C66A8F69AA6E4E464C447B7449BC44476FB + E6CDCB9A9A58965E5A1B6ABDFB165E928FF50EABB24A5CEC57D30457D6A0300C + C1FA66CC85A4E6A09ED75CF75ADE035013137C96D71D3A4D27089C2414425224 + 80A768D70583A329D477A30DA4DAC028D2D3F705584BF559FBF6ED9BDAB66F6C + 2DA038170AF0A98CC9A3A8A91B00437F7CFF57EC38FCF4B93D6FEFEDB629AA27 + E5DF0DDB2E6FDEB6A1C5694FBD2B213FB709DD3D8A168D8EA3C1C3E369AB92B9 + CE0597189D483DFBE2A70F7F738B272ED170E0D66B96810F904CFFEEA52E83A7 + 125B0578E1A2A87BD72EA13AEF30AD949FD7CA7FE658E570A18C52E948E4E53D + BB0FF4744F2712543C1EF8C3DB2A03010253478687B4D88404C1F92805274451 + 10451E50C8E7E333695512CB4B4A65353D3A3A224A228913E7CF0FEEE93AB66E + 59C757366F5AD1DC32353E5A5D169044F9D4D1E33B77EE5CB37AB9DFC7D20C21 + ABAA2CE115FED8D0F0F9D240A0215C930EF1C7863ECB04EB7CD14645D12C6624 + 45D02A294A92EE15D406401DD11341218640154DB2E025811134F20236DDDAE9 + 9C668D0A3A03A970697411C1D1A361F4DE3BB7DC797367A8603CD27D6BA64C1E + 45F307BA7365BD0386023974064311060900E843776DAD715C15EF7D849CE8F4 + C004C050DD1ECA90A403862EC8568A5EE09DFD679219E1E17BB6A0C8A4265AB3 + B4FA1F1FBFE1F53D3DCFBD74C8D28CE289A2C59E5942DB388FC2043AAD640EDF + 84E99EEB84ECF4D62DEBD76FB9F7D61F3E36FE49626D5D6DB83CFCF6AE77D6AE + 5ED6B97269264361B85A5E12E4822185A4D3A9543219E7850C476025C12049B3 + D3D349402445372E89C66213E9541AA043B4A1A6ADAD15CB88CBDA5BE389C903 + EFEFDBBE654379A42C994DA533626D79032686DEDBB7B7321CD97EE5958AC02F + A9AB1A4DA70E7FF8716FBAAC71D3F540185674F7CE0CAD4D3D49920C9BB8C7A1 + 3D875F2EDCF1577E923ED744498A40531EB0020AA570474F0648CDB5C1A3C052 + D08C105A3627C32880CEBF7FEAF67BEFB8C2154387C7E26FBD77E2C967DE819E + 3D74FC3C3CDEA74EEDFFCFDC9500B7719DE7BD718300711304788187C4FB9269 + 89BA6CC9B22CDF561D29E3CA8DD3A6B5E38E93F1D84DEB2BE9344D5C37711327 + 4AE22A76EDA96DD9B5E544D641DD160F1D94448A942889120F90044990200890 + C0E25A2CB6BBA048E2D8C5215119FF030E80F7DEBE7DFB76F9E1FBFFF7FFFFCB + 55BDF9D216AEDAFD5F5FFDEC40578AF3F4C2D38D3F7B7173520C757BFC2DE707 + 7FF561DB5C5C53ECB54CA5ED7B8FD2440163D29DB3D6DEA6461F24D3D96E3A2C + 6D9D23DB5EDAF3C19FBBB89CBD12CBE31B8A773C5C1E1E0BA7835F722A9AA62B + 5254DB34A9688AB39A923A9FF807235C03C33046E1D972B876F5DAAFCFB4EF3F + 763C4380BDF0375BEF59BD7AD032DA74F2E4D9F31768001348E4134EF7D0F038 + CD2151101662029D5AEFF701B333B854243115189552812E33032488BEAB5726 + C79855CA09F3204A916E3F7EE662E7D98E8B1687A3A47E65D1DDF794D6AC0351 + D9C1A3ADE3D3AEB1A9E9B633E7B20DD9593A0D48F9F1C9410A1FA1ACD7FA4E1F + 744E8ECC5F038861084D4BA9791FCBB07B01C892D26A3EDF54144CDE7C2DBC81 + 7165D1AF79416034140A52497D47E26F4EF42BBAEF855230F67489EEF6920898 + 5251E2263F7C667D6D9981ABEDF5415B47CF080D9137866C348CCE15BEFE8F9B + E25B7A6771AE99A53174E78F1FE752BD690CFDE9CE63295EF1036B4B9EDC5CC1 + 553BCEA4161DEDBC32DE3764BF899E20B0B63E2FBEA535CD10260483690CA515 + B8B48E8A17D63B46044999044BFD8885E2B0436837FD620CA03586C66A435AE4 + F4E987CB0F9F1AB0DA3DF31D268BA0E7362FC6B74CA074279FA13BA0CE27A4CF + B1860886EB51DE1C787A63A58E56B1DFF9FDFFCA10FEB736AD518805368B45AF + D64DDAC7F71F6D964832EA1B1A882025130A687051A8D5080F71BBBD5A95CEEF + F305C8001008951717072868F79F0E2864993481C4CD96D26C43C8E7938825DD + 577B66DDAE5187A3BBBF3FA7A282A714EB0DAE0F3FFAE4465FDF73CF3E3B3632 + 3E3E310190012814B24CE17221FFEFEFAFEB9EF08F4C0E908A2C78DE0B0AA39F + 492A18E9610AC45E30EBD304721470DC91A88E61266509194051EE407B2A858A + 182BC4221F8DC0D5DB58625A3A1A9A4C6800654D4AE2C2FDBBF7757CBAAF63CE + 2618792A2ED21AF4C772A2B98368F44C80A11D3DA36C18CAFEA4D39DBCB06315 + 6B3F074E5E7BEF8BF3348CC6EB8B9C8BF5E92C6830DC243986A67D47681E4110 + 64204028B4E2940F62394B5BA7857EFD0770BAC0206FAC315496684C06792A90 + FAF88692DF7DDA91E834B76615E56A9E9C8AFE6584439D9F2F46105838335267 + 244B0A4CEFFDF77B3D3D7DFFF9E20F9442E04AD7852C85C2A856CB33C4145FDC + 7EBE73CFBEA3F57737EAB2F35C01E2E4BE434480D0E9748DB5D579953514EEF6 + 389D340C2C3391F7DDB3FAE28D019B73685343F5FDEBEF9588A4BD66334F241D + 1D19F190D481A3273214AA350D2BD47ADD2BAFBF3135312E9548B35764757575 + BFFF3F1F39A6672AEA579715166A112F9409F3C4C8383E054BD437392608F278 + A827AC08CEFF7A2400D0E8AAA4F6510E933282A07EC24B854808E2F0C69F3F30 + 7EF53DAE28D6320A264F4D92D2FAD26D4BCAF6812D1CF148CFBDFE59D8CD9EE5 + 38C63F3FA53130C726C6D01B66DB3FBDB52FF5F9E05A4DFAF5876D9F1EECE69A + 0753FA9EF6F18261D84D7583F55AD3EB6CB179800806028C67689A0A12E779FB + 471CFD1607B097F95C60C8AC2AD61418E58DD5D95C901A992A3F8A8A725FD26D + 5845135E0BB73ABFD454341186D28280219567648581BFB1B1B4A7A3F317BB76 + 6D7FEC89A26CE5D90B5FBB661D3692C8CFCB453D2E0216945755B7B4B635B79D + F2E3B85E21338F4ED1F85B509C393465F702BD4208964BC4B4CAAD96281412B9 + CBE950C833B2B334A74EB590006275E38356AB0FF7E61A0D1E7FB0EB726F59E9 + 72954ECBC7BD265309E9C7431451B8ACA4A4B2BABBEB4A51515E4D7D95F56ADF + F0B5EBC1C090C7EA2395052243DEC2C533999E89B94450AC39F258DFD81EA524 + 10BA3055100C2144D0CFC384496E2B5B517428686493C8B8829B578224EDF0F6 + E5363B6555E73B7A2C5CA14A69C91C86D21A3D6B2D8DA1CFFD788FDB13487DBD + A166397BF43D3B867EC3244F9F611E8D5A82F313048DA17306E56AB684F96C12 + 8B5F612F51915621B9D81B76B68FA8622035BC1CFF5698757E7F3B4B1EAF0283 + 6CBE434E2D9E8B2B2E2D15E53AEA8E6268FCF9600054119377CB5D0F56978488 + D0EB6FBF4B93BD9AF2DC53CD877C944F2693CC3867866D93465341F7C51E5986 + 7C4575C5B0C5D2DCDA926D30D29F9DB3EE105F645AB67C6468A467C4AC55CAE5 + 425130408A04B26D8F6F0779E8F0C47473DB97DDE689591AFB20A8D4988B0090 + 522C275D1E97DBA5921579CD66FBF48C00832020A4D0656FDDFA64C30A8B3233 + 830421522A7781A1C35F7E8C93CAF27BFE4AA9CBF2A3FC394B1AA366038C5BFE + E27CC5D34F2E0E971A74C6542230E627F15028C449486385632BD0A81479607C + E37494FA94F9637ABDC41746FFC3B0FA842ED84059A5B62CD5AD415E7B6E4352 + 0C4DEBF2589795AC118B45F1885CBD3CEBD6E72A3DB979ECE0D84C9989E5AA55 + 72E1028CD2BABC9F0993A7B96870AEE4FE46536A6701B6DEB78CA69655251A91 + 00351933E727C1DDF4727F826BD973F4DA131B4B68C08DE9CD1D99CD240289B8 + 8926100FE5312DD2A0A24B1C989FB6C450510884D5215FBD9AFF50450E9FE7ED + BB6169EDBDBE65751D44BA112A58632A8131D447040786C6FCFE90D7E3C9CFCD + ADAC28BDD6D37538181A9A72AC08FA6D5313A7F7F4F148AFC3E93D7DF9BA2A53 + AA57C84542119F8F6964129FCF6B1BB7B93DFE108DA1282413891110F0CF3A55 + 8505F96AA5048242A3637E8F3753AD12D07ABA63DAE79AE543547181912F92D9 + DDAEA6631F9E686B6DAC2D9366E8400DE6728E05E5C685354F04864208142443 + E114CB003780821CEFB17393E05B78C2200461BCF179701242BAD805873A0FB2 + 3449969A64891E8F3BF89CC50265B46174DB83D5AC4715E5DDCCF03427AF7D7F + E31A0EFFD3480CBDFD2DE999B0FA88E4A131F2DD27EA58CB6F21A69E4B624686 + 7BD97F1B1E5A633A77797CAE79208CA1846F2ECA13F8D1DF36C607777249180D + 631BD32574F917AC69983927951126336942AC4BC8196F9B8A72378EEDF6CEAB + F3F49F180E2CCBA0D6142810728256163CA41B0468BEC58492A9541A8140E423 + 021405EAF57ACB88A5E1EE4693A9008240EBB8D5E998F5FB89AECEAEFC926541 + 7E46CBE976B7DBE3C00308489ACD83D9D9FA92A22277909C9CB287BCAEFB56D6 + 55CDCCCC78BD3CBE182000A35E9763D4D737D493B8AFABF5B452A9C2A4100222 + 9880373565BF72F5EAF4B4BDAA6E65497DDD638F3CE2F7FB56D4DFA5D21AAF4E + 7A9A6FF453413843675C98380C43283FC1E4D667FFA98B2AE4307BB2D471DD2C + 9A909224CEEC4205A6E69594549D8F38D742CAFF5B5B624A091DDFFDF7EDB7D4 + 3923FFF0EAA70BB9485CB83F7EC948AB926E7BB066F7BED895071A285F7F7E13 + D78A4D643F3FF8CE5AAE70CF3949A0ECC7CBCA6FFD767EB4EC08F5C28E553FFA + 45534CA158C47BE5D9F555CBD8D9A85894B6BB658ABF5B97FBA600164706A0AC + 40F5FCB6DA77765FA03134C0B86933184AF34A1A431B6B8C29751D1EC1E747AE + 3EBFBD3EBEEEE9472A68159E56ED59474D2BF5F1541408AF4DC536E756B7E338 + 63FC0097848A269F843B81A10045E54B0325F2807DB0C716B41AF38D1EC227C4 + B0BEDEEBC0CA2A1A2E2727270D3939148810002491CAC522795BDB99FC82BCE5 + A5652B5759C626A65696E40A33E42D7B9BFC338EA79E7C42A5D53BDCBEFDC78E + 0D4EDB8A059599DA2C04E3671B0C6AB5F2FCF98E2B3D97D66FB84F6F300A0482 + 19970715A29E093B4890188A22180A60081F114B1987FE404747A7DD8167CAE5 + C5F985DF7D6A87802FBCD0D57DBAB9C54129104F50AAD482E842A66790C76426 + 0D86E636878A7A04B8B4887455FBC8E90561263C3480A102F696149BDF7DC417 + 8AFDCBBCFF56F84B1C8CFE65D697D2919367FB5857EA7FF8CCBAA23C358DA473 + 46D29AD26CBAD99675CB53ECB62837514466EA001A23CDE707D6B0792FADAECB + FBE0E74FFEF1F3732DE7CD4038F5FDEAFADC273757A4E99A9E50574D5906479D + 5C55F7D4E79416284F758ECCB87CCC388D99AB5205D045696AEDDFBA71196B6A + 925FBEBC9186D1C36D03D629DC6A776B154C1B9351BEAA3A7B617FD048A11582 + 70DA27CEC5F8B4CD975C139B1A154D6D65E94E89440095E9F99901EBD4EC2804 + 7ACDA3131DDD836E1CA741D0ED9E35E8B437FAFA3DB8A7B2B6DE1B2005622945 + C167DBDB3DDE0004A3D3760749044C79F92E9FBFBCAC0C0C51CBCBCAF4FAACDD + 7B8F60D28C71FBE8079F7C5C5A502814F0EB2AAB0C7AE1DAC6354539797C3E6C + 504B650A0DCEA8E24868569865CC999A999EF6B845201F0E1252B97CF3430F95 + 95970D8F4C3A9D4E21C6CBCF2B9CB1D986FBAFB57D7D90CACC2F5B69A4083F88 + 618B3709629C497D4C9A4A30F2914E8A9E5CBF8B89270D41509F1FA7100E42CA + 753815A7CE47D945A38DB02C83FE86C9BEE397B97661DAB27E39FD4ABD2B9D2A + A5D0FB5B90857FA2967383EE1D7ED6C57A538EE2672FDE9F7A9F4B157A1FFF10 + 7A7CC4F173433462B2B6D7648A1EBBB784B5AA6F787AC1D699E07CB89778F59D + AF77FDE441D6FAAA624D151B62B2CACE4F3B701FC16E39E3D2E28144E6CBDBA4 + A24926F94EAAF3189F47CC0C9F397EA9D576452AE53D505F343068FEE2AB269B + C7A342912022CECD5F469110EEF54F5BA7B539B93CB92C40004F6CFBB6D7E773 + 4CDB0DC67C04E5E188E4647B7BEB99B3D59595211251AB0C55C5A50E9BA3ACB8 + F0CBA603272F5C9003C89065B2A5F7DAA36BD7A9652A18035D4EEF80B9B3B2BE + 3608C1985C80C804BC20E38EE9B24D987B07F22A4AD5B9B97299A6EF7ABF6B06 + 4573720018A1C7306A19534A5412A904BFDCEC104A5477DD17B981284D9C1104 + 0E064373691FD81574AE294FD3E98C59B287515AB7C230415A872D7EA6D8D4F9 + 8851A61CC5B434EB4BB722B4764F13D2748F625DC75F925DE9130BCD9EFEEBC3 + D6748F8ADF4E190873376D5AB1A4E9DC92DD4D57706FF2ACD591D2D4DAD7DA31 + 9CE20868E5FDCD3F9E4A771E6284E6A1874F0D46F7CD6AA94E4C499346D0A746 + 45D3D8AB2EC1C1B7AACE8380442CA0B160E7071FBDBDFB4FAD9DD7E9BB97A950 + 1B0B4D280464190D144F34ED0F65E5159996950601C4326E1B199DF00743863C + 53AEA908118833951A9DC1E822286596C168CC210201DB14CD505D3555552BAA + 6B8D59393B9E7EFAB147B76EDEFCF0B4C3F1C5577B7B6E5C2741687064ECEAF5 + 7E0A84679DB8DB394321F0B4DD26954933147204414224139D14F2F804627179 + 6585362B0BE6F1682D5F9DA5F99757DF78E38D1F6F685C55AC9364C0EE19EB0D + 72312D3E43423114816090B15A463D3F370384E20285008035FC89AD3EFE8522 + 4C5013837E60A266402A5D2F0E7471818C0546BF81A4F427BF6E4ADDBDC985FB + 5F7EF3AB7FDB7924BE8A499E3FA7ADDF492FEA83277B23D2972497F7BE38FF9D + 7FFE9CD52560756D1C610481DBC939B2203687E7D5DF9E4C1D497FF371FBCF77 + B5A5DE3F3DBF87DAFAFFEE8D7DF1E94453940FF65E7AEBFDB39C94318DE84FB6 + C1DD0215E56E9902155D0271BB3DCAECDCBA87B713A22C434EA9446514C955F5 + 2B1A0C5ACD94C3F1C99FF7EE6E3A767178CC110C8504225422E3893360BE08E0 + 8982302F08F1C47265863C1346519DDE50555B5FDF70178822FB9B0EB69C6AEB + BED6B3EBFDF78F1F38A2C8906F7A70CB2B2FBFF4CC238F9E6B6F3FDCD23CEBF2 + 10206AC82F1AB1D9673C4488A07CDE0026100220EC74B95C1E37E1F182411216 + 0935F9267D51092212047CF89953A70F1D39AE526656D796D7D5954B219F6772 + 8874CF44981399373ECAE4340DC789460068CAE8190D826004B8C5BE20088120 + 9AFC0612B409DF483039B0B2D5315BFA690BD72FDCF5B8678FD52C11F5647DEF + DB8976C1BC35D977BC677C71A33A2040907B0E754BC4BCB2225D92034F5C79ED + 97077B6E58FD30BA6955A158106B79C450B8F9DC003D0B5BD62D4B31BD5E2AF2 + DEE7E722BFB69C1FA4C75FB35C8F25DC7CB4F3CAD84F7F7FE260F375FAB3314B + 16AFC5E764C9FEAFE9F2FCB7F0B4C3606D597665318B0B27ADA7D3E0185FCEA5 + 1B395D818EDE89E21C855C9A6867DA8BD7ACAFFCEA445BE708FDB9AA445B15E7 + 3D7AF1DA4457EFFCD620D1CF8B63D6D7D43A40044326A37C2E4B452A42F7F6FA + CE9693E786172E7A9192716FB8C4E59014E1A5C88177917E8C5C11F4B7E46FBF + 642B4BE13F669781209455545A5C587A5751B10223CC03D72D4EFC725F9FD93A + 353436815350FFE8887DC20A403CA532ABA0AC9AAFC9024280D74F3A5D787E61 + 91802FB04E4E86984D5F8859A77D6878E86C7B7BD7E5EE91F1C9F1A9690122D8 + B07EA3466F5049780695EACB23C79A8E9FAC2DABBA6BE5CA0B9D5D66CBA87D66 + 767A721245512A44512443449BF61F08B83D39B9B9078F1EFACDEFDE9D75388C + 5A8D5848A323F6F63B7FB831D0BB7A55ADD3C66CDD8CCA544281068044000A2E + 002593430404C91063B58CA59F1C48C68D9B6CCF7DC48B3E4580F0A1180F4872 + 5C0CB072436AB834E0735F3AFE11DD0EAADAFCAFB1373BAA5320BA148C79FBDE + 7656184D6A468A1C4EACC4C0E8C2731CDEF8B3A6A6D4509417B504341756FFC9 + BE4E2B136AC988A638A74C2BCAD3B200E5AECFCEDE8451565369ECF5A7442768 + 4619DF11B3F1E7BA92357579319EA1E1B0FAB103CDBD17AF8E2D9CCF94A35853 + 971B3F8883CDBDF3848E29C444BCFAD2EC79DB62D4D88E9D33C7C36842EBFCCD + 8B5B9EAF5C5B9BBDB2222A8E883E290DA0075BFBBAAE2D2EAC579568E66174B1 + 43BA59184641B6F32D365B5563980B58628D01B54EE1738BF86D9D96093B1E01 + 41D1BEE8F138C6BE989E18EF624D96B1309A42169258084EDB2A9A1E8646FEA9 + A598D66391FB7A21BF6D960835B59E1E183263428950AA9CB498797EB746A159 + B7E6DEAD7FFD548EA984747B0607FBED363B0890437DBDB3AE5959865428E0E1 + D3568BC502C10886A21E7FC8E9F61BB4BA8A8AF2592F9E01F9F91474C93ADA37 + 687EF8DE07FCA1E0CE3FBCEBF678100CCB14A2EBD7AE6E68683018F56291F8D2 + F94E8D42E92102FB4FFC3F7557021E4775DFE7CD3D7BEB5CDD962C59870FE113 + 30976DC00603265C251C090994A30D3440DAF2B524F4236DCA9792E68342F251 + BE8FAF25E5FC52283184C3051BDB80B1313EE553B24E4B96B4ABD55E333B3B77 + DFAEA4D51E33B3B36B19D2E7F168F6CD7BFF77CEEFFDFEEFDCFAC9CECF6882FC + F15FDCB76EEDA5E3A3137BF61E1D1E1B5CB1A4850BF93EDD7532E26A2A6D3A9F + 5318B1B45CA3E9B46CD1445156546D7AFCC750F130A9C646989561344D8BC759 + 82A0703CBBEEE92CCF333D30347D6C9F0D8EBDFED36BCC6154F71198FCC9488B + 51FFBE398CE6EFBD9AB55CBEA80E02289BB17F68C23FE3B23BBDA5FEBE114D55 + F573D5E428D08C44E7960FB02A2C471A249B2C274E4FC537AE19C6AA20C0493C + B10F1E4DCC444CBFAC722261F43A212651BD0451E4C5E4A92AA0B9A1948D89E3 + 196B8D74CB1EE8075548153AAFAD123E1DEAF6E5C6300FCAE8AD5C4A792914EF + 74F0340746539C34D38B91D8BC189A9E5305C328D0B43AA756EF125D8A0F8F85 + 46068776EDD9138AC5ED2E4F38123A7468AFA42228065C1EF7F2B6CECE458B5B + 9B9A562D5B1A0A04FAFA7A515423309C4081C24706FA7AD9285B5956D6D2B610 + 6AEE5D5D07F6EDDF4390D83F3FFE3302450F771D65596ED9EAD5EFEFF8A27768 + 4C56E4819E9313A77BBE77FB77AFDDB8B1C45DD2D3DDD3DADE5ED6DCD477B8EB + C8912304C30C8F0CF171BEA9A9B1B6A1EEE8D19320AE5CB2E23CA71B7BEDDD4F + 4626D0351B379C183813241A2295AD882AA5120D592D1F17137A96FEF435BDCA + 6656F10D798F240BB224328CD1788366EDC7AC15C4D329184D29F5057F037304 + A320477601300A192B6CC97273DE535BC9475891E38DB2550FF8740007E8E440 + F1301A0CF3B31DA085C328403182266C34A933DB0E31AC3CC6303A9DB878627E + A8AC4E67238091E462595BBDE496BD19B7D58F564EA143E30B7049E299EB2987 + D2CDA0982EBCA55B64C2A821DE9951D194B8B9A5A27384A189B728D000EEA070 + 0C6700EE6EAF6D9D3F6F012F29651515848D3839D02741F55FD5583E0E046149 + 7BFB15EBD6363534D004E1A2E9724FA9DB615744112852A9CB53555161A799DA + BABA858B17391D0C4562AB562C23148DE7201ACE9725582DB4FDC78EB7772CDE + 74FD2644913B9AE7DD76EBAD36C60135F1602484E2D8D75FEE5655E5924B2EA9 + 9FD738BFA579D7679FBDFACAEF56AC5885A1E4A103875A5A163475B43B1CCCE6 + 77DEEB5CD2D2D15A1B0AC7C6C3BC0A709C2053C9465134A9DACF6651A6DA3E93 + A9C92BA5FE83E9CC0546EFB22E14C524390E1B11189E9E83AC1F69C167462415 + 1BE842824AFDD6D7AC4DBFB70EF8662EF27B3A7B03C3486C7344E07C685611CE + 71F44DC4A4F8141B8014544792E7D3E961689EF00D5D0AC9B59EF06B0186CE2C + 96BD35BF8559CEE405B0ECC1F23C275D9FD61A090B535075A9683E6315439322 + 59513D31A1BAA176A2E1510A2D2B6BEE5CCD0CF61FE91F1D8C27B50A90E8269A + FFC09DB7DF75DB1DE5E5E57C6032C6462783934E9BCDE572BA1CF6B161D55B51 + DED4D8C8862320B1A59DA28931174379EC74FFD000869182A671427C7470E048 + 5757282A54D7D6762C5CB862514B755D8D866308417897B4C326F7E9E79E0DFA + FCFFFAF4AF1ADB17DA3D9E077FF4D0D2A59D8A24565678D75E7EA5A7A2EAE0FE + 2E5F20505DE53DFCF5AE8DDE2B7A777DBC6D7FEF824B37355F7835424E232986 + A1180463459D193E356F88F3D66BFD9A024B0EC713130928CA66E918262DADD6 + CCEC489279C8F234B866B351A02BB560FE68B19BD5A234C4A0EEEA705BF8CBED + 2D536439168A1A4A33D1E891ACE22A9A8D023351C6D28CA82846E02405FF11B9 + 220C226598E3A997B29AD8FE4E8A4BC04CA0AE1A62965E8BDA4CA6A4BC545497 + CEE5A18DF90697BE212A6AC49A8BA4A233F151101053D0A88C8E4A8866A78321 + DF6BBFFB770203188A078281F9558D7FFFE8DFDCBCE9DA4A88A1D1C8E4D8D857 + 7BF7F49F394D5250A74713E7242162757D8DA7BE0E72CC533DDD470EEC652393 + A1C0F8F8D830AF2032064EF6F6043976F7BEAFBFDA77B0EB78F78E1D3BA5387F + F5A6AB713B8D799C0A89613445BA1CB82834D6D577B477D89D2E04EACC02EF71 + B9681BF3E6EFDF7EF5D5DF2F686DE504FE277FF78F37DEF8C39696BAB7DF7E73 + C34517AE5A505BD5B080476C1111A4C66021922A530D40DA805F3ADBD421A0D9 + 3530934E029D917708D3A2C8130435FD4E9FB8EA89CCA2AC33F6229F60A385C2 + 28D0B3382B183501559D4FCB82B4927A6F643CA84852EE6B6369E9953B271906 + 49371336A7300A8320688AC950E7B3A5EB1A131855344D1092CB3D35B3F6BE00 + 18B5CA1A80C99F8C0C05993FAC6AF4C63D98B9786775C02A653F97BDA246514D + 1799F53FBB9D4012476FC102C419FB40CFB1A35F6FAFF296630828B5D3F77FEF + CE0B3B97015596F8F8C8E9B18FB7EDE83F3604C25A24A69E8908A3BCC2019B8C + 32D1486C78CC37303C726AB00FA7A8F6B636D85E0F8C4F1CEF3EE574786419D1 + 6464F9D24E8028EBD7AFC3708D42406D4D4D8C8F49309E8A1CECED6F5FD2B9FC + B23536BBE3E481A303BDFDA15008285AB5B75C45B53736FF71E7DEAFEFF8B35B + 50047BFDF557AE58B3C669F774B636D980F0C59707184719A2CA3246602499C2 + 3C5951521A77067A825CF4CC424C4B93400180602D27BB11B0A9CCD6BB4C2135 + 134FC56CA5DE206033F3CD7829C48FADC4A588B2188B17114C4EA8069C6B2E44 + 1764706AEA50B2E242D747F9B890385E57533573677A1616B3E5EC2C8D6879FE + E9A23A5EB2EC21B6482247D04E0CC3F3C4CA4829B7BC30DF848A22168C3986A6 + 2447C25C67C7A2354F3FEF4163081B2873D1150EA71C1A1F1C8FCB083636C1ED + 393EE47255A9EEAA98CBA1D294A0D0208AF5B2AC130FD138E2B07BCBAAE3A170 + 70743CEAA0DDC130B763C7EE071F58BAA86331C7B2CB5676EEFCFCF39517AD66 + 63AC1C0847CE8C0918D2B86A79E0F470F7E1A3ADCB9601DA46D9E853BD7D1136 + 7AF9956BCA9C8E70D0B7FA8295BF78F2A72FFCC7AB03FD830FDCF7E704A6D654 + 7B9B9BE6EFDBBD7DB8FFE4F6773F6AE8E959BAE13B13AAAA32F3A7AA7642B5C7 + 80AAA9284067F3478F699864785E431024A40FB9E3F599C53BFBA865AEA39F8D + 8F365B8A696C34973FE93CE6A3122967458C2F19E64D0183FE9EEAB278342670 + BC71DCBE9DF125609A9F9939926199382D994A9C38AFCBE90CC4182469C6F082 + 94183D480E2BCD0D15D54D715E8179A968EA65C11ABDD9E092AA488A029B1039 + 39B681CD56B06207ACD2BDE4A7A2202719C552D1946449559D3451E3F5D0AAE4 + 4654A8B24742914834E667853E7FC42F12785D87306F59B0AC91735446C91216 + 7747516718714C22AE18EE80F005348C15517F90553006C1519A663A17772EED + 5C32E9F79596963634CE0B868213E3FE954B3A459EF78F8D39511C118486F6B6 + E3FB0F3EF1B78F05FDC1959DE72D3A7F7965630D50144D9676EFDF1B17901B36 + 6E6C694EECAFB86CC5F2F6851DB16878D417D8B061FDF76FBEA6D2AE553A099E + 70F1B80BE0F8548A300C531475865B6673CF74D6A96F0CE86506D5443108A333 + 034DF9D730A5BDCFA4A8C94791E70E6F7D750A462F2FE8333002D5F4A08D9458 + 3318356CA2ADC2284192EEEAF2E019BFA6A88671FB263A46B37D5B94A6CB6A08 + 8664686A7A76726E848DF2CC1846217E2676B3172593941B3E1501A37AD1366C + 86CF42A3379A93943E776ACA9906EB0784510D026962590B0ABFA83459E9A2D2 + 61CB5C664E0116DE2B5A2C8622C9C9EB610184631C2CDCA8808DF2923FAE8D2B + AE4150E5A3EB59473D67F30A2A9E58B899BC66024315148BA9E4846A83C0AAD0 + 2E89B47308ED2490DACA4A07638F8682678606F8185B5E5EDEDD7D62E7CE1D9F + EFDC01B38D8B445F7AEEB750495A74D945108A5E7AF9E5DF6CFEE0C2E6E60B6E + D884409AEB9F2055F5A3AD5B9E7AE685DEC1D32D0D759A063EDDBE2DCEB26525 + EEEA2AEFE0E9D110CF35CF6F502393074E0DC6511B55EA4D6EED0CA6722D6DF3 + A70CF4D4ABE569F868BE92297525268C410EACE0C9724FB737EF17D0C5539167 + 218C5A18A92F823C17CBB7CF4E1E60DC0EA8CE2BA25498BFB937B9F858644C30 + 0223701C9B8BD59F5346515531313A5FD86A7A93A419A6D8AA5FA346CDBA460F + 8CC4208662B0940F59E421B090943DD3874E5391C5194D239D671DAA3E15B562 + F43074EA09AA9813711B2FD34E5C968183455001B34FC74385AFD53421D918AD + 002C8CD8C3B48BA12B3C587C68DF316EA44F98376F448EBBED8C24897EDF1824 + 5C769A3E76E298BBD4BDE9AA8D344DA0108E8478CDA2B67F7BE1F9F7DFFBA3AB + B25C13059554309A2429A2A3AD9D24B00FF61F0092F8F8638F4175AA7FE01449 + E37DDDBD1FEFF8EC9D5D5FDEBE71FD23375F4B1DEAD9F6BF6FADBAC9EB2C2D9F + 8A2C81270829045500802174CE6646FEECCA353841F23C4BD1B6ACE1FA2CE75A + 2AF8CCCDF4D2ACA7C11437915240C15A897BD10658B242121DA3CEA83F547C14 + 0AF755E04750582889F91924313D945964A6667B1392B344738E47B50670FA71 + 28B6B881453B535032F06034AF639A44A23864A050F19CB256139DC41AC13874 + 3CE40344E338185051C3DCB04645F399988C720A091032235AB93D21BAC23595 + 07A46F6CF8AB6D5B5AECB4264AE77576CC6B6D0EFBFCBDDD7DB224762EE8B8F9 + C6EB60A35E555EF10F3FFF194ED272304230F4F2CB2E59BEFE2ACD1780CD132A + 2908AA09927CE5F537FC52441E7DE2172381899AAAEAF6A686FEA1FE88A8BEF8 + C61B0D8DB5B7DF745D64E4F4A87F1C6347BC180DC2A39AA7044C9F240A20FE0A + 9232D5DAE516B6B56A6896578925F600956569A68734F373D0724400A0B38009 + 99E5AC056DDB7CD6F868F1C32C2A5092A1500C8B478ADC082327D473DF3CE433 + 18892746967436492CB2198E276789AAB33D1E565B288B293F5B695980A4F7D5 + 005D97C690A7FBE5419425298784B0AA3C7D3E8A02B5FB384BD08E19BDD08CDE + E6C3F439A4A2F9D579902339E55807C273313427B4C193474E0FF533659E7834 + B2A8B395C2F1C9D1711BC3B81986D0D012DA515659169E0C51369415A2718EF3 + 32145E56161B3E2DC5055AB3C3569FA11814A293C379F3DD77D7D4CE1B19F755 + 567985489020884AB767FD551B8E1DDEFB935B6FACF5960763E1CD1F7C181E38 + 4D49013E386A2BAF9F4A0F9698FD0409A99ABE42D414270BFB36931348C93418 + CDAD78B3272967046080A785EE7EAF2148D60ED019E2485526548552A4C43DF1 + 2C431B5249DEA72F25FD277440CDFE54A67E26EE197E15529592F7695168728D + 67D6F5F19A5B62138E8D5B5E9EFAA9E43898ABCB483292DC2F0B24EFE9173078 + CEB2C97AA561B8BFBED5C130E84C573B9A7947D23C663940332333F516A227E0 + D8C6E11E6823A39882E2128AC918BCE30A8AC13B7C96E11D3E4F3FA43F63F03E + FB9CF4A5FB3CED2B8F343C198159AE91366120ED7347F2DB15A4D167F65A0282 + B28B6A549BD276015020398D7364162735C3BBEC5E51A3D0CF828A5A3339E8AC + 8FA1067ED3315AE543BEAEAD0E02B59779701CFBE8932DC13323ED4D0BAA2BCA + 152EDED45047696870D4E776B9B9087BF0F8B13737BFDBD2DC72FF233F269D76 + 56E445917551765501C363A30445569694AE5E7B59A22F565069A0F222FFD22B + 6F4E44D97BEEFA012244A341C551E5FDD1430FB3CFFED6131F1D3AA310AE7292 + 9ADE1214AAF6822827772CD12970C33C37560EB20C41901C1746685BAA68B388 + 66DADF0C489DE94201E97ED02C5FE651FC5336BD4D4B16F41EFAB66331470680 + 48792D495173550E5A62E53C5FE91F3E7B51E730D1197F666DCF56A3374012A8 + 33E2942DFD05E4A492104B0B1418CA3666D4A6C06E998AE66ADC2654D46AFE1A + ABF3C93F3489F7EEF943A0F780AA489C1CC79D74948DFA83017F243836E19734 + C81F502D2E96DA9C046C0565D9E7F3EFDD7D60D7D6ED83277BDDB5F555755E3B + 4D111AF6D1FB5B2038FEE0EE7BDF7AEB2D351E0B8F0D7FF8EE1F8E7675D5D4D7 + D968FAC5FF7EBBBFFFCCBCC50B3FDCF9E95DF73E7CACFFD45FDE7F271139ED54 + 62081B4E45154B1874B64B77765067F62995AC7CE3ED20E742A0E63AB3755E5E + 3933BE4006BA0204498D7C157716D39F9C19AFA853015A3FDCFD6D47646E8C48 + 32126D63B0391B599244C91D99A405FEDB4E99B131219BF95CEA6BF4C0F09B4A + D96338A16298AA2829C18A24C0AF0B23690B827407E875DDE4A7CC5669A8A93A + 9F4A9E25753E77267F646CF4C04E3BA69457D58D8FFB629381F36A6A289C3AD4 + DD3B31365C5F517ECBC66BFA4E9C204862CDDA4B05815FDEDEF6EC534F02926E + 68A8157D23A2A2386CEE38CBBEFFC13B5F1E39C92108FF5FAF5F7DF955949DFE + 97175EF40526DF7AF9E5071F7DE848D7FE2FB66FBBF7AF7ED8B674F5FE67DF38 + F14FBF7EE689BFEED9FB05A889B63475F8040F4533537126712C9E20A45A166E + 1AE77661041E2728599212FBF8679899659E69C23236BF4FF1D334723A671FEA + B76B8EB45F503FD2C3C4B97321BC6CCD9AEB35ED064DBB49D36ED1B4EF6ADAED + 9A76E5A79F7AD7AE2D429AADB1B1E99147088FC7C40DE7A9C069DAB2C83C4651 + 353CCE43183D1799732E8C0E96143146AF2340472E8A91591FA524C65445B632 + B8A4F3229733EAFB338666C40CE9ACE61E920F43730C4962A7F6EFA4C470DBFC + 46274D853961E592254F3CF1B8CBE33ED9DBBB72F50528894D04FD65D59507BA + 0EF90381A6A666B7D3B9B8A3BDB1A579F8CC702C38E1A06C121F8F71DCA5175F + 7CFD052B4A302C12E5D898E05ED076E1C5970CF9270E1F3DCE94953CFFDCAF1E + 7EE4213110BE68DD15FFF99B67E637B6C438F1FBB7DD363E746CB4AF4B6383A9 + 28A1C9D9F8493E3A9B0E43AA98AB50E79B424A922464A37AC3AD868437C34D9A + 937C6CF4FF8972DFDBB478DD676F9FEB50FCDBB7C37BF0E0C18AB56B21866E58 + BB76CBBA75679296D6CDAA77DE712F5D1AEFEFF76FDEACEB40A4ED0A6DA333A9 + A8F73BD7B53DF564FF2F7F3DF6CA1B0505072B8918176A026730453ED7F9539C + 51555995246CEA9C9C9CEFFC1C69F429D6866238228319BE31ED52116318E3D2 + 1999D29563958A023317F9FB30AD52514B2607A085C991C3BBDE6B2B77085C7C + D23731CFC65CBE6AE5F9B7DD51565BB7EFF831968BDC77FF3D9C6FDC6E779454 + 94324E17515261E7E2FD2383FFB375DBF1533DF7FC1F7757021E5591ADEFDA5B + D25B12B2EFFB06846058029A008280020115C55109A3A0823A517C0F1597E463 + 74183F19D051E6831925A0A2C8801D41512410240A121292C816424867A743BA + D349EF777DD5DD49A7F774647FE76B9A9BBA75ABAAABEEFDEF7F4E9D3AB5E4E1 + 09132722288EE09CA5CFACBC67C69C7B7E3814342A40121C0814F3E2375E9D98 + 91999A92025EE9C284C4EC907008610EECD97BB1B1FDA3F7D771493D61303DB3 + FCE9AA364DB3FC5C882808E70E2C31C231CC445837FF801D5AEFEBFDE04D100B + 4E0324E5701C764EB3C3555BA10E14D5859CDAC1E81D02986E0468F4148A4576 + 36DDA0F2FB6A6BAD07C7A64DB34D318DDBB831B5A868CAB66DBBE3E246545A43 + 7171584181D233F8022A8ABA50514A638E528A0A47B23593F54292F4D3F5F18D + FA915E78D384268C344D9A1739634EFB00BA7597F04DA3F73801E14A47318B3F + 366B5F3060A31461C2B83C1F2697467A0EFA6354D4835C1F751EE762571B9BB8 + A60E8930BABEA92D3A2478E1BDD3664D9F6E683D7FACB2BCE8E517B584BEFE6C + 5D4A4404EEC7533429CD9B15E37C6964745347F377477F3EDFAD16515F244686 + 266666752A54E59FEF8261E4F1850FF94784B23863EA5592BABE858F2FB95877 + E61FEBFE3A75FAD40977E742085C7FF6DCFB9B3F13732850D1962D5B2353C724 + 4525549F68122767E3DC816D135104C6509862ECBDF1BDDC0BDE46DEADE018D7 + 3CB568B6E1D861A72775DE9200B90353DF6DA3B72FCCB64624852BE45C9381B9 + F6B2DC09D5D7E79AF87B49098051FFD8588E44E2171B2BCDCAEAAAA8007D1494 + 9505BEDB65B284C24270161CEBE5F296D252DB85869696F6EDDB6D4F92343F3F + C6A2E3F7C864DDA5A54623C170B8A2A8C8982797085353B4171A14B27DBA0B17 + 7911E6F8F9BC883051CE7846A3315CF0C90ACC322C431041CACE9B3C22BE0B6B + D98F021CD0A401018866F51CF4C4FA7C4D757EC2DC6AF403CFA5791B0B848518 + C77498A68C969019A87355B0A7AADCE29D5725DF96E38F53519FC51543ED0441 + 70319FE1C014A12396FFE98984B0207F1C4B1E7F5793FCCCDA37DFBB7FE6F4AD + 5F6D93571D6FAEABF797883AAF76EFDAFBED8C330D93C68EC67078F9D247EB6B + 6AEF193D363C3412C5F02B1D9D9B3EFCE7C51ED5EB859797AF5AE91713DC78BA + FA7CCDA982258F579FFCE5AD0FB7A697C9BEF8F293A484D885F3E6D49EAC91ED + DD9B181E8E62D8A7DB772C5CFC20AAA3218301120FB5CFBC81A8897252B13DDE + 042344299CCBD569FA063AC75DA06617077CD876D6BE19FF1FA698CEA6E4E49C + 2EBFC99512EA81ADDEFD636212972ECD282A92CB64B1050520E587FCFC69DF7C + 136539B64A705E5EF5B265D6E38C8D1B83F2F34FE4E7AB8F1E4D282E4E78FB6D + 6BBA242F2F74E9D2CA47964AD2D327EFD88A5988A734275B989AAC3E591DBB6A + 85B99C8279E0D35F557DA1F0195F1A491244A0EA0AC2DCA0F7CB751096A1ADC6 + 29D6BCBB0F81A102775804BB4B70C7543D01996BBD2C0DEA6318CA8CE30C3D94 + 73E8B101270914E7DBCA76578CB719B0E1CD0EAE397CA7A2239D59F2D0768B59 + 03E111FD4D97EAFB353A440C3FB8604172FCA8F23DDF1C92FD77C2B4BC499919 + BB7E38BCAC6CCFE449E3105578C3B9C6C6CEF64B3A155979280083C665A62EBF + 7F0EF2D022541A064A32A9D531D131AB57AF5AFDCEFAF73EDD3261464E6ED874 + 1E07898D8DC3598394C74831E44C4BF7D596AEA4D83095A22D3022343967D298 + 844CC993A1279ACE51BAEE145100A5EC8643A220D87AD39A5D9E2C5EA4348AA2 + 6E7E00E40D3ABD832A6BD1EB410514499863483BBD641DFD3A1DF174889CDAB9 + DF7B41F7DB5EFA44811A7F494C5BC34DAE173050EB81AAAE4E69D1FA0186B6C8 + 645AB93CEED1470186B6C964674A4A108BFA1F5B580838694349897D0901F9F9 + 004335B5B535D3A6316A75DAB66DA18585517F2E4C5EF934C0D0CB1F6F6DFB6C + 272E140A22C24C1D5D60486256ADE896EDD35FB848F76B7C69214533B841E7AF + EBF325F3AD120B84D96E58E7A5793ECE1E79D4E85DEDA46675DDC4D0B499025B + 0906EC40F51C3A9030997738C770C727D66D7ECFB340CE78E77AD2EE1F047929 + C0DADA61FA6484EA3CC8C3C5304543557F6B73465C6C9854DCDA720967D57C01 + EFCD77FEFAAFEC31EF6E786FCAB765118989907F4074EA181C136E3DF08342A9 + 5D38636EFEAC59521431EA4C38CA81B57A0A817B54CAD0B0F0850F3DA837197E + A9AA8E888981082221211E4E4D375DED9E9C7BF7DAE79FBDD8DC1C9F9C0461DC + 3D7BBF3DF77B73D153CB11913033397EC33BEB146D6D175AFB5B188DBEAF5760 + 3707CBE5603A8311A8F80E833AAC19C7A7B50D80EDE240AFC70743F1BBB38B7A + D7E847A6D4DFA6D2129914A0EE1618B437817189B3B27A2D88199C9F9FBD6913 + 38B864D1D6357239F8BE585A7A6CD932D0A98B9B9B01573DBE6C19A5560318AD + 5CB8705E7333405227180D5EB0007C37BCF412C826888DD5D6999D5EA317CD03 + D0D929DB7779F3565014ADD1129D660C55579D8A8156183BBABA3EFB12F6CDC1 + 823211A3540A98657DC87BCB84B59B8885117BBAE18DE8D9B278227C6E5369D2 + 4813066B080C08F6048743E582B691462D65DEF58D87E1DC11CD6C78024E5F16 + E65F13151DB9505A6547DDB1FBC6A63F30EDCFFDCA96AE6EF94F0776AF7EE1C5 + C977E7AABA3A262D5894929B0DA995EA6EA580230E9B981B1212A63879B6B1BD + BDA1BD3D33249CC0E89FF694B5745C0D89098D090B435846D7628C8B8D0D8D8E + 89888987047CD8A8FFEF673B0F7FFFD3AA152B9E2D5A4132242EF003BD2B9206 + 21A60B7A6DEFFB5F7D959E98FEE0C239D5EA9E0EF9AF4C54204AF403F5CCFE2E + C0310CE80EE6705CCEB7C07023319CE038D760D0F2E08165172E71F15CF1D415 + 4CEF7C186D881F1B73B3DC45679C3E6DFFA7AAB6B6AAA8C8F6A7154C81F8C7C6 + 2A8E1E252C180A8454ABD57575A3F2F29C4A13656581EFBB8E1CB14F34C7A682 + 204347D7353695A4689E41C3256E634751CBCF1D54A807C41B6BF39EE0FE391A + 824A8A345284DE064FEE0B84DD14085A489A7440C1C73802C41ACFCD836DD213 + AD75C03B0FE7BCD2D51B4845C197C88F37736206A7B5219427BAAB60F617A53B + 753A8D442A59FBF65B0C8650573BB151C16DE73A5F7AAA2832317DFDBA37A7E5 + 4DDFB6EF90ECC8B1409C0F4D994AF1E08B6D6D3F1EA9E40B904573E736375E3A + 55738AE6F1C2939251889992770F2E16FD5675EA5FE5C7A64CCCCDC81B83F379 + 10814208FACA9A35858B16E1427ED9918AEFF71F9992999A1815A2BCD2DCA860 + C686A69A7452AEBFD0D60766182548374CF48FA2A74DCCDA060B31CCE0FE25F6 + 6E4D8330E968177500531FD6D4DF09CA7D4768DC9493076E4E5DE78B8B596BB8 + 1C0B86B69695B9A5C00040FD07557EAB48B2B2F483206B138325A575D3A61E99 + 0CF4B486C57AAF28A3664DCFFEE7067E44D8B5B4138C3E4590113D9DB73D1585 + 1C60D46D6BDD1B46DDE4F392006A013CD4B7E928F705022C258CFD004931F3AC + AE8BB160B8F923B7557AF525B88E54D41B8642E66D7403E6DE3DE1A3FFFDFC3B + 01677ED0BCFCD9B34D045AB27EFDEBEFBE81237C45534B842488C5388D573AF7 + D49DD3F42AB6FC67F3EB971B3FFC64FB0F470E9E6D3C1F9A1A71BAFA77A3C6B0 + E69147674EC9D35CE9499106058E4E0B484F268DC63EA53200829E7EFAB9B3A7 + CE745D91F75E6A54283A6252C7303476AAF26454546C4444F09AE7572A5B35ED + 5755A891084F4DF97ED7A194F42942043322D13C8170A0C1962DED59776037F2 + D1740A2F02A318469126DB3A54D7B2ACCF91273085EE74367A655424873406A9 + AE95BB79172B6D0472BEA4C47E4DBD2739B769535671716E69694D51111873A0 + FEE36271E3C68DD6B3CA8A8A208BDFBEAAA222A2B0509A9FDF5C524269B48694 + ACB4179F23954A4AA3092F98A76D686CDBB113130A03268C57965758AFC584FE + 900F02A8A8BFB6F7B675141D12F35AFAA1D80F8C3DA4BA42836F715DDD52369A + 22593B1397A702DDE3D750024B593CF3397C3F6BC88C116AF4BEF939796AA497 + 9028AEB5C2DE8A741265BFBEB1FB9C56A7EAEAB972FC44EDA2179E467FAC3C23 + BF8C4BC4BF1DAAF8F4D35D7F59F36AD6F4DCFF6CDFFCD187FF1689C50CC2AE7E + E9F9719949B5F5F51F6FF94A476827C62648E3057326E646A7A51009B1B8C80F + 0E0F87383844B1A45647B1704AD6D8AD1BFE6E440CD5B57595FBF7FFCF9A35F5 + 0DCD8B56BE363E23B3ECEB2D8FAE5C0961A233870FFEED6FEFA44C1E3F2125B6 + A3E6487C5482C9A0E3F9096DBF11C75082A4870BB7E00BF573CE03F47A923471 + 794330CABA8BF1000F9E189A64720A947727F04E37D2909015D6DD065E2537D4 + 300A407044F9018C461714C42F5D0A3ED614756DED258B2DD55E3AB66F0FCCCF + 0F2F2CCCEBEDD5B7B408626240A27CC7CEDF5F2F1EFD6E71F29A97C107A4F494 + 57D86034FCC9C7C29F580206F564C65D9E6A37BB409A0C6275CF8DEC92EB232C + EB306E2C4D0D06F5719A347527BE59036D8AF9F017FAF60C983DC80C0C872774 + B4E47AD2E87D9A5C7269C50816E643BE40B3D785F9BDBD6A854651F4F22A9E28 + B8EEEC59B2BB3B377FD298EC748E30048638BB0F9F48CBDC9735694CCECC7BB7 + 4FCD23D57D28452312F1DCC58BE7CE9B9F3E2A0CD75233EF9B8DC10C82A124CA + 42E9D1A44848984C1CAD91056A380B73C19F3DAAC8843848CCF51309A2F8423F + 0E5FD3D78FF37171648851471FD8FC51787C4256469656C374C8BB1F9A3BBBAE + 41A18701FF27016A0D6C9D6359650F53343B18D17978E8F465402D7089E11CA3 + 41E7682A701BC869B0EFEDC17478A57E642DBA05228F4C4A6BACB9D1B59827D9 + 2DEABC27D1CAE5D5C5C55D831EF5445FDFC1FCFCC4C2C2A88202D0711D32D9A5 + 0F3EB0055E125BB8AD55A33FB36C596F45457041011412A6ACA9EF28DBD75B55 + 03B21D5FF458C2AA15FC88706347A742B60FE4ECABAAB9F87A71E08C7CA2A3B3 + BFAADA4B6B2992F2D3A871BB980BB7AFB04EAE7A00EE0814197615AC8F440FF6 + E55A5F99A35D3673D07C034001EB564EDEDD45DD36C1A385D4CB259E8CAB6E7E + C6B0E64247860B200F005B4ECE688592908AC4ED972E27E56643081F521BC74D + 98B277C747715151AC4EC3E8756850042E4521552FD4AF8128AAB3B5F5AEECAC + C8B02808C35894251986E5725106426896646184CF414D106B242021C27291D3 + BF54256565040406FBC33C56143079FAAC6F23A343E2E27B146DAFBEB13E2E32 + EC8B1D3BE6CCBAE744FD6F04199E3775C61135ACA32927830586A224CD2088E3 + 94BDFBB1F5D5CB038C2782223002D30C651E50C779254B57591DF25C7ADB6E19 + E99DADD4770547CF2DDF79A36B31B4B43458D4794FA26D69A9B1CCC2DB26D001 + 925EF8E0838B16F4B49F589F2893852E58D05F5B0BCAB426766EDFDEF2F55E63 + 48244720B0D1304367D7B9B525F0E0B5D6C4EEB2FD57CBF63B15E824E6913519 + 459A3B63F93C0B39DF9B3445201877287699D9BF9382ACBEA5B0651B1D0C8360 + 1FF661744A47609876CAE09B89C0430DE6FD478C5A840F38A9F31334E248D21E + 1AEFD38415ECF95DE1858A3A8A1F4BD026D3A95F8F452567B310A351ABFBE44D + 7A03122009F69388673D5108A955A4B2EBC7F2F26E85EA817B67E9542AF9F90B + 6352523F7CFFBD9098F095AFBCCC09F227519820290189506D2A98A3F38B0C66 + 393C86214E54547EFFF39119F7E6F6B7B79F975F9A9677F79ABFAC9DB5F0E1C7 + 9F7C7842B014A28CCDFD9DE969498C11D399F4F7CFCD8D8816EFF9E6607004CB + 448F853890858B0EDD24188A50666735BBDE74C7494748FACCCC13DC581449A2 + 280E0DF25027D7272B3F750253981DB014DDC1A149E491C9628D4ADA770768AF + 3609CACB6B2B2DFDD531A689512845B8D7271009A0A2026D1F46FDE13D426E91 + D8AC8F2C4D9346F35E49948934E948A3C6EC72441868CA445BA6DA09633FF866 + 1D97C0DB95E37ED93B82B82C467269802F9ABE3D273433678366C861CB478DDE + 8BD5D2E75D48BDD5E3958ABA9DF70F0E14690D0CCA9572FCFC9A3B5BA353530E + 1C38B4F6B5E2EE9E565D6F67F59E7DDAAE5E1CF7AFD87768F95BEFEF2EFDA4AF + BBB3A3BD1563A1C5F7CD999F9BCB2548466B042C51C0E3210872FAC4890DEBD6 + B554D5C32857CD125F7F5BB675C79787F7FF3475FEFCB4DC89B84804E1D8F143 + E5A45E0B11468866E352D2FEF1F7F5C56FACE5F151D45F101694A46AEDA93AF7 + 1B81C038CE832107FF4CD8A2DA0F8688B575086CFD552E47BE7EC02538CEA148 + 021E1884C154D8099C5DB684F21C28EF36D5DF5DA5392A799479890E7DFBAED1 + 7191EFA452C42EB232101AE7D23C017E3D765B02D84293A4A85F79AB7FA5AFE2 + 16BB00216518126206A229BBFC48732C3B86A5CDBB27396D32E15ABE0D310616 + CE7BE67E4ED7F966226001DD326AB802A720266EC070A4934B30040DA79BFF11 + 2AEA5658BF40238B9C6F6D310A84D3EEBF5F32667CD3E6ADFBCA8FBDFCDA2B26 + A8EF85175FFAD3630F3EBB7AE5922796602636212C2A6BF67D716347F7549FCF + 4E4A6331A3A94B011BF458502002D406AD51DFD75F71F0607064D41339E38412 + BF79F366E74ECE494ACF088C4B0ACA4867B5860FB66ED6757719FA951B3EFE37 + 972F79EAB9A7E253E3A004EAE7CA4AA541C792B881263862FF5E833E442276ED + 1A0C43C01BD6A6910C63EBF076CE317C3D8E1B00B25B3B6B888FDAFD6DA7ECBB + 32D33B58A99747A6245DAEBFD5ADB85631FA89110EE7BABCBC488AF6D3F5DD01 + 13F436717A790CAAF22C3334ABEE56C966CDA1430C38D7EAB7307C5427A0B2C1 + 08CAD2B473596E2E74279E357DD012D2A4B7ED883712672C5FAD0AF697789BB0 + 82A03F404541AA9EA070AEA0FCC8B11C1A7D7EF1129024918C4A1A1529114930 + 3EAC56F77EF5F9E78F2D5D343E77429A3494172C3652865DBB775F3A7862F563 + 8F0487094C3424C02184C7217BB50441A567A6CD99393332380442590E8EDFBB + 683E0434658C07C69A506BB53DBDDABE7E6DBF1285C983472B7F6FBD7ADFBC07 + D2C725421CA2E2E78AC3C7ABD7AC792D3923AD87C33598F4188EBA5A3B11B381 + C6BC6D94792A72B8B7DDB0FD61834214C50095A6698B79D4D649ACDDFFFF47DD + 9340475565F9DF5F6BCB5EA954F610CC028104C4440242DAB00441547057463D + DA4E1FCF34A3CEE9EEB17B7ACE4C1FEDEE39F64CB73D3ADD62A30ECEB4EBA833 + 8A0B2A2D82806C6191040884EC216B25A9FDEFF3FFAF4AD5FFBFFEAFFA9514A2 + EF8484BFBCFBEFBBEFBDFBEEF6EE0B1949639869A824C146818A815FE9326C2F + 6CD9F3C695C662B625989E6D4253B198F1104DD399132357BA41499469A7BC62 + 97B2FC719C1B9C20B48AC79760063E230247308263FDBA9023BF622A6A805316 + 3143158A23E1537D94C882C4F7E27E4BD74C01017DD6695C1495DE1478554E4E + F694CB0BF120E89A3491F4F2C6C6D2C28AFCFC6C080EFCF2C99F4E5E1AE55DEE + E79E799630A73FFC8F3FE93874F0C5DFBEB0B97955963313409EF4B434BFC7E5 + F6B8108B23CD99E7E3A9ACDCEC850BAB61C00A5C89748D7DF8BFEF4D8D04AF5E + B1B4F6DAC5BCCFF3D99B6FF777773CF0C8C33F7DE2F137DFD9855B107135152A + E73B8E770E749EEBACABA9FDECCC198EA469924643F9B395460D0C41688E531E + 976BD4BB1643DDE87F918879542CB29CCC517914C432D3449E7ABDDE53B64AF5 + 503CDE078202B150629615A073256FA2AE1000C403ECEC39853B57FC9D56E403 + 30044C0BB7599C4D0FE281D2810623306121AC664DC3A846E4A4E67F438561D8 + 608014465E423107C48316DB2D095A1A07AABACD2A0A7061AF91188D04B4AA25 + 2A0C13C4E56C543F1F28246E56C15984546D9A4AEA7B71461043FA6104D3F27B + C405A8436103CE255DFC12CAB2B184323381A2DCF4F2A2DC9AB2EA57FFB023B3 + C0BEF9BEBB16F9BD8C6F9465A84DB7DE040549DFE8D0E2C57570467A80F7CEA9 + 297FF68F4F2DB017E03C13F4019E22FDE2B823610664D4CD1BECEB87314B5649 + B1A03020C21A13F01EDDBFEF8B8FF6DE32B0A9D09EE9282DBBEBFB7F4DF983B6 + 74BC64F135CB57AF210898F7FB016E6E59BBFAE5FFFA1FCFB8AB71C9C29DAD87 + 210C47436940556412ED980815602004D227D54C8AB8B99E65A6777946F58D48 + 87CA98A95CCD170B2290D459D1AC31A592667C9A16726D687160CBA1C561A3A6 + 742B8AA1BE09B721361A77827D136C548B4F0905C5311381231A8785C492529B + AEE1C24324CDD0415AEADB19B351CD6E89D75223C346EF4F988EA206CF409A5E + 92A83746E706CF8BCC0B46A673512A9319472EA6072680612E14071605182BB5 + C93330298810E3E891C5E54B530AC530195D64C846012A1FA8816BC475463054 + 9308C800AAA9A368752CCC70EDD03F9ECFF18F5E5B463435D6CCAB59FEDCB3CF + 9FEFEAB8E5EECDFEF10136E0C36073607C1247B85D9F7C7AA8F5D89A0DEB32F2 + F2598A2D2C2A991A1E3AD27A6AD0CB0479A8A0B0C02CB0430E32E5171069F6AC + 0CBB7D412544A0802451882F75E62FABAF5FB1628523BF40583AC7DD9E004553 + 143535EECA713A789E1100326E0FC7704EA77D7E7935CC782F8E4DA00575E9C5 + 95928B29EC348280620916381D0CEB1F649FEC8F548D0C064C668B1C80E2AB40 + 4ECEB0038A0A784FECDAF18DD84653B45CC88BC07EE8E095098D9CC9D9F4DA80 + 20F1BC74149941455561398E6558F1BC5460B04A82265C861ED3000C5481F15A + 2FC485216EC9071A7ABDF6DC825141C03133D37906121A460DD352BC210618E0 + 4424FE4957C5320451015951C4B3097980209A6F1A126F95C3576073C33D9D7D + 56B0EEBA85532C5D30A7D0ED1E82A6BC388C2339D6D6FDAD1FEEFC68EB638FB8 + 48EAE9573FAD6F585A3218FCD7DFFC5B7EBE637CC275A2ED1C8211CDF575F7DE + 9251595E6C629189339DBC3DF72A4179379B38C0721082E04455437DD51254E4 + 7C38C106A84F77BEFFCAF69756B7ACF6F9036BD6AE39DDD55E5156BE6AC5CA4B + 4317EAEA9664E219A70EEFAB9E33B7D762A5FD4141E98C6990C8BF3014A11956 + 116814677BA8D64DB57D120004C3A4ECB78A4CFB4AE1342C9946C5D228192FE3 + 9C315892B56788BF3033E11B9FFA16203FF3028B67A7C12961CAC29062A8389E + A55413C9103C90A08A78A631C9B254F8D10C604A0790247845A9D3A0B8896569 + 8D7C284699A82E96C2F463681223D038462A35A02434FA309B64195A107F30B3 + 3572105B5C5E9FD861252CE3FD83977ACCEC17FEB1E37DAE1B6EBCC161B79E39 + 7A1841C1DCF9F35F7EE5F5373EF86CF94D37AD7FF0E191099733CBBEEBCDB7FA + CE9F87606E6FEBC93E3F1D84A03965A5E37E7E648226086EA8B33B383A622BAF + C0799CA7DDBE2937E4F1E22C63B1A5FBFCFE49D754E19CCA866B1B8E1D3C60CF + C91D1FEDECEBEC7FF5AD0FAACACBD6AEDBE8F7049E7FF1954D1B6FC975E4F293 + 9DA4D707FC01C22C3F1C37DA1C61E290140D23022B83B51A9EB0BBC2464E158D + 851929E8F56828699EFC2C1115339DD6F1230ABF116934D17C48AEA4664A1366 + 93CB379402F8574A2C139D1E2836035134A6701CCFB2AC780CFDCCDA938226CE + 0484982E840EE8D64F9891243CB2B9881DC398F0071014632836DE2B9A2D8C65 + 77B13A8194054A756A5012DBABF438B9EC3E4B53E2D6FEA00F453080A05A15E2 + 8E8218745888B73A0B70C265B559DF7CF7454B4ED6CA555BB6DEFFF0C0A5C197 + 76BC84A28478101266CA2D5DF0E3279F847A07B209B4BEBE3AC8C3AB9A96BDF4 + E7D78726BD77DEB6D9E5A3F6BDFBD1BA0DDF73E6E7233633A0483648085F627C + 019CE208DCDCDDDBFBFEC7BB0E1F3CD2BCAAA5A9B1F1E73FFB29C3C34B9779CA + E6CDBFE8EA3B72E0204FB10343A3FFFDC95E5B8EFD8E9666619D9818F359282A + 4D4E0225EA821A27888EB0EA8941261A7D2EE395BC00130DA77096777924B768 + 0C3305D312698A95FAA4E7D38CE6B0208A3282004633A96573B3C8D9987C6B81 + 74F0612AC24545164AB3B387937413665741104575A3E88D17D14616329E259E + 3361A937BAEF484BE8D360D686A6A614842325CC8F3A46B448A1ED05D08118F3 + E150F616816E54D04B5833E56FEAB1EBF8E2ADB006DBE6CE9F18D95D54B5B0A8 + ACF8835D1FDF7FFF3DC32EEF91D3170394E59E07FEAAA42C7FF992250C190034 + 4C7A47723240A6C50943180CCDA9B4E1144F3328FD8777DEDF7DF4941BE2BF7F + C76DC327DB9DFE6061730349F10440D232D3218A3EB07BDFEF9E79A18BE20F9C + EDAD9E535E7EED9229F794A3B2082D29B877CBE69AA202CE1F3CDED1E985201F + CFEFFAF2CB73E388A5AA06C3511D0289D70882700C1BB3D2243B961453524AF5 + 448BA451848A86D9A7F20A84C552E9F23B19378A9B0886FAF66DD449A607431A + 3D9C128D5E54E9D96411487D9392795D10453996D2AC92480A8D31942556A015 + 95E227674A9E420A4082808D402623C275D21A3D24B1CF697384A07B327430E6 + 8CF5699A6853567B63BE35DBE9EAA24E9D3EB7E5F6CD878E1D25D2AD39195647 + 463A9E6669A8BFB1E1E696579FDB0661F8DD9B36920C8F230419F09E6D6B2B29 + 2858D2780D8F10BF7FF195FDFB0E8EF2D0A71F7F545DE874A21662C293EB2321 + 8043828264B2D2DEB1AC6C7B5961415FD78020A8BA86877886CDC8734259E9D0 + 94AFACB0BC748343980BB55557D90044793C6DBD5D87BB832B2AD7E226530C0F + 95992361408BEB70C89499A4ED5F59A25BE33122180844CC9F40C54C956A7E98 + 934A45F4D4E757346B7C3D86C16BFE51F59EB6FEAF6914D2BAD2EAF318800032 + 67D88446043D3EC5A0D3454CCF2BA41E6CB370D3439046E3E3414309CC4460A2 + 346A7473B766D788A2284D0B9397D1B3B5A9A0015D68862C7772A26920A435E2 + 811262A888519F5C14670DFF889E9B1E28E08A8B51282F3D50BE177949E6B00E + 2B63E2367D322AC00105D0699FAD1AED983D9C11E156F95941A2C14C00C40204 + BAC0801C4B3940E5ADB0C42D305226F49817AD7844687F620C405993B542EEE5 + 1704814203EDA70FFE65F38DEB169697649B7118E21737D42F59BE0C4EB73294 + F7F1BFD96A4690E6DB369B31FCE285DE679EFBD3D7EDED2D1BD6991DB910C006 + 87473B2F76B1BE00E5F60649FFAA954DE55755F0B809E131FF84F7E2D9B36D17 + 2EE6E6E62E5A383F0F856E5AB962714D6D5656066CB31D3B78ECDD77DECB21AC + F6BC0241DAB5989179C58E059515C74FB65F180D96D635E299798445BE4E44D1 + 0FB5800F9D64306D1E05911F20BF8074BCF3D11722578270E3F779CC56DBF483 + C8AFE94E547B9F0015F01EFFF83FBF43D268B40184D51498F2A60ADAE5C13501 + FC24357A5D68A2244A7FFB04F30445CC289FB00312CAA9A2B8201E48C74573D6 + C5A8E41AB26DF231AA460CA3614B5BE8A0D3F056C5C42602A31AFDF45D14374B + 390744218893324D6166750A5A100FAE86C4CB928129D7A47B78820F782B9C99 + 9EFEEEF51B5BA02C070BF17E9F4B10B41ED9FA485D7119D9DB7770FF81E7B7ED + D8B5FFC43FFDE0AEACB99594DBCDD2FCCAA615F9A5738F1F3F3D74E95255DD82 + FCB2B2346B268FDA00400F9D6CFFE75F3D35343579FBFAF5776F6AF9DB87EE65 + 3D744E76266A361FD9B3FF073F7AA27378B8F8A95F5D555D3374B1C3996D7D68 + CB9D6D5F9F6B686804653C6E360B439BE378180672062AEF33F1A83B86D352E8 + 0DF5AAF22A94CD1E089C346A1E8DF892A0884349219646E8983A369A5ABE1417 + 1A8A635480BC52A825FD85587E20F495E8A2073381262B3C279D6E9930A94092 + 1A4F2AC805E25C098C4F956934B13340EF050196A047C388D6739D3AF2BDD02A + 348161203AE8495A260F19C2C690314265F8147DC928CE48D1AF403A1905252C + 20BC1E033DA82130DA48093C81F2B49D39BDAAA4C8919933EC76D1143972A6E3 + 83CF5F5CB7E5BEE2DA3A14436F7FF087DCA5F32F3CF5EB7F79E1CF133CDCB8B8 + 1632671E3E70627E6589D08F663CED9ADAFA85B58BFA475D00414C99E94118B2 + 6464749D3EBB6DDBB6FD3DBD2C041D3F717443F372DC96819A4DDD1E1FD13D18 + F07B383A20ACFF14C4F67476B49DEF685C50D335DCD5D6D55D5A3E1FAB76B6BA + 288B9960581687B128BD946D10AD62E2A2A54BCF84A61B5E99C60912E51B4418 + 5261C545FE08F0511D5F662D0549D9462F3F27325AC4E48008CC90DF857C9A7A + 4D10C34567BA80C97A4258AC39964DB44537D55D372B339458C4638DA138BBE6 + 0D0C7F3911E8202CE8B649AC0D7A7EADC48C2EA1DD567C858F59D58031166AE0 + 96A478A222F309B584E70581143759F53D5A09F8B250CC664B7575A99D9F6429 + FEC899734D4DD71DD8DBFAF4BFBF5454B3B8B2BE49A2174342D49C12C7DD37AD + 3C3938353C32F5EBE75F9EEFCCFDD9630F365DD7C00589F151D7A1F6D6611F79 + 5DFD523F49E279692CC7F4F776E338DA5C51EE7466352D5B565A54D67AB2FDE3 + FD7B4FF5F4153BF37EB1F5A1B75EDFFE75EFA5EB1B967DB1E72F9FEDD983F0C8 + E75FECF642A0A3D3336FC3164B5E1946585829A02D964F46EE088C5492586165 + F38C16F9CB21968A20A838A724FB89A45FC898A9BE589A2A69F49B93453113C1 + 524C12799D52E64D08014B0134144552E2A36784C57A963EFACBBC3C6A825786 + 6DCE1A0349B78D24078112E9E0527CF50CD03680A7B1A668F046B5EEAF2B3942 + 92402A7F5374341166B97D5053A3D793D8841B9E20A8BCAA02E93DD6D5DFF3DA + EBEF8C8E4DADBD7EB523DDC20683678E1C1C76FB57AEBADE8C622D2DD7579417 + 3CFA9B574E5CEC16E4C33DDDFD056F7FB0705E4D7686ED64FBF1EDDBB7F78CB9 + 4D5BB12D77DD05E328ED75CF9D5BF2F3277EE4F34EFA49BFDD621BECEFDDF1F6 + 6B3B0F9F084290E924D45855F0C3BFFF49C59A8D100B11478E0D0C0CEE3BD1BA + 73F7176969B6419FA584864C7886982B8413B824A7DAE627B7A08B3AB8980C0C + 06335FDD151A3A8A611419344769291342F5C452DD7CA3977376CD123682631C + F38DC5F75C86E64B0618241CF03673624856415EB99C5C6E6D3D35C322CA4693 + 17F7343110F8286B38DBBFDA9EA0C1C566499969A7D28C0DA306DA1CB9277ACC + 6832CE9B215CB42A873FEFF606D3AC96A54BAF3EDD7EDA4B83EDAFBD47982DFF + F0E34717D52C78FA17BFFCBFD7DE80218AF64E419E292B6172A499041E8A4920 + F71CFDFA7C471F9E93C172D4C4E454DBD8C46F7FF7FB235F1D121E62045E50EC + 282B70E667A5E7DA2C260B7EF0D4D10F0F9FA0258E9343A01966EBC4B9F393C7 + 8F4313EEF2B2B9EB56DDD0DD3FE4A61841402A282F472D59015264533010B824 + 2B475CE64C13FF881C56B12E46DC4690E11FF985183ACAAB0002554FA9328B88 + 7F6726135D49151FC55186FEEEE4828B2960DAB9344B22322C77999793241134 + F6BAB49B71A61962754D99E2617312774EEC3EE295D332F13713F997E42F0069 + 919C216DE2843AC9F18FB9252D215AEB8D3180BEA1DEDECE8EBEC11E4137AE9C + 3FBFA367A0F5C8B15B1F7B3CAFB864A8AFBFF19A3A28383ADE7B91A2D89CBCA2 + 9BD735D7E66532920ACC317C90A4599EADA8AED872DF7DB72E5BC6D16C5B7BBB + E441E7C7478647C686FC1E8FDB35363C7E8942387BB678BE8305826E59B3AAA1 + 761139E9E93CD5B663DB9FFA3B7BEFDC7C7B56464655C59CE635EBACB9F92484 + 10B674204D16969527A753CAA200928EFF085B2915DC534607CD1F35B1A6218B + A667C9672B73468621CB2AAA79AB4EC053CC68043A57AAB1A5B1EAC51730F4A1 + 694B2A00B2D9336992A27C014835A2B541E9AB481AE86A595F8C008B8116272F + 098A63B814EAA433D03571D38046D10C4DD2BCC269A8034DDDABBAB8299BAE63 + 3D043A20B41096FD897861388E2565F7B4A39D543868453BA9527E886259E800 + 1275A6124811FAC3D241C97CA94EDE11ADA0CC41172723892AD50824CE6A611A + 9A42918C9AA14EAAF7410C7A514442FF049D96A345719BA5219E95129C52111F + C8F44778E1ABA2B26F3C766AFA2E06B8C0A94F4CBE3E8F7BAA69EDC6AC020733 + DC5F5B563CA7BA9A669985750B9A965D4DF55C0082289A6685AD6925F9252613 + DADDD91964984D6BBFD752BF98404D089E6EB73B57AC5CB178C922A7C39165B3 + 74B49D6B3FD7E9F27B2F74F770410A66BC664192CDB143BE891B1B17DF73EB46 + D4C2BB7DBEDDBBF63EF91F7F8470BCA1F11A8E0B96DAD30F9EBA70C952525273 + B5CDEE109B026041E31283AC41244F4CB81991C671A1B02718968FC469415337 + 1709004A293432526010F0794D260B504F5015EB0C9394F27B5B3FBAF2014F49 + CB64F037E75F4AADD03D6D4649C9E6251E8AD1E8BFC54D97232EB0307E06C68C + C41504E19C26BDB8C9A69A1A463F9048B54F6870106F210888DBB9C60DA3E271 + 4F14C989E14D5C2CEF96FF478ACAA76114D56EB39E461F2A418F15636B2A2A06 + BA3BF67F752800828F6E7DA424DB468EF49B1C05F5EB57435313F42825E6AE82 + B89E73E7289EB8E3E64D280C9FBDD8B364616D4EAE1D4631CFD8D4407F1F8320 + 55559525CE7C960C8EB9268E9C6A3FDD7E02E7D8F52B57E6386CD9267A4DE3D5 + CBAACB8A8AE6B87DDE3367BBAD19D95F9EFC6A8865DC7EDF9ECFF7E010D7D971 + FEF3435F353EB091B066F0913DBE4010485934747AA0BA4122596031B3A92C65 + ADF1B12507342D8E48E732212CC7C2E1FC2FBCDC2D1F7A55B69B3E1C9571C5D9 + 68D2053311E229021094DAB93EDB9DA0C66A0329CE29F1E6A544CF1969137D92 + 1F9F35F6A98216D96D67FC7563E0056E42933E8993EAD61093F3692A40A96834 + 8212C6C912E793A1E349B8E9F497892A022E368FAA318D7EA8BFAB2ACFE674FE + 3F75571E1BC775DE77EED9DDD983BBDC5D924B2E0F51264549D6498A922D1992 + 6C574D6C2BB65327B5D3CA46520408DA3F0A032D10A00582F68F02018C044E8A + BA41D1046E73D9F15155B62BD9912C39F121591429DEA748F1DA5DEE7DCFD979 + B3D7ECEEEC45AE28F203417277DE7BF3DE9B99DF7CF7A7BD707E8261B1FFBB76 + A5DB6239B0E754848330B59A5E5EFEE2E32B58DCD7DB619D1C1EF9879FFCB72B + 44FFF5B7CF9D38766C5F675B28181D9B986C6EE3308212A1FCE2C58B22E7FC9D + 73E776B63A8281D0C7D7AE7D3A3EB6DBA43FD9DB8F92B816E1609E6DE96873F9 + 997F79E56716BBE6DC4B7FD1BD77CFDD8060355B4646470D6A647165F5C17D7D + 664B8B801099558A3C8778590B40322B1301333DCB1497ED2ABC7CE97105413C + 23CB32189E4C5002658C4919C12F174901958551A8C4A7754CB606A341AAAD18 + 095AE1DC258FD18D8F035074BBD8D90A962B28E8F7E4EDABD5C9E6B4E7399A4D + 445199E13E6F02C031B0649D958A804B8944813E9D031F2A0FFD054C68767F04 + 3E110B0A19C9BDF86233123AA88F2208B918536602C92F5CCEA53D9618459903 + 718E61F9488C5E989B8B7BC3BFFBF0E333DF7C617A6AF26FFFEE1FDBACD46BFF + F4F2D0D4FCE5C139B74AB5F0CAABAF7CFFE5477B7727A2F1CF6F8CDFBC795367 + 6A5876BA2291C8F2F2F2E8E868B3D582894C3947F777B61CDEBDABDEA8813944 + 8D930CC3BB43A1DF5EFCF4FCE46C6FC44CA2D4F7CE7DAF7BE780B9C1EA0FB9C6 + A606B53643EF8EE32E4C978929009304BEA1C0AB09C93A07E788D649176C21FF + 65597AFDD9B77861257A91AF4F95024BF64BE7222981A4B5E446EF9920982591 + 15E55960A2BEF7A7DAC83E14DD0904594782D1421C1238BEE24DA88207DAF8E1 + CAF727B71C784D8965E3308AA7EB8B14AC1FF85DCA62372A66758B37487D8511 + 9ACA7A94B9244C3C22F0D5A5DD11D2095A8AA908F24F287D8B6188CD80DDB8FE + 29EFB30902B3E45E79EAF1E30DCD0D3787A72F7E70A579E783E3D3533796D710 + 01949003B9E861A0869DF5843EB8F2C963C7FA8D16D3E1A3C691B1C9C5659788 + 9B477BFBBC3E7F93DD2EA078D79EEEEFBCF87CC4EFA50854E0E2B1701CD5620C + 8C4E2D2D7DF0C567E2A963B410F0C40EF4349DFDD3265FC8F3FAEF3EB970F95A + 8255F537131A9D56D24B0A5965B2A4214554887CF2E97D4BE9A141309B248697 + 7895286EB9D43EA7441D489727F7C04FA3A8229226699B09F530022B9BA73757 + 2ADDC0FC6BE0310A74EA200E682B54C6AA7EA772F3C8553556E527039EA428AA + D803145BAE18C6CB3A5C65C30171350CAA9C6F740D1C93000E4C791B534E4097 + 72C8C7505C5362E4421B242CB014C48C4F4EFBA707EBAC8D6BAEE593470EEDEE + D93B7C7B3A160B7BDD4B7647A316819A6D8D044AECE9EAEC7258DD775CE2B646 + C2B1B18979261A0E73ACC0C39D3B3B5D6E8FDB1BE868EBB0DB1D885A0BC5224D + 8D0D011C819838016E78289E10056FC8B9B81409FAC553EF74B47A3DDE9FFEC7 + BF062250479BFDE2A58BA377561FE83EAEADEF8128AD888A72A31C0CECF59C94 + 5532CF949D16FC41FD7A1E82900ADE59F25DCBDD9B74BD4FF12165193A658DCB + DA700B91347B65B6288C165B3B8A637C0D58D1FB04BA921DB09C62B4FC68D548 + F49B20215477EE5441C74A5E01CAB6918A4EC88B320BCB149499931A011B1FC6 + B3E583FA2B2704C5800F7CB92554226B7374BCD245CA487CB0E9784464B491BC + 5C9925FBC1824007DC519FE7F4C93E7B4BC7ADE1F16B97AF9E3874F0AB5F3DB5 + E8BC436AE1D35F39F9FA4F7F6827301C125AACD6274EF4CFACFC6F38C17B9CCB + E7DF7FAFA5B99947507F204851C63A9359ABD3E90D069DC12832C6C14098A655 + A1089D884534384A60188961743C1A71FAD008DBAC214EF61FE259FA87AFFE4C + A0A8274F9D707943BB5BBB761F388119ED90C194E7D820DE33AC88D7728F83DC + 152130C4B08A474A5E645925E54C63114C51148D67857AA8389266EFE32D0AA3 + 852B4EED178E6E33DF7BD9754C46D26F7CB48AE2E8AB9CDBE6ED47CACF44D8E0 + D9CB2A1F393681A098ECD1CAB6405182E6CAAAD72BE59461F134C0A8B50E2123 + 7F541E24E3608B1E2F9D6D4F44D25888408C088C2835CBF998FC828D04EA70E8 + A5E7BFFEEC13A7E31CE409843FBC7469F2CE7CFB8E96871F3AE6E8EE515BAC4F + 7FFB9C6A6ED47BF33A4910678EF5397D81D189E9867A0B84E12E7FD0E5F33A1C + ED2E9F889AFC4347FA0D0623AF822291682010090662C150CCEFF7E21810C178 + 481D70BBF43AEA91DE1E4A6F68B5EACD8D4DCF7DE3E946474728E0551B4C078F + 3D4A347772D6061C53ACF60A27C399A0BCF524AD4C800F6565472A12ECB3389A + 96EB93323C82A01C2BBB3D4A23E93DB6D4DF9B6754101F8FEDEA7B0F49394637 + BC03203BF03A24FA2D63CD87A492F11B7C0D949F8C00E44D5ED1FD08684E394C + 903D2A953B03E475007C28A987CA9B0D2B525103477AA152AD716103F16167E2 + 1144A3CF4CB294B90C52453D2BAD94FAD96367EAF49A91857957D01BE1551F5C + BD76FBD6CD3F7BEECFB56A2AB8B8AA57A3A1A5059A49E030B4A3C17CEEEB675D + BE100FE19C0AE56078F0F6F0AACB6DB5D9EB4CF51A4A67B53504C3615FC01708 + 8582C16828125F5A5D8BC6C3B7468648886D6BAC6FB436F41FDA874182895293 + 04FEE24BE71C36C7958FAF5C1F9B6375269DBD15D56079AC686A2508B032A188 + AA0043D37E843048F725C9F59582A82A871F4D393389FF4911FA90CCCFA92C4F + 9A03A3F75300AC9030354147E35575D93AAB425018AE856214244812B6826254 + 46D5EC320CA35C3E33589AF5ABF61A4ADC05D82816819519058CD0327C286DA6 + 5BE73D826004466A0BC16A9D667A9008952EDEA7DC82A55F1C23F2D90904278B + 35CA120CD1B1A05A88C75C4E92315FFEF00F4333335E15F7FBCF6E23A1C0BE43 + C7DE78E79DDEC387CF3C7A3A1256418406A548526FDA6BC183E1E8F4DDE599F9 + 2547574F6B47FBF0D00886C066A321180C1B0C119AA1975757D73C1E83D11057 + 31A1F9E9D1B9794284F7500882716B53BBDD449929C268B15A9ADB7CA138BBB4 + A44779584332F5ED98AD253DCF1C0C4DF9E103A72E247739D95782F864898F05 + AAB852A5374EDE1179F16448AA9026CA7C52A93425242DA01A24C8A83D15BF85 + 80B2793B73A339DE4EEB12F025895E51ADB1790ADF75D895E41F60B80615A82A + A164DCA7B2242C3ED32405553413459D2724022818A19C16B272A652CA9DAA54 + C5A02207D02C31896881178FD218224B2570F30B0BBE702CCEB04B8B77238170 + 22CA321CC393F8674343AFBFF53F9FDF1A503537F913AA5FBDF3BE2BC28054F6 + BC2A108ACECEDFBD3D3A36393D2BBE11017AD699DB3B3A294A1B8FC59C4E6728 + 14D219F496069B5AABC571BCCE60EC686B3FD2D7D7DEDE4EE2B846A315B95793 + D5B6E6F1AFAE38C3F1D8C0F84C54509BDBF79650F4C000C4649AA05C0C4D3600 + C547A13CC5682A5CA9308849A5CAFC64DA66DE46C0B55BF28ACBF546CDCD7B2D + 3F5423A17E13593E9EBD6FDE4E1B4AEF94BA3A1BDD29101C78EF829736856004 + 15852F4155918E7B431B2694BA33450CC5D57A8E8DB174D6FFA9023B16842018 + 4A6A6018ADB0475EFF620758265155FB62048A6D330934C3901658E8A1D4F221 + 0CC31757DDF35EEFFC9AFBE187FA7992BC393A190C44221CF7879B378371A6E7 + F0211E427EF49FBF7CF7BD8B82B1FE19AA0E6285654FC01B89C721F4D6E8789D + B9C16C69A8B735D65B6C61BF3F168D040201BD4EA7A628982448AD5A7C644814 + 35E80D4D167393C564D0925AAD4E40888545A737C2AE7983C148F48BA915D8D4 + 45EA4CE954ADF9ACA82AC90B4210707B4A9A28F39C9E24633DC365A372CA07B8 + 6454CA4AC59353EE1CA9D104059E5426DAABB68F892945A096745596FA9A66C9 + DB08D5C8EF5EC529BA3A6D137F2F697030BA947B385683B995BEBE858C689EF1 + 1F86505C03A3842005AD037647316D4A2AF80C81514CFC018A0248E959AD569D + 29FB28C57326AAD7872A8BAFE2502846A84AAA461115CCD1F1E6B6D620C30D5C + FFEC9F7FF07D8232D21CBCE072AD2E382101EFEFEBB3591A7EF0F2DFFFFCC2FB + 223EFDE2DD4B5A83A1A7B5CD178C44C47684DAE9F4787CD103FB0F18F426AF2F + CCC5E35EBF3FC1D05A4CE3F1F9782C188D473986361AF4BBBA1ED01138C4D118 + 828830CAAB508FD737BFE299989A5B58997511CDADC71F1604590ADA3C0C55A5 + D84AE0842F2F099F3D2A0160B2A4489577AFAC449D2AA523957C02785E489BE2 + CB7B966C41182DB50D288E161169B73AE5E5FE591F520969DA4A2ADFF5108CE2 + 101B97054267F66543EB2A40C98A6E6F91AF84081495520F26C357402190A4EC + 0049D60638991C03AE6ED7ABA95622C20DB09054DEA16403F19520E985F1127D + 383AC6C642BB76B42DCF8CADF9231C841318AAD35107DA764C90A34D46F57367 + BF72777CE2B59FFF52EC4341C8EC92FBDFFFEB8DDE5DBB108CB8EB5E531B4D08 + 461AD4620F03C7716BFEB57824185E75F9833E2722B83D5EADBE4EE058A3C966 + AA37E33ABDCFE384998488A5319ED7690D0E073134353B343D3E3137D771AAD7 + DCBA536E592AB29D12B4E52E25D3038232611D15EBCD942BD14B0A5218E61846 + 45AAD3599A659AD17C86145045F7D9967A64B7A9480B819CFD3590E8376CE356 + 98DA3D1CADC8D880B5C34896A9CE5A58DD3C00FA95BEBDF3211CE069B61E475E + 05B8AA965DE546C97386165F4F99D3C9BF1207E45845B759D978425B936571EC + 430349ECECDCF5F6DB1766662750353538320E096C7B8BB5A7ADE1C2FB57C32C + 2B4206094A4E606BC1F8E0F49D44825DF679CD4DF6BD3D7B318CA0287D221E73 + 857C5E8FBB2EC687FCBE85E81A1BE3084CD7B6A3BDD1DE7AFDCB1BBF7DEBADB0 + DFFBD8A1FD265BEFE89DBBAB9E309388D5594D3DFBF73294CDD6B14F85E399F8 + 4B4556347979B2C15DB9189AFC2319EB85B47369A9EDCA2FA5244B9396445238 + 9DCA32558DBE1892A6A926DCE8E6C1AC94CC665BC2A8544F79C3667A1002CA6F + B1F7DA3A49646A443956E2FBEECDF828519905E93E50DEF503CC23C7E4662EDA + E090AAFCBC01B9C745B060130900A56CFC1BCF3C337367F1C7AFFED8E9F7771D + EC9D181EB418CDFC83BBE757FC4DF6A6B3278E2E787C9128ADD1500F1D3D64AD + D35FBAF4D1ECCAAADBED0E85838D545D281864687AEAEE9DF985B9BD16BB3F12 + 1C1C1D54636A0456537AAD46A39E9B9E1C9F5F408163278CE0BADFBCF9E6C8F4 + 22AEE27AFB0E1F39721CB1EC89D81C229F599A1555492829B98C0B79955533FF + 822426A23C01214516ADB0198A55EA2428AE2C55517A125B50A82F455210E4B6 + 84D10AE297CA13070C4CE58DB0DB84200CD73289905051485375CB041EBA8A4E + 3FEB1AADD6B3CB25416013796AE275783B158C2A739B2D6C00231023F023C3C3 + 8F3735D88C1AED03AD07F7EDFBCD7B1F4562B488C0F1486CCD139A5D5C79EACC + E9B69D9D3FF9C5AF2E7EFE25E7F31DE5FBCE9C7CCC6234A1A4666C7A36118EA2 + 3816080442E1F0FCDD85F985850EB501D419C3B1443CB1706746C46A8D562BB2 + A97A48D5DAD0A433D45FB8F8F1D52F47FD92D6D175ED5393A9A5FEE093B4B94D + 614DB9AC68E67B5079A9A08061CA68062050694F149F3B41162EAFCA47D294FE + 2DC5892A33A4729DC0663B3C6DE4F625B4EA5A06926F2AFC40C948D00D8E2265 + 8EDF966F114512B9452915534DAE849C9583C46115B3D0AF6334550DEC94A514 + 1D2956B48AC12A9A0DF0E74831A40AE2ADF81CB1BCE071BB3D6BEE811BD7C549 + F41D3E64AC33B5D85BBA5A5BBB3A3A3891B7C3D41AB566656176E8C697AB3E9F + D3EFBBFCFBCB731353AD36BBDD6469309A1A4CF538860B1C8FA2088E621AB55A + ADD5EA75867647BBA3A5C5D1DC62AE3311042EE24D7B5BDB534F3EA5A50C9FDD + B8150641EBA480409E18BDB8ECE4B51644A32BBB38286D66E233D942A0FC1E40 + EA97E512C9FA37151B312F8B895C1A80A154BCB5623EFA9C5EE0D736E3462B0B + C6DE7A04959358721A175B7AB232F13DB42F6D2E632BE9B3100C23B46C225AAB + 2B2BA22746500882E67D5BCB75961CAD5ACC65F382E8ABB5FEAB8AB607A5A7F1 + A2EA510445BBDAEC1393EF5D1F1ADCBFFBF0C1DD8EEF9E3D6375383430432364 + 28E88B06E8789045513ACA0454A0FE12347A67E68DB7DF7AE6D967EA6D36E3DA + 5A9DD1A423B52CCF1830B4DBD16AD71B311D4533B48DAAD75A34069D415B5F17 + 4AC460927C787FDFD35F7BF2D3AB976D24CCC7544E3E2E7214DD4DCD87FA8EBA + 189A6159048395BD0E0AB61ADCFF8822F20114155821EF48BEA2243F8C5E6E5A + CAF29892FB7D8156248F219591128C6E6129711383776AB90BE99A051B223E59 + 03FD3ED2BDB9310092923A8E89E6A8F3D6057C60285C53A181BED8A936D37B8C + 65E2D5B1A2D590425A55B9115B80FAFB8EB8B1855FBF795E254CEDEB6E7DE185 + 2726EF2CFD71981C19196B6B363BD75C03C3E39D9D3DA71E39B6F4DE27215630 + 6398ADB1818754BE808F661851B8D6521A976B9561B42DCD76BCBD7D6C7C3C18 + 0C8A7C288AA23CCB5A2DE6B98101735D5D7393852485D6B686AF3D716A767131 + 4E603BEA5BBA9ABAE7507520411BF223A4A162CC9F88943CCF17DB51282368CB + B9963C38057F85CCDF7CD352E6FF6C1614994C5F78BE5A1758DE14823615476B + 3971B8429575294ABB3A6D1DAA19DE48767B8A03053E1395682D0A810F868032 + 1405F98DEE2D1750C3D10529C77D0DCF96D7BA20257EF6B8781BF1B190C54AED + 3E7A646E6EC16EEBEAEC7C8083D840D03B353BF7C9C0ADD347FE524D197FF4DA + BF7DF75B675FFCE6737ABD717078724FCFFEC3070F05FC019EE3701CE738CE1B + F0C6E9B8D96AF607FC4E976B7272BAB1B1D1D2685B5CBC6BD0E95656979717E7 + FDDE350345365AEBA35E93E9C4438FF00265347241DAE98EFFFAEA1FB58FEC29 + A88A52B0AE6C0350794955D83C559E338591500E78160E9A194E808A20A97270 + 1A54548DBF0E18DD2ACCEA56994705538140E84B0DA2E9B9FB17C155EB2D51E8 + 81A0048CE23C4B8B3F95570F856114C1091821E425ECB6C5BA41713A9161AC58 + 4C29EB7B9F4F255FBA041D714DCC1C3F6EFD9BBFFA5630081124B4E60C901ABD + 2FEA8F09C2D183FB06EF2E7D3472FBD4F0DE237BBA9FFF93D34F3E72BCA9A53B + 48F337060696979703C1E8FCFCBCD7E3D1519A15D7CAF8E8E8EDDBE32BCED556 + 474B826528AD16C1E1A1E1E1D999995838DCDEB283D21AAD261B6234D5536A8E + 8D8EC7163F1FB9F5E5D0ADFE63C59971856405451FA26453E00C93F479526042 + E53B93FE568EA44AE7CF406BCED70572FDB6E2469359BE8BD216C2D5FC99D522 + 0C5492E9ABE446B7EE961499AFC497A218217252C0B50D08BC49FEA3B0D40348 + 1B0A628A52C992B7E2524B001FA8589758571C57C5A72EE1028121B009E75726 + A79D2B3C8E629D8EA677CF9F6F32353DFAF8633A8AB453544FF7AE0FFF9FBD2B + 0F6EE33AEF6FEF030B627110207893E2211E22451DD465599265C992253BF1ED + D8AD2CDBA927893BC9A4D1C46DA7F9C37F349D26F1D4D378C6E3D6895DD7A9ED + 692DC9876CB996AFD88A5449966489222582222992204190208E05B0C0628FEE + 821700023C4412125B7F024502D8E3EDDBF77EFBFBDE779D3AA352657F34ACD7 + 513062B6C3B8C1C8A261A9A161E5DB87DF735CED60FA49ABD562CFB73B9DDD03 + FDFD23BEA09F0F5E72387C9CBFBCBCA4EB1AEA1E746328F2CCCF7EBA7675B37A + 4E93C9CA0D0DA98DC220602F29F6499F8EB80614217D5DB5691C63D50191349B + 92586922C2257B98264842FC670292A6A8F6C9A786A67528596A30BA34EDD4F1 + 7898F91E441AADB733BF86DCE89EC8D090299348CB248F600816AF10A7CD0C79 + F2DA2110874E189AC60E7BD3F789148BA6545BCA6A3BE4980D0BEA0B73839C70 + FAC4B1AD3B6EFFECF3AF6A6A1BEFD8BEF9D69A9A1AB3BDA3A303840279246CC8 + 335085F948808FF1518C22BDFD4EB5F3F7DCB5E75C7BFB48884386953C5BAE22 + C90C4DA114E9BF1A8CCA22C7731D5D0E1DA979D41F3870E0DEC7F64983C32AD2 + A028F0FB3D9C37585060B71497D5D696965ACC3A309BE5AEA94099CEEB65B2B6 + 369880CF24141D6796C96997D3606406DA3B65CBF1E1B79460548B8026F0F91F + 27FB325A756BFEC7B9C9D646B320A3B978602DDF64FCED44A28AAC3560310E1A + 2F9EBC88115CE34DCFD87851107031B0A9B9C1D37399D45124C140A81EC96114 + 4CF9D1A30FBAFC912BED2D3BB7ACAFAB2C6A5ABD2E1C89C840824812303427F0 + AFBCF1EABA0DEBB7EFD8FEFAE177A95028128914DAF3632676C0336CB3B04224 + 42E298FA2F264A180C171416038C44481567648F77B07FA8C7926B448DB97238 + 6AA2C83B6FDF1AC1B1A9ED4E7A37255C78EA1C98F4794A64A3503A3A3AC64393 + DD3E13ECF0E346AAC9B34F3FE746375C4A300AB23A7F16BAE5F39E90F2CD527F + E95B99AF8C52D1798D8859EC0B211983B864593230A4371038F4D1274FFFE8C9 + FC5CAB8965CA8B4BC91C0390A9A0B3DD66B3D6355660C87A4106020223340503 + 5494C46834DA7AA1E5FCC58B25E5E5569228C9B3D7562D0F7301F7D04834C2B3 + 068392A327098261F41CC7F5F7F6F9BD7E95823A2E5C4214B9D7D979B1F5D296 + 1DDB6063AEABA58D86A41555259F73FEE472D83347DD8EF93C8DBD4DF58A95A7 + E6F54A06D28970F8F42B9FE99762965E6A928CA268A1C74B33D9E8FC0DF559E7 + A1F1A7BA323F27F66F259D24A5675E204937BAA6C9EBAA4892D9AC1FF2F40D47 + 9473EDBD7E2EB0EBB68D6565E540C68F9FBDF04FCFBDB07FDFFDD50A8AA1288E + A0B8C5A202851C8AFABC7E0241CBF20B0E7FF565880B561616572D2B1F1C74F5 + 74774B9228238024298A2269F587A2FCFE801893BABBAF3DFF9BE7DEFFCF43D5 + E5A585257659085B8BCA0141FA7D011B6B3A73E19B2B416875C386D95F653C93 + 939C798314C84B130D95CEEF730A50CE30DD52B75F64185D70EEB844C9E8BCFD + 46B3EFED24C578CD7F1BA3A6CF70F1FF5BAEE79E26C4172DAE68EBCBE9449464 + 38CCD17A1A0CC5025CE8857F79E5C74FECDBF59DEFBEF1F21F04193AD172E9E3 + 8B2D4D6D6BCD66FBFA75B52A485A281AB5E42B220A83605D43F5F7FF629FC7EB + 3979A9351C8B797CC3219FCFC0EAF52696C0719635A2302AC94A545442A16849 + 7965CB45C7871F7C18E203CE81DE1581FA037FF5535BE31A20F0ACD9C023725B + D7110F9C37C72E87A69907DA249327CCF0733A6C1230CE75AE2D328C2E74C4CD + 9255EA95F99251906D421A2FE2AC88425855A2108C9CFF01BF9551D1D4F9C54F + 7518CF6F951E46639CD70A0B38A45C1B705694161D3FE93499CC909E79FDE07B + BB62F248385C64621D2A8DEC74542FFF5B5990C5915047C7D91017A9CE2FC059 + 6AEB1D3B2211A9EDE7CF38BD3E0A002302C78BD0410449D2344DE064900BF9FC + 7E05521A1A1B201132B2C687EEDB1B11C2CD6BD736EFB933D83340D31442331F + 1C7EB76B689029D5D210CAB35EAD1A57DB335DF5E4CAE9DCBA38958CCE6DB22D + 25A57EA90A04CD7FCE64DFB834F1C4126391B877D1B79C74AA5C0F1A4EF18A5F + 94866819A6D32DC8A81B1A10299F94CF1CFFFCAEAD5B0A075D17BE395B906B0A + F4F7472149A7A72B9695B224EDB8D6FBE1277FFCDEA5B66D77EDFDF2F0917F7C + E12515469FFAB37DF7ED7F00B0C6E5B5B56693A9C7EF3791789EC9A8C4DDE255 + 368AA2A83A500982D4EB658A26191DDD7AB1F5D6ADB73CFDE3A7557C630BF2DD + CE9E5F1CF8EBAAAADA12BBE5D54387FA837C71A11FCC69C53F21FF48E6BE48F8 + 5BD1F47A25AECB4FFD3ADD2EB3ECEE24597230BAF4D8E80204308D6508CC3292 + 263839AA33FF26CD39B7146521EEE34C00AE15974EA7BA49A268C021C1DDA713 + C2856525C39CEF817BEE2260888F86F73D76EF96CD9B6D06EBEA15AB5EFEAFB7 + DDA2F4F5B94BEB9B3738AE5EFD9F962B0100D67E73F101F461AD74B5209014A5 + 82B49ED1A9388568697780CFE70BF8FC7979F90D2B56C624A1BDC371ADE75A67 + 77E7638FEFCFAFAFD5CA0A20E0F95FFFF2B5231F979E3C6732E95C2381EAFA26 + 8CD54BA350378B0B53A6769FA280141F5279BA7D13DEA473479EFC32291DEC8C + 776389C128842C3D185D90A50825FB8434A1D199B282CAB238A6A2C613866B6E + 49738C67BFE96531B4EF451FC3718D1ECFF4D5406F77D188A3F1965A6F7F4F89 + DDDA58FF68940BC039D4F77FF043A010202AE7586D7555A535366684F3FFEAB9 + E7C322445286001F60F2F350930584A3B824AB24B480A12ACACA070706B4DA4F + 81304212AA52CF05B811CFF09067C8E5ECB55B6CB7AE5DB3BEA101C444C090FE + F6CE0FDEFB240A40508E0D765CAB29AFB863DDBA93CE81907F88315833DE8014 + 9C1CEDBDE4DB32F16E3CE820FEC1041355A69AEA339F2C2EF2B87FFA8C736EF4 + FBA534E825415CB26BA3F3964C8FCE4593441BBD16533491577CF4132936EAB5 + A38C3B348FEEA2C22882E2735E01B8915551B27D6E1841D33E9416B01D084664 + 32D3AB5A0DAA84EFDEDE1CE29CFFFDC72F766ED912F48744091820448CC4BABA + BBCD3966536951611EFBF0DE1D186B7AF1D5B7ECF6720C55B96740D1E180A041 + 24AC43B00D8DF5061DB1BA615538C27775760EF4F7C7B4E47B320AE02EC7D5D6 + D64B361BFBE87DF734D5D4E5B1394A2008E5D0221781782D973E0C833B77DEBE + AABAD6CC90C0EB387FF8C5E6070FE0942E7347A47EA42411D8C96B1BCB1612D7 + E1939014249A271490349F94A9F15E6A2F610491FE26256F37FA7B29C1A828C4 + A6D58F6FD20A45734A9237CDB52D048ACEA18BA0842CE25ACE7D4940E0B18125 + C67849ABFF3165B02BB212CF9E0923028A12992CC5736CC8FF2551C058A91264 + F1E2F1E2A902E94C1DAC42186BD0F9439E975EFCFD8A1575BBEE647EF5DC3F97 + 57563CFED413AFFCDBBFBFF7EE87BF7CF61F4C36AB67C45F555533E80BF93C01 + 03E5AEA9C8F39C7349A110E0A300C7CD79B6C6C69532808AF30BCDB966ABD1D8 + 6532137AC6C01A9D7D7D83EEA1BAE55515E5C5B76CDCA86772FC836E28C2E758 + F4084B9696165C70F6545A2D4FEE7B882175EF1C7E9FE3F89EB68F699D75DDBD + 3F1013744DBFAB3B343480EB0C2849937A036530278D9994A77AD2F527335865 + 023F53AC48135F4FFC9908AD4ACA928832F50809721D307A23678046771064B4 + AADD4D3413B3D294EB41D179346C34B9DFC44A828A9B308AA9535414C2B23843 + E12015490529A622294A5037E02EDD34DC366D43541C45305C8CCE398A69CAD1 + D25F274E31109C583C1111445194B42A1D0485D318D9DBD5F9A78E0B8343C3FB + D76D1411E23F8E7EFA1D949425E8DDF73F7AF75CEB23971DB54DF5168BF5ECE9 + D3B6FC52955D5208F4BDFB77AF5D59B579DD1A3918F60E0FE330E4F378821E6F + D81A08FAFDAC4EBFF78E5D469BCD17E0DC8545AA3AD271A5A53C3F97C6702044 + 4E9F3A198AC476E63DA42FB2FEF0E9A7EED9BD1B40823507BDD2E5387EE6B49B + F33328CAF75D6C39FC6A4E453D5B5CEC1F725D3E79D471EA2354960B0B8B5192 + 8151B260C5267BFD268235131435A59795D1D026084C422134F6030098C62495 + 314E5EA50D8896BE14A4C5CFD9E51BBD69255E3F15C190255A1C743E2265FF92 + B5104C786255341EBFC8AB082089D1C907FDB470A565BD03328A510BBE609ACA + 15B2889B0B722A0CA76551D58067F41E9DF3D9541E3A9688202E7284E7073AF5 + 727055214BEA8893AD5DEDBDDEBE3347AB37DA1FFDF3C7B6DDB9E7D3A3473A43 + 111951D112B5E6DA74A0C5E97401A389B5581D6DEDB5CB9BEACB8A2B2A0BEEBE + 7B2745D298CEDA71F9EAA7C73E5EBFA1F94ADB1577FF80DD9A2744A3C5C5C534 + 49A330C232FAF2A2E2ABDDDD359555F926BD10E129238BE2181615D4910493C8 + 86CD1BC0AAF5835D972E755F78E3ADB7CEB53914045B51DF8448E1CFDEF92D63 + 64722C3A57DF40D017446160D353781487645A12E52B5FB8D070A8AA698307D0 + 7A7B7EDA51302A71004D44D1B47DA824FF974A45D3DB21329BFAD1F45BDF2C34 + 2F8D40F32E0C97FD262F4CFE8CEC9A98462BB38304EF1C2D85DD1CAF44A5A531 + 594609DD4C453AA748CA1C59CC31B9B8A09C9E914218C908112E253BC93C0521 + 488C1C5B618CF121241C0C759E4606CEEFDD54BABDAA541015F1EBB338EFAF58 + 557ADB8E6D3A9A19ECEB1B720DD900A82DCA8549F0C803DF3532745555098889 + 7D03EE01CF10E7EFFFBB034F98EC961C96057A03D09B5BDE3FFAE6C1833445F3 + 21DEE91A58AED407856830267843A13004B346F3A576477B97A3283737181464 + 185309F0DA1D3B200A438CFA48381CE683BA50380662E73B7A8F9EB882EB8C6A + 57306C0E8562A8101487B95884D6C54411286C8EBED4C84A211E677137E7EB74 + B5C7A2FC9615F976C2707948C2F34B926D4C9384546398B20CB48222F19E9E62 + 771FBB29897098A2CEC757B1E2B681B1EDD26BF40958BBC420291A0C67CBCAB4 + 6098052389B966B379E6F95EF38244826AA18F91607C2D35757D3E7B179DD2FF + 0B7BB23985118E0BACAABE941E46D0E98F36FBA662248D930C88D7D1880E0F6C + 20DD8F5786EE2B530AC8A0CE48E80C2C0872E161E7B59E8EDAEA658505F64197 + EBD597FF75455DDDB33F796AE39A357298AFAB59BE7FFFBE5B776C13020197D3 + B961FD7A9F67B879CDEA86D56B5440164251A095DE0457DADBBF3A7E7CDBF6ED + 28418464B1B8B21410983BE055DBDAD77BADB3ABC36EB3B9DD833D832E0106EA + 5382CE359366A34ABC455144289C2C29624CA6DE5E5748066565A51B376DA268 + 3212E5F53A06515048427008C3502812890C7B031141D45174BED54A00A9B3F3 + C26F7EF50BA3C2EDCAC7149F27B5B353FC9712BC4495895FF197326ECB4FBF63 + 5C6445C6B0B466D2F43C35DB4AFDFC9FF430BA401E8CD922DD5A2DC3F9271BCD + 464B53054250485C0012AC8E5B510B2D15108C82172BB474E645C9EB3FF4245D + 1DE725F3B9A1E38DD39094CE11A3E1998BD46768CDA8C088563B009998F68181 + 1D65CCC31B6B4E1EFCED6BAF1F6C1D1E19898C5493B235576FB19ABE39F4258E + 1E5502AEA6A6668AA02C16CBBDF7DEAF33B29E612E100C55D5D5A30C130B84AD + 264B992D57E403113E4A8BE0C83B47FA86BC7FF9F3BFA95A56892860C8E35EB3 + AE7963DB05B76FA4B16925C785D57D83DE9161F7A081A6482063086CB45AF8A8 + A0033282222AF842828C088ACA96CF9D3821F161BB25D70000A3230A0AF21C6D + AD834E274160A2C00BA2108909388E47A2825B0A1951D82444CAF20B412C72A6 + ADBD77C8FDF61F7EF7D4BE27850E1F57DC682CAB9C5C159DEC99A475D2D1BE52 + 32F5E4E44D4DFE445652A968A65910FF7C89B151A0F9152F35477045993F0CDE + 90FA299AB17EE15293C8B2244643A2109E7D66FB44594C0699E6FB7811564912 + D579CDC72241810F44C3FE6828FE0A6B2F81E762D150BCEA8904807C7D6753F9 + BE4A2109DAA03D5D2068C6EDA7EE8E113A5C6718CB7B0041DC503F3D7072E7AA + 1C224738DE7AF558A7B33BC0BF79EC5C47E735540AEB69B0B9B1ACBAA2CC71B9 + 1585A0DD3B7662106C615945867EFFBBD72EB6B4A1140154420841D595D58C8E + 292A2830307A40E92E7C7DFE8B639F4B31C55E5874CF9EBD0FDDFFA0C1622A2D + 2D830431E20F8A7C44D5CAA568B4C0665BBEAC9CC65156A78362D2605F1F1FE0 + 5416AA6228216334AEF7F60E3EFBECDFBFF7D1B1C6DABA9515C50A24FB7C5EAF + D733E0EA5739298A22822048AA88A2AAC0052471381874395D2C41EDBFE7BEDD + EBD6EA0038FEF5A9D7DF7CA9EDEBCF72FC03EAC339932E90848C995E200D2D1D + DB23BD1F4502154D66A50BC246B3B7982AF051045D5266B105123929F5E12232 + AF44D15647614C92E7C295A615452B9F1E55B48C27A4CA9E948558355E5889A7 + DCD78C3F5AC8A6665E53A626019EC88E1E5F37D63A07C13004C1118C98E5C27D + CA2D83518C4031EDBC9220C5844CC10E13329AFA1FC1D53392DAC2CBF8B104CE + E73AFFE96D6B58BB31A62AE00F3FF1643F2F1E3CFAA50AB186E2E52A3FC450C7 + 9E3B6ECB2FAB3D7DF2C4B03F585A56AD22578FCBFDF99F8EBF79E87063E78A86 + 356B96AD6CE0022392225D6EB9A8A7092FC7D50174CB2D9B9BD66D241946D5D2 + 7FF2CCCF4ACACBB4478CD654B9ABDD81C2C8F2E5353A92282AB0ABD780A1A8D9 + 6C3A75EACCF088E701EA11039BEB0F780C7A568E0A1DDFB49D3ADBA6C0E8A6E6 + F58D4D4DAD7DFD83FDBD7C34AAAA2A0481C3180A2B0A09E1413E02C39A076820 + 121B8A79721862F7D65BCA8A8A519C69EF726CBF6DEBB057E2A4903C96BC3999 + 9F8F426442707DDA31961A0A95F4A7E6E0A7F98DCE4845C78F342B48BA796C4E + 8A24AB7D7DA35B71036431FB7FBADBABD21C598A5E3F114E77ECB8D13F3CAAE3 + 2328763D875DD0CBD71C3F34CF7149F37BD5D0531E4BAC36EB4E571145255070 + 2CA222A9AAA8CF6ECFD4AED10AA2A0FFCBDD95C0C6719DE7B967766667EFE55E + BCC4432475521765EB88645D3EA4D46EA236710CDB7553F4401B274562A4315C + C3280A146DD102418BB86851A44D9CDA71EC248E9D386E2497B6CE4AB20E5222 + 2952E472792CC9E52EF79E9D7BFA862B927B924B91B2E43E12D89D9937FFCCBC + 79FBBDEF7FEF3F708C30E820AE289A2AA973F90E6E275CD733A6600880500C90 + 4834DF1E59D364C59CF03FFFC4AEE33B6B2383FD74DDDA86A6DABFFECE379E7C + E473FE9E1B94C396C2EC1D1DFB4249D13F1D5FBF7DF7E8F8C4B51FFCE8D8B163 + 67AE5DEEBAD5379D8A5EBC7AE5F2C5CB8DCDEBFABA7B43B189C950F8DD4B57C7 + 79EEF8D1479E39FE045B57C37333BD7D37EBDB5A51A7891B1CCD70E9AE815E46 + 823734AF4D7BDD35553614853841C450CC54658FCB99F3172EB9BC75DD7D439A + 01723BAB2E9E3ABDC6EB755958A3C130154B661485C1B13827C09A426218274A + 499EA7189A008F8622048685E209C01EAAAA1CEBDA1AAC467CF3DAFA97BFF6C7 + 43C3FED6E6866822F5D6F5302F4A342055B715F89CE6C8328EBC8998722FA118 + 4EB5591726AD08434B51D1B93DF721242D0ADAF0674FA9D74A0D66F7CFC8B478 + C9A63C52E4CA930057FA643A58082955213040A9E6D7F1B5C519EA729BAD6C7D + 3D2B679675CAD2AC2977F669F36A9732C15EECEA599B302010A7685DCB2E2049 + 4BDEFA6C7D9D69EA413EE1D9456755D72E67F39EEAD08C200B305124514BC5DA + EB9C47B7F93ADFFFF9A4283CE65943429C4951766F695BEBC45FF997D71C56E7 + B79EFDD2643ADAD9D9D9B2A1FD6660F49D777F59B5A6E646DF0D8A201F7FE4E8 + F973E782A3639140203070B3BAA50E5DBFF9DDCE4B676E0D36340F3D67602012 + F75FBCF0FA7FBDF7CD975F86504292E4486446E0F8754DAD36A7D30C38A7CB25 + 88422436034694AEB37D3389B8C35DD53F3C387CEE0C6440514DF3F7F5BEF2E2 + 771E7FF4604373533A95E8EEEE31B01677B52F9E4ADAAD669EE7D38244D31A41 + 10248E034A8BCF068EDABA7E63C7A66D288163A2D864B733B01613935D376E0C + 0F8BAEF5AA9633159AFDBAF06BCB85C8824E558A17CC2F35818EA19BFA659B78 + 8978269F412F2650F814471AE9659CA0DD878AE35D2877D34607D56DB3E555F3 + E8CF7F230078801E0B2E8112E49D180614E9734BBE6DF02C8A2CE8C9F2F4295A + 382F1DDE329BB1A4A594EEEF954902528993451DB540FE5297D39D6B01C15BCC + 756F4E84065188EA7398DF7CE33FFFEAEFBFB7EB73BB1E7EEC888C6042226524 + 78CA44FB07C77E30F0C9865A9FA7BEE9464FCFE864C857DF1A1395FEE180DBEE + 11F9CC438F3C862A5A6B63B381A036B7B71BEC4C9DDB77F8A1FDA76EF50E8D8D + 01AA4823443AC1F7F6F4A5D29C0BC193F18428886B1AD6D4D6D49A8DACC0F3A7 + CE9F0B04FCBC282652C921BF7FF3966D47BEF2142FCAAFBDF5F6AD8180C025AA + 4C74438D7BE3734FCDC4131F749E4D72FCF0E490C3EB6968684824923D3D7D80 + 1F512465202958D5804A0F0EA452298A2463A9381352ED56A726201CC743A80A + 8E4B80FECFCEEFE5226996BB97E8065A259474DED344C17404CFA33FE56645B3 + E53306A3D03D5D625AC4036DA9F356BCC4B43AE9DBEEE8D2B709E96A076C5F28 + BA4994AA8A8096A258A123F34A8D3A73EA03E894451E68BFD99DF012D5EFE0F0 + 4201B414C0346E609725A2E4144845F3E0BAAB0E3A169A3973EDE69006558F4F + 6A718E68D84A305E251630E2D02B7FF1CD175FFCDB3EFFC8BAAD3B6BAA6BC233 + 51D640BB4C96CB57BBBEFD077FC265D2188A1E7DF4D18E6DDB001344096A622A + C42A72475B4D358323AA80C2DA89D77F72B1E796AFBA2E9548CE2E6523990C2F + 4960084423E1F0E83880DA4C703228294A46E0EB6B6B6B1CAE7A8F4F92351341 + 597083BBD1FBE4979EA8F5F9F878E474F7B5C9C949B3D5D23F31159E8ED4D4FA + 4C26F3C0C02D0243688A02D41850418092BCAA8C8743232323349279E9CFFE34 + 1EE34494C2CCD66428B8A6AEBE1195B5B9B8010B487A7B39579B4D0FB2C42F26 + 774634F753CE06D5CE9D2F2DADCE6BF3425609463F2D1D55CA0808FAFF41A9BF + 7DA0F21CE54BD7BCABEF6039CAED1DDD28D05E658103E41425697439B6FA95DC + 8C0628A8C4674782E5873858FC0AC5476FEF9125010C4138C5C02B905E518DEC + A88029374603FE889EB4D9EEB0A513CA47DFFFB1D962DDB4A1CE6C213BF61FFA + EEDF18425C8C668C4F3C7E2C128B25046DE7F64D1F9D3E2508B19686BAA968B8 + CAE78AA453195E094ECFC4D2314512D7AD6D7CFCD0AE8D2D9BFD7EFF375EFC4B + 18C70F1F3996988CC46E06385149C90A2F88384E4238E0F52862A09C10C23046 + 93CDCA52A42C4A18851B8DCC230F3F846A72DD9AFAF65D0F4099F8487FFF0F7F + F40E6DB74BB26435334696990E850D0C4D32B434ADF119DE6460805AA2624874 + 661AFC718AEA1F99484BD0EB3F79E3CAADA1BD7BF734575959B3D56A3246E61D + 3DE13924CD6B94F9FC9F8B345CDED7EC36E82B38313F9C6B8BF3D06CB92FD968 + F97EA32AEA6C0C305C162B9FADBBD76535D4E14F9D8CE6BF83956278C513A68A + ACF1298D306079B4744553A2B22C2802A7555C7F154B36E2354E504BE1E0122E + 5B853B8A066045D3104489A7E2DD377AC0E691037BCE5EEFFDEA4B2FB7785DFF + F4CA0BBB0EEF8754A465DB8E9A58643A1AA308CA6EB5B11A816F231AABDD0082 + 6049F2D8EC67AE5CF9DFABDD070F3CDCE05B333115F447266D6ECB1F3EF77B35 + CE9A5F7D7852E0D2D32274F2E40997D335D8DF67B7D9D3194E11240CC38C362B + C0C1B828185873B5CF0B746D80E7148CD066B6AAA6FAB77D5E984420DC70FDC2 + C55468342DC8DD81F146824925798FDD63B3DAAE5CBD6C7738045110552D1A8D + 930862B6983558451485C410495177B46F490BE27BE7CF9FB93910CE64BEFABB + BFA3C663173ABB4D0FF93C8DCDF30DA4CD2610998BD29CDB784B75967C3A0A40 + 662E3E561E86E69FA2E5EEC3F2E57D06A611255EC048A27218BD4F9E6A85B701 + 432BC5D195DC406EB4A7BB53726DA835404B0181C408BA92FA8B1759E4742C83 + 966930BFB2A5AC5C949384B4BEBCAECFE22DCBB7757935F470AF2861B5D83D55 + 962FB66D7AFAD967BEF6C24B2286231476EDCA159781FED79FFEC255BBE699CF + 1FC308E389CED36313C1BD7BF727D3E97DFBF6ABA90C0CA17687EB46EFDB3F7C + E757D369FEC0D6072313C1898921D669DCBE790302C93BB6B43FFBE5E35D3D3D + 8EBA96642A76FA7467C7F61D23C323DD7D3D269CDABB6B37CB18481866245914 + 651C4104494E09BC086E912061C0ECE40C9F4CFCE33FBFCA85A7BE004090C039 + 5172BB7CB2065FEFBE9E4A25B76DDF3A383C0C382D270AD1789CB59A6545A10D + D4DE8E8E96BAFA2F1C7D8CCBA467D209F0A4E124178C24D82A2638D41BA63BDD + 0D8DB7A7D4B368A8DBCD17F97F9671A9CFFFBA80A6AAAA60385D8CA125D5F965 + 183CDD51B95BAB1E60ACC0887B6E25B3CC1B9FB5E65E911BEB6A84D0BFF38B7F + EAF9411591D7D7AC2BCF01556AF546E253BA8D410593A0A5E657169D942CB58A + 51AEC34B0247A2ECF256FDF3564ECA5F74AE02D80DF46B1227BEFDC2B79E3CBA + 9F20194813AA6D361C4600B3FA8F377EFC77BFFC68B3D7DD54532DC3684F60A4 + EB7ACF8DC1C0C1439F0B464294A84E4E8ED993336BD6AD75BB1C274F7E28CD64 + B6B6B64645BEC7EF6FF178180DF2D82CBFFFECD346A78BF4D48E0E0CFEF9F3CF + 5FBB7625169B812439180C0EF887E25286C2198BD94C1AF4F4A034CDF60747FD + 63A3B4D56A7355E93152D233F1E8B4984CD959765343A386A155D5AE702C7AA3 + 6FD8E9742A8AC60B82A6C7F143089210249136337603BDB6A1F1B927BFD25665 + EFEDEFDADC5217189BE262F1C9C0C8EE963D7B3AB6FEFCEAF5D8E494D5934D8A + 376FF734EFFF99B37258366AB356BC57D51DEAE1CA30F476D10D293CCD07E636 + E182CF054BAC521F39052EF53B878BEAC245B24BF6A5C5A411061241113EC5E5 + 118CB237566E5AB1F0DEE0FC8D72D2CA40215C56D4EC368AA3048E179C5B9E22 + C1C58D0646595951555929796F3054BE310B1BA9F0DE0AA4C1F912E7F7AA8A98 + 5BB1B8A32CA3CFCC37049C3B5109E77EC27A6F961014CB3590BCFD05CE97B220 + 2D6F03F050450FE807E79E91237EEE48A134A8A4B4DC73A032D28A1E6CDE3249 + 455034EB3E0F174A9ABB858233F364173D42FEC16C054A16823D17ADA4D8EA70 + 521A6234105226D1DEB6EEE9679EE125E9E3CE3333C9D45478AAC73F6CF77AFB + C726FCD18491C248007826F3D94F2EFFFBDB6F6DDEB465DBA6F640FF10244B1B + 37ADB7B82CD150A8D9E5B1DA589CA1AD4E2769366236A799A24F7CF0EB443C99 + 49A71059F478BC144DF392A8032045837F93C51299895DBA7215EC5FDBD468B2 + 9A2002C06406CA64DADBD676B46F92790E0C11712E9DC8648213931E8F3B341D + 1A1F1D07186AB19ACDAC2993C99024693130E958CCEBB05799F4E8251BD7B7BA + CC66376BDEB971E3B607DA15583D7DA9CBE46BB47A6AE6FB17F88900BA82CC3B + 4154321995BF0D4A3A1967CDD6851D79950B431E885CEAF2FBDFFF0CC2284D01 + 4CCAC4538520541E47EE3D8CEA467018B2121805AAAEACDBEADC1318D55396A9 + B276DB2EBDA8E5CAC8C817531246F310022A0008BD682846C0F339014B035F09 + 1855244196327938352F7945309AD39E2561B4F0C4DB5F350DE889D4DCB0B118 + 8CE60C2D390D01178E3185300A411E1C193DFF9B8FFFFBCDB19B3DED6BD7B66F + DAB06BCFF6C3870E9B9C4EAFCFE3B2922696FAE8425782CB6CDFB91B41C9F0C4 + 780268F529DE627392ACE567273AA702C183BBF7D5565703EEB86DE7963AAF77 + 667C6A5D6BEB7878AA2FE0AFAF7283112D1E4D2423D1D1C100419962C9A490E1 + 5C3E9FD962C3718A3418714A4F2482A2D8C474A467601083E0437BF7D206039F + 4A208ABABEB575435323E0A42A2A4793A981E1202768048EE9AB4CD3615914DD + 1EB7D5E504A7ABA2A86404BBD9D2D2D4E034333E9FC761B355994C1B9B1A6BDD + 55550EAB46429974383435AD9AABADB5CDF33D4B9D4D315A2EF27FF9B2E0062A + CB00E439DAC866B74B62E8823AAF414266B561B4E8C05D81515068339B8E26EE + 228C969756098C166EC37A38151CC7E7ADA773AE5091B46C5D49561469F9309A + 23AD3C062EC546A1AC73875CBAE5CAC8C8177327300ABA3132EBB7B32C18D554 + 80A2E99C2BE76350011F2C9432BFA3F076169E33976996E18FB9309A7D140405 + 1D002D2298731F05303AFF25AFA5F2C7985CC0D5942A3E2C87FA8D8CB679E386 + 07773E2009BCD9EB42185CE3130696D976701F9FE46666525576074950EDEDED + D1D8B4D56241202D34316962191A47CFF4F6D63AAC7B1F7C90658DC78E7D1E08 + 6649D2EBAB79EFD4B90F3EFC68D78EDDB74646FFE1BBAF3AAC8E03FB0FAA903A + 14F003BD10A016802EA0BBEBEABBDB6D341A059E8F4463692E63B358F6EDD983 + 22F0D9CEFF713A1D8CDD29C593D3F1685A51C7262323531114271C4EBB24E91E + 102696B5DA6D00730D1881A32860A55EBBEDE891234D8D8D403D1744712A34D1 + 3F389C4CF3B88116D33C2C2A1042251403EE6D44E7AC77643D2C2F321B70BC44 + 6F2C2A05B0A81749145545A10C3494CB3CCB60A8A6BBA7EB30BAE4DC68C11C52 + 053CB9F27247D254454571AC823CABF751994DF9BEA2DB85F3BBC65DBCD532EF + 04A000D093EF2CAAC81D5C6EBE00069EEF305ABC8C5D68810F78E8225ED04B1A + A22EBF5796B579CADD218B1914CDC9D6B9E4BC6785AB4CB3493258292A4EFA13 + 8181A7FEE88B8F1D3D8AA5F87070040E23B48315854C5FD7F5ABD7AEF50D8C7E + F9F87197D7F7FEAF4F0A1CD7D6DA16094F4BBC20F31200A9863575BF45920C45 + 6AAA545B534F10A4D96A23EA1BA622898189F07028120A45266726DEFCE92F6C + ACEBC0FE43F4B5CBB22C89AA266732B4C91C4F733E924411844BA72155638D46 + 9BD5CED08C22CBD170E4C2F94B00ACC130B2A763274E9B82B706C7A7424EA75D + 458870243C333383A198DDE954746B4F98C009DA4218701CD04F1BC37EF2C9D5 + AE9E1B4D755E9680118C343066415649586330DCC192E84458888571A77B4E69 + 83B27EF6B934B2E4EFA6DCCF51962400CA4516A505F3A185E99B3E6583A75580 + 61F0E2F5B4693836BB58BF6AC8523A49D62A3D991E2D68B921470BE8EDBDF6C5 + D2E728114C532A31C25F6AE85DDCBEA70016F5C9846558E0EBB1450A5C574BD4 + 5F35A7D2B20F5D848A7A6215214D52C6CA8556B4CA34CBBEC4D8B49208D75859 + 96A6320247709C2C0BBDDDD7EC5E77702AF2EAF7FEED3767AFEDDBD5F1F5AFEF + 2769E3E0E0484FDF4D005E81911112C1589A61190642B4B6C6E6752D2D02C707 + 02237687A3B6D62BE3783C99BC7EB38F8BC5681CDABE71DD86E6F589443A9948 + C4130992226D4E276D305AAD769FCFCBD0349FE10DB48120B1E850D4EDF2AA22 + 37160C8A5C9AA1989FBDF58EAA8A75D575E7AF5CFCF0930B06DA64757A87C7C6 + 13097DFDDD62B5E8DA74863759CDA09F911806DA4B13441243A6A6A75F7BF3ED + 1D9BDB363456D7D4366024439024A4CABCC045E3D39313499B6F98D1615437B8 + 072A537108D74A7F79B3F5C0D080CD871C2C4142A1220CBDBB2BF577B1881C8F + 53CBB079BAE76536E89A0AADD8BE405F40BCFD065737C853450266C394DC3D5F + A63BBFC3DC6300ADE69A6859EDB334295DC9627DB6289220681A4131F0C2E45D + D1F05DDAA463B1D70D347A419CAAAE41ABEB3A84686ACC1F70986DA80CF79E3B + 0754F2E1947CE252EF14A40776361108CFC51E686B898F4F7D7CE1148C233845 + DF1A1D8B25D3BB3A760643336B9A609C66C3B164E7A933470EEF57540526D483 + AD750EB6CDC6E0D0FF117765BF8D1CE99DDDCDBE9B6C9EA248EA1A6946C768EE + 6367EC19DB489C5D8FE3DDB513C4F67A176BE478CC4B1EF29CFC057909820049 + 900439B05820C86E9C78EDC076168EEDB5772ECD680E8D6E89144FF1BEBA9B7D + 315FB3250E4F51D2C84E4110BA8BD5D5D5DD55BFFA7D47D527087FFEC73F1AF0 + 8D6992282B0AC73B18CC6AA7D9019FCFE572028BAC6986D2299C8CF36E3E9D2D + DE9E9F2748ECC498FFFA4BCF73A8EC73DB35ADF2773FFDB7AD8278F9CAA5C8EA + 6A3E9542118C22488FCB9DC9668106C2A0AE212ACB50C944AA948ACC2C3E1A1A + 1DF18F8DDC59584111742D9E73385DBFF932BBBE1AC2ED74AE284319321F69BC + 16202B986517F3F6C93C5A97826A9A46B344DB52FABD30743FAB98668E1B6C59 + 51B5B5CD5423D3EBE23CAE9D493514CD0AE2CED0C2ADD889512F1C5444391CCB + 76AD10E6AAD1806105CBE42AA96CF97008A0290A4E9162B1D2D9D571ABD53F60 + F73859B8119C43DBD2B90A7C11788483DEE5085518752EFACCEB41D1FA78EB55 + CDD7AF6FA96BF7AC20C61DEA6E7D71BF47819EBE56DD9BA069FB9E5C0FE8F374 + C8D7D65AAFA6CA5541C329163BE8F6D59DE2D26ECD35B1C45A9160D0C3562BD1 + 74EEE37FFC1714C5FEF0D557C727264B1501A454E8FA940591CBD2ED5FDF3A75 + 667A7C34F0FCC58B5F2DCD3D78B260E52D6363A38B0B4FBEBA792B10086C4562 + 2FBCF8C2D8F1899B5F7D994E6780D8ADADAFFDDE1BDF3B7FFA2CA26B918D8DAB + 17CF52EEA1AD5886A618822040A897AA554992145956902ACB71995C56AC4A6E + 97E77F3FFFAA582CDDBA756BD477E3CC9999D9511F6EE7EFDCFA75215FE46DEE + 48249249A5264646D3992CC772F97C3E9948B0368EAA1188E1ED5B4DC6E3206F + 2EAEAC5DBE74756C646469334C12B4C3E1B2E2F4D2D2DAFFFCF2F3E0D4388BE3 + 2486A513D1314B630953D352A65AADEFC7EB1C4CBAA6D517D17503508BA51343 + CDD33E30EA75D94CC40C47B20D24026CF5389FCA264F5613BB85B9E9E33E3858 + 5C4DF6EA592C4DCC4C18659EAC25EB306A24C0DF33D381702CD7C8D9BB9FD6D7 + 9975E98500A0176687716BD3C073322301A7AA6A738FA3F154B16B6DDF44EA26 + D41FF4E688C946BFB9DD9BBB3410C3295D2EEFBBF811A43DACAE9DC2BEB1D364 + 53F0A8BEFCF1504DEE576BBF29A266EC5D528437899334D2B22ABC53D7D1B5AE + D6BD5D6A16B5926725AD58286DE713B7EF3DFCD78F3E536B96A08DFFE10F7E67 + 3D14E213A9D75FBE6E5189B333B31F7CF0216B23CF9E3E3F32E27BFD95EF2892 + 90DECE700C716AF664241C4B67D3E170A8542EDEF8F66BE7CE5FB073FC763C72 + 7FEEFECCD4F8CF3FFECCCDB1CF9D3F194FA6C4686171332656AB088A1228AAC9 + 2A906C6B7D0FAA72B90CCDB6B3B69BB76EA6B39953B3B3A4AEB0561CB528BAB1 + C70AC1D08E71BF97E0BD284B5572D9622E5F2E958D70B39A562816811E053D1E + 9FD78BA196DA890954D1799B1304FC8BA74F4D0DFB4F040234EFA26DAEE5D5F5 + D1F16365594C45220ED7C0FAE6C6E96A9522889DAD969BDED901864ABDA8666C + F7A5D7ED66ED5BE8752E766A86D43E309ACA964C1875D8E906C6F1B6A74ED100 + 9D4F768F791B6D1EA4737BA1615BD700ECBB780AB00F0318DDE72357CB226D63 + DB32A19E2B6747CD6345D50B25C96C2AD40C7F57CE8EDC9C0F7741D26F24D51A + 715F3B7ED8FFEA1A0C430D42BA978DE7A836D6E859814148B1A313EDFB6B076B + 2DC1EEFB9737F60C3DA01AB98FF4BE3FD97D5F56A6E60C4D918C0D0470639F40 + 439DD7A3D13DB1B4E1CC60A9C9BA6211A59B5FDEB660421480A93EB83F9F7B40 + F06CAE58BC7EF5CA5BAFDE286604A773B09849AE2FAFDA39CE6A25CF4D4D65AF + 5EFDE5E75F08A5024171004C6EB70B3AD8DD7BF770C2F6FA6BAFEABA5ECC1570 + CCBAB8BAF9177FFBCFD7CF9EBD76F9DCEADAFA6A389D83B6E3184950AAA26104 + 06CFC050349C56E52A6F73CC3F7E188DC5BC3E9FC3E128C6A2D592504A454986 + DF5CDE486DE7DEFAFEEB201BE6E46A341C29640B5602073E2B837C89E33445B9 + 1866D0E3962A6527C3E473650AA7C562F9A5E7AE0406DC9950682D9A32F4A736 + 97C737B0F6E86E2E1A77F36EB954A994CA94DBA51B9F1ED9E1EDCD09E9F1663B + 4ED4FA6AFA5AE74F1DCA504B6B74FB1E30BAFB95D2BBD009606AC2286025DEB4 + C7D22E741A17787725FD3D4825FCF4F38F1E343F575B85BDFA697352A42A46E0 + F0C91B7663A8E1C2EC9079BCB8B6BD16CE34B8F3F4F880C97F2FCC063FFAA272 + 28E9BEA965875E8C54373321E8E1710C35029C63DAB3B5BFA35507465618F68A + E9437A34D5EF25EC9BEEF7FBAFD06C555FD2792863FD115899DA1FD6D89F54D2 + 6409B512A8D50AB2A411FCCA886B8DD45A9DB47A37AA06DD42ABE9245ABBB3B0 + A8A1C250E0184DE09AAC24F2D97FF8E9BFE78BE55333C72E9D3A1B5ACF58ACEC + EFFEE09D52615B557514D1454100C11C64D87832E91F22A0EE50383C7DF2A495 + 2463C9C8AD3BB7799AC06A966B972F97F46A36977FB0B0B0B4B6E9F17AF21555 + CC94EEAFAE026FE4391A70D6F05572F0524562284656B44A4918F4F983C36304 + 8A6DA653C0ED24E0AE6AF12FFFFAAFE0A6BFFFE31F6D46A3AB77EF66D26927EF + AE22354194868343C56291A58DD850C04957D7565459F50F066996C1AC184C24 + 91AD68643D144D158213768AE5A01E635138669555D96673E8F57D1C8DEDF390 + C6BB6A7DEB96B6EFDD3DA94AB35B48ADF5DF6E6673CE2EE2F665A34F61D43C68 + 6065BE243AEA080838582889F53206434C672B660113BC2AA25C284B0D411E78 + 62B36E1424EE468570EC76B2C0494D652BD43C12740606EC700CD47235946928 + 6175CDD8CE16A74859D8896F01254D2C060C5D5CDF6E7E0438853E09606A5418 + 7000C21AE5FD0E5379BAB8B1EDF7DA211F7ECDE48466FC3593DF6B83020C6DBC + DC74AE128EE745A925BC38FC3431ECB1D7197A22550AC773F08C5D86183419D8 + DC33D041637712143938F01DB1B08D2046043555168EAAFE3DAEEFB118B48B59 + A6DF9E6847C01F2DFDF1B847533AF76F6EAD485715DD7009AE4791353DDB76E7 + 5B0056AB15C7CC0D87BA7B9320888ED81D2CC2B2CB0B9B9343C70659262117A0 + 82B1A07F2E31BFB1BCF4FCC573CBC9AD85F5E81BBF7D637AEA54399313CB65AD + 86C93A1A89A7F365C125EBAA450C85362D38323E3E11DA588E24C2B1D4712F06 + 0367B450CEBD73FDE2E8F8B8CDC6075CC3278E4F7F72FBDEDDE54551141D14C9 + 912443123011A8992A8AE9E94281E75D1E92E479C7CAD2923F38303E392AC9D6 + D0FAEAE2E27D9F7F1024785DA96EE7D20AA2B2369644318FD73B1A08C6B7A23C + 8C228E4E2492E17892E3B8E7C786393B9D28E4326285B112CBD1ED871B9BAF1E + 9F6668DA4E105E9E4F5624D5AA3B3D83A675DE5C71DDC3BCB497035C23A98A4C + 1A1EA33D00D4D24A4B9BAEEC6FA90742EA69B229350E5643A94BA7462C756005 + 187D2AD1EF22EFB4619E02041401B04C8C0BC57230134E4FF8905DDDE868D0E5 + 71EE88E723BBF00A70C973D48BDF9AB0EEB254B7931B1FF1CC3D8A34047F59AC + 120CD58051403AF3C044C9B6B41ACE008C5AEA82FF0E8C069D1E87715F86C147 + FC3B0BBFA025835EDBA737D71A175E38191C0E381AA780F21323EE5FCD854C8D + 01A461BFE3C2C940C39DDBE364A6C6BDBFBABB592C37C52FAA8F1998F6F57AF8 + ECBE2FBC17B0A0287A5822DC3EFA9F51F6C7AC64DDAF68DF319AF6E5DAD37C6A + E00E6AC51B12FD6170F2E0CE0C4762657AA68B74AD6606116A7C695D01F11F53 + 242BC93CB54A353514ADD57092256987D7E5024E1A080686A3E94CAEE0E4EC2F + 5FBF3615F0B118F5E12F3EFEFB9FFD623E145745F10FDEFD71763B89A8EAE0C8 + 88D3E1D4550DA8622299B43B1DC00453DB29966185B2E471F804414AE9B283C6 + 86061C7FF6A77FE205595B9430BDA6A2981BE47FA713FA73A55822EC30D991D9 + 42215FC8A216AC24945555E69D7CA95CDAD8DC78EBB56F9F3E7DFA8B4F3F5E5B + 5FFFE19B6F7BFD3E007D78549665DD1E0F86612C45131405B47CC0E7753B1DA5 + 5229168B4912D0B21A49D2D007EEDD9B4BA5332F5E79AE2456E636160757275F + 9ABA343276EC49623D9D4DB987C738DEC372EC8E1DB741470F6341A8699A0AB3 + 5607805A3A74A3ED37E83FAA9B54A206509AE411A8683C5930F34D60F5EE1A9D + DA14A3CD32BB495A9B53289A058A671E034402B6027B85F22F5C3630D4300D3D + DABA797FD3BCF0C2A9A1068803A527E8A77BA999580CC5BACAEC90098CD828E6 + 68685477DE02E0EFDCE3C8CDF9B020C9F5D6520D4406E4353134BE5D0464BCF7 + 380AED81565D3933DCB8691D432D85B278EBC1D6DC420C78286E45AF5D1C6B31 + 7399F733C2FC1CDA3AD434B2FEBF1D48CD64844ADE6B57D07E4FDAAF9B1B0A8C + F61D9E3A2FE9C8E96B9BAD751D1D076D6CFB65DD429DB7E7742FD2EB4DB5DE12 + E8AA2C149A2480A60B818059E964BEE0E25DAFBDFC1BE72F9C75D8990B3393C7 + 2727489238776ED6C53BC5B2A22B6A45D5DEFFE493F73EF8F0F1E2D2C2EADA66 + 280CAFF9C4E42449D1D158BC522EFB7C3E3BCF0B8260636DD9743E99DC2E00A3 + 41D095AD68A65CC18CB81E882408776FDFAEC12833C286A31CC940CD85722991 + 4A89701BA552AD0A048E52340EF49A24A06E6A7B3B25962B53E3136FBFF9E6EC + D44C2A91882713A22810040973B103F0D4C60506073D1E772E9F8B4663854281 + 24298EB381ECB6B8BCB4007F4B8B997C0EC0DAE71B5C7CB410DED824483A9A4C + A4CA956822C3BA870802B3D4C379EEFAB234FEFA7FDBC61FCC28E6AAB95A3B09 + DDB1C83F15E4DB43E0B5B3D12ED368835D7ADD068499980899804DA65CEFB01B + F06A4AF490F245B1ADB6C5B504E023E02F7C14966ED9DE1CA093A14913041B96 + 7AA0A5E65DEE3EDA0208ABDFAEF2CA8BD3D6BA546EC2B461650A706D6DEF2A4D + 9BA9974AB461C107E033B5AB80A4464ECD02C4134E45490188340BE33806327E + 3A2F80202F880A5051331F4056518D0D65A0F0B50BA35095CF6B8BC40B2D2341 + AF8BF5CF96EA7AB3AFC9587FB0D53CD00C2BC92AD572B365FC40B7D88B3F42E5 + 4660B8FE737C1B7FAC07E63C8447ED11AC64EA7AE1BEE96D1771BDB39C2255A0 + 429C623AFCEFD14CB13CEAF28C0F4E3C5C7838BFB2E671BB35CCB2B2B5EEE6A9 + 99A113A77CC75EC99757123F5351CB7A38AC05FC1C45DE9B9BF78F8C4C4E4E2D + 6F6CA6CBC002CB80A4044180D0E3E27892B5552401AFC959517AEFFD0FCE4C9D + F00E059D9C4D13F2EB2BABFEE9D941BF7F6D79C5E6F5419F2EC86221BDCDE935 + 2BC7610068A806280998C8B08CAA2A77EEDC3D373333E01DC8677242A1E0F30E + 3C5E5B2F168A188282387F62748C77D8F2821089454AA5225B57D76633191B07 + 326E2993CB8E8E8E81801FCF6C9FBB70FEBC2847D6A3401AD3D99C8E28DE419F + D5338492AC65C769D4588950ABB57C817DAC05DD395414B95D316AE998316B9D + 7C747FEEF74FD5A34E4E5676C68C89AD853A8C321401623BCC81961E7C1030D4 + B2A7DDA92DF907F89D7EA3EA0DFA092C15886D83F3D6AD4C5614C30C8FDF6748 + 0DDBBD20B5F81B02985AEB8CD2C47133AD8533F0D790B700528D472E4B759EDE + 320C40BA6F83D1BA85E9202DEB36DC30D430D6EFC6DF3D5A0FFC832704C50956 + 912B4F837A1FA211DD2EB112F453037D871BD09EABCD8CE845DDA6ABAFCDCAB4 + 4F27FC7EEAD19E57B67A42A95501FABC15279B2BC4195BCD31F4E8ABB95C6CE5 + CEFA52285FB15174269988564A0E8E7ABC109A387672F6F4F9770501E158CEC6 + A7F3C5A242C75736D51AC2E0D4F999D31C4347D3618B5EA581BE205A451682C3 + E3C5AA54900A94A66F8712AB242A6BD5D0EAB6A621979FBF4A325CAA242ECE3F + D0750967584C45956235A7294549C2A12E864A978A2549B43138A28A1C4F6BAA + B2B1B1A95BB0703C9C8C273D0E2FCFD90B42C6EB72D979A72049D1ADD876220D + 4FE670B0146BAF0861C482A318F404C4E9B23B5CB6AAB13F346AAD955902E11D + EE95D812A3A93597C7191C635C86DDC5DCDDAEF1CE5A5E60372D78670218C58D + F54B5D15A31D0E50ADC2C5BE563199EA51609D0D883431D1506E065C70301A74 + 31145ECFA9745EBB9F5B342702DF51025CBF34DEF6134DEF8C2E239C78552118 + B25A32241DA0813485377B62B5259E337E6AC3CA3D524311B18765DF94DCA166 + 60A06D3B76309D6EADB5BAD40152C33348E580A29815D57BCD1C470FA57DEC30 + C68EA0246784C3ECEDF47E500B3746D09D1199FAD7BA1356D330805954FD48BD + 940EAE63DD3F4A76B9B8871A78E7E21A7052C05193AA9B79708438C7C2A2FAF0 + F697C74E8C9DF048C180AF5212E4AA1C8A27EF6FA52797C27FE4F6FCD68D1BF9 + 4C26572E472289E476DAE71F280AE5D1E191B7CF5F78B830FF5FFFFDDEA0CB8D + 616832959470A093928AD4104DE319EACAD949D64DA9D5D2BDFB773EFDFCCEDB + EFBCFDE2D56FADC5B669D20AD0532EC8B26EA101B8D3B2262A1C08FE5AB550AA + E432D91127131CF4E07AF56FFEE9278422BFF1DD57E6179EFCC77F7EF0E6F75F + F70F0ECA08C6D1544910939954D590D59052A148DB38F886BCC3E17039ABF564 + 848C27081BCD6E87B724B1524594B9A505DD52F20D9D1449A76D689CE1DD96BA + 99DE7C3F8DBED9F6F2FA7D31C3DB8966C8FD01A8A599AE5AF607A3B5541D4681 + 729A8A5141924D70694064833FEE03346B7B9CB5A5C5B5646B46CBAB91259964 + 2913464DA33F609F7FC0DECC1FCDE471B23BBA885CC572B0D49F40028287E2F9 + B6B675C56B43AAD76BE62E3F8DDA0F847B7536BAB7A8FB75BB8EB62718CF38C9 + 188E3BFBB738F56C9521CB0330D7B33ABC96F6C71F51D4AA5994AE85BA3F7B7F + 31BC47935B5971FDC22EB8DCEE20D70D62EBE75D2686AEBE75D0871459225AC3 + 8E62B4831E3BB978F7B32B4EDFE8D83140B1582C5ACC174ABA06C8B8148FFFE4 + FDF7DEFDDE77832EB7C3E19C3876ECD69DBBE962CEE5745136D63BE03D839C2E + E5B3098033459144C58A68A2244A169D24AC2465BDF19D6B52B52214F2C1B120 + 76EBC1C3470FAFBF78DDEBFC3FE6AEACB96D2C3B63DF0982E0266EDA2DC9F2D2 + 76DBEE65BA67E2EE64B24D4D55E621FF60A6F29EBF90DF914A551EF29CBCE6A1 + 93543AD3EE71BBEDB6DCB6254BB2444A22C54D24B1EFB9002D89FB22C9D373CB + 0B015C9C7B71007C38E79EEF9ECB12180C402E7F780861642295C128D6316C0C + A64CDD3665D390A5F90FD6166673F9AD57C0600EB3B4DAAA1F1C955CE0C39098 + 2B398A2CD5EA55C5B0CBF5136062EBAE7B58392668329D9A59A59946A3F1CDA3 + A3F5B5155E88144BA55848B034239948C85615D8B9D96CCC62A30C97A4E2192A + 14F1FC4CA3A75A3C53EA840FBAF74ED9C03AC170620480423D466807E09EAE50 + 3AB2A133706C9384CEDC7355F3F1142094701AA69FDC73EFBD8E8ED294B4F62C + A933F2131404B254CD7AB71974D7543426126A773E5F3C6907FA6FAFA69A927E + 761614D895F74E29A50318FE432EFE2C16CF73E7162E80E3B5C5784B368A1509 + 20B2EFCE074737772B6D29388EB4E95F96EDF6BB9EE03E39AE8BA1DD38380D03 + 1F791F799EAEC013F7E1CF5F3DD4D2DB5345276AA5EBC283A584090A41474F91 + 1C6F3FF60F9D4C3697697A12FEE5F439004E07F7A3D7AF8782B9F91E41C1C00C + 3D456EDB76130B77161FFC996237C2B07754281C148BE0149265666322F0E22B + C5FCEFBFF9EF0F6FDEB3511498A8368E3C7DFA24168932140D9CE65C6A269BCD + E64B478A6540344131B4AA283A0C454812B42A86781D862DC55EBD7EE7B7FF30 + EBEAAA2137590A6518BC25CBCD6653316DD5B2602C944CCE44C27CA3D1845C6B + 616EF6D68D7543516202FF77BFFA6B4B962D5DBA75FB0304C3E3F1D88BD261B9 + 524A08D196AADAFEA41207FC50341D23B0B028B214FD66EB4D319F7F4B11B158 + 9CA248D5325E6EBE1463218A12AFAFDE689A55920A13D145424CBDE33804E99A + 3BEF3D3CDE043A871E0BF41F3E65C20C5DC51EEAC4D04E349DC8A9EF01C7CE4D + F03B7D6A8A368281D1B11FFC61053B8D6E03737269D69F9B7F6B35F5EDB37DF0 + 63692E766BD58F89EFE66BCF5F1FB5ABE9B2CACF441114F11CB75A5700AEC544 + 16B8F65F7CB20CE0B23DE8197042DF05ACAA0D65726B145C48ED448D461860DE + 8643541B5517736234C2FAE456DFFC8400980218052D2ECD4677F27E0E81BBEB + 99F680E91F9E174A95DE2F8A3F1001FC71FC12E960C0ADF6EF353265C2BA09BC + D78BDCB1AE124C70C21CC7746D33C84C3A5E86E77F185004DC78940892C84113 + D98F3D427AC64EFD90D7D5B0942E333C3A963D3AC525F5361EE4B9711CB4930D + E279B4905EB8F9295BFFB174F8C3DBFDBCE9401C00242ED468359752E272367E + 78987FF2E24D2235B37F58BA77FF8110893CDBDAF26C3B2146B3B96C6E69057B + F1AA5AADE15C98657955566BBAE22950E120736B799684094D31FFEFD1130F42 + 6FAEE60E8F763C13BAB9726D6377DF41A04AB3E9E25434C1C1884312682C123E + 2AECA10EB3F5F2758385E792D13AC048DD9B9B9FBF114F87291CBC324224CC71 + 9C66688A6B6334EB07601D2722FAC9EF6549F2B3EDF9164CC8362C7F013E31FA + ECF9C6E3179B776F2F3FFCF4BEA6D555884663197C66090B45DB97EF4FE204DF + 954ECED33437DFB20C7F6DFAC900B4EB9FA04CFA4A0383F48C275FED482952ED + 80D16A7D5290EAECEC99E578EF660EA015C065E0CB1F959BE964389508FFD5CF + D754DD8C06C629F8E4BEEA98ADEF5836303D08E69D5F0F00F7F3070B01BF0A01 + B8D68EB39F35D8948D6F9FE5A7512CB4B155FCFCDE0286A10F3F5EAA9D28C012 + A783F1DFC251A38DAA00D3E75202D879F35AB21DB56F0FCE564F5480B0DD2E5F + 401D6DE7E69E544383810F41FCE4BF8E3DA19CE1F22E5A696481518C0C124101 + B3DBF28297A31BF1BD20C88F0469F7D077998CFD618A5E5D75F76BD2281368CB + 1FA585079C34B91B7EE1E1D121C30E7DE78EF0EB87657BEAB35B1DC7F2C3CA1D + 4D6224C7A6EE3130B0EB8A34B7AF9CE81C4E27C568BD5EAD5594F585142F445F + 1CEC1CBD7A83C190DAACA5A2B14DEC6D5D910E2AA552A51A8B67AEADDCDC7C7B + 801104CBB0F556E5B85C28ABADD731E1EEFAB281002BA4FACFFFF61FA0E1DFFD + F637E938CF22E14C4878666C9021D2ADC38D668B6259E09DB324150D09F15098 + 4110AD25375D6C1FAAFEB8F14AD25D319D431C67319D6E48D546BD21C90A0657 + 9ABAC74733622C2E0A026A51D97842D1F57C7E1F38276B2B6BB3D92C7880544D + ABD5EA3C47CF24E6C548BC50AA5A741815D24424D356CB69E69F21B6243CE8CB + D75D1CCB6AA76AEEABD24FC03F7B9CCE8F0C1F68EB6EA8D391EF74993B2DD30B + 4493A0C0F66C1B89C0663CA3E27FFFA2B093AF427E4C89686368ED44FEDFC73B + 3D011FE0D793DCBBF10470E8BF1E6D0308D6BAC725C1E6EB9DF2578FB6A79D06 + 0AB0F2EB276F6B41DF8005DAC650009DDFBF3C3C6DD1FDFAFBBD6AC307F13047 + B61D7C60A8FEE1F910BCF6825507A70BD8F7167F623DFABED7E9ECE8F0B4C783 + A719F1574DA17192F573B3513C4E72FE6FFF0FE76F067B40053F15348CF4332A + 2753503F69D49F5C399A09EA4DB077189D6C2C7B74A84A86091CD2216FF0395D + E3726EC787F48CCF4808A209F3B4706371E9DA4282CE0A06ED69E9986098D69B + 835A3233F7EB2F3FFB68653E2BD0CD4A11C789D9E48CAD9B85FDFCFEF68EDE6A + 6612D199B888C39074D2B00DC3B64CC475711475619816A20C17727499A51002 + C1499C4550B25C2BC98D6A8C2267055EAF97E5E689A6AAA5D261A97A9CCAA5AE + AFAFDEB9FBC1DCFC0249D29663A8460B02B62A8319B649500CB04E5B4DC9369D + E241516AB5488CF0B3E78B2243D11141004FD07C6EF6FAFA0DF0AE981630492D + 0CC7565656C548747B2FAF21242AA4F0502CB8055EF05171474299D7FBA7F778 + 40BC0FD28C7654F13A31B3833AEAF5DF7ADF34B8F3B7FFD4C9BD1BF4131EF15F + A7B0BEBD3034A02EDC271B06562481A3A6E57450F4FD0F719BF0748ADDBDD298 + 48888D84ABBB873DDD0496637BFA66C770EAC5971201A2DA91F7B331811E61C0 + FE6D739E9AB2D6C95DED5FDFC95FB186263B7308C01034C4D7EBED5B7B0358B4 + 9A6E1AAA3EE07E8D96D6ABBC51371AEABAC9F0D548EB7F6C86AC4607F52D14D2 + BF6247C77FE74417539701949E35D6372F7DF4BA4C6715472F28D22B101A22B0 + ABF71DD5E04E81BD1A843BCFEEB9E42EF108467142306DB453B5B057AF6007CF + 3DEDA57CFCA2717488432C16E6F39563DBF2588E4B8AE2723A777074F8ED8B1F + 1022B4B07C4DD3D48554E6170F3EC9A6334795E39DC2FED6DBDDC2DE8EA55A55 + B5F9E9ADD5DFFDFA5733E9B807300645F7B63729020578A7EB3678279EBEFEF1 + E9F6EB9968A67054DBDA3F0CCF245002939B32CD85EEDFBEFDE9ADDB148E62C0 + 61B4F48D57CF51965B5E5E330DA5B4FB9AC2B1476F0F7E7C9BD7A5D6E31F3657 + 6FDD999F5FB255992730910F21185A3EA9310C130DF1C008B58345C8EAB53A06 + 131CCF73420289CD638BF7F0CCDAD9851B2678EBE0CE64605345102CD3D45439 + 1416DB4F51D7B11E0BB4EBB8FF4BAA95FEE51FBFBCD2B4CD97700AFB2738B5E5 + 755BB8BD0DE82D4548C581DEDDB6A5797ABCC764BE6409B07814530A406780B0 + FDC0D75B1CDB761CBC2F15CB142598123A3A63DE1F3B583FA9D409BCF50B8D3C + BC737DFD2C67EDD5A22EC4521A586FA8FF3E9DC04BF8F55D32CE4F0958C841D5 + CEB109A008310E873E0B35B866ABF1EA708FC7A514C902539084DC7A597AB1B5 + 277CCEFFECB32F0C867DFAF8D9FADA2A41F9AE014D9238ECA59209CB35CBE552 + 8D22618C22786A796131954C3E7AF2F87F7EFFF4E1CFEEFDCDC38F51C82D14CA + B59A6C1AC7754542B9301F8A452344A8615AA661DB5ABD51978F0E6202FFC9CD + 75926210CBD6754388CC5011F1E8B8A12B2D53B5EA721981B14C26F3EA791D34 + 4A9334E47814411028128FC5498A0AA6F634CB86A5A88A69FBDFC57ABD11E563 + 74388927E690E4322AA6CFB51338F57E7CC9EBA08E9EF9F813DC24D3D4319F78 + DFEBBF434301B4FDD49D6FBCEFECF7EF9715EE0FB55B36C9D2C142A157D2DDCB + 2D2532563EE8B0DB151DBA80827CDA138A785798EAE98A68F317A834368C3309 + 4BA9BDCBB1F4DE5D171D1E9D84A5348DC09141A3612A183605EAAC3E00D2419F + 631BA75A898FD9FBF1793423ED6FEE1CEF9C545AF3119CE7C3072DFBC9EE9BD9 + 1B2B3C4D6B8ED152A44F965758188FF39C6B28300225393AC3D3559E81102241 + 1298E7D524E9D10F2FFFFDF10F36815C4B47130287B886ADAB3B8513C9863D13 + AD5A082CC4E2311541EA0D4DB66CCD5F62A45E0790EA9858A95CD72DEFA46560 + B682E094AC388E8661644C6E9535C3D17488E17996C309DA1FED8249DCC321CD + D13981550CB9563E16C518A4DBA54AD3B3B1B9F9453C9A42A3594F9881681EF2 + 67A1209EAF271FD110F003BC5968CF6D9BA478B665D10C3B16453B0FF6D830FD + 30FA134C87B94C31647F78F4AA607450B94A8504B73C608F22BD2FDFE442500C + 05C59D0E46FF18C1FA8BF66440086558A6F7EE33CE4FB34DED9D293A4E9313E3 + F2A073A7A33D0D8DD74F67E40E0C34F94F910BA3283C4826D8818A8BCB5FE4E4 + D75FBFFDFEAB5AAD6A40084332045CC728746B7BF3BBEFBEABA8FAE6ABD7F757 + 6E1061C606A26CCB813DCB00DE6DD3756D860DD128BEB7B3F30D64FFF9977F81 + 4412823F6790C429864570C7AD814EC5C478757FE7E5F6F69D3B1FDE5E5FF5EC + F2C6F6A6A16B188AB98E5D291D71B3B3F593DA8964398E47E34E846731146E18 + 1AC35048B56698164EB31C4BA218A26B1A0E5C7D9A92145592A488188946E38D + E3228961084B31B2B3343B9798491BE1A41D4E38AC10D89A281CBC4F6DBBC4DF + E31BA48314384CD741095888C0432447A068E7FE5E277054BED14B94A9BDBBCB + BDAF5A4B8E64125377E112D5A1A1CCE8890A803FC727678CF5EB87760BF583F5 + 93648ABAC0654EECD68E387EC11B7A719692631BFDA6E818C9C370B937563ED0 + 3D19E8938F61298D2500F43439441D6790E9C72BC71C477076F1A3ACA9CB8683 + C80513386E00314CD3D095F95C667189F55CA852AD8A7C58524C0CB2C083B55F + 382C556AA022784A09005FB6737870F0CBBFFCE5DAB5655B55E23CE321AE5AAD + 02048F86A9DCCAC293AD97DF3F7D1A17428B891883C149218E42B0A6A9BA6100 + AF9C651902478F4B7BB985E56832EEFA430E22853A4785423C1A2F376526CCC7 + E271496A341A2DF0C3B1402780BF06E92D0D803643B1B66D335CE8835B39F0C8 + 5B140FF1718F9FF1E8F0A9A67C45F9AB9CF9AAEA8CACF7A97A78B18235ECBC41 + B668E7F6E898DF84307A95C0375EFE34D50D45F35781A7084BFFA9565B9BAECF + E0E367DB0E7E9168BB7716B908C8A3F078AAF9D576FD12ED4CC40085C62F84D9 + 6FCC39B669B757A51FE9869F6E4C887E53A3DE881E8E6C68B8E0CE73067CB7E1 + AEC687B40A531C7FFDE17A6C4179FD957AF83C25965B8D9A140E3DF8F07E389A + DA79B3735C2CA66752140CEB960EB013005236370B1F9754D3D2552D954CDEFB + 60354463A463CBAEB35B38D83D2A86292C9D4A3AF923CFD2EB2DA9727272B0BF + 9363B144762637375FA8359F6C6C02241522615557F307793A44C3385E6B3624 + D5984BC74361BEB6D1304C87C40884227192A62D7F8E3441909A61188A8AC328 + CB33248209EBD765609C2A5684E765DB3319D10518CA464E95E30083140AE62F + F99CB91EBF7BE2C7D3B20C1C2347902EC69126FC820D796AAEBABCCF06F4964A + F11CB8A7233B309DE37C251739D094F19D906061A68B053DDA05F8F5C0207506 + 52CD7FB25199AB88320DAA37C20D077668903E6E68D30327D70F8EE2F4980AC3 + 506FC473346831A501F0D669300E1EDE18C18C3D1F2B18EA0F75C9F750920967 + AF878588BA8182036F5EFFB8B5FB1678CDEB14CB736CB952F697E0B09DFAF131 + F8BE0BF168229BB350786FEFA07454BCFBF017F7EEDC2FEEEF92962BA9DA9BE3 + CA772F5E2E66621FFDFD6F80FF7FDC2CCF44F96C34A4A92D177664CDAC958E01 + 2EE6D269C27310C7939BADA828528CB0572AD72555352CC4D6B2A9244C53E5E3 + 42249556254A96559AA0089C806C141886B17098C14986625CD3A24816C36914 + B734CBB669D1E1675C2E767E9901865A963FD16300B77642D21CF0E781C1CB84 + A0BE33074770FB5322061B7EB6ED996B5F4203192B63584A50FFC76F50B07A52 + CED3804E0F7852064A833831ACD45BC33B364CDA69CDAE8BEFEF3E3CA9B00167 + 0FD0AB9FD11CE06037DB67B0B4417A0B0A4063EF744191819A1DC5521A28BA5F + 7570B7C4617D9BE4C919F6DFB92ABB093DE70AEEDE77F60FB0CF6C4B734CAD8F + 1B75AACC912CA57E81E71AEAA33D9DEEEF15D87D5A572303594A032EAAF72FD4 + 23131E2633486510ECE9BB9C3EADFA9B24E7D249DDF62AD59362A3A22B551C81 + 73B99407B904499EB49AF9D271A15269A87A2C9DA5B850B1586CD5EA0FEE3E58 + 9A5BD878F2148128D3865B4D85F050810B471322C122955AD1752DC8D64E1A27 + 3A0CBD39286EBCDA26711A47F08554FAE71FDE975413384C2C4302CF89406060 + B2F9E3B30C0373F45EB96CF9D9D3E760C715C342329AA8162BCDDA4938148EF0 + 423A956A2952A956C7289664780F232D366A8BB3D099290AF9F1657FD558D737 + A1CF722AF6BD4663BEEBB665388E4D51EF88F7A332500E015053939EFDE7BF8E + 74EADF8BEB76F5F2805F0F9CFA3F15BF7E82E8B46DD92E89A39DAB424ED9487B + 7874CADCA37F3A51A6618D4D3859C8E7D90323D427B88CAA775133FDA2A39903 + A48CF5D687B63F86F9E44F031B978FB58B59E541081FCFCC5D43CD46FEB9C638 + 926B382BD7AEBF81B7F3F98205C39B47FB4A4B4AD9C69A63E1FE1296612FA65B + 9EF36A7737B5B03023C66BE5CA2C47441251C7B58E8EAB34857B3083615A229E + 6D4AE6DBAD9D8820E666E7D3992CF0DE798E3B91E4BD7CC176AC8817E50501A3 + 18F1FF99BB92E63692F45AFB0A140A85850029095C442DAD566B5AEEE9095FA6 + 1D7638EC71F8E4832FBEFAEA1FE08B2FBEF977CCD9CBD847DB138EF62CA1F6F4 + 22B5A4164991224188D881DA97ACCA721608125B15002E922615215625AA7243 + E2E5FB32BFA540D1246B7BC036EC52BED8E97430D7B953A914654905D67E152B + 666FA6CB6BB5660386C0D675DBB145CF0D0806A6142C9DC7057962AE1391F51B + 98243471E17713A50A6CE81C8FBD187A8EEE47D9173B62BA9C02CB55D232BF05 + 184007890699815C7FE506C4FD26AEB95791939E814B97B1AC0BEE39E0F865D4 + 9E3EE829D3B56C8F4624D433C3C82FDFCC597ECCB1DFBBD9CD5C5EAE9F57FC04 + CCCD5B0BC6764847B143C61D0C8778CC0EE9CCD6C11AE3876956BABBF5A8A280 + 46752557B034B3D9ECAAA6EDE161ABDB1158AE5828204AC8B36C369B4F71E241 + F5F8CB5FFFEF8F3F79B8F7FA0D47931BB73734CB44E4CFB0C149B38F93743A95 + 2B17499E15200673C56248909E07399A0E20DC3B7CD3E9A367481FEB64492A25 + 4ABAE198B61692B4DA3744960D536926F057D3691B4C00EBED5B95ACC8EFECBD + 5414393A91C5704873904BE30C3F0E6744881A1245625EA8A1986C9616A93A09 + 676690B12FCCD2CFF1AB7393A8A560945D292EF3D8074CBD81C213914D5FB9A4 + 65D3B23A69719930F2AA8907EC65632B0D52E45813A37C37C94749B874E68749 + 3C76367D2FB03D1AFAAE01037FF878D216E234F2C619558F61CD786EFC21F9F2 + E7F51395CED5489D6DD6D8E34954F62C0B2729FABC7A1C3BF5B5993897504B4A + A093EBFF10907E9F852297C52151CECB47C7C7AE078AABE59DFDD7A55CE15679 + AD90CAF088E986B8695A8E61FA9EC34999BE07FEF5DF7E71EFF63A46875D4D63 + 90604EF1AAEE8B695E1004C3B032A9743A25764C5D43AF802024590795015C5E + 14A300F4A669548FD292EC38D08DD454C86E57CF881C8793A163F78D31609586 + C08A2A261944B74392A022D70C68B006CBC629FD26022F24C9102701F03D0031 + 24D58593D16396FB590503835A72100E2F113A27B2C69E89D11B8DB5A7184B6E + A3B97887EBAC0758CC848BDFE35BA2E74B968646925CFD68B3B97B14C9F5496D + 9BB3373AF978DC86E692DBA3CBECB40EFE400286C4F979FDBCEDD184ED1E34D7 + 99000FBD53738AD9C15D505A6CB713AFDEC9F6E828251D224D81D7C03F749C53 + 96A559F6FB95EB47AF24F1D70564F41C4D2709294152A7B13063EA8F23A422B4 + 0BEAB7D0D6EFDCD9826C1168A690CD83D059A76FACDE5C6DB45AB622DDB951CA + 65F34850A668CE4468E87A685E7DFCC98FEEDEDB766D33230AC0369F3C7D9E49 + 898F1F6F869034CD8669E994903721A5E96835772CC7E9F57A8822CA3269FB41 + A7A3D31AEBD93EF03C12276FDC8408416986A2288682BEDA6D111890A454B3D3 + 0A71AADF35D23CC38543600D10D1A5518D5621A7B44C0BF3ECD031616608A390 + 1CFAA8878323F9B325757C3416C6E48A92E7DA911DFD9C7DB138689D89627F15 + BDD1B9F3F17247B617139C271F8FE47ADD1CCAF589AFFCBE1CD66303F754BE4F + 2DA5F69430300347EF73E4FA8BEF7B5E5612BFD6C14BD4F18CDCC301773C63F1 + 147A775A4AC3FCA53452275B97A8733CD5D8449E3B085435AE06308CCE9E30D5 + 1822DC086B38E66D6F55EE566E989ECD29B210E2CF765E2962CA751DC8F36CA5 + D2EC779F7EFBB594CBE7F22511114E8E0B18666DED46AFDBDDDD79EE39AE67DB + B72A5BD934229E190485AD56B375D2ED398EE9415152B2F94CDA45BC1257350D + 4DEB80268DAE193A2E478B04C5E694BC24C987478782C066153E95E64D030420 + B2F5B440904A494404ACEA39B09EB41BA298E9B51AC00F694180A486EB4D323A + A8E2A1BC16C95F1E426D0F463C841941DC845CB168AE8521009E98CA24EC7BC6 + 943103A0A3B43C8C5EC3A6E33BFD45DAAA99CA497AB337C7C7CF07D3059A6908 + 84036772578B294251245ADABD0B6C8F5E8306E892E55EE7F6E8200501982F08 + 6317DCCD9C4B819794EBC7CB89D5481DF1C9C4E5611E211D6BCD591F48921E8B + BC369D325C50125D488A6F75CA72FC0AA5DE13355FEF70A5F2E3C71F9381E7D5 + FB3881D535E3E6C6466563F39B274FDEBE39C8E673BAA93FFAF4D3BEE5B4BA6D + 656BBB42411EC3C1F1DEFAE63A5B2E459E20285AD70D3CC40F0FDFA86AAFAFF6 + 3112CFA65332417B1E6834EB1C4D970B255990D1F22E08DC670FFF80E344DB06 + 86E5920C77D26E956FAD03CF85905829953C4F69F53A181E54EB4D0BC35ACD13 + 2467DCDBDE26692A24C27CAE9892E42FBEF8935FFDEA9714824F0C046ACDEB56 + D1589499A02B1671654DE0D2ACBCCA738CC8D13D13F42D1FFD9C188A34DDC01B + 0F6D9930E17CDFC3A3BD550A4B06C7F36F69E60B1F7D34BD37FAFE21E652A435 + 31399A912929348FE40867C95796AAE212E3B21C5A9C3AC33FF57A3757F24B4C + D179FD3056E8B5B66D595A97F0CBBF8C28124BD126A06B188234DEFA68B68AC4 + FDD625F5EF13C9E339ECCD09F7B4C01CFEF2847410FC4A1C3FB23FC76A9109B2 + 94B62D1EAF0AFD30083AB94D8228AE1247305071892DAC1655FF6D18F861D6AF + 77DA5DBB9BE1B2A063E39255BEBBB27E7B6BB599C7585CCA29B5E35AA1A0E4F3 + F946A3D968B60EBDBE2F63BA616C6D6FD0365F6FB49BCD3E21518252E0394E10 + F98D8D5BAAE67A0093D3CCDE7EADB8912FE6A446ABF7F2701F910551600B4A3A + 9F0BF365E1E8B881C8032FB00CDD6102488910005F92D320088B8515020F38D6 + 13B89026C39EE685B8F5F5F787E93C4704DC83FB0F5EED7C6D5A1A5A4B8F6D5C + 59D519AA1F9A4CE7D9BF0096C633A9CA5AE9819C39785DBBF7F0B317FED66EDD + 9C18D3B8045C9765B9A48F23C396986F7762D68CA72B1A83BE2B7633B7BCF82A + 06E7F53692EB3DCBF9FD3FACC722B93E58C29C69FE08E391753D4DFA5E30FF9D + 77982E87CB4999C96A02530EFF97F1917C967F41B97E690DAAF9154C94993830 + F354F1C7DB79FA39C3A506163BD356F6190EDE25BFD9C8DA220D8163A0D5353C + F8F7CA83CF21746BBBDF61A19F2FFCB4DBEC2AC51C227D8D83EF4D4D5D5BFD9C + 21D45EEBC5ED8FB65906216F9FA4F1D28D32A69B3489FB964ED8D5522A78F8D9 + 1FA1CABEFBED97F73F5EAD57AB3C04DBE50C2B4ABC20A2A98766B06D9EB022D6 + E968322B97A4FEAD9B2B24A917D3F483CD0A1685A7A47C005123699A59CDAFD4 + EBDDCDCDD57ECF741D6FA5BC86E3D0307C96A35C07B43AC6D6469E24896643DD + 7975B2757755D76D5D77241140E7AB15D90CD2B8922FB6D022D039C18376744E + AF6B2707CD3A8EBFC24986A5B57EFFED0FDFDDFB9B7F5A3C1D2307A380E3C5F1 + EF61228DE6D63CF45C7A6FF412CA771F4679344A8E6A482B399D2420BC7844F8 + 8B37FB3296F563B59CCAF55731CFC706BEAE7D34533DFF124A924BAF50EF3925 + 78F458B2079790EB97B4AF9FD4DCBCE4415312DC6363E5C61ED9E338C2502246 + 9C0F119C3DCA35C8FD273EAE7481AB75DB52AE48334CABB6E303CF072E08E9DD + 17078EDEA359AE55ABE96A1F86E4FE6E95679090EFF7DA27866E03D7B7DDA0D1 + 3010BD530D1D83168E5308D46AD56ABFD3EDA9E6D3DF7D1D19B6FB816106B4D9 + 22A91E1E293E23580669B9D86874564AC567DFBE1438A150CA732CFDD5FF3D67 + 28FACE9DF546ADEEFB7EA15CD474E3374F9E6D6D57FEEBBFBF7174E3E1A7771E + 7C72BB566B209C7D5B6B7DF9D5E1CFFEF821CFD16FF6AA36088574AADDD37FF1 + 1FBFFDE9E79B728AD64DAF6793D6B7079A6664792A2B5038491FB62D4511D008 + BC396CD9B60D3CAF70F323DD09160A67007804410D82F1C4CFC045B32F1C3DB5 + BCC2D395D37BF8754655D89A2995F38CC03986F5E12061E97A432CF0D13FB8D8 + FD687291C440AE27D0CA1184CBBD76610162C9FE5C757B34DEF7E804F59EABA5 + B4A8C0B172E792C7B8EC24197C8983A6C587578B09695403CD8BC47878FA3142 + 8A783ACDA51DB3AF63DE40178AB2F51E42C07E3BD2026418E6D5AB86AD3B7286 + 7FF1D51354092F086FAA6DC3B2578BE900235B0D03388E1F84D5B75D45C9009F + 6837F54251442069DBC1EE8B970C85B90E24708BA6D054638F6BCD2C629EB260 + 6AAE9CA1298A3A3AACF67ABA636A41E0B71B2DCFB6D3B25C3FE96CAC2A6F760F + 5CCF4FA79866EDC4B08192953C1BC010774050DD3F4214D5F74175FF10E28C69 + 5ADF7CBDBB92656DD7AFD63B1CCFA1AE20A6F1EBDFED17F3725F33D16DE40E8A + 240EEB3DA652EAF78D66BB87986C5E1165398590D136DD877FFAD7CFBBF619C2 + 254E5BE0B934C38E063769D493549FC2A9FB4418BD2A065D980C5D790BF2F4CE + 1D9CD70F60346160DEF961FD6C33637FE6517BA11F00E05FC58B33764648E744 + 8A9F3F6ECB3E74D5EDD1C55FF77CB5A74591A52F29D727D9D72740F312074DD7 + 4D4851CF193E45522C96909048F3BC2DADF3AB86D5755D17913224E37A1EA8DC + 94119F3423FFE5A420F2DFBFAAAFDFCCA50406C940ED766F6DADA4DB88C90630 + B011AED56A2D3FC0F65ED70188E26859A6899667C413D16D881396E5ACACC8A8 + 45B6ED75DB5D43A39A4DCED48D478FB7449144F377AD9CB54C4BC9154812812D + 56AFD56529851194E9C0D7BB87DBB76F28D91422BF9220EEBEDCCB6745BDAF32 + 0CF5FAD51EC3B05D9300106652ECEE515B912B5EE07182C4B01C92D438865235 + 53D32C86A16559721CEF3464E1CE611DAD232481375BD182C1710CEAF8D6FD07 + 8EF2B17E648C0D664C8A3C9BC260DA4FF3E90BF3559FC2D9ACE13B239BFA2415 + C77825C2D1559C3AE1B42EE1D9DD8C0AE4ACBA636C69F86CE6745386A501C793 + 4A0AA2A591D26E92A2505CEE546957B5AC9F53DAD8F04553818EBC87129366E5 + F34B9BBA89A67B30302D8E696F42F3A6C72FBE79D357495F506C8F635A8ACFF9 + 33319AF8E4CD9946245A2ACEF2C6FF8E1B954F16848F37039F7E0F9B7A171F15 + 381AA4B33FB3714326CA1C1F9A8B9BD84F97327A862069864F0F8EE663ACECCF + 0B305CA80861D8DDE977FB2489B73BFAEE7E677DBDFCFAA089447AC7090E0E1B + 2873A598B5ED286AA465FB0787CD425E62590631CC83376F754D35ECF0E4A4C3 + 32B4285008197D1020447CB9D3703CBFDED073593E080255750DDDF001E8691E + C3D26ACF20492A974B1FD51015859615DEBA917DF10281232908C2D3E7C79AE1 + 20547DF6DD0F2BE542219F79F1C3DB46AB5FADB5D1A28800BD58CCEF1E6987D5 + 76E0FB2CC7219EDBD5DD071FDD7301B6F3BA8A1A8990D4346D7A104C17B51CF8 + 01C7B191C268C4C5319A6170825655D476DDB1CCBFFABB7FD8B31407C46FE89D + EBDD7A9E836AA7A8F9A1BCB1116AC6A227360450CF369EFEE7CF2F24D45FBFCE + D3F51ED663A7FA989ECFA545B3AB5EADA5EFD60DFE448311921273BE88451C10 + C7D1ACF72932001361CE96D135BF5EEDD16BD6459DEA254145812220BC00494C + 163E2E7A283426832FB4684A26E34B11D2E1D3041262198E6684D1C9D78CF2D3 + B868AFD21B95344F10C4774FDF201C5494FC51CD4408D851BD97CFF72A955524 + DDF77A51AC2A8AA63B5DA3DBE9767B45CBB45D00590E4124ECD45518428A660C + C36DDA40146894FAAA89EA4FA7E57607108447900C6A0402AA3707352923FEE8 + D1EDB775ED97FFF30CF1C442517EF5F250EBDFF53C2B5F283C7DB66F5A5EBFAA + 16F2CABDFB5BCDA6EA79B0D5EC588EDB6C765896DBDAFCC3D28D8D833A48ABBA + EB3A476FFB1BB7CAF7EE6C1AA6DBEBF70F0E8E1162521415858709E069E01CD7 + 71341C9724110FFC28A2324975BB6AE41D0A833FFEFC6E5BBCAFB6C19C4DA3D3 + 01F37DC0F3A984518FB99CCE8BA3AC8390763FFBC7C1E5F97FC38FA6FE9EDFCC + A1A7C3DB2436BAB8B478F614F75B88E168A77742561215A9B57F7C15363AEAC6 + BC9E5E8A8D4E96864A60454EE0593C918DC67776FC328A7367BB2E12DFC2C927 + 9286149FF90E1775169F7931B66D57A5B709DE9E4E47D0074E009CB9E4F1EC6E + 3A28DD0CC39D248F334C759690CE387C1A1FE26B25A491FA05C552341739DF88 + 09E1174F487906BBD5FDE78AD0797DD87BBD57854180E471968BA010A14F2693 + 06C047F304954933B4E7BA0855D1054511AEE305418868290000958590CBF703 + 349D582EFA789019259489FEA7194ACEA4102B440410C290E3A3ED5ADBF1089A + 755D1045192370252320E1A8D5317C48369A1DDDB01425E37BC00300515D84D4 + B6E506218EE82749112CCDF9BEEF3AAE65BB8A9C41EDF1FC000967BA6190C4D0 + 5A1AFD8F5A88F806BA475D40A3837A812EFC20402FA25E3CFA64FD2FFFE2F16F + 84BFED99FECCCC9D483E405DB7C554662237F9486A8A7B4E7F1A6246B7FEF3BF + FFB325D8E88539E8F59FED2C57E2F029ABA765CA3946E03CCB7D17D54CBC117F + FA30A39B98CC6D23DD0B3FD220A52EE1D0FE2C45FE9E061E48A744FBABF5F42A + 275457CB4CE0D2244943DF9D307F7E07D647173D688A6BF4250969F435D21C92 + E3F15190CB49269A4C48D11A8AAFFEE4CE46FD8B3F97DB6DADD5E8B88E994973 + A2C8731C15C220E273432DE3E8707F6004795A52643A795AF4E0BC6A50DE606D + 0E23F310E22C06FC697307818F88E8141FC3CF2BC707CF46D7E82384E068420A + 52C10FB07E5FD74D17C9EC624A48A73862A0E36C5AB6873830C449CC08808B93 + 34424954BF1FBD18ED810FE63335305081A836C77175DDEEF77A5197C3D0715D + CB741043454551242E6753528A02AE9DCD13C3D0BDC9B008005A3FB8F9464EF3 + 559C26B327149E2E861F97D2797A1FE7E6E775981D4DCC4A9ED57C0F955EBDBD + 4818474C8122994B8ED1E035441C7C067AFE05578E6BEECA753E3E8BA5914602 + C50E0969D279FD54D123B849DA509AE7E66E8145D39CAD931955FCF9C81EC146 + 04A0EC19BB1C3F6B5A8CA408D34AA2FD936D3A2F671DCB624850CA2112CA0481 + EF18AAA9856741C06078964E83339F26224227887828CBFD3F7357F61CC7719F + E73EF7C67D030401523C454A322952A4242A726C2B4A259165E7C165EBCD29BF + A6FC94E48FC843F290AA54928754394E4A4EC996528E141625521725D1904402 + 240802048863B10BEC39F7995FF7E0D81B0310A434A280C5EC4C4F77CFCCD7DF + EF9611D4121E705854EF0B212820B04B2274A3B692C6B940295D7FB3ABDE6633 + F02519B81A22CAA9ACC1879848262200B93C906094DF0FE8A4EBF09447460185 + 49D3926C9301660A7C39088E8617C1D081B85AC84C0F3C57D72DCBB12C5B5375 + E88C288AD0B168848B45A151E493008CD5732D94C2DC31526BEF18918B655752 + 0CD76B541AD4C5844510B8AD5BD4F87EB478262B56F0CAFD8FD0E1E9F11BEBB7 + 36355FEA1A1B28AF151CB3CE7EBD3747CDFDEB5BFDE6E172A170E7698A0C93EE + A8E11E145E4F53D8F3C9DB3EE2DBAA1E6D3EACA6E14C0172D1AC00AF0D51E117 + BC1BF258053E0D3AB2E770F80A92DBDADBBE86905270CF5070274FB3D82174F7 + 0F26C830C3B1D277069588BF9E9E9ABE7E67DAD40D788E606926284210249C96 + 13753D708D0B9826C8F3247ADA90084F23DD3A0908A5A9EAEAEA0AE293840FE2 + 39CF899C2044E3F14454BEFF20934967A17B683F2F7868DBC4700F812C7AF648 + DC3CB696FA1B9312F411D5ECB42C0BF35C1FF782E0789E4341440480BE8980D2 + 41064497CEACDB38BE20A8524782046E1816002808EFA669711C4A6D42A0CA31 + 3660224AA4C2501C43B6B7273B3A63DD3D13C3B13B626A48E9BEF8874CDC742A + 6AECE0BE02150DE2687793A577E3FE56DCC1EAFB8937A66A578D24FA0D50B9FD + B9A86BD986A2C9C968319D0B7746C3D7FF3159990894BB08D1519A635B1DD47A + 6EE011676897632CDD0A71DA5E65F3FD757B6AB1B309220548EA9A5A831676E7 + 0EBAA30369EB367724A4158F4F9D0F29228034200247312C76E4226B2FDCE8FF + 7A42CA53EEC5A14CD298BAF9EE8DF4E232C7B06DEDC9EEA17EC028D3B2807921 + 7539054CCD05B495245994648E05011F972426B6D32021AB374D5986A1A94A10 + 5FACA268C8F2B90BCF4283EDEDA991B1215555819F4E4DCD67564B7DFDBD9CC0 + 2346EAB981D40FE8C6B21C11680D304D854B003EC2A50008017C870F0C129E69 + E8059C6D1AC10FC7B1B3F7D7295A465A5CDB467EFC963D7C009A42AE2B34CD04 + 370D1BD591716CF6DE326A1610D9F1A1DD42A1E8E04DD7F4A9BBCB37BEBCC7B1 + ECC881AE4363CB3DBD53473BCECDF067CA26BD6517C2B9BEEDEA7A21ADB65699 + F3AABEDA16EAC36FFBCF1F4311A6DD039ABA5E4CF67795B3852D76B61F5B4335 + DC43C532059B874A31BA9CCF3C4C441383D96860CEDED350F67D6EF6A3C9BA66 + 6986F31CCB779DA6F1F5CDB16F6707D21D229A1E969052582F41B31CCE74476E + C367751ED2A6485AB1898C7B989FBAFBDE6FD79616DA3BDAC7C6471DC755CACA + E4E4B4AA688EEBD9D89E82742141AD04C20F7CF5A3B198280980969C2006461B + 10A56DC715052196EA868BB39C0072743C1ED3B5F2E4C4ECE9334F03B0251211 + 3922D98EF3F9F5895B37BF06B003DCC3FDA63CE4CB496E543421B60D6CD00760 + 8D8964EC7B3FB8D89E02A98BD1790978A88020D8BBF1C5EDF72F7F367D2FA7AA + 1A0CDAC3517DD02C8BB33E13780F740C7A4F23B3810F4C147622B1DCF501B351 + 211E1691DA482C9A6C4BC1700AB9FCAD9B739393F3BDBDED274EE4470FDE32BB + 5E9A364703568A2397A86625035AE41F69B4CFDFFAABB1FBFD9EDE85C7AAF70C + 795153D1619113E3918D1A4D8F7B2821AD4CDBE2223C700E8B229AF6AC1E45F1 + 822CE309FEAE6D6BFB3A0FBBD312EC5EAE8713184EB28DF2B69E7FC71CC9B55F + 343734551DB38380DE581BDBE0088C9E3403DC13D6800DB8D9DB0C6F32D10863 + 09CBFF3B79FBDD175E3C179785D9999962B1188F45BABA5203036392C0CA9128 + 88BD81B33AC016CF32480046432213A9842409D00B94FB19B13417381DE26AF0 + 08DA0ED04096E378948F599F99995D36A837FFEBBDF636B9AFAFAB7770B07FA0 + E7AF7EF163F80A9FE6E20DA5D78101C2F95B462F022F11408875DD1C18EC4EC4 + 6590CA1717B299D5AC61B98A6A6556D749DF7CF5D573006DAA66F83E05D45529 + A9D007CFF7F2B982E320952B74391197785E544A798EC575405D94B7B4A878D0 + 0755D14DCB2B960BD99C0D1415C529702C5C7765796D69313B34BC78E63BE963 + 47FFF8367D463301914D9E9743467F36F9C6276AB174E3673836BA0763FDE313 + 88ABAE5BC925D47C39D216D761CAF79390EE6E1AC24F826B63C91E6074AFEA51 + 02A7CEA36C778B90EE5D3DDAE2B0C6473F2AB9BE617C3D4A5CCCCB8EA1D49FB2 + 8303694B4353CBC8A5D6A859D9D7ED5927B17B11D27ED26CA328ACEA1CCBE108 + A9CC3AB2BFAE4DFDCF60BB7E97723EBAFA613211B9F0DCA9F1B1C16432C2D2B8 + 803D8A32B6089489D12502352689438669E47BEBB996A15881D51BA76C042119 + E0CB4281707006857337F37CC9F464493C7E7CEC776F5FBFF6DB2FFEE2CF5FEA + 1FA0961757BA7B3A1131DC74B582A30DC39C9F9901304E7574B6777501F6F99B + 299280C602262E2F2CDC9E5CBA35B5B89856D6D690F11EA8E42F7FF95A5B5BCC + B2AC6854C0EDD09E1B578B69E8273D16C573C2E4F386651A9665D2517E139D91 + 165692C855CF047E8C34B164DC750945B3B3396D2543E4F32AA03AC7910BF3AB + CBCBF9B3E9FCD1E7CBF7E5E71E18C891AC156256DECCBA3F9A8BF85542FD7E1B + EBF776D2BE5A72B47C29D691E423925EAC7EDF9AF19DD6D77EC49CDB47953E91 + B9926B111B1AA20F3C873C45AA35A43B29EF5A1F1676E7239BA286BE4134CBF0 + 92636ABB370AD5425EDDB9E1C3E11B6948117632D870C46E149E6BA221AD777E + DA513F24B1CEA87F63F2F2AF45C6985BA74551387FFEC9E3C746458101311CE9 + 182D3FA81A0CE41290D4DB90BBC98008530C72590F3498C486F712722B4221C9 + A6EE2275AA0347733C88FCB4A1D9AEEF8912F527AF3CB3B8B8FA9BDFBCB7BC9C + 3D71BC2FD59E222BAC34285F8965AB8A0A3F01B01DDBEEE8E9096A2DC257857C + A9B8B6B29633FEEFFDA9954C0179A1A2C59EFAD33F7BBEB7B753D34052F44539 + 695B3AB68C91B64BFBF6860B3D45B986691572656C06DB9E17C47F29A4870D7C + 5A839D11918C0FC64607134B19F3DEFD4CB1A4E2D827F7FD2BB780649F7E2157 + 105FAD8A4E69F5B4353AAA89D41F4C43100CFA22DE53EF36DFF023D9E2175179 + 0259FF05D9E8D8FD0F09DDDA0F8B6B24058454AD557E7CCB9CF0832D28D205B7 + 3F64830D6F10ACD52E52FD7BFE96CF47E329ADEA11D9BCC126F7BED13D6AD0D0 + 5E1B6CE9871F1C80D18A0132B5B9A3F284ED53762CBC5CD9DB9A28D2B0B1A148 + 8107523347B322CB890C27008C92E456ADAD561EFE35036C161E4A2065A87388 + FA6CE6835F518E6299D6A1C323AFBF766974B81BAB403102220F50848C382BB8 + E3D9960B32B26B079EA108D331AC6F3827A1363D646E42479A8E69991A8AA3E7 + 620931D5C64593A5926A9B0620A31C6163B1F8D73767A7EFCCC762E2F8F8A01C + 8D04C5BD035312C332FDC3C35D7DBD9158BC98CB0261142554B218E6C4B62C68 + F3DEFDE2A79FCF28650557B3A57EFAC6AB975E3C522EE71CDBE17809A9620D15 + 109FA419E4466DE98106130622899C4FB03058A27A85F1495A510C14D2B6B913 + 1E76177BBC023395453A129155DDB2918E82D235DBD78B83039D79B2A7B589BE + 256E56EDDD6A0788FDD797FFBD1A4609A2D9BBDE144689E62F553318ADDD4B86 + 68AD2156ED04A328C4DE8C77B7C14F1098776AAD71830F5197A9E16CB68415DF + 478217F2A3A71AB7D668EAEAFF422ED0FE5615FBAAD7B445F79ADFAE86772B24 + 2E132D6E7AB35F55135A0534B521F0C8FC40B308387CAF4944531D8C568EA176 + 30B5ED6F9F4FD6368DED36B07134C64D8615817E523862B5BADF9527EF1D4939 + DA7B52FA72F1FA5B865284D1BEFCF2F9EFBFFC0C903E433782C01E861391FB24 + D051E00E20A763428AD9A817A8417087990D768CF3B663C07571EE4DDBD4151A + F02C9544DA5B0A453A44124984712C0B2CB3BD4DEEEAEE3870707060A0C3D014 + A0ABC84C84ED4B586FC14CDEF8F2E3CB1F0C8F8D8A925C2EE423F1846558EB99 + 55805986E535BD7CE1E2532CCB150ACA4FDFF8FEF9F347D6B259071096847379 + 007A5D2D23C729B4D18EA511DBB9657D49E6389E873E3888A5E284CA846F9A4E + A9A8055629F41860EF00FC3C508AE618862E09742A19352D4FD34DD8C9D1BE9E + 9D3B7EB82BED74ED563B5AF9753D0A0730BA07BFD16FC411AAA1DA2B94BCA9E6 + 4A722A6E9435E21BD976395B8EE558F04ED074235C0EE96984B2E26F0435054A + E11616EA500D86747BDACB789B9B679A2888EB34982821BC107111F332F0EB57 + 3BA256C5386B07D37CF870650AC5B993A89C1C1BE80F378C4535D9F12B35A45B + 9FEB7CE6773661556C80A167DBEF966EBD5FCA65A3B1D8F97327CF3E73585514 + 1739C6539C20D12C8D008D16693EE203ADA310150474F436AC4CC86D08E09E66 + 786CABC701403E70509DB24DCB3601467939464BBC6D1B000C8C279240AD25B6 + BDAB9DA2798FA08A6BD96347414EE272B9E283B95900C1672F3C2749E2E4CD29 + 40B7934F9D1C18194AB6A7526D4910FC2DCB564A8A5ACADB9641B8ECD7534B00 + D007C7923FFBD9770B85F392C8160B259E1729EC730A3C94C4E5390DAD4C7B1E + C70962A4CD43D00F7D3711A7761D59622429552A03DAAAD846CF82D4D6D9DB0F + 53A8944A855CA1542CC31090A18B22388E86E1C20A025CE2C0601216BAD54CCE + 7213CADA6A6EE29DDE53A34BAA1C62CA2B44FB1608EBFB4D4D4CFBA4F7FC86D0 + B6EEC24A36DF353EC4C982A5561417D95BC6BC473F26E48A8FFF31CD34A461FA + 40122878D9F5CC1D4DF68F6C440FEB875FA5116DAAC1DCD247D22C0F2FBEEF9A + C80B0718566B1B7ACB65600BA6C920B6910C481C8DB318D33867C8E62C6FF6A4 + 22177D530FFF9633D5CAD6049FCF762DD1F357961F2C0F0CF51F1E1F3CFBCC21 + 1090011A5911E5DF2430FFA4489EE60481E36D07C462CD3355D2B559D2A53896 + E1459F116CDDD4724B72C7202DF041A82523C77CC762A418231500730DADE85A + 26816B8FBA36079F2D8A056E0AFCB4ADBB57D354A55C144489E213B6B65E2E97 + 799E5F5D592A15D5E9A9B923270E47A2F2EFDFB9925FCF9F3973B49CCF42E723 + 11E9DA47D36FBDFDE9DFFEDDCF595EC8175451604CD30462E9C0B207FF5C5C3E + 195628B879BC88A2F96C9365E1E115D00C92511450E522D77D8666FA532216ED + D134A1023C2E528CB2436D40154A252DBD945D5DCD6AAAA1691BAF390AC172AC + A1BE181CBAB65E1E1D4CCE4ECD5C3CF84E5E785DB32A67BFC193B5D32DAB3D22 + 341BDD83BFE7EEDEA45D1CB2AB5380F86B8572AC33B57E7FC5AFF6A9254334F4 + 080B8A3469062571404ABFDD7B3E553408AF3F8D0BDEE1C4F87BED4EC839DAE1 + CB87B65C55E15E534845A0C70A142380488B14A6E8A71754E16DEDF984F92445 + D09B413E20AB23C9174777576912C3FA9056F53A0C216D89A409C14AEA13B3D9 + 1CCFB3D188F0EC992754CD60A508DC5FDFB590C001A0C8A3009F747A6D62627A + 7E6E11AFC6A80220005254163BBB1203033DA9085CC876B492C770EB8552BCB3 + 871758783A2814D2246BE522168D091F05B2BB88C6FA2E813DF561A7A629401B + 399E5D582CFCD33F7FF8CA770F2C3F58585D4903079423D2CC9D85FFFEF55BD0 + E34834F2D2CBE73CACA604F49E99CD5CFBE896AAA865556773A4A228920C2340 + 0EA7587AB03CA45240AFA4E759BC0063E049542D97831F02CFBB3E95CBE5D633 + 69E84E4F7F9FA9ABEBB9727AB5985D2B961513A57D22089EA7DBDB62BD3DA903 + E303C74E8EA6D3858F3E9C2C9756A0AB387B0009D71A1948CE2F9574CB857565 + FAF3EB677F78E9F27C2A84C1BEEE59A9BBBB5B1B53BD7FFF99C99E80739F7B52 + CEE6BB0F0D0931B9D664BF8FC37CA81C255587C14363DB2EC7B94C98F2CBCDE7 + 0A5E216C84454F6A68F191080B707B93EB7785CBCD60AABA267BF519181641E8 + A6510437E161B76E24D8C2272710F9B199257000A2028D21B9019AE4160DADD1 + 90EECC2E9B12D29DBC02426C71A6B8747FA12D15072EFCCAF79E45799B220994 + 00C4367D9226389072A9A5072B57AE7C75677A41D7348685FF689EE38137836C + 0B04CF9D706591EBEFEB3C7174E0082B790CA5AC15EEDCBC3D347EB07F64D0A3 + 7C105A40F8F5190E281E800D5AC251482859413A9031C7B29CCE36E1F90B87EE + 2FE43BDB96315672207A9F3CFD04ACDA3007ED1DC94241FDE20F5F4207E0CF62 + B13C76B06FECD0084DBB8669C613491A1637C7AAC150DCBCBFB894EFEB4D9240 + 9B054637BCE9E9F9F44A3E957080090882787B6AF6CB5B4BB3F7B3F98206741B + A9C23735DFB07E8802DBD11E3B7E6CE4C2B9C3AFFFE8B9AB57276F7C3EC5A03C + 50280F80EFDABD5D11586D589A587A9039B678B527F9A3E57C08DFEAA6E9EF2B + 3EF9A1A2981E137FDC6B2C53282F25002665BD18698B9B652D5499A6FD85F1DD + B70614D2646C46A21FA62D14E1C7D01EC7D81B890542BA3D7D43E36E45366BC8 + 5AC3F3EAA12E88EF4641EB1B7F9255BF6B4DF6CDFC462BAF53E743BABB10B66A + EA498420A431CEEC766E320CA0A677EAD43808ED3E2B91042A3E43B20249C137 + D627D76EFCEACD8F4B253599888C1E1C1C3F38D0DD954CA6622CC7023CA98A56 + 28AA0B0FD2BC184D17A97BEF7EF5C2F9F1AECE1850EEBB13370036F3A5726EAD + F0472F3D99597558D2A71D07E5FC00611EC5778250CFC22BC30BE2E0D8115D55 + 01FB7EFE8B278A4575E5C17C21B7669BA6C030722C3630D0EF18E5FBF3E9AFBE + 9E8345CBA6A8FEC1BE934F3F25484244165C94419F1658D2B14DCB40E1F09518 + 0A7709A8EF954FA65FB9747C78243EBF987BF33F3F00B83D75BA5F166555A7AF + 5D9B9BB8B9E8386E2A218D1FEC16780627DCF32DD341095573E55259BF3F9F99 + 9D5BBDFEC5CC5FFEF0FC8B978E0B22FFD1D50916515212D8314DBA2C4D61EF2F + FFE6F58F9FFEF1F9D56287EB55A3E40EB9EF6BFEA8DAC7343863E7C7E2DBA2F7 + 0C7D94AF640B722AC64745E4FCF4E87BF0B0C34414CA8555B7717D91D07D4075 + 1971401EB1871A7FCDAFF528E5FA9A43C21A9AAACFD802A6C647D430C756ED87 + B7088524A4BB11ED81139E88DFF317A62222073874F040B7876CCE2878880414 + 6445CF526E7CF2D97FBCF9A961D8679F1EBF74E1D8C8682F703782A27D6F0315 + 482A052BC999334F00E602E3FBB77FBDF5BBF7AC1FBC74BCAD2D1A8B8EA5B3EB + 57DEFBFCECF9A766E6D6EEDD5DBA7061DCD074EC66CA71829CCD1674333B3C32 + 84C4638A8AC463412AA79E68BCBBAFD7347417E7C4C32E0A94AE2A0784E891A7 + 9EC6DA4E92460A4C07A1250EDEC709213180BA81C6C0C75A675CB88120448139 + 3A9AFA877FB9FC377FFD5A26538AC8ECA9D3C35199D10C7FE256269D514F1F1F + 3C38D2D69E1249540F54C3899C49A4B121694DB3D2D9F2DC83FCDA7A697939FB + F7FFF8F61B3FB9F4DCB3E3BA667EF1D9A42004B94850FD2594BE4F16D34B6BE6 + CCEF07DB7E32B7160E37897A0A5AFB4DA5C31351E9F412C661A5CE63A7DE25A9 + DE3526646B4DFD69EAAFD1B0C19ABEF9B82E7C241533CA9ABFB50AEDBDA04883 + 1EEE97F768B0FD3F7557D6DCC6959D7B5FD0E806406C24C19D5A282B966D59B6 + 3C63CBE37166C653934A25934AA552954C2A55C9432A6F79CD5B9EF20FF23095 + A42A55C9CC78628F9778B725796CC79B6C4916A995142971010910407703BDAF + 39B741892B162E4A9C2EB200346E9FBE7DFBE2EBEF9C7B9610D9BC221FD24E02 + 5B0D70F3FD7DE7A78DDE36DB47B5DD68E2ADDFED7CA7DACEA2DD0ADC524C64D3 + 87B506F78EDBC197688B97520742BA59EC46715D89DD26799BD3D6C6833B3B3F + 31943F417CE56B324E11470F15A484442070F2602AE30C4F84FEDCE437FFF9C6 + D76148FEF99F9CF9839F9CEC4989C0B03C1F438EC3015A6341614C7EE845096D + 7DCF4B48ECB1E3E3C9740A90AF5AAE24130272A56288F12387CE9EBB30F1D048 + 6F3E0B004833BC6ED8C5C55550F5E7EF2EF715FA68866A2EB9C16FC7B16C43D7 + 3094050A25D323A282CF3892C30852926399588CE5050E28ADA9E9915F6978CF + 00EA3717975042521C8353288A01FA38459275B5065FBDFEC12410CB6363527F + 7F9CA509DD0C666E972481397D6A74E2508F18435EA7BAE154AB75D3B42DB4B9 + 5A0339B726457AA037994CC45996C9A404C2B79349F1C89181E2B2ACC87564AF + 0891CFFF40219B4A4A8B8B2540EDBE2327E7559431AF0BFFA7D6AA3DA0B3A94F + 9DFFC56E1C9EBECDAB4C5D6C868C169A7849D85D947DD77AEF019A4731B4CE18 + A2F050C76319AA7DCBF6E34546588CD60CD05AD3B74DAFDFC742D30E2B7F7B67 + 8E3B9EAC2521ED7A7EEE93902669439757E10EC6627C3E9F449EB1AE1D061EAA + FE4992EACAE29B67AFF821F9B77FFDC343E3594DB771020577711C40181920D7 + 74C41441BC633BCD600CD705BD58C8F6884000AF4F190B4BD56C2E95490BB76E + CE189A397668143946B128FA239E600431258871CB0E0029399605445E5D5DAD + CBB2E320AF7E3E26E4FA072531168401C099AA28D0E3544F82E3184070CB42A9 + 9AE1D4B2AC0871310A43C238867230D2361159E558F2C2A5D2CDDBE53FFDC3C7 + 1DDB3434239B8E0F153258E07A9E15F8289AD9F3C9C1E1FEE1E15EB5BA629A5E + F3BE8971E6D0C42986594B036568FAC2FCCAE27C11A03D9762F3E90C34B32DFB + EAE4F4D3CF9E3C7D7AE2BF56AA51A2D53021C507FA338669F7177ACB2BB5311C + F6B7F27CEA04AD9BDEED601BFD96AF32EDD7174B5DAE487954F02EB8E79ABE9F + 4E1FEC106CDF3CC775690A1EF9C4EE2357376E0C434735EFFCB0B32B47B79D6F + 63C9DCDBBDDBF542D366AB68AB8E74110E8F611BF16EDD5CD0EEE9D272C9FEE0 + 547B9EC28E4BB37A494925E27DF91449526154143EF01C82E141B57FEFECE5B9 + C5DA5FFDC58F0F1FEE030C254886611938F0EA8D3BC5E58AA903593368962DF4 + E74E9C986068CA47816D518C28861CDD0F4F8C978A259AF444515A5D5D9A3836 + CAC5628D4A310A6420E12CF154C6717DA556B9E5799F7E71C3D0B4179E3B1679 + 2EA0442B8656575717DE7DBFF8DE87577FF6C7A763B4C7C6443EC6BFFDFE57A9 + 54F2D489315BD75CD753AA658665633109AEF1B32FA71CC77EE2783FF2B1F7FC + 274F0E3F717218988222CB301ED0B917BE773CF42C60AB70163E2EE50A4996A5 + 4CC36AD62FC1A21C66C821A158592C565555C7092A9B4B9C3A79E4F0D1D15B37 + E6EECECEE3B8DF7450ABABF5B9D9E58989A1E1D1BE995BF32C4BCB8A3675EDCE + C8507E603057ADA84E659624063B26DB68C14AB7FE8EB628F5D826A563E3CECD + AF3BE8A2ADF4BBAEA46D3B7E0F7A3DBEADDDB6CE7AB61B4B49F01CB37533DAB1 + A758A6D6DD3B58BD1E6FFEBA087C9B8574377A7DA425A27C68C807C06F33AAED + AFBFE5BB4E7AFD9E046E69DC5544D3CE3AF81E14F08DA158780BB1EB22B78787 + B6B61874A9DA47AF7D497C1CFBA251AB0C0DF6F6F52641D3C6C2284C3EF0282E + B6387BE7FC4793278E8FBEF0BB270D0B8551721C5B558CD75E3F7F756A9AE7E3 + C99E1E8A661CCB99BE355BA9A8B94C8A46199288288B73334A384CA492C05909 + 2080817FE8D851D07B74A5044A90EF59C8A1811674CD5EBCBB50ABADFA8E3D33 + 5BACD48C89F18C665886E9F02C79716AF1C5D7BE38FDE8E0509F08C410E8A752 + AB2AB2F24FFFF2CEB59BF38FFDCE7018848DBA8C508DE1FEE3A573D7AECFF334 + 736366F9DAADE2D28AC2447EF4BE6B037984490ECF9F5C162D8B25D3D9B82489 + 621C47154071ADA1015D45E65A8A50EBCE7BE76EBCF5CE575726EFDCBCB978F5 + DAEC850B37A6A7970ABDC9C31323A9746A71A1723FFD8865DA85813C4DD3B767 + 9622DB036E18B6D630799EE57806C0B6C49DD8B8C8D476557EA7EFA31D48A9FF + F0173BC128D6F287BE7BE0FB3F83D1EDE6D1E68BEFBAC9BE8CA9EA6B113E071A + 5CDF425E97D2761208930BE92EC8A7B1E3F562ADC5C0248AB848D8B2EEF426F0 + 6823703F308AB5B9F5AD5E360DEB66D3E1DE4C995DE1DD7624DD87857493E4AE + 8DA409DA928C4950498E1F1FE5189AA4E928A4C7457C19232E7E7E2525F22FFC + E0518A61226B26D5D0AC4F3FBAE8BBDE73DFFFCEA9271E1E18C88D8E168E1E1D + 1D1E1ED01BDAE2C232A8DB0C85A345199AC6D68C9501005CE0DABEEF539CC430 + A4671B51D63B82E5B84F3EBFF1DAAB67F3F9148185A2408D0DA69486BD50548B + 4BE5F985D54AA5F1E2DB938F4CF4FFF899C3E8098D0009E5B51B19CA8871FEC5 + 57FEFBD05032F42D145D85FB9F7C793321267FEFF9477A44E6ECC753EF9CBF04 + 27393C94ECCBC6E06AA1E7919B33E53881AE1B996C86E5E8C82881830655976B + 388AC9C27523F8ECC25DC0D6F191CCD1F1FCC8507A6428974E4B0B4B95C58532 + 8BFB63478614D582BEC5059E24504166E0D78542667676C5322C22DA2CDBB56C + 6770286F9BE6B2F8546B7E89B552EDEFEF6EBE3A565B18ED72F6B7A1A7EB5F74 + 057CDB7E8EADD7437696D6E6F88D30EA7834CFD21C636B9D08E981C1E8D6A35B + 48DB41604448E1578312897633802DC4A08D8C7CE840B36B313DF61A5F8F7546 + D29D7BB62B68FEFF40480F164945CE15D4CB02130E0DF52294416CD40F7D9F64 + 58C33016E78AD98C38305A009606CF59CFC7AE5C9E064AF7C4771F1F829DC88B + 8888D0879012F1DEFEBC63BBF5BADED323226FD300A35051E2889346253631DF + D60D479012810B3F0A34D900867AD37CAA2779FDC612CC992F2FCE0003AD35EC + EB33A58C4879D10AFCF442CDA8AB57AF2F04213ED8DF030AF8E52BB75F79F5E3 + 23870A37EF54D349BED09732ACB052D53C374C89DC97976E3234B15A51470633 + FFF0773FE8EF1574D35B2EC964146802B411F034087C299968920660B172A5E6 + BA4E141E4180669FEF89E5334222CEA492F14C464A8A5C3E2D8C0E6590A770E8 + B8B6377E64E8F2C55B3A90E5580C0F51CEA9D1B142B9A4AE966B64A4D235E377 + 0707733DA9F82C7E321AF22E2C5DE196D7F5B7AEA94D7DF8CB5DC6D4EFC5DF73 + AFA21F8C79144316D26A76BC60289A6358DD1F75F0D7D7DD164594F88EEB6D43 + D2DD9D0BA626DDF4B6DB5A6564573DDECB651CC0425347CFA7362EF2FBB690EE + B4D6B4DB31E838465B8DA470DF4109CDF7F2AEEBD174547F9B880A3731ACAF9A + C9389DCE2410B646EB4DCB4B72528A1D3E7D826228D701DDDF056533F01C9266 + 693E4ED3D4B1878F206764A3016CCE732D3807F0CD669C12C5024D657C4DB36C + 0F271802F3E68B75A4E77BEEFCA252ADC8D52AC1302C60D6D45C4937DD10C7EF + 169567BF7B8C6596C2C0AD6B668C251BBAA595EB80CE8F3E7A349D49C2A5ACA0 + E5A8FAF46C491478C05943536FCE2EDE5D584949DCE30F0F03A62DAE98725545 + B94B083240CB5F816998E97C8EA228509A48929665D536750245BBE2995C1FC3 + D0E59565D37040436398669D12BE5EB71D571DE9173CD72F2D97470E8F140673 + B333F33068E36385642AE97A7E4F5A0C3700203C156CCB4AF78858D0816FB6FB + B4792FB5938C039F23DD2E45ECD569B5CB1F7C784FAFF70C599372A9EA7CE900 + 575D0E7A74D6BF716D17D59ED8AADAEFBA4FC031FCC8217FA708D1BDACD71F90 + 03E9B6AF3B85D8B7C2B12DAEF89DCA2CB75911EAEED2DB78E3EF76AD69DB0962 + 941B9596233CDBC604E40A0A1F093AA49838C19814438AC9244150CDC84B2946 + 26F824480165C3B54C4797A3E478382A0EE2980C2FD17C8CA0084E904C4D8149 + E4BB9687AA7010A8D8320528CD93B80A4FEB0FCE4D3EF5D8C0CB6F4E7DFCD90D + 020035089F7CB897252D1E7094E74B559DA311DE559586E3205F76D3751F1AEF + ADD5F5C9772F81D418CF3FFDF42328CD9266826A5F2A979796168E1D3DBA546A + 8C0F88674E4DACAC94E5BAF98FFFFCC99DE5477EF8647E6E5903CEFBAF2F7DF1 + FC770E0FF6A5688649A61261E0C1E3A15E6F18758520C9C0F753D97C3C1E0B51 + A25286A41C64470D9B41AA5832C592644AA9A940BE5DF4ECD0B3B9F4DCED05D7 + 71805FF33CE3D85E222910510ABE28760D379DC0B49A59AB77BEAF2D77B46EDF + A2367AD8E17337E77F705B97A76AD3AC5EAAA2CA8709A14591C01D2D256157CD + 76C6E5B00B692DBA1CE5340324B55D77EB2DDDED98E318C7D2148D923FED7AE8 + DA9891C2D65D09BB11D8EAF0B69777DF73EFFE50B619F970D34BCBBBB4F1A870 + 43DFB79DE27EA9E17692D7431DEFFD6FFCBCA1FF5B77855822861F4B2E87AE89 + 7411AC997B2424A2E4521881B220B1E80FF966362BE251043400C4B403CFB335 + 198BD28B347561944549975DD3682E577242A25A966DC783C66BA53BC3808B27 + 194E50CAF364608122CC32287DBD28C600B0566A263CBDAB7AA03AA4D230805A + 829CE1420F8505319E05D4D64CF7ABC9E5524585790534589595A565250882FE + 5C2A93C91D393266DBF6FC52CD27E3F9421FC8BC5BD2AAB5FA6FDE9F7AE9FDB9 + 9FBFFCCD62A951530C8E650CC38AC1D3220CE01A4DC36A2832CC52181D805451 + 043A8919BAA9D4EADE7AA666346800B23181B65CC2F1C820242DC34042223F3F + D3B4809302A7E6B82881CBDA21A876345ADB8A4283C3AD7F5B3E6DDEB1614AAD + FD856B5F74F83975986A5DEDFCF6E16BB4C98B65299B2299B69AF2C1F67D1FD2 + 02341F50F19B7D9E2B8C62ED69966EE1E2FA40AFBF2B99AD234B7642A156876F + C7BBEEC4629B01EE81CEDD36489A8E1339BAD2DF9BC8E4B22CCBA1AC71AE13E5 + 5D46CE6F3427B07C0C70D3D2F5B5A2C614AAC3019F6D4D21A31D586466A56940 + 2106B897A56B519E91806268ADA1AB3505E1088A0542E745099F084AA994BEFF + EC4321C15EB9B614177950EB45315E532D3F448CF8D5B72F02C78CC7A8449CEE + 4D0B86651E1BCB364C9FC4F16C8F14E3906B28499215D9B87475FED07036C680 + DA438B420C38AF69D9BF7CE593F31F7DA3D6CD3B4599E36859D17FF5F695F2AA + 72F956F5EFFFE6B981DE84657B425CC010830ED45AED5EC5AA109E16344359A6 + 5D5E59B10C13B82A4E30E486BC3D8090AE632F155775C3858BC5D78777CDED9F + 58771844A9A41C2F8C9CA9B96D88B91545B7CCABF5DDE1BDF6F7B67630DA857F + 7FEB661D5A7401C11D7F00BBDAB649B27513745B29DBB3C7629CFFEB080B74D4 + B1DDA01D8FEAAA4FD11C22698EDEB58036BCBDCD5CD95B7FC38E2DBA27A4F75B + ADBF744148B71E7CE084B4C5A9D6BC917CCF1AEC8BA77B4441E0A2183CB7B926 + 1446C6509AE54067F78C861B1592430946711CF92A39765D730882645954C264 + 7AA6A49A64AD6E6BBA852ABC4796048AC20D4D6FD60F01228B12D7208BB929A6 + B21525FCB75F7DDED06D383C8ADD746B8A727BD92459012E0F761632C2ED15FD + ADCF177EFDFE74AE27C6F1DCD5D9D572A50A6F4AB23379BBFAC6B9C9EBB78A67 + 9E185B95CD57DEBD74E1CA524292E0B429891F2B24A6E66A8D86156590C60177 + E371E0890C3C03708A6279785EF0044A1C83AD3D0608C276308EE38137564ACB + 81EF5555CFC7D91BD3ABA60D5C18455101470F4214A78787A88CA82049966935 + 079EA623177D546BAFE9310DE849E956A0EB3AC390915D7867C4BC7F8736B1CE + 8D7FDBB63DA46DDEE37670E6D1EE73947458B69297CAB9F101B6CEADADDA1FD0 + 651D6C38D37D5B1ACAF8E078A0E9F02CB3DE724F565A544014B44096F66CB755 + 9B7B82BB37717667F7ECE2F0366B409DA38F76B690B6B7E2B6B663765E6B7A20 + 4652C30E3D0634665FD3EA2C9BC1507A1D1F45F412285F111EB892C42137D200 + F32C93A29920AA7104A76258E6FA4C75F6B7537181AB555537C07E76E258717E + 81087940D810E503440BF88E8572E6FB2E8A3542E9EBE3B1B8247CFCE9ED7265 + 0E946BCF012D99E5585E6DA82C4D2F14ABA383B9DE741278AEAC791F7E351725 + 8EF23FB978F799C7477FFDD6D786E32F96359851201A10EB8F7EF4985CB7DE38 + 37655936F4DC7143CB7601C4AFCC546FCD9618860A229E08BD9F18EF2DD58C7F + 7FF3E6EF3F539012624F260F2234B5CA0B71A3A1CA8A5F596DE47B73BA6E0245 + 0D03BCAE360AC3034BC5EA07BFBDFCFC99E3F08C292E56807B5BA60932134909 + CE52ABA928375580C1E307D018901428B0E7A3B07D18555956134911082E1CD5 + EE31DACD33B6D9266CA9D4EFDE50D5759383DAC2EEBE68DF23DFF51A1545CCA6 + 088AEC20686DD7BEAF707F02A0C35E94B2643FE76AEEE658662723E95E2EB11B + C6B897EF3B11B770639B7D12D2B0334D3CC0ADA3915436B190CFEA86D5D07484 + 1F681F423D642575CD10AD37854164E5714DCD902BAE1D392AB13C974C3F75E6 + C4C9278F73427CF8D0D09FFDE54F789EAEAECA30C1ADFAAADD50A2756AB3E963 + 85CA877836FC13A027B3F137CEDF5075172827862A1AA1ADE9B00C73E4C3CFAF + 2EAC549392F0F5B522026B9A1262CCB5E9A2DCB00BBD69C745A946E8C8C5FD47 + 678EC778F6CDF353401E633C0ADA5C2E2BC3C3BD3555BB343547452BA5882212 + 047C9514858611AC54DD9FFFE69A6A525222D12C574AA21486A422ABA5E2AAE3 + 628EE3D4CA8AAA6855459B9A9AFDE94F9FEF49492FBFFEC56B6F5F1A181A68D4 + 1BC043B3F9ECC8689FEDB872AD1E159D22532911399F1278A9A4C088592EA628 + 75E8A724C6588646599FB0CD1CB32DDF5CBF736BF557C28D44B6351BED8AE6EC + 85037EAB36ADA2F09220F4241AE5DA3EC6E120B6EE4EE49A0E1E15996DB16ADF + 7D774340D2489B6B6620DF7727DB30C4B6CC76779DDF2721EDCA1FE18113D26D + D7B495933A4EA0D28719E79BD55A697474A45971C873ECFFA1EE4A9FDB38B2FB + 008319CC8519DC00418027485107ADFBB256B623255E97936C5CE56C55B62A29 + 573EA6927CC89754257F4352950F396A379BCAA6E26463EF26BB59ED3A1B970F + 59966C494B1DA42492E20192004112F78DB931793D4352940492102DBB9CF940 + 0E667A7ABA7BBA7FFD7BAF5FBF873B6C2D4DC408C3C1B8ECC0FC5A98DCAC031A + 022145264A04E1E31860AEA7CF1E387BEE10C8FEA954F6D24FAFD83505B00300 + 94E2D8060073B5CAB85C769B15260E39982FE672D7AF4F65F3B568D86D29122D + 5FD53CC72BAA22C9920DF867CBC8E42B0058C04FADB2DAEDC6E763731432C246 + 86A6C0078F8E0ED094F3D287E34072ADF00DD04D0104EBF52660BEE922045ED9 + 42EE725A3A4DD10449F4757BCBD5C6D59B0B0BC9DCB9D30A89A2013A802BC084 + 411290BE95CF5507E2414D539D2409A878F3E6BD783CFA177FFEFBB3B349AFD7 + DDD313641852D71402E6011755AF8B25938DB21C23F0A8CA50E07CAE5CA935A1 + 9AF05E685B9FCF0540AEE07C4753E6E38EDEDB77965D85FAE78621ED3A4F07D6 + 8258C74184F65606749457F2FEFE2EA95A57A50E0D2A9F5BEB3CAB5C8F994352 + 9555C96EA729D2F605E47ACCF4F388A665035344793BF5D033CAF59D37D32E22 + FE060E6E6F00F5A86536D2746243FA64C377267D7FC9A2FDD3350711763AC79D + F1F727E63E044C31873FA6235FF70EE08F30F5D95ABA013CD14951764111EB68 + 3F128EDFBD337DFDC6BDFEFE6E86A515594D265726C6677D3C75F2F8304DE176 + 2747D2F4E2ECA422CBBE60106D6CD335D31AD5B1BA909A5B5855755D92351CD9 + 18B5544C9365180E92B9858E6CC812DA92BF45C56B58E53474455191FF6B0CE5 + 74672271B5292327AFC8D813B3420A88A2BCBC92879EE6301D4498D60386A4EA + BE00EBF37A3EBAF6102052E0D97AAD56AF9569970F754819F95466402AC7F15C + B6307AB88F75B9E4467D241ECCE62BEFBEF37EB95CBB78E118CFD38DA6C20BAE + B1B12982205F79E5858733CBAA82AC03C3211FE1800A22075785425555641275 + 7503A4FE4000851551F851E3090F453BFAB7DFE6C63A1FDD936E742F0ACDED93 + ED2DB78E23DC3D35A49E4CA64A72B3541322FEC2E2DAE3BCAC2DF67714536427 + F5E817065F73D55E53605CEC6A90BF1B3B84B1479A81353559DD906B77236CBB + A0DEFF1742FA25FAB5EAB0D83B7BC82F8B381DF16B9A512C96C341AF624202B0 + 3C28348000F2D7096229F050A7D38EBB15A94990E48B670FFCF0C7973FBD3266 + 469645FEF17AFBBA4F9ED81F090B76A78B64A8623697594E03BCD12C8BBA3A42 + 3A03F85AADD658C949C02813A99CAAEA2C4BBB0596A229BB1922201810623D81 + 4643ACD744A09696C52610491432C989C23F910461C731BBD575CC18022D1D53 + F556ADDA4CAFE4A0E0B15810D0F6C1D4D252328B223CD9ED2CCB9E3A121765B5 + 5C6D420DE04940F05AB5C279C228C2882C39089CA61D2C434DCF6686F6170786 + FAC6C7265C0C71F248FFD8F8E22F7EFEE9F5CFEFF9FD8262924DD249BEF9C6D9 + 7CAE34F37011DA92743ABBBABC9AAA0A5E0F4C27E572DDA2C6301378BD82D74D + 8B069B946398A16C76950E3E5F9B1FBB0AF57B1DEB5F07F1FDD9CB50592B8486 + 7A582F0F32FE1E326468A22BC0FBDC0C89BC3F60F95223B95A16A54E8320EDA1 + E4807AA6D2CADE2ED0489B5C425E16E9BC300C0A067F29D211F271A8E275B952 + 932C654FDBE5A69D9766AC9B30EDF7473D7006925F225D7A5EB5FD8284341AE2 + 690A796B9D4D95B19D8EAF8A90B62DF8F6CB4DE586D134BC14C3E573D9EE4800 + 5390A4AD4A12C9386D2D02C9F6926ED3549F97511D04E3A431D371DCEFBE7971 + 6DED288057369305241C3D10E358CA46D03881EBB298B83FD5A8D73C3E1FC8BF + 1AB2C0B4E336BCD9100BA5C6721605910701E5AD3FB878F6E4104511B803C0C1 + 3037CBA37F7088A2546F48487789E3008E3822C9C0F5CA4D51419138919A0912 + B75896E27917F03EA4E86C8D003744BE756CF6D103BDFFFBC1D8E1D1DE48980F + F80587DD7EFBF6FC77BE75E2DAAD442A5DC894548051BF82828BB4D0FB708676 + F06E36B95AF9AFFFBEFE677FFA5B03C3038987F3010F71FE747C6E219FC95516 + 975611560AFCAF5F38CA71CE5219C5B60080EEE98D504E5C6F81FCCE4F4F2F4B + 92E27422A0D3F4566F6FD06E2844D7F1446647D1737B62FAE4D9EE427D3BE1F2 + 5907C333267B6ECF3D6B6EC5E54CA02F22374455EC2048CB960C470683FB0682 + 5BAFF93C2C5C79B8907B98C87590C133CBF598393A1549410184282792A87651 + 5962009ABC0B9916AEC3A8D311EB12D0DDD50AC028B009345A8093AADA36CDB4 + D36708FBB97D7D3EEB7C2D5F6FCA5AFB42EC56C84EDEB591E431BC6B2BC347C3 + 2E2F4F21184D969E8FF4FD9C45FB364DB0F55DC0E68AAA5FF0867F752779F0D0 + 7EA4D703315C55A546D34933368783C18DB1BBA9FE3E233ED42589C83849D355 + 98D2060742FBF6C514496E81248E997EE86D0643621F7D3071E3F6FCE1216FB8 + 2B60437A55F38EDDDEA8D512CB9562596CE9DAC163F1F840E0C1D442A90432B6 + 5C2E57245192D516703A5946DEE3A3B148BDDE4CA5D280A4D6BA9C8B635B2830 + 3259A9543917E7F3798BC552369B0324F57A04DC4134514CD146539400E60581 + 5B4AE68156379B207C1BD5BADADFED4AAD7AD3ABC5994461622A17EE2E7AFDA1 + 7C66D56C935620E0EA2EB9EFCFACFECBBF7EFC876F5DA0692A31BB4811D2E888 + 3FDEE705F876097CDF606F4B9344516168F2CCA911209E2DE4EB5EF5F8D136FF + 642A6FC50D022ACABBD8FEBE80A2AB4DEA0090F59D0665473F1E1D4FBB26D93C + 6C8FFFD972117BA213D81EBB606B9362FDCA1E9C333D95FDD6546DAF3E5DBCA7 + 726B9321F2406AB30121956BE2E326856D4AB8598F6307BB077A2C04B1011E35 + 906268DDAF9DDF835C8B174ACD5D4BD8B99B92C7AA627148F43A47DB2FB2F517 + C0A8D309A5B2C1DC8E99301A34D96815D8685DB659FB44ADF5C7F58DC61D7A2A + 41674746C2D4C62E06556B152ACDF65F1F6BDB7DB6ED51ED3ED7D6E7DA3A2BC1 + 36BB5934E4A24DDBD8B96409DBD274EBCFEDCDABC8B3BA2CD952AA0EBD966CFD + 6977F2BD6CFEA30F6E0A2E261EEF0271DB342805E9DE70500C90BEC462EEEAB5 + 09AD8507031C08BC7A0B28A669CB019F01846C0789A33D6B4809F0934B377FF0 + A36BD992F8FA8543011F870C46D16A390ED3E7D242FAA31BA952B509C279AD26 + E67285B15B0F1E4C26B2D982CFEB8E448243F16857C8B7985C3D7BEA852347F6 + 174BB5CC6A8624480741E23871F137BE61B4F0B3678E05027E9AE14E9C3C1608 + 86A62667FAFB63D168E8E4A9134747871555F7B8DD67CF1C39756A54D7ECFFF1 + A3ABD7AECF64B25582207265F5E6DD799824F456AB52517BBBE8DEC1FE7AB526 + 890D1B66671847B1AAD124313DB33C3DB332FAC2E0F0481FCDB2A493F6FA85A1 + E1DEE1911EB7C0E82D9B2489C0A035B5B5902CA16D606E36101074AD75F5DA64 + A3DE04A60E6D72F8483CE86775F7A1F17A9FA2B55F567D56FDA82AD527AFBCB3 + 57BBD1AFA97AB47DBA0EF749D7CC557B2EE0AE668A9D188E0150C6BADC700200 + 7A7F2603B2BC757DB0C77768380C2723FD8144B2A06ACF120769FB9A3F7D0779 + 86C491929424889DD34ECC66767E2D0C6D8622450C5390654DDB02B72F194311 + 02E7DCFC190B0B334B856D1FFF520969A782CB574848DBAB893B5C6E32E657C4 + E103A786873FFFD97B378E1F1D84F95235BF9469F1A910247FE6CC019A72BEFD + CE276FBF6BBC726EE4F4B18158B707473B4351D910A26A5853D36EDF49FED30F + 2FB334FDED570F75055959561D248AFC0172772E937F309F5D58A99ACBE298A2 + 6867CE1CBD75EBFED2D232104C10938107381CA4A2E8B5BAEDF2D5E99FFFF2B6 + 8C943F363157050C85AAFCE09F7F090878F9CA04E40608FE939F7EAA6B3A80FA + F51B73ADD64341B807F410260028F6F4CC9A5B008ACA86439EA624BFF9C68B82 + 8B4CAD563FBD310D023724C8979B97AFCD0EEDEB8FF60E4C4F945B06B2AD8F0F + 08374BE2FEA1EED985B5BFFAEBFF3C77EEE0C9E3F1BE780C0ADC42719D5093B9 + 5C6C365B9C9B5C59CB8B50E7F3915E981E80FCE60BD55CAE8C137660D3C0C187 + 862239919863BE5193B5F6FD62F79EF3E4A9B19B50FFF510C3F776ECB50CC554 + 26188FAA922C96EBBB66B8CE430DECCE64BA527BA40A984F1640B602B91E0014 + A0763557DBBC05B0DB15E04D07BAD85AAE965C2D21BBE28DA1BCAF3F8021D36B + 14A2ABA7CB1D0EF020A7C1E3A9D50A643810F3053C0C0C2310CC5326A9C44C25 + 6957CC833CF4E806D0C090CFE573D39AD602192D536C6C163EE4634DF590CD12 + EADB3616F4E39E8887A381C3C0DCAE2EAF55A15BEFDAC203518F7521B5568D85 + 913AD227304F10529F9B8152C115C8D341D807A26E005F515267168B4D098D49 + B8E270D89B92B69CA96E798AF609687FF442BA1CF6710C8DFAEACCD2BAEE1572 + 8886D1F61820D46B1B35DD64A0B3C9D2D6920E740BD002F0A24CA191CAD6D0E0 + DB02763E9EEE86079D0E5533B2A5463AFBE8D3C3C5EEA00B4E4A3589C0EDBD5D + BC28EB538B453307C3EBA2BB831C43C1833A10BD74AEF1CC4AD29D969B304DD7 + C7D2EE0327BE797BFCBB1F5E9EFCD6EB470DD140808422D6E962BD4631DCF997 + 0F0783C2DFFEE37BDF7FFBE31F5FBA7970387AF6E4B0DBCB4722FEDE58E8EFBE + F7DED4D4E2C060EF91FDBD6FBE7628DECBD71B1A6E6A2AED382E49F2D2D2EACD + 7B99961523CF86C2257DEFFBBF40FE4A70BB6188C97403046200269A265986AA + D7CAD075DD3CC3303448D05006F85729576559416BDFAA6AB7D3278E0C423EE5 + AA04885CAD549B2078CBC8091ECBBB96D2F9FB0F57005539066832F137DFFD1F + 9081AC3851763BB297D20C636AAE78E3C683575F7B291CED4D2713206B314EFC + F8E1F08D5B69BBCDDE94C5F7DF1FBB7AF541A4DBD71B0B7A7D3CB445B9545DCB + 9456560A2B2BB9DFFC9D5739A78C545EB25CAF8B8B4BF97AAD01656639EEF4E9 + E1BAEA48BB5EAD4A9D4383B1DBE9FAF1AC4BBD9DAB479F9FF5E857A51EC54CFB + F6723AE70A795551DE61878F757405D00083E91AD8A879E151BEF3C922005653 + 7CE4470170F0DCF13E81A33653FA3DCCBE81C0B55B8B95FABABF3EF889215C90 + 06633E7E3D2516F6BB008B2131ED242CB40354125C14F05FCC1C9DC351AF6260 + 20F045423CCBACD3529F8786349BC4D0D48D22CED80E46D1011DFAD07088A541 + 306C298A0AF805BC32B556B93BBDB6A5CDDAB45DD88F02DA889236B3580018C5 + 1021E54D187D7400200E9BCA53409CA89906D543A0011CAFDC4A027AF29C331A + 42D7D70A756D9DBC1B0707033C4742CEB34B4582B00FF77ACD044DC04DCC44CC + E11E0FB40682D142C3029F03037E6867F473CB3682F347A33C6BEEFBB2D9BC02 + 058879EDEEF266D95E180A20A0DC90A3C33EA62F22DCB8B7AA997B720046E331 + 01AE972A123C6BA50118857FA3717F7780DBCC27E86501646F3EC898912E3B26 + BC5B3A655B245D2D8A65F258E4C46FBF7FF54A77C4B37FB8CB4120D207022FA0 + 58B35611AB952E0FFE977F74F1D287939FDD5E181B9F1F9B4804BC7C7CB03BE0 + 73CFCDA72261F7481FFFD61B076DBA0293168AE269EDBBB0E3A9A5D4B5BB2B8B + E90AED5C5FA834B59C84D7CD21E37E5573F1EC85970FD14E3B4591B76E25326B + 3964F2A9EBA130F7C77FF26D862192C9FC3FFCFDBB04D6C271076673C8927A70 + 38F89DDFFB3590E23FF860FCD2A54F0202072F0236FAD22B878E9DDC974E17C7 + EE2E7CFCC97D435749CA0992B5A82AEBDE456D36595140FCFEE4B3C4C870AC67 + 302E8A8D526ECDC04817E778F1540C607A3E213B1CBAAA2A89F9F4DCECB2E561 + C0F20C00F4D3E773B3A438D81700040799AA54AC8C8FCFF33C075CF5E8D17E96 + A5E6D478460B3C0507DBA04427E9366CF577D08D6EE0C21E3DE163EDE0EA79AB + 47DBEB4777CB70DBE2A154809E2443511C23373695A46D320C78B89E0892E853 + ABE57CB9F14486F0512D597EB37C2F9DECB730747A21F770219F2F35FD5E16C6 + 7C775848672B16765830EA241DB2A2DD7A900680B03498F02034DBF8C355C0B5 + A09703A6E0E1E944AA68ADA28E0C04CC6E888228CFA74A90333035107958866C + 888A653060EA46D194F9846EB45297AB08C46D0787822E136BD26BD5E56C0DA8 + 0147136E175AA22994C5EDBE7A38C0F54610CA0086668B0D90EE816800262696 + 4B2DE311E69A6C94C19039B7131828803BE035D046DC8E7A430E71495BC4247D + F5A65A6D9836831431328090773953CB169B2054F647516B43CB142A68D63918 + F75BC1FEA05E4057E175F00A0032B832BF5CAE369468D8C598CC1468D6FDB93C + 704CA8113CE22471B8DB404E576D433D9E3E547E2C536C4E26F2D0565E0195CB + C353E96C0D438A0E07C24A1B66915CA88F246B8974351E73F799EF420F2E1425 + 59F7F24EC8DCE37202277D4A49BAF56C2725E9966EFA4867AAE998E61A52347D + 656682A371C0056082E8D39B77755D0389D586E9874782670FC70EEEEB1EEA0F + F5F5842201211A165EBB78E4E24B07FAA21EC035AD85F6F6200CC509274DE5B2 + C54FAECF7D74731971D30D93644810EB1268A2453A6C941337743DD6ED3D7B6A + 5FA52A7DFED9C4FA8E0F9B2D9B2DB02C73F8F0E0DDF179B84E514E737F2706AC + 1C4E4E9FDA9FCF95FFEDDFDF47E65936BBB9795F5B5BCD9F3F3F7AFC48FFBDF1 + C5C97BF30CE970D8308E76EA0642CFCD9600FC932443931A2343A160A4476C8A + CD7A05C56E520D2FE708FA79E445C5402B63507DCB7524898CAE9CE1B0EFF56F + 1E8D750BCD86640E5AA4FA809A1E7EA16FFF4837E3B42D2AD105EAE58E3679EE + 72FBB1FBAAD498FCB433DDE8F354687E35B975FE7CBBA3BC920F0C4418CFE3F6 + 4F9DEAF5DA1C20CB3FC250B47C8F528BB27AEE582F12FFFB03772657B6CE2FD7 + 6E2F020AE74B0D789037358F77A6562CE580DF5306E91E4E806CE637D6AF7034 + 1B63BF824CD0F48C82D09E1C8D602645B24070E703068CF59655A46740380BFC + 1AF84A08386997F070B1B05D15C37E8B8E196B792408C35FEB0AFCDD2A9E6F1E + 0BCBA51933B7BB52E6C2E93ECC0456EB41984840AE0FFF1F73571E1BC775DE67 + E7D899BD977B90CB4B142952942C59B6A2F83EE2C6A9ECD4415DBB7590BAAED1 + 16FDAF08D0FED1FE57A07550A04580FEDD2240D1A04051204781C4A88B4675D2 + D476244BD6611D34258AF74DEEBD735FFDBEF76697BBCB5D7297A28D3E0BF4EE + DBF7DEBC7933F39BDF77BCEF4B8668474A7219A22B80BF40A34A1503C8298C0C + 723DB48C867614B2A95800182810493A4964A37574F4C6F426801DFD7CEE641F + A000905390EE61A580D2426559D6AF4E6DA03D900034606B222A010F558DFA4D + B72E30CD5C514BC63132D0503AEC6247E3DAF4261C3357C28EC786623DB4A36E + B5DF34B5CFEEA676CEA481F197F2B3F67FFEF747B2AC3C72E658A227A46906D9 + 11C4321C6FBB0E2C911810CF4CF6F3A2C8F122CBF3D0DBB25C5D47DB2106C917 + 383A3A504B59D62E7C30FDDE870BAEE370BCB72158D3CDA71F9B8C85F94F6FDD + 0F87023035D334AF5D9F7BFDB517B673AA4E3C8BE97C815DDEBBB7ACAAC6D1A3 + 996834A2AA0ABC4300D98126F7F727604620E5431BE8228A649B94CB40E37259 + 9D9DDFFAD9856BC4984E70D7D0E155575177DE304075CB9A76F1FA462C76E9F5 + D75F3871FAF4FCFDE0E6EA22905D2928256C2BDDD3078217AA0A4C9B65790CAF + 62EAE94C5F6FA6C707F0AB5BC9BE3E55566C541658C7400622C155B79CC195E8 + 79AB1B1F9CFA2BD6EEA187E2304880F686D1FF1F62F8A1977D5DC01D27BFBC95 + 3C9A818BD1AC24ED725C7AE7A1D59E94254FA6C696DB3959D54CA039E99E8644 + AFD9BC5CB34AD5B6CFD714ACA6D9DA60A5283ADCA662C04FC92CD0BA70508845 + 029DCC3B11F79A6986158B48D593F1C17323FA05B8D18906B3F91CE105304C24 + 71A0B4B401A021CC1CD5B8433DCB007FBB8C3EEBDB9E1293B6AF57372D6D9446 + 07E38092009100A954C6077A484578970C1E0D27000181C6A4AA1306EA0A78DA + 9B0A017426A258992D6856A34D6F03457E9C46537D34240408432FCA46920AEC + 3E741AA79306117E4749EA32F9929623200B7F81B64BA4635931007029D334A9 + 5DCE758196AE6C599D7AFBEFB595A01949FD13AF9833CABFFFF4C2E272EE2BCF + 9D193F9AD28937BC8F7339C60F54136E5CC3652D83F1D9166B313EFA52C5FEAC + 8FA3393D7DA2C06F1594EFFFDBC7BFBC32C7B198BDBD763CE0ABCF3CF5D089D1 + 3808C5730BEBD4E23F918CEAAA3636D6FFD2CB4FDCBB3BCB71987C341A91CE7E + 694C51B4FE4CCFDB7FF08D1FFDE042A954066A78F2E4D0B1D10460745F5FE2ED + B75FFAF9FBD7D637B2AEE3026E8E8F83B8C3AFAEE7B7B650C10AEC188509DC44 + 60074451D574D60BEEE703FCCB5694FFF8F9FD42C97AEDB5E7274E4EC412898D + 9525BFBF6C9956A95082D1805D06450E8092E3F8BEC10909419F094752A14838 + 168FC2B0701997E61774A0B245794E1950467FAB52D9370B68573626FAD57B3C + 3B60A387AB1E3D5870A6EE76853E80AEB67A5B9B9A5EDECC47D23D552569734B + B9BA73345AC59DFA120C08403F812D521C84AFB45E511BF4ADB28A301AD81DB3 + 6E676AAD1C305AB91E60E25CF4C9477511CDA6CB60B4F04EFC1D189EF55463A3 + 833DF53FD98E03C00A22640DF5EA871BCEC4E8073FCF3DFDE850FD8FC031117C + 5B2B97AB26FBC602AC1360143E6492E15C51F5586A76E71DB696958F1F4DD006 + 544500180A5C1B601450150E57ED22EF4C74E783876ADE6752782F87A46FA837 + 3244540A58AA8C90226CAD3121AA1EAE09BCB76167201DAE578FD2E275ECDC27 + 7FAF08FC0D488AD2FDE8EF64DCC2FF7EF8C1A5CB779E7AF2F4375E3ED7970E83 + 186B18A6CFF5C8A68FD8A008867ACF9A808230BC685555566716F2FFFAD36B0B + 4BDB7059EBC332C02C80A50E8DF4F76682BFFFCDA796D78A5BD90ACFB1E3A369 + DBB261BCF3E71FFBD2B9F1623E6B3B368BBB9878802A4DD54F9F3A3272E4770B + 8522CB72CB8BF39A8AD20FA68D1B0424FD5AA9849A31511414B95C2A55327DC9 + 175F7CD4D08DF1637D40577FF0A38BC727FA9CF5A2A269B5FB8725489A57B4F7 + 7F75FFE6D4EAB7DE78EE85E71F4E26E3854229992DCCDD9D536519D64594C478 + 22D13FD49FEA4BC23458CCBD4C53F50186DAD98DCDDC76F1D3A9959942FCC8F9 + D78BE58E03F5363D6B6D7FC3E08578BFB8F81EEAD4E1E9709DEC0FB3D91E6E4F + BBA1B8C3B32545CE95FC412996490233F57C80EA865050EDE8714981E7102EEB + 463F31DA3B4C34A71FDF58A402EFBE27772831824DDDF0B10C7D3C5AC3D59E65 + 3327EB8DBE20F0A89824335A9D179437F39AB12820F1F0AFE97446877A6ECF6C + 321D7B21952AF02C9801114302FB058F22CD2D17EA1A002BB2D013201E48A164 + 8DDC365B54017C037E7E9088E730B58D6CC583236F51F79F01A076D633DFEE34 + CC97AB79BA1A40D9C335FA3D57D4733B765F4FEF4F05FCE67248488AC6AEB13F + 3ECBE60BB9FC071FDDBA766BE5D9674EFDDA53E37DC9B0853EA3844A53F0C613 + 773952F285CACACA2670D89BF736AFDC5C01E13D5CA712A10544722920C6E361 + 211872DDED91C1184AC4AE0B62B2433221F282383E79B2542CDE9DBAA52A155E + 0800DEB9A8CA342449181CECC323B1CCF4D46728AEDBB8251FEE431089282B56 + 555ED7D46834F8E6379FB04C4C040257B3378DAE1DDFFBFE073CC79354A0DE64 + 5822DD2B8EBB5964FEF19FFEEBF2D599575E3E77E2F85022111B1CEE872322C3 + 15788072101CE1C471CF15BA1620FE960AC5E9E9C51BB797A6A6D71796D6DEF8 + CE0F97CA4CBBD2C5E3D1C8550986C2B5E4F6DE0CDAE1D05F9C0DFD904B67C7CA + 2F6FF64E0C477AE3A58DBCBB2B01D6E26A61722C0D62D1C393999BD3EB2686E1 + C171FBD3118AA10C6E0C55E0A6DACECB2942A0E0A79A780EA486566EE75BF915 + 75E340CA10338EC0FB4C8B64ACF3F9A8414956F67136A0A5A2784AA36259DFAC + 12406AF42723B07E09339ED7FB9302F5A3EEA2F030D489FC3EFA139C1A88E708 + A3DDAC3E10D2E32349BA260CC1CDEAC85E6320A46383B1542C40189F0B180A6C + 14A4698163873391BA2EADBD35770E4C3E17659D1246059D01F21404E1BD1894 + 78C23DDB86F32E553C4104049599A582D751E4E11D902B5751B555A8D3467569 + 2B6B3DD3119226461E4EC53F9B9818BE733FFB2F3FBCF4E3F76E7CE5C963671E + 3A9244473217161F7819CB0134F1E5BC72736AE9F6674BCB6B85F52DB9ACE87E + 9E95C45611BB1917C08BF38104C3C5FBFAF3EBAB86A97B69AD59B2771C48A269 + C462D191D1F13B37AF92F8CADE1B054096483F663018E005C141C513E2209C29 + CD93CCF382659A98DDDB766459B549261018FBC444B2229BD1486865BBD47457 + 9043BB322CB1E8BF7865E6E6CDF9D3A7469E7FF6D4D86846145841C0BD7BF486 + 4413BF6E6E6DE4E6E756B3F9F2C2726E75A31C12FD3D92F3EA5FFCF9B23FE632 + DD4713DE53C0776A185ADD54BF2F8C1E7403E8A163E2172ED7D3B23DBBD277FC + 88655872B6D9663235BB914947621169B83F4EFD43819346C3527FAF47D3A667 + 37A950BFB45638417C420176B7ABAA4FEAA20F657629BBD77C5AAF468BCB7C7A + 22736D6A0DE07E3019421F7A9B6DEFF8D9D0BD58D16D0B4D0D47FA63B98262D9 + 0E60E8A327FA19A276B83EB50E0F1E3CFDA666A27309E97EA4DF93E86FDDDBAC + 13BDF1C7D3E3BDA34371601980A4C8C47DFBBCF26BE7BC4C609427100CB5BB8D + 5480B300A384F9A22E925ACFE02F10D800B1DA6F78123D099EB1434877806BE7 + CC5D17BD6B891BD3505F787EB558920D5881274FF7A3DED3C7FCECE28265D77C + ACEB6251F830DE30ED38980ECDAF95CA8A01C2EFE3A732549CBF70798964B16E + E193BF736D6B705E676EDA51D4EC87A4577D2F1F75CA4966FDEC64F2E4686266 + 29FF3F1FDD7DF7C2A73DB150221648F58441886659B650D6E7163773F9B28F65 + FD20D863C0EF5DCF7BDDACA82215802F100C3AE94C616315F92C8F880CD0E162 + 5228C634CD682C2649410493FA770066D07350F160033BD45DB4ADA3A04D228B + 627C3CDB46E824514CADAA63008874E8919A4C87D53B9A54556DC104D06E460A + F05960B5C85D59EEF2F5D96B37EEA712D1DE54B8271AE849C4E085817630CB59 + 5FC72DF6E58AC1725C34248D0DC42BC5FC91E7DE2A0C7C7D75B5FC80625EB33E + D47508D5E7AA3FE2EF9DB1D10EA5EBCF553DBAE7913B0CD673006C07E0C82D6E + 248EF4999A61C85AD3101F7E328FDEA0110958CCD870A2DE736569B5F059754F + BDAC189FCD6D0192C6C2D2AF3F73BC58D1425595E8E25AA1DE3FFFC005F07AB8 + 3F06686E58762C220202C09B7C65837AE9EF73D2800B0BEB85B1A184E8E7BE7C + 7A00A0335455E6CE2DE7094F6103B879DF87C97B4956512AD10396792A8BBAA7 + 7D71BD489D93A04D1B8506D3529C22E6783D5ADD1355B347D5AE1BFC4A4D588C + E78685F5E81E9024363AD75DCBCA4C37E5CEECF6B36787E003FC05D11EAE08B5 + 1DCD2C162CC2749AE23AD7D8E29DF9DC338F0CC0D767CEF4E74A3A10588A5033 + 4B45CB7BD374B8BBA98D33E97E483A9F78435CFD7B402E40A93313A9543276EB + EEDAC2E23AC8EFF717B6BCC4993E4692C4540A77674029974AAAA2F8D88640DD + 86699190265E2551A702D8598170482E4A86A6904A9A8B935C664C7DCC73204E + D7EBDDD17D12A3E93B96616ABA6568D0C53235D6020416185E703184A8C5FBFD + 98CFC3717D559D2CEE5E35CCE1E1845515741CC70D062580CEDACA530D555951 + 008E23E160BE28AF6F663912BF8FA0B3ED63B960404AC48243999E9004B2BE6F + 6D6D9B1F79369F7931B7D2DD93E5EE578BB23C6228DBD4B68B9476FB1E63AF66 + 9FF3685D1EA6BBA175592DAE67639924BF4B1A322CEB1797EE5FBBBD52DB3B0F + 37CADA66096AAEDE59A96F393DBBF5F1A74BAA6652591E9E584004C0D66BB757 + 0F3043CFD054570062AE4DADC2BD8DB2B6CB54E0EBCDE5B2AC3B4D2199DDD6A3 + AF6E96E79671730EDC9D51CC90C3EA863D35BB55DD5980A29324FA0551E04401 + D8A2401EBCF5AD16284995980C717B4243B0CBECBBD6B59F973DDC27E2798339 + CE6B52C35690E8E9076A406788884DCDFABB8ED89C9CAE464881815EBAB9A6E0 + 6CDD04D115C08B01C85DFD26A896D38585FDF8F6BA4AF4C889A828F979B89A20 + E0CF2CE75B2AB9DB276E62989641F8EBCEA2B9AA3AFBE9813F532A15C03D1069 + 038203AB3D3038904C267AD3C9542A914E27FAFBFB12C91E7445726D43D78048 + D65B26E1464DA5A2AFFCC6390103D3909B04A4634DB5891727A6C31351010D40 + A7C965209928DF383619017DCEFD7EA9FE0488F4631A86A6EB9A03475331FD93 + 0D421CE62931D12D09F0CEC7420B86F16E48F80AD59AA61E19E891248C200E54 + A037157DF2EC31DB6E584238E5802802F300AACC0B9CE41748DC52FC291E8F9E + 3E3EFCC864FF48261AC400BCCEF2F2662EF850F8F1B7B215D3ADD2C5FDFF513F + FA963FEC7C415D05B5297957A32AD4A355EFD1AFBFB3E74DEE6BFC5357D9FCD1 + D7AAA2B513FEAE1F3AF0EA6718A6B5BEAABD57FFDEFDF7F4C36FAA4D0CF7B13C + 9F5BDA701AD373B60A2CE2DB63BC6040084AE8E84EF6E0B75C88BDD6B67169F0 + CF6F7EF52483EC4CF9F0EA0260742C12304DA72823B8B03C078F380678F6B14C + DB911AAA43413FCF71F0D8ECD2AB7AF3D27403B357A01761EBF56E7343B4B970 + 8D170A08ECA393A8EBB8737F6B76B9C0F8F63C40CBD5DE2F6409D35C8DFF0F48 + 7C0885031FA27337514B829E790DD05C67F60C5CD270D8E643B4394ADD819AAB + 7C4C322A654B5AF2F677C687E3200583D09EAB38976F6F28AA2660027A6C4A55 + 93E84564597245AE1FD834ED743AF2377FFDE6C54BF3FFF0BD774549884623DF + 7DE7CD6422220482D0B2942B94B31B9829DEB1057F20D2D31388C4793F0F43DE + B87AB9379D4AA7D3141C31B7B369B88E5ECC17AF5CB9F3F4E3939AACAC01F348 + 243860AD7E510A84D7D637A47034140CCAA52265C498430950DB940D37F257DF + 7D575561E5D9F3CF4E02CF7CEF1777EA737FC2B9645271D6C2D0D18EEBD01520 + 9FDD74AA677C28E958982CDA75AC4A4571079F0B7FF95B65CDE958F2EC94F879 + 6114AA32092D4A61F3C77FFBDB9DB051F7B02B5B1AA53BEEDBB2598B215BB73C + 30BD0500056124DAD7D300499D1CD33BB0F71B902C00D06A1C1377EF5EFB10D2 + 5D853AEDE3EE52FA148108AE198AD6C849DDBD0694158384AA6A6B9B9244C12F + 0A0250830EEE9D1D956267372B09B8872D1789D77D6327B7D5B08753803EA3C1 + 8A32DC6E327D0293053A5C63C4F5CAD426FFAA86B9B7E0A44CB79C344B5C02B2 + A7FEF2937977AB0064D34E049973277B3994A0A97BBB5BDB9E0468467378D446 + 0161B952D158D67FFEC5B3B1585855CDC14C3C20B87655E789CA50F28905DA48 + A8A883599B381B11D311C500D573E820C59B36E3DA20611BAA4EC393027A12C7 + 780B3D38713618221A2AAC46464CB24B31485701026D2795C0881086D9EC9C04 + CBA41B26463CAD6A566C54DF4B93638363837120BF706AC0A3359B7BFE0FDF89 + 3EF17B0443998E9968ABB2AB159A95D0F9C1E77A97AD61848E2DF59F8319BDF5 + 90BB6A1FF4C87BF4EF72E8EDB9B5F4D84038192DD7ED6EEA301EFEE7B25A1DC4 + AEB22DDBD590F604447F935EACEB097827EA23A977506366EA9653F3696FB248 + 777E522E138D88A7C7D3E8424B348C20DA5B5D84C56AF26B6B17F9A93926D38E + D5BE8304A23B2BBD67FCA7BADEED4240352DE78EFDAB4113DA859E94111FFBD3 + 19DDCD2FFC739CDDEE0931278FC6AE4F6FA0F5855C6E2271832CECAF07565A0F + 80C9B1AE6D1B8091805327277A7DB66ADB21FA2BC8E33B2E05D883A55B304DD3 + 00E01330F30202A92E97E12CC4A008402A572AA66EA0C59FE77D1C072D05BFE0 + B0689E72513D80D0BAC3882921678145FAC81C71D333CCA7650A715537458925 + 894701989D9E78ECD4F800EBA0AEBCACE89BF94AEFD823675FFD935FADFA74B3 + 23EF94BDEFA7E61A9F5DBDB4AD794F770E4F5F10F07DD1657F7BBD57E7D8D985 + F5DEF14178312B85725799CE3B3FFA6164B76818937252172550D13BA73657A8 + 5ABDFF0584F77F4024D2A2811AB0FDA7D2D6D1024BA9A22762DEC624A084B766 + B676F56FFE52372C73F848DA0AE3DA9C5B3392EEC2D2F6607D48482AEBF8CAD1 + 26FF28122DD8DBD739F55E3CAE014904F287B19A78F84F0C86C2986B3397ABAD + 10EECAC7749EE87AC0F1AC18F09F9A48ABAA1694483A1914D53DC80846E386AE + 3BB6E912111EAA796262723DB5206B9B1A0035860CD1758CCC02D0C8B91CA656 + 36024C08F7291349DC3434A7CE5580283E30F2B84B3D871826160DE2BEFEDDCC + C065FC985809A3A5C08D3732980A49C2D6762E9BCBDB2EDF7B64FC6BAF7E7B89 + 3B7E71E1609B3D9BAEE8EE2A8790CED6C8473B7408A30705C6F66FF7037A29B5 + 7D1ABB7000E830FC68CB02720A70D2C44806EE43A5E53ED1960FB677E0B60925 + 0E4699E993F493F7A7F6ED089C94D14C95F149C415E6A067DFB0C8300E305CDD + 67C1A360E9F8C43E0821FDE5278B02CF8270AD367AA17637D881CBC182D8375C + 875631491BC1FDB09094A9BAA5D67F9535FBBA160D885FE5265E4C4F00183101 + 3F2BF9D10A8F8E6A36B359D45357FFEECEADBB24B91BA319E623678E4682AC26 + 2BDF7EEB71D9B07BE39C2CAB62D444F7264CCD891C1270311D8DE536D741A436 + 34BCE12DCBA62A02622CF2D1F07A243F98097F710315834A5906DD45790F6A70 + 92AC651ABB710A182EC633219156845A9EF3DA7D8B31F480D7B21882CA7683A1 + 5030181482712E1CCF0C8F9F1939E9C6C767F3EC951240BFD6D4B7CB1BA04D3D + 71D7AB99959A2D5FD5BFDDB0D1DDB4E941BC38BB79363A6CDB1D68773F0DDAC1 + D48CD25A369A49000B33148D391CFED834A98E328B7455D0B7844C5612FD88A4 + 0F4C485DF20C515CC6874137DBC47BDE979062A56764EFC621F93009E95E07EB + 341DC83ED19D994343D28663357EA5CE0374E0A2D26C9C8A24FB1C67DA25914C + A5807F7222E983DB595533718E17FDAAA2C275FC3FF6AEADC791242B6744DE9C + BE94ABAB6A7AA6BBA7E99E9DDD9DD10EE2B268D80176175E785A10F0820412FF + 81179EF81188777E055A24C41FE0F28084104FBB2FD03B7DAF2E5FF3121199C1 + 3927D276A69D69A75DAEA95E559E7657B9F2121169A73F7F27E29CEF80E78239 + E90ADE4D092007B4D6602A2D093040D2384C30459F99456C1383A0E7E3512663 + 13C90467F74F2F061399C4258D1853DF9846C4969E1C45AAA223CF28DAC95ACC + 069B2B3A1974AF46938F1E3CF8E3BFFEFB9FBF65BD8E73D275E12820E02F66E2 + FFE6199BA796559E4B3DDE8C390E9D655666D74C73AF6CEF2CA6E3FAF50D5B3B + B66D76D0D4AF37164DE631DC120E6727DD7D3B3EFA91FB18F00B956AE6A3E2E4 + 4E4EDA74159139CCF59DD4CD3270FB547AA4B98E6B9BDE787267ECE1478F575F + 860B88FDF4D1E0EA7FAD284A500054A9A0DF499218DC70A6B338114C991C7CF0 + D0B1A81C001DC700D28CDE4D4D4591B1413837A1DA4A549F994A2E53FB98C684 + 508B799F704EB73F74FDB7E3ABC8EF50D414963E49BBBD13C776448A1ACF18F5 + 99A33FAA861A471EF30049FF2F4E246C0802EF4FFFE8CB9FFEF37F9C0C4F7FF6 + 96C7228D84783B2995A223AEB81B2C363FEDBB0D06C70143599365E9EB258336 + 1ACDF531F1E87EFD1106A5C761EF6CD0BD7732FAFA0D66B257876F6D8B7CB236 + 4F28453A553658D1E61AE3D8DA260E3C8D33E96776C7B31DDBAA31B6F67B6D67 + 454416F31C5B6825E121E4AAA053F54BD228F869BD851B0A7E5ADFB31113B525 + FE69A38B6203E597AAA2C7B55E36CE29BFB1E5E16F8C77EDF8D56761E9F93F38 + EB5A27FE8F7FF84522D2376F2E1F3FEC9FF71D01DC932F792F904E95A50A7E5A + CC951647C5109DA150BEE32D6B8F9BA5AABCC725C430B68AA044D747FA9E8F35 + 4C0C594E339144171F7C041EFF9B575FF7FAA70E2DE56759369928ADF2EFF470 + 1E59D6699CA83FFCFD5FFDD16F3EF8C77FF96FD447B5EDF30F3EDC0695FB2B33 + 35328E4BF39553A2A5B0097ADE7C9AEC16C39EF678210E397FDBAE6DD732BF9A + 2A21870FCE1DCFBDB6B088DEF8BB69833B62A23676C3DD2B62015FF84A1D227B + 533734F8FC60E1F28EE7AD00BA2A5EA971F0D37A0B8D829FCA2D97E39374F1B0 + 5DAF6F7DC0FC3ADB5EBB2E5D3DA0EA1E8BBD6C7654EA8B02C4CB7D15BB5BF5AE + 0BD75868DB9A86F283FB277FF5E73FF8F4930F9F7EDC1F0659D7B394D4A5E190 + AC089555D697A3C92C9A53243EB9E179ECBDC919E5C54ED7DF3242D4A03FB0A8 + 5032012CA6BD0374BAAE2DC1F7B7290B885A1BBDBD14B3CB8BB3BE5419D62045 + 6D46E72FFEEC075F7DF9E9B71E9F07BDE1F9C5BD1FFFCE175DCFCEAFAD708537 + 6866FA6189A185AECD77C82AD6896CCFD5867DC67F2DE0BBF1174A37D8B26B20 + 1AB54B0095EE3DFAC0769DAAD3AABE28B6DC048DB0BEEAA06637D61256812D8A + 3089A344085979AE5EFBBD7B5CF96FE00EDD8E0F48EA763CC6D9CED3AB46B7D6 + F1CD236939D7BE7268B548AAD7865746D2B56BAA0A262D76BED191B57EBF142F + 67BDBBCD8BD0C5A6844295A6E92C9ECF85CD344056A6AD75C5030A83C2FF9666 + 4BA13D6A282B104F7A679733B96BDD1BD28A314F19305B2CD98D33A1364E0B64 + 83E119F04BD80A0417E77F80F672A6D3E4FBDFFB502A13B28AA9A816F7920438 + 6ADAE976FFF24F7EFDABEF3FEE77DD2278E922A4AE3D0EB6550B98AD64A52C07 + CD2ADC5C5DB099EB38A4BB3DB6EEDA75E005D735DA3C0EFF68837AF7EC15DC2B + C049B96B5FBFB5F58BB97E1B35978AB977B114898C6B90F4E0A19975A720F0BC + C0B35DBE361FB3F8756B1396CD9154578C736B4CBE558BA4C5D38F86A4E5EED6 + 59B02E756AD1028ED7E986B10274F45C06BE48FFA4DFEB07697961301FA29912 + C50D6C713DCB244E330874CA1D2F60CC5E766A263A4D330E2ADF7291C4C6E1EF + F6025ABB77E10870F0A5904934CB28292991E917DF1AFCE40FBE83E976DC96A9 + 956A0BDC7FA0A581CFEFF5B9501478BAE104543F0CEEEDF358C74ACC29E5BAF2 + 1E2DF7B4C4D1BD60F416FDFA637CF276037D0DDE6C698B7E0327057E079C9417 + 671BB790CE2D73050711D2354EB2EB3558218188042029B0D24D19C08309A945 + 44C5E1367C2A7CF4F1DDC6B4F49B20A4F59D6F45D2AAAFE76A245DF6543D8170 + 53485AEAB1CAC107C8E20861E2C18523A51CF47BDFF9F623CE4A9AB498299452 + D6A3791BE9475608C53706ED0075985E8D1C37C0377739706DD1342762AC1774 + 6D9BF1BCEA5C4A4FB0AA33550A1193D11B29130062CAB2672296BFF76BE73FF9 + E1A3FB67EEF79E04240B61238C7602E0AC30E644920AA5DE4820AA793FF53E8F + 92715D7F680D881EB2C4A4BFA940A57D3A3AA8876B0590AE1920E9D9E3FBA70F + 2FC62F2FD35238FAB52EE368A1F8F5A350B1A4A930CBF7DCA5D2CFBE43AB6C9E + 330EFE7DEAA4F061CA54A6B05E634927A936366EB1A77044F5D3E21F85963746 + D424FE697D203B23498B47AD75B1DE46B9978A04A75247AB57B7D85785D2B355 + 7A31ADCDF8FCE21828971201EEAB2F3F7FFAF4FEB79F9EF7BA80A74A2F68261C + 014E747F38A068F9DCA07B78E3949046A964D534E6B0C5CBF7D3B216A8CBF2B0 + 51C7713A8087DD4063C4672650DFDECAF2134CA2BF856BE1B809FF8B10BC7896 + 8AC4B3F1CAD2543A4E2E8402A0AFD2E5F7FCC6A28FB68E86148C303463D54CA5 + F2EF839DFA8A46B76D3D96557CDF571FB6C5E33CE608D7DB7AF7EC35DCA9A70F + 3F703CF7A006176D1E343D72182135964ACC868E934496D3999B13D2EAF1D15F + 36CE96022D75D1C7C72A94B7E4CFEF3B495A3A75F5B29579E26EDA7B1C4EBA39 + 93B07111C56BAB74F033AAD019F44F1E3EBCFF5BBFF1E9C949B05863A4B3B20C + 80F2D1274FC1FB5EACC46BA2A2D66C3C26A82DCDCE60E4B14E0D6C2E07659C7A + 03DAE095C307C12CC167186587CC54C421E996E6F302301EF8070E3EF04D78C4 + B14855369D837B8442D041A793D1FC6D667195AE48621525DD8B7DD63F6C93FD + BF21F6B48DC1EEEDD4D7DEA1BB37D67ACD37B25E7F8D8B68EED7578C89569CD2 + E1C38B1C49EBDB6C1E5CA99BBCBC4DAE6D2B3A837B95CC9304BCA744366E7B0D + 186A07C6A83C5410787E17D7F13981E9B62FC2EAE6AEE7DAD7BF30B548DA4855 + A47E09682F24AD9C902DAE5115BAAB5DBEDFEAE06716034AD71B9C003A469140 + D58252B41403247DF58BAFC379CCF9726E8A919E0849E771BE1A094E11508EBD + 9D87A69BD5284C7C522A27D58C85F399C092651CB633AC789CC1ED6502A74C36 + 2A504E29113DA328318F384EA21845C4332C64EFA1B81F0D5BA80DBDC7351CAD + F1F8F778009557AC81DBBF01E0FBC3E8AE0FE4A17608BDDD0F6CAB371EFD5250 + 494FA9D347178772D25D23BA19426A0C6EFA04EEE95864992E1CD960540D468B + 8AA59E1B043E305317B314B74891DE0C926E12D2CAC1D64E92AE8E3B3E92AEF7 + A5AD5227BAD85D6D8FD59D5A589E0BA54238609C072E012683B215BB440686EF + B710623619BF7DF1324D51A289F660514F9EA322CF87C21810C8D1EB97D090E3 + 7A563ED7409E3AB70B423508AB403229B65E67524C47230AAECFA928D640CE32 + A9B208B013BFBFF3C76C1A4A11C12E9BDBF3E95889181DFF6C37BC2D5FA7431E + 8C86A6D98E16CB50AD17EFC9E16CB421F01D15A774832DF9E64308EDB65DBB17 + 9A9676F58B37E0AA9C3DF910C0621BEA1D16F9B4E741A583775E3B7C1F0B6990 + B459546903425AFE0B3E940149A002D700379FEF311B7B98ED42D202C0559F59 + B3707FF3485AEAA4DC5D758FE54EE92F4436EE794E2FF0E1097C49763ABEEBFA + 2C9F9C44837BD5EF0483E149D00D826E0FB8E7E58B57F3C91CC8E3A0D7BFD7EF + E5C2F779D028C334D114ABC3335C425A9423E53CB3EC44A48EEDE4636098F2D4 + 09BA5847C4C5720C24DEACF2B9DF0CFF40EDBD0C27CD53A3C387527C6918C62A + 9E9A6BCDA4448195ACC6B3AEDAB41B6A576FE0E26104F0526BFDDC2AD0AC6CFA + 466FE2CA8F531514EA5DE736D97194411EA987AB67AF652C860FCE5D5268BE66 + 9BBAFA95ACB998EB1152CB2842A17B850EBE5EF5ADB7B5B4A70133021F1F63F5 + 5151DFA95ACA3F1621AD1F7115925691CF2A242DF6766348BAD6DD4E242D760A + C866BB0C001423CF5C87128E68B12953D17CC60D02529A3C2098C3D8B0DF393F + 1BF64E4E80872649F8EEF573387CD0EDD86C19E7C4A89852968433892223F916 + C3546DDB9112682D8A3059B43086E849C1A14A888CBC7424AC7C4169A9FE074A + 919AECE185CC076A3133E6FA36F04F60C1706BC038552A4D54D641405A17E754 + A6A259C99DD75B4173F1BEAEF61C00A3951FC023404F437ADB6CEF1ED07CBDA1 + 5776831B0149E36978F6E4A3CE49AFF6E4C3229F0E1C7B33426AC69569E3E0E3 + AC7F9AE9060D979F36C27D045360A6E0E607AE6B9829DB38ED08485A8D89A5BF + 6B90B486276E02DA62E7519174AD3BAB389950E8711D4C39002832D0C0872F29 + 7B11C7091F75CC449A8F477118128C3A84A42C9FA5C4322194146F63B291A698 + 79CE96D5A42D5261E2E1640AFE39CA3B15E655B14A270AEB5970EE3C8A10AE2D + 93FBC493388AA2B945FA239C3B9EEB99A163C0289151BDA62FAA51E7C9660EDC + 759EAD2FCE073A6398F8BF0AF5AF809E6B3D080273C2BB8DC1AE11D5D2D1D7CA + A9D747952969D6FCE6C6DAE6F7DFB1DC5575C4369DBBEA33666FC770A70C3F3A + 837B309E85DF4CE4932E87BDEC3872CB6BA12DF0B628EF39735CA7838CA6EEE0 + DDC14F7506C3746CEE383E7C8A139BA3E29A2C48415FC374D3F8A78A6BD92E01 + 551102B57A2177944D5E9CBEEAC82A84386D6A41AD8F62D5A3555084A2F9496E + 5168267311061DB6DA99778DF19D99EA06435C18B21DF0C279E6A290081CC06D + E3A1DBE89463213A66078EC896524CF0249A8CE3D9344B2578FE9EDFA57A0AD0 + AB36D14B009128C9075E7C2760E0D7E38428D6B3C3D545CFA30A1FE8A39F9E9D + B95E07FC78137A45914E25D4922A7D707FF8E0C1F9E8DD1BC0D37ED7BD0C333B + D37629BE55D7DF617B7EC49020D3CAD2EAEDAABA93EA3798E7DFF0CC54DD58B7 + 26ECE89D1B0E1DCF62E3B1270A56D7135E4DC72FDE0D1F5EF42F86FB88CFEFC1 + 1CF7BEFC7D9AC515FC3001663A4719E06C9FEE1A11D2E51D019FE22E3253CF07 + 27B4EBD9AE4D9EFEE18474D778EA2649F38D159CB486246EBCA6EBA9A2DB3969 + E9FACA44D3AA6AC6D2EBCF10C500F71CDBF7DD5E80E1BF04F0EBEB4EC0207FF7 + B73FBF37EC62194E5456766DC7E7F0B08123FA8EDBB15DF8E9E2779A1F747D2F + 9ACDAD42ED19F4C215AE9B63D085EF2C9A270782D828960BF583278F1F398E07 + BCD3023C775DD7F761BBC5EC8C4EEF767B0F1E3D2141C53C8234A5BCFB652FF0 + AD3D1C04C3B3019CC9ED45D22902346BE6CBEB267EFEF281189A59D59EFED2BB + DF38ADF8565F878D56F2986D2CA421433984B716BEE7D777D445566FEF69DBAE + 4A42BA620A9527C693792AE4F9270F38E793D7A3464D568FEB1B21A455572113 + 8919D0E067F940749CAA015712D2DD2DAF994D52D0C051A463167281FDA47922 + E07503F237875C1F935FA6AE9B3AF9A5CDDB43E5D71BAEE0A4A5840322A8F5C1 + F9D6B2475AC3C12948F0DB1D80449C12297F12CA21FAF0B3173846B708B3CCE0 + 3BDD76B102A817E8149E76B0B432556DF2FD4E1C85491C5AECA2801B8BCA0945 + D69187DC03D2E1F428206CAFEB33B7E3381D68D1542E8106A324659446057632 + 1CE67250F02E0B75766F3873ECE92C5ACC3E588E8B6CD9F660840E850AA03C6E + 3E79C14A6FF3B6DBBA34C09AA3E86B5AEFA5CF53C3B830F3F53FFFE96FF769A9 + B5D65AFBE533E05D3FFFB7FF4AE6CC6885800340B3971CF5EA995971825DE0D1 + 53CC3C06CBEFD088C050D0942A75920F8F8EBDE300CC20C9452EE9DA54BA195A + 86AE998D61A634410420EBA2B624B792589C0E871F3F3AFFD77FFF1F522F415C + EB743A599A6AA5B08E13069C620EEB3FFCCD8F6EFBF5ABB667CF9EFDF4EF6EDC + A96FADB5D6DE37D3324972424831994A499CAFC4182469F22F8D1ADE8E24114C + 96A73C624466CC9FB7091F27E30873ED194E95928EB38915A5271A1C1A2C2D6B + 681DCEA832005B804BFDC5E7BF723AECC3083CCF13021A998A38C1408254C201 + B7FD8AEDB016465B6BED6E194DE8017E2A9C314905EA6CC7339544A94AA89E92 + A2C94AA393B7631626A3207AA3844F800CCFD9AB172F66D339AE592D3014A39D + AC7CAA11186BAF3F5494120ADB6DC79ECFC2CFBEFBE4BB9F7DEC071E34025B26 + EFC6AF5FBC4830671FCB31797E70DBAFD90EBB79F5FBD65A6BEDBD329D724695 + E15582724BA8A610A732D13A45BD25EE624E9391FCA2C9D54D46BA9CF5857D70 + 8AE374240AE22D75472CA35AAA69DA14FCFE388E98091AA57307274322BCB64A + 0185E5E79F7DE2FB7C321E439F7094946914CEBBFDDE74A667D3991489A944F2 + 3E5BCB465B6BEDAE1932CD8C8AD661DA10B9F318C6A99412498AE5E41539FBAB + 55ADA2617ABE5EAC8061D8929A4FA64A264047552AAD059A6679202A47C51B91 + 2C05F3E184FEE0C4715C8CC94F53C7F186031F00964A8DE2246B1C85D09AEF77 + E0F4C9780480BE4C01786FAD85D1D65ABB2B66A63BC338A1984D444F8CAA072C + B35DA349874EBA48004D69599E6DCE8D82A73E9BC5575773AA494731F4A44782 + 2AE0422A21CD06385262F17A053D465144A79AA8019434F53CCFF170310A8FE4 + 168AA468CBF57DD30532658A424AF34028DDC2686BADB5F65E187AD5B6339BCD + E6B349A6046228C218CE683AAE6BD822CB1878D93ACBF1D1AA081802A75B4D26 + 212EBBE384A8D2E899A3D45D3C9F4B112B2930711E311A39691809F0E8391E9C + 09912329B76DD7F39885110284B9C87C7D1803F51645C284E5C32904E5D6FBBF + C4D4CE8DB6D6DADD309CB5B481F8A18E2780A48B939EE0482B994E47B3D3932E + 3351FB5833DE241D9948D17542CA1D4F5BB8F883D5B45309B8A9448CE27B6128 + 6582314F9AA54A32E6BCBB9ACA24C6D87C8C48E5E3D15C2965E61330F7141931 + 8A8D52AB58C399D3E46946759B697109786AEA719470BEEDD76E87B56CB4B5D6 + EE8A0154795E07EB1D01335CC88D3EFFFAD5743265762E76678ECC36D2349706 + 08882945A4D1840BF5D05692001B45443482B5F8679C447314675AA41CD89CC7 + E1ECEDEB57407B499E19859CA13B21A4416C0A1040F9122CC14072A461189EF4 + FABDFE2095A2E915DE92B530DA5A6B77C74C76A5594F42ED1154FC4CE2A25C21 + D6A4CBB39F2A0DF54D3C0F23EA3555B48786525CAD52247D87F4147ECF276370 + F2799E6B8921A3490C38AB9885F596538C917233F869DB809E71246CEE284994 + 53E3D483C68A0C220EE341AF4FF5EE5B36DA5A6BADBD0F86AEB23269E2806BD3 + D1249C4679D6FAC2287F9D849A7575E2A3C972ED04284D824BFC566A74460099 + C19DE7848019612B86012CEA85C00F29B17A32C7F4530E581B4E66E0E003CEC2 + F989C4324DCB6A4B84E396420D521DCE43236272DBAFDD0E6BE7465B6BEDCE98 + 09560228B46D5CA9B77CAC249C976AA2FD8CBBAE4B19A259AEBBB1414B5DAC7C + 8869A09C3900C894C494A1D76EDB52A596469128AC514C01F94B2C86BD0EB54C + D27C5AA5096135A7E52C8A1B9049BE004515ED01457BBD2ED3A9D6BB8418DE03 + 6BD9686BADDD0DA3A57A64760CF3E851C5CEA42A99C27546291FA828822467A6 + 4866955A246997B82AD5D3304E49B9DECCA882576EE49CA91A8736B1A80B324A + D9F458982497D0E72CCF71CAF2C9537BA96ACB6C8CD89742928E547A7CF9B51B + B016465B6BED6E182D0BD1328E497FEF00444573898A2024B4C71DC7763DD70F + 1877166A7C9B4C10D10F786522541CCE0137176C91E5C5446C07D9AE952F4299 + 16700656C40EA9A02E9A41ECC5A5F9CC88E6A5B9E7CE2C8AC5C215AE2892976F + 26A8799ABDEF4E7D0BA3ADB57657CC767D145B223D278E9220BE9429406777D0 + B5B86B7B1D0785473D405974B76B248CA185308A441263DE91664A2983A1424A + 804EA92489455959419B1367111C68D8DD147D3522B619525733B7C0A299C030 + FE2C9D87289D9F355692BC456B61B4B5D6EE8631D63F7BCA1DCFA4B7735A1102 + FED91B0CFA83618AF1A081ED78287D6F92DF59057C994D491CE782FB54B90BF8 + 2CAE086134BE564A4671A2A45A26E3538A3DE67AE2A467BE852FE3F08D023E6D + C69FC03B4582704C33A436E68B2AB553B2EFD6AD85D1D65ABB2BE675CF38F7F4 + A2EC874A6219CF3DF0E3BB1DEEC0C333A5EE082B6B90814A27A98CD3B23B601D + 9342649A0B21504FD4802CA5931624C69992C942229C34E773E93C4B8A74F42E + 464CC7EE8CC234A5826679856FA130418ABDF7308AC5009E3D7B76DBC368ADB5 + D66EDCC62F7FF6E2F5256059182AA0816272056075394D049B8BCC9FC5E9743A + B7B19A139F4EA3B757B3FE9B09B74A050D0129E7B115CE43AE43A0AEFEBBE9EB + D1EC721A5179E4341600973813FAEA72A2ECFEE528C4224F8E4BF9A311734627 + 6FAE62C5AFAEC6EFC61120E4681ABD7C3D7AFE72343BCDC65793AB693C0D85E3 + C45753F1F6723E9E458E9B75DFCDBA9757EF2D463D7FFEDC32DF007C8F1A41AD + B5D6DA2FAF55143D5B053595333FEBEB17AECC38EC95C6ACFF1F8E13F618D15C + 01394E0FEDC22D466436238C189C00D8740600EF62B94ACCBC51680000000049 + 454E44AE426082 + } + WaterMark.Width = 145 + object Label1: TLabel + Left = 162 + Height = 15 + Top = 88 + Width = 116 + Caption = 'Welcome to JvWizard!' + ParentColor = False + end + end + object JvWizardInteriorPage1: TJvWizardInteriorPage + Header.ImageIndex = 1 + Header.Title.Color = clNone + Header.Title.Text = 'Title of page 1' + Header.Title.Anchors = [akTop, akLeft, akRight] + Header.Title.Font.Height = -16 + Header.Title.Font.Style = [fsBold] + Header.Subtitle.Color = clNone + Header.Subtitle.Text = 'Subtitle of page 1' + Header.Subtitle.Anchors = [akTop, akLeft, akRight, akBottom] + Caption = 'JvWizardInteriorPage1' + object Label2: TLabel + Left = 24 + Height = 15 + Top = 91 + Width = 52 + Caption = 'Some text' + ParentColor = False + end + object Edit1: TEdit + Left = 24 + Height = 23 + Top = 112 + Width = 216 + TabOrder = 0 + Text = 'JvWizard' + end + end + object JvWizardInteriorPage2: TJvWizardInteriorPage + Header.ImageIndex = 2 + Header.Title.Color = clNone + Header.Title.Text = 'Title of page 2' + Header.Title.Anchors = [akTop, akLeft, akRight] + Header.Title.Font.Height = -16 + Header.Title.Font.Style = [fsBold] + Header.Subtitle.Color = clNone + Header.Subtitle.Text = 'Subtitle' + Header.Subtitle.Anchors = [akTop, akLeft, akRight, akBottom] + Caption = 'JvWizardInteriorPage2' + object CheckBox1: TCheckBox + Left = 32 + Height = 19 + Top = 88 + Width = 78 + Caption = 'CheckBox1' + TabOrder = 0 + end + object RadioButton1: TRadioButton + Left = 30 + Height = 19 + Top = 119 + Width = 92 + Caption = 'RadioButton1' + TabOrder = 1 + end + end + object JvWizardInteriorPage3: TJvWizardInteriorPage + Header.ImageIndex = 3 + Header.Title.Color = clNone + Header.Title.Text = 'Title of page 3' + Header.Title.Anchors = [akTop, akLeft, akRight] + Header.Title.Font.Height = -16 + Header.Title.Font.Style = [fsBold] + Header.Subtitle.Color = clNone + Header.Subtitle.Text = 'Subtitle' + Header.Subtitle.Anchors = [akTop, akLeft, akRight, akBottom] + Caption = 'JvWizardInteriorPage3' + object ListBox1: TListBox + Left = 21 + Height = 187 + Top = 85 + Width = 187 + Items.Strings = ( + '123' + '456' + '789' + '0ab' + 'cde' + ) + ItemHeight = 15 + TabOrder = 0 + end + end + object JvWizardInteriorPage4: TJvWizardInteriorPage + Header.ImageIndex = 4 + Header.Title.Color = clNone + Header.Title.Text = 'Title of page 4' + Header.Title.Anchors = [akTop, akLeft, akRight] + Header.Title.Font.Height = -16 + Header.Title.Font.Style = [fsBold] + Header.Subtitle.Color = clNone + Header.Subtitle.Text = 'Subtitle' + Header.Subtitle.Anchors = [akTop, akLeft, akRight, akBottom] + VisibleButtons = [bkBack, bkFinish, bkCancel] + Caption = 'JvWizardInteriorPage4' + object Label3: TLabel + Left = 27 + Height = 15 + Top = 94 + Width = 31 + Caption = 'Finish' + ParentColor = False + end + end + object JvWizardRouteMapNodes1: TJvWizardRouteMapNodes + Left = 0 + Height = 294 + Top = 0 + Width = 145 + Font.Color = clWhite + end + end + object ImageList1: TImageList + Height = 32 + Width = 32 + left = 320 + top = 120 + Bitmap = { + 4C69050000002000000020000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000008484841D8787 + 87A8878787E6878787FF878787FF878787FF878787FF878787FF878787FF8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787FF878787FF8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787E6868686A78484 + 841D00000000000000000000000000000000000000008484841D868686ED8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787FF878787FF8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787FF878787FF8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787FF878787FF8686 + 86ED8484841D00000000000000000000000000000000878787A8878787FFADAD + ADCAF1F1F1E7F2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF1F1F1FFF0F0F0FFEFEF + EFFFEEEEEEFFEDEDEDFFECECECFFEBEBEBFFEAEAEAFFE9E9E9FFE7E7E7FFE6E6 + E6FFE5E5E5FFE4E4E4FFE3E3E3FFE2E2E2FFE1E1E1FFDFDFDFE6A8A8A8CA8787 + 87FF878787A600000000000000000000000000000000878787E6878787FFF1F1 + F1E6F2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF1F1F1FFF0F0F0FFEFEFEFFFEEEE + EEFFEDEDEDFFECECECFFEBEBEBFFEAEAEAFFE9E9E9FFE7E7E7FFE6E6E6FFE5E5 + E5FFE4E4E4FFE3E3E3FFE2E2E2FFE1E1E1FFE0E0E0FFDFDFDFFFDEDEDEE58787 + 87FF878787E500000000000000000000000000000000878787FF878787FFF2F2 + F2FFF2F2F2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2 + D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2 + D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFDEDEDEFFDDDDDDFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFF2F2 + F2FFF2F2F2FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4 + D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4 + D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFD4D4D4FFDDDDDDFFDCDCDCFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFF2F2 + F2FFF2F2F2FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7 + D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FF868686FF494949FFB9B9 + B9FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFD7D7D7FFDCDCDCFFDBDBDBFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFF2F2 + F2FFF1F1F1FFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDB + DBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFD2D2D2FF121212FF646464FFDBDB + DBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDBDBDBFFDADADAFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFF1F1 + F1FFF0F0F0FFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDE + DEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFB8B8B8FF717171FFDBDBDBFFDEDE + DEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDEDEDEFFDADADAFFD9D9D9FF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFF0F0 + F0FFEFEFEFFFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2 + E2FFE2E2E2FFE2E2E2FFE2E2E2FFADADADFF717171FF5A5A5AFF707070FFB0B0 + B0FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFE2E2E2FFD9D9D9FFD8D8D8FF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFEFEF + EFFFEEEEEEFFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6 + E6FFE6E6E6FFE6E6E6FF646464FF050505FF484848FF575757FF262626FF0101 + 01FF9D9D9DFFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFD8D8D8FFD7D7D7FF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFEEEE + EEFFEDEDEDFFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9 + E9FFE9E9E9FFC8C8C8FF010101FF8B8B8BFFE9E9E9FFE9E9E9FFE6E6E6FF2525 + 25FF474747FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFD7D7D7FFD6D6D6FF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFEDED + EDFFECECECFFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFFEDED + EDFFEDEDEDFFEDEDEDFFD5D5D5FFE6E6E6FFEDEDEDFFE9E9E9FFC3C3C3FF3434 + 34FF3A3A3AFFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFFD6D6D6FFD4D4D4FF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFECEC + ECFFEBEBEBFFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0 + F0FFF0F0F0FFF0F0F0FFCACACAFF626262FF313131FF080808FF0A0A0AFF0D0D + 0DFF383838FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFD4D4D4FFD3D3D3FF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFEBEB + EBFFEAEAEAFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4 + F4FFF4F4F4FFD2D2D2FF0F0F0FFF313131FF8A8A8AFFC1C1C1FFF0F0F0FF4A4A + 4AFF383838FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFD3D3D3FFD2D2D2FF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFEAEA + EAFFE9E9E9FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7 + F7FFF7F7F7FF868686FF000000FFE4E4E4FFF7F7F7FFF7F7F7FFF5F5F5FF2525 + 25FF313131FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFD2D2D2FFD1D1D1FF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFE9E9 + E9FFE7E7E7FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FF989898FF000000FFA6A6A6FFF9F9F9FFEAEAEAFF696969FF0000 + 00FF292929FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFD1D1D1FFD0D0D0FF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFE7E7 + E7FFE6E6E6FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF4F4F4FF525252FF000000FF0C0C0CFF070707FF616161FF8383 + 83FF080808FFE9E9E9FFF9F9F9FFF9F9F9FFF9F9F9FFD0D0D0FFCFCFCFFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFE6E6 + E6FFE5E5E5FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFE4E4E4FFCECECEFFECECECFFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFCFCFCFFFCECECEFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFE5E5 + E5FFE4E4E4FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFCECECEFFCDCDCDFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFE4E4 + E4FFE3E3E3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3 + B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3 + B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFCDCDCDFFCCCCCCFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFE3E3 + E3FFE2E2E2FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3 + B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3 + B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFCCCCCCFFCCCCCCFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFE2E2 + E2FFE1E1E1FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3 + B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3 + B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFCCCCCCFFCCCCCCFF8787 + 87FF878787FF00000000000000000000000000000000878787FF878787FFE1E1 + E1FFE0E0E0FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3 + B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3 + B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFB3B3B3FFCCCCCCFFCCCCCCFF8787 + 87FF878787FF00000000000000000000000000000000878787E6878787FFDFDF + DFE6DFDFDFFFDEDEDEFFDDDDDDFFDCDCDCFFDBDBDBFFDADADAFFD9D9D9FFD8D8 + D8FFD7D7D7FFD6D6D6FFD4D4D4FFD3D3D3FFD2D2D2FFD1D1D1FFD0D0D0FFCFCF + CFFFCECECEFFCDCDCDFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCE58787 + 87FF878787E500000000000000000000000000000000868686A7878787FFA8A8 + A8CADEDEDEE6DDDDDDFFDCDCDCFFDBDBDBFFDADADAFFD9D9D9FFD8D8D8FFD7D7 + D7FFD6D6D6FFD4D4D4FFD3D3D3FFD2D2D2FFD1D1D1FFD0D0D0FFCFCFCFFFCECE + CEFFCDCDCDFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCE5A0A0A0CB8787 + 87FF868686A5000000000000000000000000000000008484841D868686ED8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787FF878787FF8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787FF878787FF8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787FF878787FF8787 + 87EC8989891C00000000000000000000000000000000000000008484841D8787 + 87A6878787E5878787FF878787FF878787FF878787FF878787FF878787FF8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787FF878787FF8787 + 87FF878787FF878787FF878787FF878787FF878787FF878787E5868686A58989 + 891C000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000078C2 + DEFF72BDDCFF6BB9DAFF64B5D9FF5EB0D7FF57ACD5FF51A7D3FF4AA3D1FF449E + CFFF3D9ACDFF3795CBFF3091C9FF2D8FC8FF2E91C9FF3093CAFF3294CBFF3396 + CBFF3598CCFF379ACDFF389CCEFF3A9ECFFF3CA0CFFF3DA2D0FF3FA4D1FF0000 + 00000000000000000000000000000000000000000000000000000000000078C2 + DEFF02CCFEFF00CCFFFF1DD2FFFF3BD8FFFF58DDFFFF75E3FFFF93E9FFFFB0EF + FFFFCDF5FFFFCAF4FFFFBBF1FFFFADEEFFFF9EEBFFFF8FE8FFFF81E5FFFF72E2 + FFFF63E0FFFF55DDFFFF46DAFFFF37D7FFFF28D4FFFF1AD1FFFF3FA4D1FF0000 + 00000000000000000000000000000000000000000000000000000000000072C2 + DFC13CC5EDF900CCFFFF17D1FFFF35D6FFFF52DCFFFF6FE2FFFF8DE8FFFFAAEE + FFFFC8F3FFFFCDF4FFFFBEF2FFFFB0EFFFFFA1ECFFFF92E9FFFF84E6FFFF75E3 + FFFF66E0FFFF57DDFFFF49DAFFFF3AD7FFFF2BD5FFFF23CAF7FF3EA6D2F80000 + 00000000000000000000000000000000000000000000000000000000000079C2 + DB156DBDDEED1DC7F5FF11CFFFFF2FD5FFFF4CDBFFFF6AE1FFFF87E7FFFFA4EC + FFFFC2F2FFFFD0F5FFFFC1F2FFFFB3EFFFFFA4ECFFFF95E9FFFF87E7FFFF78E4 + FFFF69E1FFFF5ADEFFFF4CDBFFFF3DD8FFFF2FD2FDFF39A8D6F43CA3D2610000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000071BEDB3F65BBDDF613CCFBFF29D4FFFF46DAFFFF64E0FFFF81E5FFFF9EEB + FFFFBCF1FFFFD3F6FFFFC4F3FFFFB6F0FFFFA7EDFFFF98EAFFFF89E7FFFF7BE4 + FFFF6CE1FFFF5DDEFFFF4FDCFFFF40D9FFFF38B0DEF53BA5D39C000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000067BADB884CBBE3F424D2FFFF40D9FFFF5EDEFFFF7BE4FFFF98EA + FFFFB6F0FFFFD3F6FFFFC7F3FFFFB8F0FFFFAAEDFFFF9BEBFFFF8CE8FFFF7EE5 + FFFF6FE2FFFF60DFFFFF52DCFFFF3FBDE9FB3BA2D1D44992DB07000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000008080FF025FB7DBC93CC2ECFA3AD8FFFF58DDFFFF75E3FFFF93E9 + FFFFB0EFFFFFCDF4FFFFCAF4FFFFBBF1FFFFADEEFFFF9EEBFFFF8FE8FFFF81E5 + FFFF72E2FFFF63E0FFFF4FCFF4FF3BA1D0F13EA2D12100000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000064B6DB1C5BB1D9F13DCCF5FF52DCFFFF6FE2FFFF8DE8 + FFFFAAEEFFFFC7F3FFFFCDF4FFFFBEF2FFFFB0EFFFFFA1ECFFFF92E9FFFF84E6 + FFFF75E3FFFF62DAFAFF3AA1D1F5399FCD480000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000005DB0D64A54B0D8F54DD8FCFF69E1FFFF87E7 + FFFFA4ECFFFFC2F2FFFFD0F5FFFFC1F2FFFFB3EFFFFFA4ECFFFF95E9FFFF87E7 + FFFF77E2FEFF41A9D7F43AA0D083000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000054AED7984EB6E0F563E0FFFF81E5 + FFFF9EEBFFFFBCF1FFFFD3F6FFFFC4F3FFFFB6F0FFFFA7EDFFFF98EAFFFF8AE7 + FFFF54B9E2F93A9DCFC655AAAA03000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000049B6DB0750A9D6D855C5ECFC7BE4 + FFFF98EAFFFFB6F0FFFFD3F6FFFFC7F3FFFFB9F0FFFFAAEDFFFF9BEBFFFF70CF + EFFE399CCEEA3399CC1400000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000004EAAD5244CA6D3F36CD6 + F6FF92E9FFFFB0EFFFFFCDF4FFFFCAF4FFFFBBF1FFFFADEEFFFF8EDEF7FF389A + CDF53698CE340000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000004CA4D05749A5 + D4F589E4FCFFAAEEFFFFC7F3FFFFCDF4FFFFBEF2FFFFACECFDFF43A2D3F4379A + CC6A000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000043A0 + D0D43D9ACDFF3795CBFF3091C9FF2D8FC8FF2E91C9FF3093CAFF3596CDD50000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000449E + D06C4AB5E1F69CEBFFFFD3F6FFFFB5F0FFFF96EAFFFF4BB2DFF63294CB6B0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000449D + D05647AEDBF19CEBFFFFD3F6FFFFB5F0FFFF96EAFFFF44AAD9F13393CC550000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000439D + D04143A8D6EF9CEBFFFFD3F6FFFFB5F0FFFF96EAFFFF3EA2D4EF3493CB400000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000041A0 + D02B41A2D3F19CEBFFFFD3F6FFFFB5F0FFFF96EAFFFF379CD0F23192C82A0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000046A2 + D1163E9DD0F79CEBFFFFD3F6FFFFB5F0FFFF96EAFFFF3397CCF73192CE150000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000055AA + AA033D9ACEFD9BE9FEFFD3F6FFFFB5F0FFFF95E9FEFF3194CAFC55AAAA030000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00003E9CCFF394E4FBFFD3F6FFFFB5F0FFFF8CE2FAFF3296CCF3000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00003F9ED0E48BDCF6FFD3F6FFFFB5F0FFFF84DBF6FF3498CEE3000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000409FD0D082D5F2FFD3F6FFFFB5F0FFFF7BD3F1FF3599CECF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00003F9FD0B97ACEEDFFD3F6FFFFB5F0FFFF73CBEDFF3598CEB8000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00003F9DD09E72C7E9FFD3F6FFFFB5F0FFFF69C4E8FF3498CC9C000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00003D9ACE813795CBFF3091C9FF2D8FC8FF2E91C9FF2F94CA81000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000D580 + 2B06C671391BCB713522CB713522CB713522CB713522CB713522CB713522CB71 + 3522C5743A160000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000C870377DC871 + 37F7C87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC871 + 37FFC87137BF0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000CA6F3535C87137FFC871 + 37FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC871 + 37FFC87137EFFF00000100000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000C771384DC87137FFC871 + 37FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC871 + 37FFC87137FFCB71352200000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000AA555503C871376FC870 + 379FC87138AAC87138AAC87137F7C87137FFC87137FFC87137FFC87137FFC871 + 37FFC87137FFC872375300000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000C871374FC87137FFC87137FFC87137FFC87137FDC87137FFC871 + 37FFC87137FFC970368400000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000CC66330AC87137DFC87137FFC87137FFC87137F9C7723880C87137FFC871 + 37FFC87137FFC87137B500000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000C871378AC87137FFC87137FFC87137FFC7723880C9723626C87137FFC871 + 37FFC87137FFC87137E800000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CA71 + 352BC87137FAC87137FFC87137FFC87137DABF804008FF000001C87137F0C871 + 37FFC87137FFC87137FFCA753518000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FF000001C871 + 37BFC87137FFC87137FFC87137FFC77138440000000000000000C87237C1C871 + 37FFC87137FFC87137FFC7703849000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000C9713663C871 + 37FFC87137FFC87137FFC87137A3000000000000000000000000C870378FC871 + 37FFC87137FFC87137FFC772387B000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000C6713912C97136EAC871 + 37FFC87137FFC87137F0CC703319000000000000000000000000C972365EC871 + 37FFC87137FFC87137FFC87137AC000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000C872379DC87137FFC871 + 37FFC87137FFC871376600000000000000000000000000000000CB6E342CC871 + 37FFC87137FFC87137FFC87137DD000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C873373CC87137FEC87137FFC871 + 37FFC87137FEC87137BDC87137BBC87137BBC87137BBC87137BBC87137BEC871 + 37FFC87137FFC87137FFC87137FECF7030100000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000BF804004C87137D0C87137FFC87137FFC871 + 37FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC871 + 37FFC87137FFC87137FFC87137FFC77038400000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000C9703676C87137FFC87137FFC87137FFC871 + 37FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC871 + 37FFC87137FFC87137FFC87137FFC97136710000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000CA72351DC87137F3C87137FFC87137FFC87137FFC871 + 37FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC871 + 37FFC87137FFC87137FFC87137FFC87137A20000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000C87137B0C87137FFC87137FFC87137FFC77238570000 + 000000000000000000000000000000000000000000000000000000000000CB6E + 342CC87137FFC87137FFC87137FFC77038D30000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000C7703849C87137FFC87137FFC87137FFC87137B9000000000000 + 000000000000000000000000000000000000000000000000000000000000CC66 + 3305C87137F9C87137FFC87137FFC87137FCCC66330A00000000000000000000 + 0000000000000000000000000000000000000000000000000000AA555503C870 + 3762C87037A8C97136EAC87137FFC87137FFC87137FFC87137D2C87137B4C772 + 3880FF80000200000000000000000000000000000000C770385BC87137ACC871 + 37BBC87137F7C87137FFC87137FFC87137FFC87237C1C7723889D5802B060000 + 0000000000000000000000000000000000000000000000000000C8713778C871 + 37FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC871 + 37FFC971363D000000000000000000000000C872375CC87137FFC87137FFC871 + 37FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC87237530000 + 0000000000000000000000000000000000000000000000000000C97136C0C871 + 37FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FFC871 + 37FAC4763B1A000000000000000000000000C87237A6C87137FFC87137FFC871 + 37FFC87137FFC87137FFC87137FFC87137FFC87137FFC87137FDCB6E342C0000 + 0000000000000000000000000000000000000000000000000000C971365FC871 + 37E7C87137FFC87137FFC87137FFC87137FFC87137FFC87137FBC97036DCC872 + 375300000000000000000000000000000000C871374FC87137E2C87137FEC871 + 37FFC87137FFC87137FFC87137FFC87137FCC87137E0C8703762000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000CFA47DFFCFA57DFFD0A57DFFD0A5 + 7DFFD0A57DFFD0A57DFFD1A67DFFD1A67DFFD1A57DFFD1A57DFFD0A57DFFD0A5 + 7CFFD0A57CFFD0A57CFFD0A47CFFCFA47CFFCFA47BFFCEA37BFFCDA37BFFCDA2 + 7AFFCCA17AFFCBA079FFC99F78FFC89E77FFC79E77FFC69D76FFC49C76FFC49B + 75FFC29A75FFC29A74FF0000000000000000CFA57DFFD0A57DFFD0A57DFFD1A6 + 7DFFD1A67DFFD1A67DFFD1A67DFFD1A67DFFD1A67DFFD1A57CFFD1A57CFFD1A5 + 7CFFD1A57CFFD0A57CFFD0A47BFFD0A47BFFCFA47BFFCFA37BFFCEA37AFFCDA2 + 7AFFCCA179FFCBA078FFC99F78FFC89E77FFC79D76FFC69C76FFC49B75FFC39B + 75FFC39A74FFC19974FF0000000000000000D0A57DFFD0A57DFFD1A67DFFD1A6 + 7DFFD1A67DFFD2A67DFFD2A67DFFD1A67CFFD1A67CFFD1A67CFFD1A57CFFD1A5 + 7CFFD1A57CFFD1A57BFFD0A47BFFD0A47BFFCFA47AFFCFA37AFFCEA27AFFCDA2 + 79FFCCA178FFCBA078FFCA9F77FFC89E76FFC79D76FFC69C75FFC49B75FFC39A + 74FFC29A73FFC19973FF0000000000000000D0A57DFFD1A67DFFD1A67DFFD1A6 + 7DFFD2A67DFFD2A67DFFD2A67DFFD2A67CFFD2A57CFFD2A57CFFD1A57BFFD1A5 + 7BFFD1A57BFFD1A47BFFD0A47AFFD0A47AFFCFA37AFFCFA379FFCEA279FFCDA1 + 78FFCCA178FFCBA077FFCA9F76FFC89E76FFC79D75FFC69C74FFC49B74FFC39A + 73FFC29973FFC19872FF0000000000000000D0A57DFFD1A67DFFD1A67DFFD2A6 + 7DFFD2A67DFFD2A67DFFD2A67CFFD2A67CFFD2A57CFFD2A57BFFD2A57BFFD1A5 + 7BFFD1A47AFFD1A47AFFD1A47AFFD0A379FFD0A379FFCFA279FFCEA278FFCDA1 + 78FFCCA077FFCB9F76FFCA9E76FFC89D75FFC79C74FFC59B74FFC49A73FFC399 + 72FFC29972FFC19872FF0000000000000000D0A57DFFD1A67DFFD2A67DFFD2A6 + 7DFFD2A67DFFD2A67CFFD2A67CFFD2A57BFFD2A57BFFD2A57BFFD2A57AFFD1A4 + 7AFFD1A47AFFD1A479FFD0A379FFD0A379FFCFA278FFCFA278FFCEA177FFCDA0 + 77FFCCA076FFCA9F75FFC99E75FFC89D74FFC79C73FFC59B73FFC49A72FFC299 + 71FFC29871FFC19771FF0000000000000000D1A57DFFD1A67DFFFDFDFDFFFEFE + FEFFFEFEFEFFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFEFEFEFFFEFEFEFFFEFEFEFFFDFDFDFFFDFDFDFFFCFCFCFFFBFBFBFFF9F9 + F9FFF8F8F8FFF7F7F7FFF5F5F5FFF4F4F4FFF2F2F2FFF0F0F0FFEEEEEEFFEDED + EDFFC19770FFC19770FF0000000000000000D1A57DFFD1A57DFFFDFDFDFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFDFDFDFFFCFCFCFFFCFCFCFFFBFBFBFFFAFA + FAFFF8F8F8FFF7F7F7FFF5F5F5FFF3F3F3FFF1F1F1FFF0F0F0FFEEEEEEFFEDED + EDFFC1976FFFC0966FFF0000000000000000D0A57DFFD1A57DFFFDFDFDFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFFFFFFFFFFFFFFFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFDFDFDFFFDFDFDFFFCFCFCFFFCFCFCFFFBFBFBFFF9F9 + F9FFF8F8F8FFF6F6F6FFF5F5F5FFF3F3F3FFF2F2F2FFF0F0F0FFEEEEEEFFEDED + EDFFC1966EFFC0966EFF0000000000000000D0A57DFFD1A57CFFFDFDFDFFFDFD + FDFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFDFDFDFFFDFDFDFFFCFCFCFFFCFCFCFFFBFBFBFFF9F9 + F9FFF8F8F8FFF7F7F7FFF5F5F5FFF3F3F3FFF1F1F1FFF0F0F0FFEEEEEEFFEDED + EDFFC1966EFFC0956EFF0000000000000000D0A57CFFD0A57CFFFCFCFCFFFDFD + FDFFFDFDFDFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFDFDFDFFFDFDFDFFFDFDFDFFFCFCFCFFFBFBFBFFFAFAFAFFF9F9 + F9FFF7F7F7FFF6F6F6FFF4F4F4FFF3F3F3FFF2F2F2FFF0F0F0FFEEEEEEFFEDED + EDFFC0956DFFBF956DFF0000000000000000CFA47CFFD0A47BFFFCFCFCFFFDFD + FDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFEFEFEFFFDFDFDFFFDFDFDFFFDFD + FDFFFDFDFDFFFDFDFDFFFCFCFCFFFCFCFCFFFBFBFBFFFAFAFAFFFAFAFAFFF8F8 + F8FFF7F7F7FFF6F6F6FFF4F4F4FFF2F2F2FFF1F1F1FFF0F0F0FFEEEEEEFFEDED + EDFFC0956CFFBF946CFF0000000000000000CFA47BFFCFA47BFFFBFBFBFFFCFC + FCFFFCFCFCFFFCFCFCFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFD + FDFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFBFBFBFFFAFAFAFFF9F9F9FFF8F8 + F8FFF7F7F7FFF5F5F5FFF4F4F4FFF2F2F2FFF1F1F1FFEFEFEFFFEEEEEEFFECEC + ECFFC0946CFFBF946CFF0000000000000000CEA37BFFCFA37BFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFBFBFBFFFBFBFBFFFBFBFBFFFAFAFAFFFAFAFAFFF8F8F8FFF7F7 + F7FFF6F6F6FFF5F5F5FFF3F3F3FFF2F2F2FFF1F1F1FFEFEFEFFFEDEDEDFFECEC + ECFFBF946BFFBF946BFF0000000000000000CDA37BFFCEA37AFFF9F9F9FFFAFA + FAFFFAFAFAFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFBFBFBFFFBFBFBFFFAFAFAFFFAFAFAFFF9F9F9FFF9F9F9FFF8F8F8FFF7F7 + F7FFF6F6F6FFF5F5F5FFF3F3F3FFF2F2F2FFF0F0F0FFEEEEEEFFEEEEEEFFECEC + ECFFBF946BFFBE936BFF0000000000000000CDA27AFFCDA27AFFF8F8F8FFF9F9 + F9FFF9F9F9FFF9F9F9FFF9F9F9FFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFAFAFAFFF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF7F7F7FFF6F6F6FFF6F6 + F6FFF5F5F5FFF3F3F3FFF2F2F2FFF0F0F0FFEFEFEFFFEEEEEEFFEDEDEDFFECEC + ECFFBF936BFFBE936AFF0000000000000000CCA17AFFCCA179FFF7F7F7FFF8F8 + F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF9F9F9FFF8F8 + F8FFF8F8F8FFF8F8F8FFF8F8F8FFF8F8F8FFF7F7F7FFF6F6F6FFF6F6F6FFF5F5 + F5FFF4F4F4FFF3F3F3FFF1F1F1FFF0F0F0FFEFEFEFFFEDEDEDFFEDEDEDFFEBEB + EBFFBE936AFFBE936AFF0000000000000000CBA079FFCBA079FFF5F5F5FFF6F6 + F6FFF6F6F6FFF6F6F6FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF7F7F7FFF6F6 + F6FFF6F6F6FFF7F7F7FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4 + F4FFF2F2F2FFF1F1F1FFF1F1F1FFF0F0F0FFEEEEEEFFEDEDEDFFEBEBEBFFEBEB + EBFFBE936AFFBD926AFF0000000000000000C99F78FFCA9F78FFF4F4F4FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5 + F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF4F4F4FFF4F4F4FFF3F3F3FFF2F2 + F2FFF1F1F1FFF0F0F0FFEFEFEFFFEFEFEFFFEDEDEDFFECECECFFEBEBEBFFEAEA + EAFFBE936AFFBD926AFF0000000000000000C89E77FFC89E77FFF2F2F2FFF3F3 + F3FFF3F3F3FFF3F3F3FFF4F4F4FFF3F3F3FFF3F3F3FFF4F4F4FFF4F4F4FFF3F3 + F3FFF3F3F3FFF3F3F3FFF3F3F3FFF2F2F2FFF2F2F2FFF2F2F2FFF1F1F1FFF0F0 + F0FFF0F0F0FFEFEFEFFFEEEEEEFFEDEDEDFFEDEDEDFFEBEBEBFFEAEAEAFFEAEA + EAFFBD9269FFBD926AFF0000000000000000C79E77FFC79D76FFF1F1F1FFF1F1 + F1FFF1F1F1FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2 + F2FFF1F1F1FFF2F2F2FFF1F1F1FFF1F1F1FFF1F1F1FFF1F1F1FFF0F0F0FFF0F0 + F0FFEEEEEEFFEEEEEEFFEDEDEDFFEDEDEDFFECECECFFEBEBEBFFEAEAEAFFE9E9 + E9FFBD9269FFBD926AFF0000000000000000C69D76FFC69C76FFEFEFEFFFF0F0 + F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0 + F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFEFEFEFFFEFEFEFFFEFEFEFFFEEEE + EEFFEEEEEEFFEDEDEDFFECECECFFECECECFFEBEBEBFFEAEAEAFFEAEAEAFFE9E9 + E9FFBD9269FFBD926AFF0000000000000000C49C76FFC59C75FFEEEEEEFFEEEE + EEFFEEEEEEFFEEEEEEFFEEEEEEFFEFEFEFFFEEEEEEFFEFEFEFFFEEEEEEFFEEEE + EEFFEEEEEEFFEEEEEEFFEFEFEFFFEEEEEEFFEEEEEEFFEDEDEDFFEDEDEDFFEDED + EDFFECECECFFECECECFFEBEBEBFFEAEAEAFFEAEAEAFFEAEAEAFFE9E9E9FFE9E9 + E9FFBD926AFFBC926AFF0000000000000000C39B75FFC39B75FFEDEDEDFFECEC + ECFFEDEDEDFFECECECFFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFFEDED + EDFFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFFECECECFFECECECFFECECECFFECEC + ECFFEBEBEBFFEBEBEBFFEBEBEBFFEAEAEAFFE9E9E9FFE8E8E8FFE9E9E9FFE8E8 + E8FFBD926AFFBD926AFF0000000000000000C29A75FFC39A74FFC29A73FFC299 + 73FFC29972FFC29871FFC19770FFC1976FFFC1976FFFC1966EFFC0956DFFC095 + 6CFFC0956CFFC0946CFFBF946BFFC0946BFFBF946BFFBF936AFFBF936AFFBF93 + 6AFFBF936AFFBE926AFFBE926AFFBD9269FFBD9269FFBD9269FFBD926AFFBD92 + 6AFFBD926AFFBD926AFF0000000000000000C29A74FFC19974FFC19973FFC198 + 72FFC19872FFC19771FFC19770FFC0966FFFC0966EFFC0956EFFBF956DFFBF94 + 6CFFBF946CFFBF946BFFBE936BFFBF936BFFBE936BFFBE936AFFBE936AFFBE93 + 6AFFBE936AFFBE936AFFBD926AFFBD926AFFBD926AFFBD926AFFBC926AFFBD92 + 6AFFBD926AFFBC926AFF00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000C5C5C51FC8C8C881C9C9C9CCC9C9C9E7CACACAFDCACA + CAFFCBCBCBFFCBCBCBFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000C6C6C662C7C7C7F4C8C8C8FFC8C8C8FFC9C9C9FFCACACAFFCACA + CAFFCBCBCBFFCBCBCBFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC + CCFFCCCCCCFFCCCCCCFFCCCCCCFF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000C7C7C757C7C7C7FEC7C7C7FFC8C8C8FFC8C8C8FFC9C9C9CEC9C9C95FCDCD + CD24D1D1D10B0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CCCC + CC0FC6C6C6EAC6C6C6FFC7C7C7FFC7C7C7FFC8C8C899AAAAAA03000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C5C5 + C56AC5C5C5FFC6C6C6FFC6C6C6FFC8C8C8CFCCCCCC0500000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000C5C5 + C5B5C5C5C5FFC6C6C6FFC6C6C6FFC8C8C8660000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000FCDEC1FFFCDEC1FFFBDCBFFFF9DABDFFC9C6 + C2FFC5C5C5FFC5C5C5FFC6C6C6FFECCEB3FFF0CDAEFFEFCBACFFEDC9A9FFEBC7 + A7FFEAC5A4FFE8C3A2FFE7C19FFFE5BE9DFFE4BC9BFFE2BA98FFE1B896FFDFB6 + 93FFDEB491FFDCB28EFFDBAF8CFFD9AD89FFD8AB87FFD6A985FFD4A782FFD3A5 + 80FFD1A37DFFD0A17BFFCE9E78FFFCDEC1FFFCDDC0FFFADBBEFFF9D9BBFFC6C5 + C4FFC4C4C4FFC5C5C5FFC5C5C5FFF0CEB0FFEFCCADFFEECAAAFFECC8A8FFEBC6 + A6FFE9C4A3FFE8C2A1FFE6C09EFFE5BD9CFFE3BB99FFE2B997FFE0B795FFDEB5 + 92FFDDB390FFDBB18DFFDAAE8BFFD8AC88FFD7AA86FFD5A883FFD4A681FFD2A4 + 7FFFD1A27CFFCFA07AFFCE9D77FFFCDEC1FFFBDCBFFFEFE2D8FFEFE2D8FFEEE1 + D6FFEEE0D5FFEDDFD4FFEDDED2FFECDDD1FFECDCD0FFEBDBCEFFEBDACDFFEAD9 + CCFFE9D8CAFFE9D7C9FFE8D6C8FFE8D5C6FFE7D4C5FFE7D3C4FFE6D1C2FFE6D0 + C1FFE5CFC0FFE5CEBEFFE4CDBDFFE4CCBCFFE3CBBAFFE2CAB9FFE2C9B8FFE1C8 + B6FFE1C7B5FFCE9F79FFCD9C76FFFCDEC1FFFADBBEFFEFE2D8FFEFE1D7FFEEE0 + D6FFEEDFD4FFEDDED3FFECDDD2FFECDCD0FFEBDBCFFFEBDACEFFEAD9CCFFEAD8 + CBFFE9D7CAFFE9D6C8FFE8D5C7FFE8D4C6FFE7D3C4FFE7D2C3FFE6D1C2FFE5D0 + C0FFE5CFBFFFE4CEBEFFE4CDBCFFE3CCBBFFE3CBBAFFE2CAB8FFE2C9B7FFE1C8 + B6FFE1C7B4FFCE9E77FFCC9B75FFFBDDBFFFF9DABDFFEFE2D8FFEEE1D6FFFFFF + FFFFFFFFFFFFE1C8B6FFE0C6B4FFFFFFFFFFFFFFFFFFDEC1ADFFDDC0ABFFFFFF + FFFFFFFFFFFFDABBA5FFD9B9A3FFFFFFFFFFFFFFFFFFD7B59CFFD6B39AFFFFFF + FFFFFFFFFFFFD3AE94FFD2AD92FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1C7 + B5FFE0C6B4FFCD9D76FFCB9A74FFFADCBEFFF9D9BCFFEFE1D7FFEEE0D6FFFFFF + FFFFFFFFFFFFE1C8B5FFE0C6B3FFFFFFFFFFFFFFFFFFDEC1ADFFDDC0ABFFFFFF + FFFFFFFFFFFFDABBA4FFD9B9A2FFFFFFFFFFFFFFFFFFD7B49CFFD6B39AFFFFFF + FFFFFFFFFFFFD3AE94FFD2AC91FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1C7 + B5FFE0C6B3FFCC9C75FFCB9973FFFADBBDFFF8D8BBFFEEE1D7FFEEE0D5FFE3CA + B9FFE2C9B7FFE1C7B5FFE0C6B3FFDFC4B1FFDEC2AFFFDDC1ACFFDDBFAAFFDCBE + A8FFDBBCA6FFDABAA4FFD9B9A2FFD8B7A0FFD7B69EFFD6B49CFFD5B299FFD5B1 + 97FFD4AF95FFD3AE93FFD2AC91FFD1AA8FFFD0A98DFFCFA78BFFCEA688FFE0C6 + B4FFE0C5B3FFCC9B74FFCA9872FFF9DABCFFF7D7BAFFEEE0D6FFEEDFD5FFE2CA + B9FFE2C8B7FFE1C7B4FFE0C5B2FFDFC4B0FFDEC2AEFFDDC0ACFFDCBFAAFFDBBD + A8FFDBBCA6FFDABAA4FFD9B8A1FFD8B79FFFD7B59DFFD6B49BFFD5B299FFD4B0 + 97FFD4AF95FFD3AD93FFD2AC91FFD1AA8EFFD0A88CFFCFA78AFFCEA588FFE0C6 + B3FFE0C5B2FFCB9A73FFC99770FFF8D9BBFFF7D6B8FFEEE0D5FFEDDFD4FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFDFC3B0FFDEC2AEFFFFFFFFFFFFFFFFFFDBBD + A7FFDABBA5FFFFFFFFFFFFFFFFFFD8B79FFFD7B59DFFFFFFFFFFFFFFFFFFD4B0 + 96FFD3AF94FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0C6 + B3FFDFC5B1FFCA9972FFC9966FFFF7D8BAFFF6D5B7FFEEDFD5FFEDDED3FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFDFC3AFFFDEC1ADFFFFFFFFFFFFFFFFFFDBBD + A7FFDABBA5FFFFFFFFFFFFFFFFFFD8B69EFFD7B59CFFFFFFFFFFFFFFFFFFD4B0 + 96FFD3AE94FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0C5 + B2FFDFC4B1FFC99871FFC8956EFFF7D7B9FFF5D4B6FFEDDFD4FFEDDED3FFE2C9 + B7FFE1C7B5FFE0C6B3FFDFC4B1FFDEC3AFFFDEC1ADFFDDBFABFFDCBEA9FFDBBC + A6FFDABBA4FFD9B9A2FFD8B7A0FFD7B69EFFD6B49CFFD6B39AFFD5B198FFD4AF + 96FFD3AE93FFD2AC91FFD1AB8FFFD0A98DFFCFA78BFFCFA689FFCEA487FFDFC5 + B1FFDFC4B0FFC9976FFFC7946DFFF6D6B7FFF4D3B5FFEDDFD3FFEDDED2FFE2C9 + B7FFE1C7B5FFE0C6B3FFDFC4B1FFDEC2AEFFDDC1ACFFDCBFAAFFDCBEA8FFDBBC + A6FFDABAA4FFD9B9A2FFD8B7A0FFD7B69EFFD6B49BFFD5B299FFD5B197FFD4AF + 95FFD3AE93FFD2AC91FFD1AA8FFFD0A98DFFCFA78BFFCEA688FFCEA486FFDFC4 + B1FFDFC3AFFFC8966EFFC6936CFFF5D5B6FFF4D2B4FFEDDED3FFECDDD1FFFFFF + FFFFFFFFFFFFE0C5B2FFDFC4B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFD0A88CFFCFA78AFFFFFFFFFFFFFFFFFFDFC4 + B0FFDEC3AFFFC7956DFFC6926BFFF5D4B5FFF3D1B3FFEDDED2FFECDDD1FFFFFF + FFFFFFFFFFFFE0C5B2FFDFC3B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFD0A88CFFCFA68AFFFFFFFFFFFFFFFFFFDFC3 + B0FFDEC2AEFFC7946CFFC5916AFFF4D3B4FFF2D0B2FFECDDD2FFECDCD0FFEBDB + CFFFEBDACEFFEAD9CCFFEAD8CBFFE9D7CAFFE9D6C8FFE8D5C7FFE8D4C6FFE7D3 + C4FFE6D2C3FFE6D1C2FFE5D0C0FFE5CFBFFFE4CEBEFFE4CDBCFFE3CCBBFFE3CB + BAFFE2CAB8FFE2C9B7FFE1C8B6FFE1C7B4FFE0C6B3FFDFC5B2FFDFC4B0FFDEC3 + AFFFDEC2AEFFC6936BFFC49068FFF3D2B3FFF2CFB0FFECDDD1FFECDCD0FFEBDB + CEFFEBDACDFFEAD9CCFFE9D8CAFFE9D7C9FFE8D6C8FFE8D5C6FFE7D4C5FFE7D3 + C4FFE6D1C2FFE6D0C1FFE5CFC0FFE5CEBEFFE4CDBDFFE4CCBCFFE3CBBAFFE2CA + B9FFE2C9B8FFE1C8B6FFE1C7B5FFE0C6B4FFE0C5B2FFDFC4B1FFDFC3B0FFDEC2 + AEFFDEC2AEFFC5926AFFC49068FFF2D1B2FFF1CEAFFFEFCCADFFEECAAAFFECC8 + A8FFEBC6A6FFE9C4A3FFE8C2A1FFE6C09EFFE5BD9CFFE3BB99FFE2B997FFE0B7 + 95FFDEB592FFDDB390FFDBB18DFFDAAE8BFFD8AC88FFD7AA86FFD5A883FFD4A6 + 81FFD2A47FFFD1A27CFFCFA07AFFCE9D77FFCC9B75FFCB9972FFC99770FFC795 + 6EFFC6936BFFC49169FFC49068FFF2D0B1FFF0CDAEFFEFCBACFFEDC9A9FFECC7 + A7FFEAC5A4FFE8C3A2FFE7C1A0FFE5BF9DFFE4BC9BFFE2BA98FFE1B896FFDFB6 + 93FFDEB491FFDCB28EFFDBB08CFFD9AD8AFFD8AB87FFD6A985FFD5A782FFD3A5 + 80FFD1A37DFFD0A17BFFCE9F79FFCD9C76FFCB9A74FFCA9871FFC8966FFFC794 + 6CFFC5926AFFC49068FFC49068FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000 + } + end +end diff --git a/components/jvcllaz/examples/JvWizard/uformmain.pas b/components/jvcllaz/examples/JvWizard/uformmain.pas new file mode 100644 index 000000000..94ea38729 --- /dev/null +++ b/components/jvcllaz/examples/JvWizard/uformmain.pas @@ -0,0 +1,66 @@ +unit uFormMain; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, + JvWizard, JvWizardRouteMapNodes; + +type + + { TForm1 } + + TForm1 = class(TForm) + CheckBox1: TCheckBox; + Edit1: TEdit; + ImageList1: TImageList; + JvWizard1: TJvWizard; + JvWizardInteriorPage1: TJvWizardInteriorPage; + JvWizardInteriorPage2: TJvWizardInteriorPage; + JvWizardInteriorPage3: TJvWizardInteriorPage; + JvWizardInteriorPage4: TJvWizardInteriorPage; + JvWizardRouteMapNodes1: TJvWizardRouteMapNodes; + JvWizardWelcomePage1: TJvWizardWelcomePage; + Label1: TLabel; + Label2: TLabel; + Label3: TLabel; + ListBox1: TListBox; + RadioButton1: TRadioButton; + procedure JvWizard1ActivePageChanged(Sender: TObject); + procedure JvWizard1CancelButtonClick(Sender: TObject); + procedure JvWizard1FinishButtonClick(Sender: TObject); + private + + public + + end; + +var + Form1: TForm1; + +implementation + +{$R *.lfm} + +{ TForm1 } + +procedure TForm1.JvWizard1CancelButtonClick(Sender: TObject); +begin + if MessageDlg('Are you sure?', mtConfirmation, mbYesNo, 0) = mrYes then + Close; +end; + +procedure TForm1.JvWizard1FinishButtonClick(Sender: TObject); +begin + Close; +end; + +procedure TForm1.JvWizard1ActivePageChanged(Sender: TObject); +begin + JvWizardRouteMapNodes1.Visible := JvWizard1.ActivePage <> JvWizardWelcomePage1; +end; + +end. + diff --git a/components/jvcllaz/packages/jvwizardlazd.lpk b/components/jvcllaz/packages/jvwizardlazd.lpk new file mode 100644 index 000000000..1feedfeef --- /dev/null +++ b/components/jvcllaz/packages/jvwizardlazd.lpk @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <Package Version="4"> + <PathDelim Value="\"/> + <Name Value="JvWizardLazD"/> + <Type Value="RunAndDesignTime"/> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <SearchPaths> + <OtherUnitFiles Value="..\design\JvWizard"/> + <UnitOutputDirectory Value="..\lib\$(TargetCPU)-$(TargetOS)\design\JvWizard"/> + </SearchPaths> + </CompilerOptions> + <Files Count="2"> + <Item1> + <Filename Value="..\design\JvWizard\jvwizardeditorform.pas"/> + <UnitName Value="JvWizardEditorForm"/> + </Item1> + <Item2> + <Filename Value="..\design\JvWizard\jvwizardreg.pas"/> + <HasRegisterProc Value="True"/> + <UnitName Value="JvWizardReg"/> + </Item2> + </Files> + <RequiredPkgs Count="3"> + <Item1> + <PackageName Value="JvWizardLazR"/> + </Item1> + <Item2> + <PackageName Value="JvCoreLazD"/> + </Item2> + <Item3> + <PackageName Value="IDEIntf"/> + </Item3> + </RequiredPkgs> + <UsageOptions> + <UnitPath Value="$(PkgOutDir)"/> + </UsageOptions> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + </Package> +</CONFIG> diff --git a/components/jvcllaz/packages/jvwizardlazr.lpk b/components/jvcllaz/packages/jvwizardlazr.lpk new file mode 100644 index 000000000..435f93a6f --- /dev/null +++ b/components/jvcllaz/packages/jvwizardlazr.lpk @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <Package Version="4"> + <PathDelim Value="\"/> + <Name Value="JvWizardLazR"/> + <Type Value="RunAndDesignTime"/> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <SearchPaths> + <OtherUnitFiles Value="..\run\JvWizard"/> + <UnitOutputDirectory Value="..\lib\$(TargetCPU)-$(TargetOS)\run\JvWizard"/> + </SearchPaths> + </CompilerOptions> + <Files Count="5"> + <Item1> + <Filename Value="..\run\JvWizard\jvwizard.pas"/> + <UnitName Value="JvWizard"/> + </Item1> + <Item2> + <Filename Value="..\run\JvWizard\jvwizardcommon.pas"/> + <UnitName Value="JvWizardCommon"/> + </Item2> + <Item3> + <Filename Value="..\run\JvWizard\jvwizardroutemaplist.pas"/> + <UnitName Value="JvWizardRouteMapList"/> + </Item3> + <Item4> + <Filename Value="..\run\JvWizard\jvwizardroutemapnodes.pas"/> + <UnitName Value="JvWizardRouteMapNodes"/> + </Item4> + <Item5> + <Filename Value="..\run\JvWizard\jvwizardroutemapsteps.pas"/> + <UnitName Value="JvWizardRouteMapSteps"/> + </Item5> + </Files> + <RequiredPkgs Count="1"> + <Item1> + <PackageName Value="JvCoreLazR"/> + </Item1> + </RequiredPkgs> + <UsageOptions> + <UnitPath Value="$(PkgOutDir)"/> + </UsageOptions> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + </Package> +</CONFIG> diff --git a/components/jvcllaz/resource/jvwizardsreg.res b/components/jvcllaz/resource/jvwizardsreg.res new file mode 100644 index 000000000..b5fe7bed7 Binary files /dev/null and b/components/jvcllaz/resource/jvwizardsreg.res differ diff --git a/components/jvcllaz/run/JvCore/JvJVCLUtils.pas b/components/jvcllaz/run/JvCore/JvJVCLUtils.pas index 953af4925..91f1aed0a 100644 --- a/components/jvcllaz/run/JvCore/JvJVCLUtils.pas +++ b/components/jvcllaz/run/JvCore/JvJVCLUtils.pas @@ -688,6 +688,8 @@ function JvMessageBox(const Text: string; Flags: DWORD): Integer; overload; ********************) procedure UpdateTrackFont(TrackFont, Font: TFont; TrackOptions: TJvTrackFontOptions); +function IsHotTrackFontDfmStored(TrackFont, Font: TFont; TrackOptions: TJvTrackFontOptions): Boolean; + (******************** // Returns the size of the image // used for checkboxes and radiobuttons. @@ -6449,6 +6451,30 @@ begin end; end; +function IsHotTrackFontDfmStored(TrackFont, Font: TFont; TrackOptions: TJvTrackFontOptions): Boolean; +var + DefFont: TFont; +begin + if hoFollowFont in TrackOptions then + DefFont := nil + else + begin + DefFont := TFont.Create; + Font := DefFont; + TrackOptions := []; // compare all + end; + try + Result := ((hoPreserveCharSet in TrackOptions) and (TrackFont.Charset <> Font.Charset)) or + ((hoPreserveColor in TrackOptions) and (TrackFont.Color <> Font.Color)) or + ((hoPreserveHeight in TrackOptions) and (TrackFont.Height <> Font.Height)) or + ((hoPreservePitch in TrackOptions) and (TrackFont.Pitch <> Font.Pitch)) or + ((hoPreserveStyle in TrackOptions) and (TrackFont.Style <> Font.Style)) or + ((hoPreserveName in TrackOptions) and (TrackFont.Name <> Font.Name)); + finally + DefFont.Free; + end; +end; + (******************** { end JvCtrlUtils } diff --git a/components/jvcllaz/run/JvWizard/jvwizard.pas b/components/jvcllaz/run/JvWizard/jvwizard.pas new file mode 100644 index 000000000..27e2637e3 --- /dev/null +++ b/components/jvcllaz/run/JvWizard/jvwizard.pas @@ -0,0 +1,3177 @@ +{----------------------------------------------------------------------------- +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/MPL-1.1.html + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: JvWizard.PAS, released on 2001-12-30. + +The Initial Developer of the Original Code is William Yu Wei. +Portions created by William Yu Wei are Copyright (C) 2001 William Yu Wei. +All Rights Reserved. + +Contributor(s): +Peter Thörnqvist - converted to JVCL naming conventions on 2003-07-11 +Andreas Hausladen - fixed some bugs, refactoring of the Wizard button classes on 2004-02-29 +Micha³ Gawrycki - Lazarus port + +You may retrieve the latest version of this file at the Project JEDI's JVCL home page, +located at http://jvcl.delphi-jedi.org + +Known Issues: +-----------------------------------------------------------------------------} +// $Id$ + +{+---------------------------------------------------------------------------+ + | CONTRIBUTORS: | + +---------------------------------------------------------------------------+ + | Steve Forbes <ozmosys att mira dott net> | + | Chris Macksey <c_macksey att hotmail dott com> | + | Wayne Niddery <waynen att logicfundamentals dott com> | + | Raymond J. Schappe <rschappe att isthmus-ts dott com> | + | Theodore <thpana att otenet dott gr> | + | Max Evans <max att codecraft dott com dott au> | + +---------------------------------------------------------------------------+ + | HISTORY COMMENTS | + +---------------------------------------------------------------------------+ + | 02/18/2002 OnStartButtonClick, OnLastButtonClick, OnNextButtonClick, | + | OnBackButtonClick, OnFinishButtonClick, OnCancelButtonClick, | + | is added for TJvWizardCustomPage with a Stop parameter. | + | | + | Note: these page click events is called before the wizard | + | button click events. | + | | + | 02/16/2002 Suggested by <Theodore>: | + | 1) ModalResult property is added for TJvWizardButton | + | 2) Width property is added for TJvWizardButton | + | | + | 02/12/2002 1) Suggested by <Max Evans>: | + | Having the next/finish buttons to be the default | + | button when a page shows. | + | 2) Having the cancel button to be the default cancel button. | + | | + | 02/11/2002 1) CanDisplay function is added for TJvWizardRouteMapControl.| + | 2) OnDisplaying event is added for TJvWizardRouteMapControl, | + | so the route map can decide if it could display the page | + | item or not. | + | | + | 02/10/2002 1) Introduce TJvWizardImage class. | + | 2) Clean up the code (TJvWizardGraphicObject, | + | TJvWizardPageObject, ..., etc) | + | 3) Now the TJvWizardPageTitle is inherited from | + | TJvWizardGraphicObject(known as TJvWizardPersistent | + | in former). | + | 4) Suggested by <Tim Schneider>: | + | Controls in the wizard page with aligned set to | + | something should be aligned properly without covering | + | the page header as well as the watermark. Hint: | + | overrided AdjustClientRect method is added for | + | both TJvWizardCustomPage and TJvWizardWelcomePage. | + | | + | 02/09/2002 1) Finish button can be displayed separatly. | + | 2) Bug fixed: Changing the value of EnabledButtons property | + | of TJvWizardCustomPage at run time doesn't refresh the | + | buttons' status on the screen. | + | | + | 02/08/2002 Bug fixed: the OnEnterPage event is not triggled properly, | + | they would be called at the time the wizard is loading | + | them. 'not (csLoading in ComponentState)' added as the | + | part of checking condition in SetActivePage method | + | of TJvWizard. | + | | + | 02/07/2002 VERSION 1.6 RELEASED | + | | + | 1) New property EnabledButtons and VisibleButtons added for | + | TJvWizardCustomPage, so the developers can customize | + | buttons for each page at design time and run time. | + | 2) Remove Enabled and Visible properties from | + | TJvWizardButton of TJvWizard. | + | | + | 02/06/2002 1) Bug fixed: change TJvWizardWelcomePage's color from | + | clWindow to other colors or change | + | TJvWizardInteriorPage's color from other colors to | + | clWindow, the pages won't display in correct color. | + | Hint: | + | By assigning default value of Color property in | + | published section of TJvWizardCustomPage and | + | TJvWizardWelcomePage class. | + | 2) Suggested by <Steve Forbes>: | + | ShowDivider added for TJvWizardPageHeader to enable | + | or disable drawing the page header divider. | + | 3) Use Object.Free instead of FreeAndNil, | + | Rectangle(ARect.Left, ...) instead of Rectangle(ARect), | + | so we can support Delphi 4. | + | | + | 02/05/2002 1) Added by <Theodore>: | + | ButtonHelp added for TJvWizard. | + | 2) RepositionButtons method of TJvWizard is improved. | + | | + | 02/04/2002 function IsForward added, return true if FromPage is | + | forward to ToPage, return false if FromPage is backward | + | to ToPage. | + | | + | 02/03/2002 1) Bug fixed by <Theodore>: SelectPriorPage calls | + | OnSelectFirstPage event rather the OnSelectPriorPage. | + | 2) Suggested by <Theodore>: | + | FromPage parameters added for OnEnterPage event, | + | so the developers can detect from where it enters. | + | 3) Suggested by <Theodore>: | + | ToPage paramters added for OnExitPage event, so the | + | developers can detect to where it exits. | + | 4) Suggested by <Theodore>: | + | OnExitPage event now is called just BEFORE (not after) | + | the page is hidden and BEFORE the new page is actived. | + | It provides the last chance to the developers to stop | + | changing to the new page by raising a message. | + | | + | 02/02/2002 VERSION 1.5 RELEASED | + | | + | 1) DoAddPage, DoDeletePage, DoUpdatePage, DoMovePage added | + | for TJvWizardRouteMapControl | + | 2) Overrided SetParent added for TJvWizardRouteMapControl | + | to detect if the parent is TJvWizard or its descentants.| + | 01/31/2002 1) Improved the RepositionButtons method of TJvWizard, | + | so all the buttons can be positioned properly regardless | + | how their neighbors are. | + | 2) CM_VisibleChanged message handler added for | + | TJvWizardButtonControl, so when the button is visible or | + | invisible, it can make the rest buttons in proper | + | position. | + | | + | 01/30/2002 1) Rename the methods of TJvWizardRouteMapControl | + | 2) WizardPageMoved method added for TJvWizardRouteMapControl | + | which fired after the order of the page changed. | + | 3) OnPaintPage event added for TJvWizardCustomPage, so | + | the developers can custom draw the page. | + | 4) A TJvWizardCustomPage parameter added for IsFirstPage, | + | IsLastPage of TJvWizard to test if the specific page is | + | the first page or the last page. | + | 5) Buttons property added for TJvWizardCustomPage, it can | + | easily access all navigation buttons of TJvWizard. | + | 6) Improved the process to handle the button visible | + | property in more efficent way. | + | see UpdateButtonsStatus method of TJvWizard | + | | + | 01/29/2002 1) Pages property added for TJvWizard. | + | 2) PageCount property added for TJvWizard. | + | 3) Page List Property Editor added for Pages property | + | of TJvWizard. From this property editor, we can | + | | + | a) Add new wizard pages. | + | b) Remove selected pages. | + | c) Drag drop selected page item to change pages' order. | + | | + | 01/28/2002 1) Bug fixed: if the current active page set to disabled, | + | the wizard would not go to next page. | + | 2) Page screen flicker problem solved by setting | + | the DoubleBuffered property of TJvWizardCustomPage | + | to True. | + | 3) ParentFont property added for TJvWizardPageHeader. | + | | + | 01/27/2002 VERSION 1.5 BETA RELEASED | + | | + | 1) JvWizard About form added by <Steve Forbes> | + | Thanks for his great job !!!! | + | 2) Improve the design time button function, press Back | + | button at first page will forward to the last page. | + | While press Next button at last page will forward to | + | the first page. (See FindNextPage method in TJvWizard) | + | 3) Fixed AV when delete only one page in the wizard at | + | design time. (see RemovePage method in TJvWizard) | + | 4) NumGlyphs property added for TJvWizardNavigateButton by | + | <Steve Forbes>, to solve the problem where the | + | NumGlyphs property of the actual button always reset | + | to 1 when it is created dynamically. | + | 5) Layout property added for TJvWizardNavigateButton. | + | 6) Set ImageAlign property's default value of | + | TJvWizardPageHeader to waRight. | + | | + | 01/26/2002 1) Suggested by <Steve Forbes>: | + | Anchors, AnchorPlacement, Indent property added for | + | the text in TJvWizardPageTitle. Remove Left, Top, | + | Width, Height properties from TJvWizardPageTitle. so | + | it is much easiler to operate the title and subtitle. | + | 2) Image property added for TJvWizardCustomPage, | + | both Welcome page and Interior page can display a | + | background image. | + | 3) Image property added for the TJvWizardWaterMark. | + | 4) ImageIndex, ImageAlign, ImageOffset property added for | + | TJvWizardPageHeader. the PageHeader use ImageIndex | + | to retreive image from the header image list of | + | TJvWizard. | + | | + | 01/25/2002 VERSION 1.2 RELEASED | + | | + | Finally, JvWizard has its offical icon!!! It is very cool! | + | Thanks <Steve Forbes> for his great job !!!! | + | | + | 1) Move OnEnterPage, OnPage, OnExitPage event from TJvWizard | + | into TJvWizardCustomPage. | + | 2) TJvWizardPagePanel added, suggested by <Steve Forbes>. | + | 3) Glyph property added for TJvWizardNavigateButton. | + | 4) HeaderImages property added for TJvWizard, it is an | + | image list, which stores all the page header images. | + | | + | 01/24/2002 1) Rename TJvWizardTitle to TJvWizardPageTitle. | + | 2) PaintTo method added for TJvWizardWaterMark. | + | PaintTo method added for TJvWizardPageHeader. | + | PainTo method added for TJvWizardPageTitle. | + | 3) Remove the DisplayPageHeader method from | + | TJvWizardCustomPage. | + | 4) OnPage event added for TJvWizard, fired after the page | + | shows up. | + | 5) Pages, PageCount, PageIndex property, and default code | + | added for all virtual method for TJvWizardRouteMapControl.| + | 6) Compiler directive added, suggested | + | by <Raymond J. Schappe>. | + | 7) Handle Design time package and Run time package, | + | package file name convenstion suggested by | + | <Steve Forbes>: | + | Design time package: JvWizardD?.dpk (bpl, dcp, ...) | + | Run time package: JvWizardD?R.dbp (bpl, dcp, ...) | + | here the ? = Delphi Version (5, 6, ..., etc) | + | | + | 01/23/2002 1) Start Page, Last Page buttons added for TJvWizard, | + | default they are invisible. | + | 2) Visible property added for TJvWizardNavigateButton. | + | | + | 01/22/2002 BorderWidth property added for TJvWizardWaterMark, suggested | + | by <Steve Forbes> | + | | + | 1) Remove the TJvWizardButtonBar, now all the navigate | + | buttons are located in the Wizard. Hint: | + | Add overrided AdjustClientRect for TJvWizard. | + | 2) Bug fixed: Add csAcceptsControls control style into | + | TJvWizard, otherwise it won't accept other controls | + | like JvWizardRouteMap. | + | 3) Bug fixed: TJvWizard.GetChildren procedure, it won't | + | display another controls (include JvWizardRouteMap | + | Control) even if the control is in the wizard. | + | 4) Align property added for TJvWizardRouteMap, so the | + | JvWizardRouteMap can display at either left or right | + | side of the Wizard. | + | 5) Align property added for TKWaterMark, so it can be | + | displayed at either left or right side of Welcome Page. | + | | + | 01/21/2002 VERSION 1.1 RELEASED | + | | + | Suggested by <Chris Macksey>: | + | | + | 1) Add OnSelectNextPage, OnSelectPriorPage, | + | OnSelectFirstPage, OnSelectLastPage events, so user can | + | redirect the page try to go to. | + | 2) Add OnEnterPage, triggled before the page shows up. | + | Add OnExitPage, triggled after the page is hidded. | + | | + | 01/14/2002 1) Add ShowRouteMap property for the TJvWizard. | + | 2) Add destructor in the TJvWizardRouteMap class to fix | + | AV when browse pages after destroy the TJvWizardRouteMap | + | component. | + | | + | 01/13/2002 Make the TJvWizardRouteMap as a separat new component | + | so the user can design its own routemap and communicate | + | with TJvWizard smoothly. | + | | + | 01/12/2002 VERSION 1.0 RELEASED | + | | + | 1) Fixed by <Wayne Niddery> : | + | Under certain circumstance, the Wizard did not always | + | default to the first page. Add overrided | + | Loaded method in the TJvWizard class. | + | 2) Restructure: add TJvWizardHeader and TJvWizardWaterMark, | + | I hate to list all properites like: HeaderColor, | + | HeaderWidth, HeaderVisible, ... etc. Instead, I group | + | them together into particular class, and it can make | + | the whole component has a very clean property | + | structure. | + | | + | 01/11/2002 1) Add word break feature when display title and subtitle. | + | 2) At Design time, display page name in the wizard page. | + | 3) Let the TWizardCustomPage paint and fill its area first | + | and let TWizardWelcomePage and TWizardInteriorPage | + | do the rest. | + | | + | 01/10/2002 BETA VERSION RELEASED | + | | + | 1) Delete BackButton, NextButton, FinishButton, | + | CancelButton property, instead of a Button array. | + | 2) Introduce TJvWizardBackButton, TJvWizardNextButton, | + | TJvWizardFinishButton and TJvWizardCancelButton Control | + | 3) Add TJvWizardTitle class, HeaderColor, HeaderHeight, | + | HeaderVisible property for TJvWizardCustomPage. | + | 4) Add WaterMarkColor, WaterMarkWidth, WaterMarkVisible | + | property for TJvWizardWelcomePage. | + | 5) Paint method of TJvWizardWelcomPage improved, | + | TJvWizardInteriorPage, so they can display header | + | as well as title and subtitle. | + | | + | 01/06/2002 1) Add TJvWizardRouteMap, Improve all existing functions | + | and class. | + | 2) Add TJvWizardCustomPage. | + | | + | 01/05/2002 1) Add TJvWizardNavigateButton class. | + | 2) Add BackButton, NextButton, FinishButton, | + | CancelButton property for TJvWizard. | + | | + | 01/04/2002 1) Add ShowDivider property for TJvWizard. | + | 2) Add GetButtonClick, SetButtonClick for TJvWizardButtonBar.| + | 3) Draw divider in fsGroove frame style. | + | | + | 12/30/2001 Initial create. | + +---------------------------------------------------------------------------+ + | TODO LIST | + +---------------------------------------------------------------------------+ + | Wizard page can be transparent | + +---------------------------------------------------------------------------+} + +unit JvWizard; + +{$mode objfpc} +{$H+} + +interface + +uses + SysUtils, Classes, + Controls, Forms, Graphics, Buttons, ImgList, Types, LMessages, LCLType, LCLIntf, + JvWizardCommon, JvComponent; + +type + TJvWizardButtonKind = (bkStart, bkLast, bkBack, bkNext, bkFinish, bkCancel, bkHelp); + TJvWizardButtonSet = set of TJvWizardButtonKind; + +const + bkAllButtons = [bkStart, bkLast, bkBack, bkFinish, bkNext, bkCancel, bkHelp]; + +type + TJvWizardAlign = alTop..alRight; + TJvWizardLeftRight = alLeft..alRight; + TJvWizardImage = class; + TJvWizardCustomPage = class; + TJvWizard = class; + TJvWizardPageHeader = class; + + TJvWizardButtonControl = class(TBitBtn) + private + FWizard: TJvWizard; + FAlignment: TJvWizardLeftRight; + procedure CMVisibleChanged(var Msg: TLMessage); message CM_VISIBLECHANGED; + procedure CMDesignHitTest(var Msg: TCMDesignHitTest); message CM_DESIGNHITTEST; + protected + property Wizard: TJvWizard read FWizard write FWizard; + property Alignment: TJvWizardLeftRight read FAlignment write FAlignment; + public + constructor Create(AOwner: TComponent); override; + end; + + TJvWizardButtonControlClass = class of TJvWizardButtonControl; + + { The wrapper of the TJvWizardButtonControl } + TJvWizardNavigateButton = class(TPersistent) + private + FControl: TJvWizardButtonControl; + procedure SetCaption(const Value: string); + function GetCaption: string; + function GetGlyph: TBitmap; + procedure SetGlyph(const Value: TBitmap); + function GetNumGlyphs: Integer; + procedure SetNumGlyphs(const Value: Integer); + function GetLayout: TButtonLayout; + procedure SetLayout(const Value: TButtonLayout); + function GetModalResult: TModalResult; + procedure SetModalResult(const Value: TModalResult); + function GetButtonWidth: Integer; + procedure SetButtonWidth(const Value: Integer); + protected + property Control: TJvWizardButtonControl read FControl write FControl; + published + property Glyph: TBitmap read GetGlyph write SetGlyph; + property Caption: string read GetCaption write SetCaption; + property NumGlyphs: Integer read GetNumGlyphs write SetNumGlyphs; + property Layout: TButtonLayout read GetLayout write SetLayout default blGlyphLeft; + property ModalResult: TModalResult read GetModalResult write SetModalResult default mrNone; + property Width: Integer read GetButtonWidth write SetButtonWidth; + end; + + TJvWizardRouteMapDisplayEvent = procedure(Sender: TObject; + const Page: TJvWizardCustomPage; var AllowDisplay: Boolean) of object; + + { TJvWizardRouteMap base class } + TJvWizardRouteMapControl = class(TCustomControl) + private + FWizard: TJvWizard; + FAlign: TJvWizardAlign; + FPages: TList; + FPageIndex: Integer; + FImage: TJvWizardImage; + FOnDisplaying: TJvWizardRouteMapDisplayEvent; + function GetPage(Index: Integer): TJvWizardCustomPage; + function GetPageCount: Integer; + procedure SetAlign(Value: TJvWizardAlign); + procedure SetPageIndex(Value: Integer); + procedure SetImage(const Value: TJvWizardImage); + procedure CMDesignHitTest(var Msg: TCMDesignHitTest); message CM_DESIGNHITTEST; + procedure DoAddPage(const APage: TJvWizardCustomPage); + procedure DoDeletePage(const APage: TJvWizardCustomPage); + procedure DoUpdatePage(const APage: TJvWizardCustomPage); + procedure DoActivatePage(const APage: TJvWizardCustomPage); + procedure DoMovePage(const APage: TJvWizardCustomPage; const OldIndex: Integer); + procedure DoImageChange(Sender: TObject); + protected + function HasPicture: Boolean; + procedure SetParent(AParent: TWinControl); override; + procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; + function PageAtPos(Pt: TPoint): TJvWizardCustomPage; virtual; + procedure WizardPageAdded(const APage: TJvWizardCustomPage); virtual; + procedure WizardPageDeleted(const APage: TJvWizardCustomPage); virtual; + procedure WizardPageUpdated(const APage: TJvWizardCustomPage); virtual; + procedure WizardPageActivated(const APage: TJvWizardCustomPage); virtual; + procedure WizardPageMoved(const APage: TJvWizardCustomPage; const OldIndex: Integer); virtual; + function CanDisplay(const APage: TJvWizardCustomPage): Boolean; virtual; + property Wizard: TJvWizard read FWizard write FWizard; + property Align: TJvWizardAlign read FAlign write SetAlign default alLeft; + property Image: TJvWizardImage read FImage write SetImage; + property OnDisplaying: TJvWizardRouteMapDisplayEvent read FOnDisplaying write FOnDisplaying; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + property Pages[Index: Integer]: TJvWizardCustomPage read GetPage; + property PageCount: Integer read GetPageCount; + property PageIndex: Integer read FPageIndex write SetPageIndex; + published + property Enabled; + property Visible; + end; + + TJvWizardImage = class(TPersistent) + private + FPicture: TPicture; + FAlignment: TJvWizardImageAlignment; + FLayout: TJvWizardImageLayout; + FOnChange: TNotifyEvent; + FTransparent: Boolean; + procedure SetPicture(Value: TPicture); + procedure SetAlignment(Value: TJvWizardImageAlignment); + procedure SetLayout(Value: TJvWizardImageLayout); + function GetTransparent: Boolean; + procedure SetTransparent(Value: Boolean); + procedure DoChange; + procedure DoPictureChange(Sender: TObject); + public + constructor Create; + destructor Destroy; override; + procedure PaintTo(const ACanvas: TCanvas; ARect: TRect); + property OnChange: TNotifyEvent read FOnChange write FOnChange; + published + property Picture: TPicture read FPicture write SetPicture; + property Alignment: TJvWizardImageAlignment read FAlignment write SetAlignment default iaStretch; + property Layout: TJvWizardImageLayout read FLayout write SetLayout default ilStretch; + property Transparent: Boolean read GetTransparent write SetTransparent default False; + end; + + TJvWizardGraphicObject = class(TPersistent) + private + FColor: TColor; + FVisible: Boolean; + procedure SetColor(Value: TColor); + procedure SetVisible(Value: Boolean); + protected + procedure VisibleChanged; virtual; + procedure ColorChanged; virtual; + procedure DoChange; virtual; abstract; + public + constructor Create; virtual; + procedure PaintTo(ACanvas: TCanvas; var ARect: TRect); virtual; abstract; + published + property Color: TColor read FColor write SetColor default clBtnFace; + property Visible: Boolean read FVisible write SetVisible default True; + end; + + { Wizard Page Title class } + TJvWizardPageTitle = class(TJvWizardGraphicObject) + private + FWizardPageHeader: TJvWizardPageHeader; + FText: string; + FAlignment: TAlignment; + FAnchorPlacement: Integer; + FAnchors: TAnchors; + FIndent: Integer; + FFont: TFont; + procedure SetText(const Value: string); + procedure SetAlignment(Value: TAlignment); + procedure SetAnchors(Value: TAnchors); + procedure SetAnchorPlacement(Value: Integer); + procedure SetIndent(Value: Integer); + procedure SetFont(Value: TFont); + procedure SetWizardPageHeader(Value: TJvWizardPageHeader); + procedure AdjustFont(const AFont: TFont); + procedure FontChange(Sender: TObject); + procedure WriteText(Writer: TWriter); + protected + { Get the area where the title text should be painted on. } + function GetTextRect(const ACanvas: TCanvas; const ARect: TRect): TRect; virtual; + procedure DoChange; override; + procedure DefineProperties(Filer: TFiler); override; + property WizardPageHeader: TJvWizardPageHeader read FWizardPageHeader write SetWizardPageHeader; + public + constructor Create; override; + destructor Destroy; override; + procedure Assign(Source: TPersistent); override; + procedure PaintTo(ACanvas: TCanvas; var ARect: TRect); override; + published + property Text: string read FText write SetText; + property Anchors: TAnchors read FAnchors write SetAnchors default [akLeft, akTop]; + property AnchorPlacement: Integer read FAnchorPlacement write SetAnchorPlacement default 4; + property Indent: Integer read FIndent write SetIndent default 0; + property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify; + property Font: TFont read FFont write SetFont; + end; + + TJvWizardPageObject = class(TJvWizardGraphicObject) + private + FWizardPage: TJvWizardCustomPage; + procedure SetWizardPage(Value: TJvWizardCustomPage); + protected + procedure Initialize; virtual; + procedure DoChange; override; + property WizardPage: TJvWizardCustomPage read FWizardPage write SetWizardPage; + end; + + { Wizard Page Header class } + TJvWizardPageHeader = class(TJvWizardPageObject) + private + FHeight: Integer; + FParentFont: Boolean; + FTitle: TJvWizardPageTitle; + FSubtitle: TJvWizardPageTitle; + FImageIndex: Integer; + FImageOffset: Integer; + FImageAlignment: TJvWizardImageLeftRight; + FShowDivider: Boolean; + procedure SetHeight(Value: Integer); + procedure SetImageIndex(Value: Integer); + procedure SetImageOffset(Value: Integer); + procedure SetImageAlignment(Value: TJvWizardImageLeftRight); + procedure SetParentFont(Value: Boolean); + procedure SetShowDivider(Value: Boolean); + procedure AdjustTitleFont; + procedure SetSubtitle(const Value: TJvWizardPageTitle); + procedure SetTitle(const Value: TJvWizardPageTitle); + protected + procedure VisibleChanged; override; + procedure Initialize; override; + { the return value of ARect is the area where the title should be + painted on. The result of GetImageRect is the image area. } + function GetImageRect(const AImages: TCustomImageList; var ARect: TRect): TRect; virtual; + public + constructor Create; override; + destructor Destroy; override; + procedure PaintTo(ACanvas: TCanvas; var ARect: TRect); override; + published + property ImageIndex: Integer read FImageIndex write SetImageIndex default -1; + property ImageOffset: Integer read FImageOffset write SetImageOffset default 0; + property ImageAlignment: TJvWizardImageLeftRight read FImageAlignment write SetImageAlignment default iaRight; + property Height: Integer read FHeight write SetHeight default 70; + property ParentFont: Boolean read FParentFont write SetParentFont default True; + property Title: TJvWizardPageTitle read FTitle write SetTitle; + property Subtitle: TJvWizardPageTitle read FSubtitle write SetSubtitle; + property ShowDivider: Boolean read FShowDivider write SetShowDivider default True; + property Color default clWindow; + property Visible; + end; + + { Welcome Page's watermark class } + TJvWizardWaterMark = class(TJvWizardPageObject) + private + FAlign: TJvWizardLeftRight; + FWidth: Integer; + FBorderWidth: Integer; + FImage: TJvWizardImage; + procedure SetWidth(Value: Integer); + procedure SetBorderWidth(Value: Integer); + procedure SetAlign(Value: TJvWizardLeftRight); + procedure ImageChanged(Sender: TObject); + protected + procedure VisibleChanged; override; + public + constructor Create; override; + destructor Destroy; override; + procedure PaintTo(ACanvas: TCanvas; var ARect: TRect); override; + published + property Align: TJvWizardLeftRight read FAlign write SetAlign default alLeft; + property BorderWidth: Integer read FBorderWidth write SetBorderWidth default 1; + property Image: TJvWizardImage read FImage write FImage; + property Width: Integer read FWidth write SetWidth default 164; + property Color default clActiveCaption; + property Visible; + end; + + { Wizard Page Panel class used by Wizard Custom Page } + TJvWizardPagePanel = class(TJvWizardPageObject) + private + FBorderWidth: Word; + procedure SetBorderWidth(Value: Word); + public + constructor Create; override; + procedure PaintTo(ACanvas: TCanvas; var ARect: TRect); override; + published + property BorderWidth: Word read FBorderWidth write SetBorderWidth default 7; + property Color default clBtnFace; + property Visible default False; + end; + + TJvWizardPageClickEvent = procedure(Sender: TObject; var Stop: Boolean) of object; + TJvWizardPaintPageEvent = procedure(Sender: TObject; ACanvas: TCanvas; var ARect: TRect) of object; + TJvWizardChangePageEvent = procedure(Sender: TObject; const FromPage: TJvWizardCustomPage) of object; + TJvWizardChangingPageEvent = procedure(Sender: TObject; var ToPage: TJvWizardCustomPage) of object; + + { Wizard Custom Page } + TJvWizardCustomPage = class(TCustomControl) + private + FWizard: TJvWizard; + FHeader: TJvWizardPageHeader; + FPanel: TJvWizardPagePanel; + FImage: TJvWizardImage; + FEnabledButtons: TJvWizardButtonSet; + FVisibleButtons: TJvWizardButtonSet; + FDrawing: Boolean; + FEnableJumpToPage: Boolean; + FOnPaintPage: TJvWizardPaintPageEvent; + FOnEnterPage: TJvWizardChangePageEvent; + FOnPage: TNotifyEvent; + FOnExitPage: TJvWizardChangePageEvent; + FOnStartButtonClick: TJvWizardPageClickEvent; + FOnLastButtonClick: TJvWizardPageClickEvent; + FOnNextButtonClick: TJvWizardPageClickEvent; + FOnBackButtonClick: TJvWizardPageClickEvent; + FOnCancelButtonClick: TJvWizardPageClickEvent; + FOnFinishButtonClick: TJvWizardPageClickEvent; + FOnHelpButtonClick: TJvWizardPageClickEvent; + function GetPageIndex: Integer; + procedure SetPageIndex(const Value: Integer); + procedure SetWizard(AWizard: TJvWizard); + procedure SetEnabledButtons(Value: TJvWizardButtonSet); + procedure SetVisibleButtons(Value: TJvWizardButtonSet); + procedure ImageChanged(Sender: TObject); + procedure WMEraseBkgnd(var Msg: TLMEraseBkgnd); message LM_ERASEBKGND; + procedure CMFontChanged(var Msg: TLMessage); message CM_FONTCHANGED; + procedure CMTextChanged(var Msg: TLMessage); message CM_TEXTCHANGED; + procedure CMEnabledChanged(var Msg: TLMessage); message CM_ENABLEDCHANGED; + function GetSubtitle: TJvWizardPageTitle; + function GetTitle: TJvWizardPageTitle; + procedure SetSubtitle(const Value: TJvWizardPageTitle); + procedure SetTitle(const Value: TJvWizardPageTitle); + protected + procedure CreateParams(var Params: TCreateParams); override; + procedure ReadState(Reader: TReader); override; + procedure AdjustClientRect(var Rect: TRect); override; + procedure Paint; override; + { DrawPage is called by paint method. all the derived page controls + should call this method to paint itsself rather than the overrided + paint method. } + procedure DrawPage(ACanvas: TCanvas; var ARect: TRect); virtual; + { called before the page shows up. Page: From page } + procedure Enter(const FromPage: TJvWizardCustomPage); virtual; + { called after the page shows up. } + procedure Done; virtual; + { called just before the page is hidden. Page: To page } + procedure ExitPage(const ToPage: TJvWizardCustomPage); virtual; // renamed from Exit() to ExitPage + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure EnableButton(AButton: TJvWizardButtonKind; AEnabled: Boolean); virtual; + property Wizard: TJvWizard read FWizard write SetWizard; + property PageIndex: Integer read GetPageIndex write SetPageIndex stored False; + published + property Header: TJvWizardPageHeader read FHeader write FHeader; + property Subtitle: TJvWizardPageTitle read GetSubtitle write SetSubtitle stored False; + property Title: TJvWizardPageTitle read GetTitle write SetTitle stored False; + property Image: TJvWizardImage read FImage write FImage; + property Panel: TJvWizardPagePanel read FPanel write FPanel; + property EnabledButtons: TJvWizardButtonSet read FEnabledButtons write SetEnabledButtons default bkAllButtons; + property VisibleButtons: TJvWizardButtonSet read FVisibleButtons write SetVisibleButtons default [bkBack, bkNext, bkCancel]; + property EnableJumpToPage: Boolean read FEnableJumpToPage write FEnableJumpToPage default True; + property Color default clBtnFace; + property Caption; + property Enabled; + property Font; + property Left stored False; + property Height stored False; + property PopupMenu; + property ShowHint; + property Top stored False; + property Width stored False; + property OnEnterPage: TJvWizardChangePageEvent read FOnEnterPage write FOnEnterPage; + property OnPage: TNotifyEvent read FOnPage write FOnPage; + property OnExitPage: TJvWizardChangePageEvent read FOnExitPage write FOnExitPage; + property OnPaintPage: TJvWizardPaintPageEvent read FOnPaintPage write FOnPaintPage; + property OnStartButtonClick: TJvWizardPageClickEvent read FOnStartButtonClick write FOnStartButtonClick; + property OnLastButtonClick: TJvWizardPageClickEvent read FOnLastButtonClick write FOnLastButtonClick; + property OnNextButtonClick: TJvWizardPageClickEvent read FOnNextButtonClick write FOnNextButtonClick; + property OnBackButtonClick: TJvWizardPageClickEvent read FOnBackButtonClick write FOnBackButtonClick; + property OnCancelButtonClick: TJvWizardPageClickEvent read FOnCancelButtonClick write FOnCancelButtonClick; + property OnFinishButtonClick: TJvWizardPageClickEvent read FOnFinishButtonClick write FOnFinishButtonClick; + property OnHelpButtonClick: TJvWizardPageClickEvent read FOnHelpButtonClick write FOnHelpButtonClick; + end; + + { Wizard Welcome Page } + TJvWizardWelcomePage = class(TJvWizardCustomPage) + private + FWaterMark: TJvWizardWaterMark; + protected + procedure AdjustClientRect(var Rect: TRect); override; + procedure DrawPage(ACanvas: TCanvas; var ARect: TRect); override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + published + property Color default clWindow; + property WaterMark: TJvWizardWaterMark read FWaterMark write FWaterMark; + end; + + { Wizard Interior Page } + TJvWizardInteriorPage = class(TJvWizardCustomPage) + protected + procedure DrawPage(ACanvas: TCanvas; var ARect: TRect); override; + end; + + TJvWizardSelectPageEvent = procedure(Sender: TObject; FromPage: TJvWizardCustomPage; + var ToPage: TJvWizardCustomPage) of object; + + { JvWizard Page List } + TJvWizardPageList = class(TList) + private + FWizard: TJvWizard; + function GetItems(Index: Integer): TJvWizardCustomPage; + protected + procedure Notify(Ptr: Pointer; Action: TListNotification); override; + property Wizard: TJvWizard read FWizard write FWizard; + public + destructor Destroy; override; + property Items[Index: Integer]: TJvWizardCustomPage read GetItems; default; + end; + + { JvWizard Control } + TJvWizard = class(TJvCustomControl) + private + FPages: TJvWizardPageList; + FActivePage: TJvWizardCustomPage; + FRouteMap: TJvWizardRouteMapControl; + FNavigateButtons: array[TJvWizardButtonKind] of TJvWizardNavigateButton; + FButtonBarHeight: Integer; + FShowDivider: Boolean; + FOnSelectNextPage: TJvWizardSelectPageEvent; + FOnSelectPriorPage: TJvWizardSelectPageEvent; + FOnSelectFirstPage: TJvWizardSelectPageEvent; + FOnSelectLastPage: TJvWizardSelectPageEvent; + FOnActivePageChanged: TNotifyEvent; + FOnActivePageChanging: TJvWizardChangingPageEvent; + FHeaderImages: TCustomImageList; + FImageChangeLink: TChangeLink; + FAutoHideButtonBar: Boolean; + FDefaultButtons: Boolean; + class function CalculateButtonBarHeight: Integer; + class function CalculateButtonHeight: Integer; + class function CalculateButtonPlacement: Integer; + procedure SetShowDivider(Value: Boolean); + function GetShowRouteMap: Boolean; + procedure SetShowRouteMap(Value: Boolean); + procedure SetButtonBarHeight(Value: Integer); + procedure SetActivePage(Page: TJvWizardCustomPage); + procedure SetHeaderImages(Value: TCustomImageList); + function GetButtonClick(Index: Integer): TNotifyEvent; + procedure SetButtonClick(Index: Integer; const Value: TNotifyEvent); + procedure ImageListChange(Sender: TObject); + procedure CreateNavigateButtons; + procedure DestroyNavigateButtons; + procedure ChangeActivePage(Page: TJvWizardCustomPage); + function GetActivePageIndex: Integer; + procedure SetActivePageIndex(Value: Integer); + function GetPageCount: Integer; + procedure RepositionButtons; + procedure UpdateButtonsStatus; + procedure WMEraseBkgnd(var Msg: TLMEraseBkgnd); message LM_ERASEBKGND; + procedure WMGetDlgCode(var Msg: TLMGetDlgCode); message LM_GETDLGCODE; + procedure CMDesignHitTest(var Msg: TCMDesignHitTest); message CM_DESIGNHITTEST; + function FindNextEnabledPage(PageIndex: Integer; const Step: Integer = 1; + CheckDisable: Boolean = True): TJvWizardCustomPage; + procedure SetAutoHideButtonBar(const Value: Boolean); + function GetWizardPages(Index: Integer): TJvWizardCustomPage; + procedure SetDefaultButtons(const Value: Boolean); + function GetNavigateButtons(Index: Integer): TJvWizardNavigateButton; + procedure SetNavigateButtons(Index: Integer; Value: TJvWizardNavigateButton); + protected + procedure Loaded; override; + procedure AdjustClientRect(var Rect: TRect); override; + procedure ShowControl(AControl: TControl); override; + procedure Paint; override; + procedure Resize; override; + procedure InsertPage(Page: TJvWizardCustomPage); + procedure RemovePage(Page: TJvWizardCustomPage); + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + function GetButtonControlClass(AKind: TJvWizardButtonKind): TJvWizardButtonControlClass; virtual; + procedure DoActivePageChanging(var ToPage: TJvWizardCustomPage); dynamic; + procedure DoActivePageChanged; dynamic; + procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure SelectPriorPage; + procedure SelectNextPage; + procedure SelectFirstPage; + procedure SelectLastPage; + function IsFirstPage(const APage: TJvWizardCustomPage; CheckDisable: Boolean = True): Boolean; + function IsLastPage(const APage: TJvWizardCustomPage; CheckDisable: Boolean = True): Boolean; + function FindNextPage(PageIndex: Integer; const Step: Integer = 1; + CheckDisable: Boolean = True): TJvWizardCustomPage; + function IsForward(const FromPage, ToPage: TJvWizardCustomPage): Boolean; + property ActivePageIndex: Integer read GetActivePageIndex write SetActivePageIndex; + property PageCount: Integer read GetPageCount; + property WizardPages[Index: Integer]: TJvWizardCustomPage read GetWizardPages; + published + property Pages: TJvWizardPageList read FPages; + property ActivePage: TJvWizardCustomPage read FActivePage write SetActivePage; + property AutoHideButtonBar: Boolean read FAutoHideButtonBar write SetAutoHideButtonBar default True; + property ButtonBarHeight: Integer read FButtonBarHeight write SetButtonBarHeight; + property ButtonStart: TJvWizardNavigateButton index Integer(bkStart) read GetNavigateButtons write SetNavigateButtons; + property ButtonLast: TJvWizardNavigateButton index Integer(bkLast) read GetNavigateButtons write SetNavigateButtons; + property ButtonBack: TJvWizardNavigateButton index Integer(bkBack) read GetNavigateButtons write SetNavigateButtons; + property ButtonNext: TJvWizardNavigateButton index Integer(bkNext) read GetNavigateButtons write SetNavigateButtons; + property ButtonFinish: TJvWizardNavigateButton index Integer(bkFinish) read GetNavigateButtons write SetNavigateButtons; + property ButtonCancel: TJvWizardNavigateButton index Integer(bkCancel) read GetNavigateButtons write SetNavigateButtons; + property ButtonHelp: TJvWizardNavigateButton index Integer(bkHelp) read GetNavigateButtons write SetNavigateButtons; + property DefaultButtons: Boolean read FDefaultButtons write SetDefaultButtons default True; + property ShowDivider: Boolean read FShowDivider write SetShowDivider default True; + property ShowRouteMap: Boolean read GetShowRouteMap write SetShowRouteMap; + property HeaderImages: TCustomImageList read FHeaderImages write SetHeaderImages; + property OnSelectFirstPage: TJvWizardSelectPageEvent read FOnSelectFirstPage write FOnSelectFirstPage; + property OnSelectLastPage: TJvWizardSelectPageEvent read FOnSelectLastPage write FOnSelectLastPage; + property OnSelectNextPage: TJvWizardSelectPageEvent read FOnSelectNextPage write FOnSelectNextPage; + property OnSelectPriorPage: TJvWizardSelectPageEvent read FOnSelectPriorPage write FOnSelectPriorPage; + + // BCB cannot handle enum types as index + property OnStartButtonClick: TNotifyEvent index Integer(bkStart) read GetButtonClick write SetButtonClick; + property OnLastButtonClick: TNotifyEvent index Integer(bkLast) read GetButtonClick write SetButtonClick; + property OnBackButtonClick: TNotifyEvent index Integer(bkBack) read GetButtonClick write SetButtonClick; + property OnNextButtonClick: TNotifyEvent index Integer(bkNext) read GetButtonClick write SetButtonClick; + property OnFinishButtonClick: TNotifyEvent index Integer(bkFinish) read GetButtonClick write SetButtonClick; + property OnCancelButtonClick: TNotifyEvent index Integer(bkCancel) read GetButtonClick write SetButtonClick; + property OnHelpButtonClick: TNotifyEvent index Integer(bkHelp) read GetButtonClick write SetButtonClick; + + property OnActivePageChanged: TNotifyEvent read FOnActivePageChanged write FOnActivePageChanged; + property OnActivePageChanging: TJvWizardChangingPageEvent read FOnActivePageChanging write FOnActivePageChanging; + + property Color; + property Font; + property Enabled; + property Visible; + end; + +implementation + +uses + LCLStrConsts, + JvResources, JvJVCLUtils; + +const + ciDefaultPPI = 96; + + ciButtonWidth = 75; + ciBaseButtonHeight = 25; // button height for default ppi + +type + TJvWizardBaseButton = class(TJvWizardButtonControl) + protected + procedure ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); virtual; abstract; + procedure SelectPage; virtual; + public + procedure Click; override; + end; + + { First Button } + TJvWizardStartButton = class(TJvWizardBaseButton) + protected + procedure ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); override; + procedure SelectPage; override; + public + constructor Create(AOwner: TComponent); override; + end; + + { Last Button } + TJvWizardLastButton = class(TJvWizardBaseButton) + protected + procedure ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); override; + procedure SelectPage; override; + public + constructor Create(AOwner: TComponent); override; + end; + + { Back Button } + TJvWizardBackButton = class(TJvWizardBaseButton) + protected + procedure ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); override; + procedure SelectPage; override; + public + constructor Create(AOwner: TComponent); override; + end; + + { Next Button } + TJvWizardNextButton = class(TJvWizardBaseButton) + protected + procedure ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); override; + procedure SelectPage; override; + public + constructor Create(AOwner: TComponent); override; + end; + + { Finish Button } + TJvWizardFinishButton = class(TJvWizardBaseButton) + protected + procedure ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); override; + public + constructor Create(AOwner: TComponent); override; + end; + + { Cancel Button } + TJvWizardCancelButton = class(TJvWizardBaseButton) + protected + procedure ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); override; + public + constructor Create(AOwner: TComponent); override; + end; + + { Help Button } + TJvWizardHelpButton = class(TJvWizardBaseButton) + protected + procedure ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); override; + public + constructor Create(AOwner: TComponent); override; + procedure Click; override; + end; + +//=== { TJvWizardButtonControl } ============================================= + +constructor TJvWizardButtonControl.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + if csDesigning in ComponentState then + begin + { !!! Add csClickEvents in order to fire the Click method + at design time. It does NOT need at run time, otherwise it cause + the OnClick event to be called twice. } + ControlStyle := ControlStyle + [csClickEvents]; + ControlStyle := ControlStyle + [csNoDesignVisible]; + end; + Kind := bkCustom; + Anchors := [akRight, akBottom]; +end; + +procedure TJvWizardButtonControl.CMDesignHitTest(var Msg: TCMDesignHitTest); +begin + inherited; + if Enabled then + Msg.Result := 1; +end; + +procedure TJvWizardButtonControl.CMVisibleChanged(var Msg: TLMessage); +begin + inherited; + if FWizard <> nil then + FWizard.RepositionButtons; +end; + +//=== { TJvWizardBaseButton } ================================================ + +procedure TJvWizardBaseButton.Click; +var + Stop: Boolean; + Page: TJvWizardCustomPage; +begin + if FWizard <> nil then + begin + if not (csDesigning in ComponentState) then + begin + Stop := False; + Page := FWizard.FActivePage; + if Page <> nil then + ButtonClick(Page, Stop); + if Stop then + Exit; + inherited Click; + end; + SelectPage; + end; +end; + +procedure TJvWizardBaseButton.SelectPage; +begin + // default action: do nothing +end; + +//=== { TJvWizardStartButton } =============================================== + +constructor TJvWizardStartButton.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + Caption := RsFirstButtonCaption; + Visible := False; + Anchors := [akLeft, akBottom]; + Width := ciButtonWidth + 10; + Alignment := alLeft; +end; + +procedure TJvWizardStartButton.ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); +begin + if Assigned(Page.FOnStartButtonClick) then + Page.FOnStartButtonClick(Page, Stop); +end; + +procedure TJvWizardStartButton.SelectPage; +begin + FWizard.SelectFirstPage; +end; + +//=== { TJvWizardLastButton } ================================================ + +constructor TJvWizardLastButton.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + Caption := RsLastButtonCaption; + Visible := False; + Anchors := [akLeft, akBottom]; + Width := ciButtonWidth + 10; + Alignment := alLeft; +end; + +procedure TJvWizardLastButton.ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); +begin + if Assigned(Page.FOnLastButtonClick) then + Page.FOnLastButtonClick(Page, Stop); +end; + +procedure TJvWizardLastButton.SelectPage; +begin + FWizard.SelectLastPage; +end; + +//=== { TJvWizardBackButton } ================================================ + +constructor TJvWizardBackButton.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + Caption := RsBackButtonCaption; + Enabled := False; + Visible := True; + Width := ciButtonWidth; + Alignment := alRight; +end; + +procedure TJvWizardBackButton.ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); +begin + if Assigned(Page.FOnBackButtonClick) then + Page.FOnBackButtonClick(Page, Stop); +end; + +procedure TJvWizardBackButton.SelectPage; +begin + FWizard.SelectPriorPage; +end; + +//=== { TJvWizardNextButton } ================================================ + +constructor TJvWizardNextButton.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + Caption := RsNextButtonCaption; + Enabled := False; + Visible := True; + Width := ciButtonWidth; + Alignment := alRight; +end; + +procedure TJvWizardNextButton.ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); +begin + if Assigned(Page.FOnNextButtonClick) then + Page.FOnNextButtonClick(Page, Stop); +end; + +procedure TJvWizardNextButton.SelectPage; +begin + FWizard.SelectNextPage; +end; + +//=== { TJvWizardFinishButton } ============================================== + +constructor TJvWizardFinishButton.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + Caption := RsFinishButtonCaption; + Visible := False; + Width := ciButtonWidth; + Alignment := alRight; +end; + +procedure TJvWizardFinishButton.ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); +begin + if Assigned(Page.FOnFinishButtonClick) then + Page.FOnFinishButtonClick(Page, Stop); +end; + +//=== { TJvWizardCancelButton } ============================================== + +constructor TJvWizardCancelButton.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + Caption := rsMbCancel; + Visible := True; + Cancel := True; + Width := ciButtonWidth; + Alignment := alRight; + ModalResult := mrCancel; +end; + +procedure TJvWizardCancelButton.ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); +begin + if Assigned(Page.FOnCancelButtonClick) then + Page.FOnCancelButtonClick(Page, Stop); +end; + +//=== { TJvWizardHelpButton } ================================================ + +constructor TJvWizardHelpButton.Create(AOwner: TComponent); // Added by Theodore +begin + inherited Create(AOwner); + Caption := rsMbHelp; + Visible := False; + Anchors := [akLeft, akBottom]; + Width := ciButtonWidth; + Alignment := alLeft; +end; + +procedure TJvWizardHelpButton.Click; +var + ID: THelpContext; +begin + if not (csDesigning in ComponentState) then + begin + ID := 0; + if Assigned(OnClick) then + inherited Click + else + if (FWizard <> nil) and (FWizard.ActivePage <> nil) then + begin + if Assigned(FWizard.ActivePage.OnHelpButtonClick) then + inherited Click + else + ID := FWizard.ActivePage.HelpContext; + end + else + ID := GetParentForm(Self).HelpContext; + + if ID <> 0 then + Application.HelpContext(ID); + end; +end; + +procedure TJvWizardHelpButton.ButtonClick(Page: TJvWizardCustomPage; var Stop: Boolean); +begin + if Assigned(Page.FOnHelpButtonClick) then + Page.FOnHelpButtonClick(Page, Stop); +end; + +//=== { TJvWizardNavigateButton } ============================================ + +function TJvWizardNavigateButton.GetCaption: string; +begin + if FControl <> nil then + Result := FControl.Caption + else + Result := ''; +end; + +function TJvWizardNavigateButton.GetGlyph: TBitmap; +begin + if FControl <> nil then + Result := FControl.Glyph + else + Result := nil; +end; + +function TJvWizardNavigateButton.GetLayout: TButtonLayout; +begin + if FControl <> nil then + Result := FControl.Layout + else + Result := blGlyphLeft; +end; + +function TJvWizardNavigateButton.GetNumGlyphs: Integer; +begin + if FControl <> nil then + Result := FControl.NumGlyphs + else + Result := 0; +end; + +procedure TJvWizardNavigateButton.SetCaption(const Value: string); +begin + if FControl <> nil then + FControl.Caption := Value; +end; + +procedure TJvWizardNavigateButton.SetGlyph(const Value: TBitmap); +begin + if FControl <> nil then + FControl.Glyph := Value; +end; + +procedure TJvWizardNavigateButton.SetNumGlyphs(const Value: Integer); +begin + if FControl <> nil then + FControl.NumGlyphs := Value; +end; + +procedure TJvWizardNavigateButton.SetLayout(const Value: TButtonLayout); +begin + if FControl <> nil then + FControl.Layout := Value; +end; + +function TJvWizardNavigateButton.GetModalResult: TModalResult; +begin + if FControl <> nil then + Result := FControl.ModalResult + else + Result := mrNone; +end; + +procedure TJvWizardNavigateButton.SetModalResult(const Value: TModalResult); +begin + if FControl <> nil then + FControl.ModalResult := Value; +end; + +function TJvWizardNavigateButton.GetButtonWidth: Integer; +begin + if FControl <> nil then + Result := FControl.Width + else + Result := 0; +end; + +procedure TJvWizardNavigateButton.SetButtonWidth(const Value: Integer); +begin + if (FControl <> nil) and (FControl.Width <> Value) then + begin + FControl.Width := Value; + if FControl.FWizard <> nil then + FControl.FWizard.RepositionButtons; + end; +end; + +//=== { TJvWizardRouteMapControl } =========================================== + +constructor TJvWizardRouteMapControl.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FImage := TJvWizardImage.Create; + FImage.OnChange := @DoImageChange; + { !!! Add csNoDesignVisible in order to make it visible and invisible + at design Time. } + if csDesigning in ComponentState then + ControlStyle := ControlStyle + [csNoDesignVisible]; + FAlign := alLeft; + inherited Align := alLeft; + TabStop := False; + Width := 145; + Visible := True; + FPages := TList.Create; + DoubleBuffered := True; +end; + +destructor TJvWizardRouteMapControl.Destroy; +begin + if Wizard <> nil then + Wizard.FRouteMap := nil; + FPages.Free; + FImage.Free; + inherited Destroy; +end; + +procedure TJvWizardRouteMapControl.DoImageChange(Sender: TObject); +begin + Invalidate; +end; + +procedure TJvWizardRouteMapControl.DoAddPage(const APage: TJvWizardCustomPage); +begin + if FWizard <> nil then + begin + if (APage <> nil) and (FPages.IndexOf(APage) < 0) then + FPages.Add(APage); + WizardPageAdded(APage); + end; +end; + +procedure TJvWizardRouteMapControl.DoDeletePage(const APage: TJvWizardCustomPage); +var + I: Integer; +begin + if FWizard <> nil then + begin + if (APage <> nil) then + begin + I := FPages.Remove(APage); + if FPageIndex = I then + FPageIndex := -1; + end; + WizardPageDeleted(APage); + end; +end; + +procedure TJvWizardRouteMapControl.DoActivatePage(const APage: TJvWizardCustomPage); +begin + if FWizard <> nil then + begin + if APage <> nil then + FPageIndex := FPages.IndexOf(APage); + WizardPageActivated(APage); + end; +end; + +procedure TJvWizardRouteMapControl.DoUpdatePage(const APage: TJvWizardCustomPage); +begin + if FWizard <> nil then + WizardPageUpdated(APage); +end; + +procedure TJvWizardRouteMapControl.DoMovePage(const APage: TJvWizardCustomPage; + const OldIndex: Integer); +begin + if FWizard <> nil then + begin + if APage <> nil then + begin + FPages.Move(OldIndex, APage.PageIndex); + if OldIndex = FPageIndex then + FPageIndex := APage.PageIndex; + end; + WizardPageMoved(APage, OldIndex); + end; +end; + +procedure TJvWizardRouteMapControl.SetAlign(Value: TJvWizardAlign); +begin + if FAlign <> Value then + begin + FAlign := Value; + inherited Align := FAlign; + end; +end; + +function TJvWizardRouteMapControl.GetPage(Index: Integer): TJvWizardCustomPage; +begin + if (Index >= 0) and (Index < FPages.Count) then + Result := TJvWizardCustomPage(FPages[Index]) + else + Result := nil; +end; + +function TJvWizardRouteMapControl.GetPageCount: Integer; +begin + Result := FPages.Count; +end; + +procedure TJvWizardRouteMapControl.SetImage(const Value: TJvWizardImage); +begin + FImage.Assign(Value); +end; + +function TJvWizardRouteMapControl.HasPicture: Boolean; +begin + Result := (FImage.Picture.Graphic <> nil) and not FImage.Picture.Graphic.Empty; +end; + +procedure TJvWizardRouteMapControl.SetPageIndex(Value: Integer); +begin + if (FPageIndex <> Value) and (Value >= 0) and (Value < PageCount) then + begin + if (FWizard <> nil) and (Pages[Value].Wizard = FWizard) then + begin + FWizard.SetActivePage(Pages[Value]); + // read PageIndex from Wizard because the OnChanging event could have stopped it from switching to the page + FPageIndex := FWizard.ActivePageIndex; + end + else + FPageIndex := Value; + end; +end; + +procedure TJvWizardRouteMapControl.CMDesignHitTest(var Msg: TCMDesignHitTest); +begin + if PageAtPos(Point(Msg.XPos, Msg.YPos)) <> nil then + Msg.Result := 1 + else + inherited; +end; + +function TJvWizardRouteMapControl.PageAtPos(Pt: TPoint): TJvWizardCustomPage; +begin + { Return the page object at the particular point in the route + map control. Return NIL if no page at this particular point. } + Result := nil; +end; + +procedure TJvWizardRouteMapControl.MouseDown(Button: TMouseButton; Shift: TShiftState; + X, Y: Integer); +var + APage: TJvWizardCustomPage; +begin + if Button = mbLeft then + begin + APage := PageAtPos(Point(X, Y)); + if (APage <> nil) and ((csDesigning in ComponentState) or (APage.Enabled and APage.EnableJumpToPage)) then + begin + if APage.PageIndex = PageIndex + 1 then + Wizard.SelectNextPage + else + if APage.PageIndex = PageIndex - 1 then + Wizard.SelectPriorPage + else + Wizard.ActivePage := APage; + end; + end; + inherited MouseDown(Button, Shift, X, Y); +end; + +procedure TJvWizardRouteMapControl.SetParent(AParent: TWinControl); +var + I: Integer; +begin + if AParent <> nil then + begin + if not ((AParent is TJvWizard) or (AParent is TJvWizardCustomPage)) then + raise EJvWizardError.CreateRes(@RsEInvalidParentControl); + if AParent is TJvWizardCustomPage then + AParent := TJvWizardCustomPage(AParent).Wizard; + end; + inherited SetParent(AParent); + if AParent <> nil then + begin + FWizard := TJvWizard(AParent); + FWizard.FRouteMap := Self; + FPages.Clear; + for I := 0 to FWizard.PageCount - 1 do + FPages.Add(FWizard.FPages[I]); + + if FWizard.FActivePage <> nil then + FPageIndex := FWizard.FActivePage.PageIndex + else + FPageIndex := -1; + end; +end; + +procedure TJvWizardRouteMapControl.WizardPageActivated(const APage: TJvWizardCustomPage); +begin + { Called after the page becomes the current active page of the wizard. } + Invalidate; +end; + +procedure TJvWizardRouteMapControl.WizardPageAdded(const APage: TJvWizardCustomPage); +begin + { Called after the new page was added into the wizard. } + Invalidate; +end; + +procedure TJvWizardRouteMapControl.WizardPageDeleted(const APage: TJvWizardCustomPage); +begin + { Called after the page is removed from the wizard. + Note: do NOT free this page. } + Invalidate; +end; + +procedure TJvWizardRouteMapControl.WizardPageMoved(const APage: TJvWizardCustomPage; + const OldIndex: Integer); +begin + { Called after the page has changed its page order. } + Invalidate; +end; + +procedure TJvWizardRouteMapControl.WizardPageUpdated(const APage: TJvWizardCustomPage); +begin + { Called when the page changed its status or caption. } + Invalidate; +end; + +function TJvWizardRouteMapControl.CanDisplay(const APage: TJvWizardCustomPage): Boolean; +begin + Result := (APage <> nil) and ((csDesigning in ComponentState) or APage.Enabled); + if not (csDesigning in ComponentState) and Assigned(FOnDisplaying) then + FOnDisplaying(Self, APage, Result); +end; + +//=== { TJvWizardImage } ===================================================== + +constructor TJvWizardImage.Create; +begin + inherited Create; + FPicture := TPicture.Create; + FPicture.OnChange := @DoPictureChange; + FAlignment := iaStretch; + FLayout := ilStretch; +end; + +destructor TJvWizardImage.Destroy; +begin + FPicture.Free; + inherited Destroy; +end; + +procedure TJvWizardImage.DoChange; +begin + if Assigned(FOnChange) then + FOnChange(Self); +end; + +procedure TJvWizardImage.PaintTo(const ACanvas: TCanvas; ARect: TRect); +begin + if FPicture.Graphic <> nil then + JvWizardDrawImage(ACanvas, FPicture.Graphic, ARect, FAlignment, FLayout); +end; + +procedure TJvWizardImage.SetAlignment(Value: TJvWizardImageAlignment); +begin + if FAlignment <> Value then + begin + FAlignment := Value; + DoChange; + end; +end; + +procedure TJvWizardImage.SetPicture(Value: TPicture); +begin + FPicture.Assign(Value); + if FPicture.Graphic <> nil then + FPicture.Graphic.Transparent := FTransparent; +end; + +procedure TJvWizardImage.SetLayout(Value: TJvWizardImageLayout); +begin + if FLayout <> Value then + begin + FLayout := Value; + DoChange; + end; +end; + +function TJvWizardImage.GetTransparent: Boolean; +var + AGraphic: TGraphic; +begin + AGraphic := FPicture.Graphic; + if AGraphic <> nil then + Result := AGraphic.Transparent + else + Result := FTransparent; +end; + +procedure TJvWizardImage.SetTransparent(Value: Boolean); +var + AGraphic: TGraphic; +begin + AGraphic := FPicture.Graphic; + FTransparent := Value; + if (AGraphic <> nil) and not ({(AGraphic is TMetaFile) or} (AGraphic is TIcon)) then + AGraphic.Transparent := Value; +end; + +procedure TJvWizardImage.DoPictureChange(Sender: TObject); +begin + DoChange; +end; + +//=== { TJvWizardGraphicObject } ============================================= + +constructor TJvWizardGraphicObject.Create; +begin + inherited Create; + FColor := clBtnFace; + FVisible := True; +end; + +procedure TJvWizardGraphicObject.SetColor(Value: TColor); +begin + if FColor <> Value then + begin + FColor := Value; + ColorChanged; + end; +end; + +procedure TJvWizardGraphicObject.SetVisible(Value: Boolean); +begin + if FVisible <> Value then + begin + FVisible := Value; + VisibleChanged; + end; +end; + +procedure TJvWizardGraphicObject.ColorChanged; +begin + DoChange; +end; + +procedure TJvWizardGraphicObject.VisibleChanged; +begin + DoChange; +end; + +//=== { TJvWizardPageTitle } ================================================= + +constructor TJvWizardPageTitle.Create; +begin + inherited Create; + FAnchorPlacement := 4; + FIndent := 0; + FAnchors := [akLeft, akTop]; + FAlignment := taLeftJustify; + FFont := TFont.Create; + Color := clNone; // Transparent +end; + +destructor TJvWizardPageTitle.Destroy; +begin + FFont.Free; + inherited Destroy; +end; + +procedure TJvWizardPageTitle.DoChange; +begin + if FWizardPageHeader <> nil then + FWizardPageHeader.DoChange; +end; + +procedure TJvWizardPageTitle.WriteText(Writer: TWriter); +begin + Writer.WriteString(FText); +end; + +procedure TJvWizardPageTitle.DefineProperties(Filer: TFiler); +begin + inherited DefineProperties(Filer); + { Write empty Text to DFM because the default value differs from '' } + if Filer is TWriter then + Filer.DefineProperty('Text', nil, @WriteText, FText = ''); +end; + +procedure TJvWizardPageTitle.SetWizardPageHeader(Value: TJvWizardPageHeader); +begin + if FWizardPageHeader <> Value then + begin + FWizardPageHeader := Value; + if (FWizardPageHeader <> nil) and (FWizardPageHeader.WizardPage <> nil) then + AdjustFont(FWizardPageHeader.WizardPage.Font); + FFont.OnChange := @FontChange; + end; +end; + +function TJvWizardPageTitle.GetTextRect(const ACanvas: TCanvas; + const ARect: TRect): TRect; +var + ATextSize: TSize; +begin + ATextSize := ACanvas.TextExtent(FText); + Result := Bounds(ARect.Left, ARect.Top, ATextSize.cx, ATextSize.cy); + if akLeft in FAnchors then + OffsetRect(Result, FAnchorPlacement, 0); + if akTop in FAnchors then + OffsetRect(Result, 0, FAnchorPlacement); + if akRight in FAnchors then + Result.Right := ARect.Right - FAnchorPlacement; + if akBottom in FAnchors then + Result.Bottom := ARect.Bottom - FAnchorPlacement; + InflateRect(Result, -FIndent, 0); + if Result.Bottom > ARect.Bottom then + Result.Bottom := ARect.Bottom; + if Result.Right > ARect.Right then + Result.Right := ARect.Right; +end; + +procedure TJvWizardPageTitle.PaintTo(ACanvas: TCanvas; var ARect: TRect); +const + Alignments: array [TAlignment] of Integer = (DT_LEFT, DT_RIGHT, DT_CENTER); + cOutlineColor = TColor($00FFD8CE); +var + ATextRect: TRect; +begin + if FVisible and (FWizardPageHeader <> nil) and (FWizardPageHeader.WizardPage <> nil) then + begin + ACanvas.Font.Assign(FFont); + ATextRect := GetTextRect(ACanvas, ARect); + if FColor <> clNone then + begin + ACanvas.Brush.Style := bsSolid; + ACanvas.Brush.Color := FColor; + ACanvas.FillRect(ATextRect); + end; + with ACanvas do + begin + Brush.Style := bsClear; + DrawText(ACanvas.Handle, PChar(FText), -1, ATextRect, DT_WORDBREAK or Alignments[FAlignment]); + { Draw outline at design time. } + if csDesigning in FWizardPageHeader.WizardPage.ComponentState then + begin + Pen.Style := psDot; + Pen.Mode := pmXor; + Pen.Color := cOutlineColor; + Brush.Style := bsClear; + Rectangle(ATextRect.Left, ATextRect.Top, ATextRect.Right, + ATextRect.Bottom); + end; + end; + ARect.Top := ATextRect.Bottom; + end; +end; + +procedure TJvWizardPageTitle.SetAlignment(Value: TAlignment); +begin + if FAlignment <> Value then + begin + FAlignment := Value; + DoChange; + end; +end; + +procedure TJvWizardPageTitle.SetAnchors(Value: TAnchors); +begin + if FAnchors <> Value then + begin + FAnchors := Value; + DoChange; + end; +end; + +procedure TJvWizardPageTitle.SetIndent(Value: Integer); +begin + if FIndent <> Value then + begin + FIndent := Value; + DoChange; + end; +end; + +procedure TJvWizardPageTitle.SetFont(Value: TFont); +begin + if (FFont <> Value) then + begin + FFont.Assign(Value); + end; +end; + +procedure TJvWizardPageTitle.SetText(const Value: string); +begin + if FText <> Value then + begin + FText := Value; + DoChange; + if (FWizardPageHeader <> nil) and + (FWizardPageHeader.WizardPage <> nil) and + (FWizardPageHeader.WizardPage.Wizard <> nil) and + (FWizardPageHeader.WizardPage.Wizard.FRouteMap <> nil) then + begin + FWizardPageHeader.WizardPage.Wizard.FRouteMap.DoUpdatePage(FWizardPageHeader.WizardPage); + end; + end; +end; + +procedure TJvWizardPageTitle.SetAnchorPlacement(Value: Integer); +begin + if FAnchorPlacement <> Value then + begin + FAnchorPlacement := Value; + DoChange; + end; +end; + +procedure TJvWizardPageTitle.AdjustFont(const AFont: TFont); +begin + if AFont <> nil then + begin + FFont.Name := AFont.Name; + FFont.Charset := AFont.Charset; + end; +end; + +procedure TJvWizardPageTitle.FontChange(Sender: TObject); +begin + // Font has changed, set the ParentFont property to False. + if FWizardPageHeader <> nil then + FWizardPageHeader.ParentFont := False; + DoChange; +end; + +procedure TJvWizardPageTitle.Assign(Source: TPersistent); +begin + if Source is TJvWizardPageTitle then + begin + if Source <> Self then + begin + FText := TJvWizardPageTitle(Source).Text; + FAnchors := TJvWizardPageTitle(Source).Anchors; + FAnchorPlacement := TJvWizardPageTitle(Source).AnchorPlacement; + FIndent := TJvWizardPageTitle(Source).Indent; + FAlignment := TJvWizardPageTitle(Source).Alignment; + Font := TJvWizardPageTitle(Source).Font; + DoChange + end + end + else + inherited Assign(Source); +end; + +//=== { TJvWizardPageObject } ================================================ + +procedure TJvWizardPageObject.DoChange; +begin + if FWizardPage <> nil then + FWizardPage.Invalidate; +end; + +procedure TJvWizardPageObject.Initialize; +begin +end; + +procedure TJvWizardPageObject.SetWizardPage(Value: TJvWizardCustomPage); +begin + FWizardPage := Value; + Initialize; +end; + +//=== { TJvWizardPageHeader } ================================================ + +constructor TJvWizardPageHeader.Create; +begin + inherited Create; + Color := clWindow; + FHeight := 70; + FParentFont := True; + { Set up Title } + FTitle := TJvWizardPageTitle.Create; + FTitle.FText := RsTitle; + FTitle.FAnchors := [akLeft, akTop, akRight]; + FTitle.FFont.Size := 12; + FTitle.FFont.Style := [fsBold]; + { Set up Subtitle } + FSubtitle := TJvWizardPageTitle.Create; + FSubtitle.FAnchors := [akLeft, akTop, akRight, akBottom]; + FSubtitle.FText := RsSubtitle; + FImageAlignment := iaRight; + FImageOffset := 0; + FImageIndex := -1; + FShowDivider := True; +end; + +destructor TJvWizardPageHeader.Destroy; +begin + FTitle.Free; + FSubtitle.Free; + inherited Destroy; +end; + +procedure TJvWizardPageHeader.Initialize; +begin + FTitle.WizardPageHeader := Self; + FSubtitle.WizardPageHeader := Self; +end; + +procedure TJvWizardPageHeader.SetHeight(Value: Integer); +begin + if FHeight <> Value then + begin + FHeight := Value; + DoChange; + end; +end; + +procedure TJvWizardPageHeader.SetImageIndex(Value: Integer); +begin + if FImageIndex <> Value then + begin + FImageIndex := Value; + DoChange; + end; +end; + +procedure TJvWizardPageHeader.SetImageOffset(Value: Integer); +begin + if FImageOffset <> Value then + begin + FImageOffset := Value; + DoChange; + end; +end; + +procedure TJvWizardPageHeader.SetImageAlignment(Value: TJvWizardImageLeftRight); +begin + if FImageAlignment <> Value then + begin + FImageAlignment := Value; + DoChange; + end; +end; + +procedure TJvWizardPageHeader.SetShowDivider(Value: Boolean); +begin + if FShowDivider <> Value then + begin + FShowDivider := Value; + DoChange; + end; +end; + +function TJvWizardPageHeader.GetImageRect(const AImages: TCustomImageList; + var ARect: TRect): TRect; +begin + Result := Bounds(ARect.Left, ARect.Top, AImages.Width, AImages.Height); + OffsetRect(Result, 0, ((ARect.Bottom - ARect.Top) - AImages.Height) div 2); + if FImageAlignment = iaRight then + OffsetRect(Result, ARect.Right - ARect.Left - AImages.Width - 4, 0); + + if FImageAlignment = iaLeft then + begin + OffsetRect(Result, FImageOffset, 0); + { if right side of the image area still in the page header area + then adjust the left side of title area. } + if Result.Right > ARect.Left then + ARect.Left := Result.Right; + end + else // must be iaRight + begin + OffsetRect(Result, -FImageOffset, 0); + { if left side of the image area still in the page header area + then adjust the ride side of title area. } + if Result.Left < ARect.Right then + ARect.Right := Result.Left; + end; +end; + +procedure TJvWizardPageHeader.SetSubtitle(const Value: TJvWizardPageTitle); +begin + FSubtitle.Assign(Value); +end; + +procedure TJvWizardPageHeader.SetTitle(const Value: TJvWizardPageTitle); +begin + FTitle.Assign(Value); +end; + +procedure TJvWizardPageHeader.PaintTo(ACanvas: TCanvas; var ARect: TRect); +var + R, ImageRect: TRect; + AImages: TCustomImageList; +begin + if Visible then + begin + R := ARect; + R.Bottom := R.Top + FHeight; + with ACanvas do + begin + Brush.Style := bsSolid; + Brush.Color := Color; + FillRect(R); + end; + if WizardPage <> nil then + begin + { Show Header Divider } + if {(csDesigning in WizardPage.ComponentState) or} FShowDivider then + JvWizardDrawBorderEdges(ACanvas, R, fsGroove, [beBottom]); + + { Draw Header Image first } + if WizardPage.Wizard <> nil then + begin + AImages := WizardPage.Wizard.HeaderImages; + if (AImages <> nil) and (FImageIndex >= 0) and (FImageIndex < AImages.Count) then + begin + ImageRect := GetImageRect(AImages, R); + { R is the area where the title and subtitle paint to. } + AImages.Draw(ACanvas, ImageRect.Left, ImageRect.Top, FImageIndex , True ); + end; + end; + { Draw Title } + FTitle.PaintTo(ACanvas, R); + { Draw Subtitle } + FSubtitle.PaintTo(ACanvas, R); + end; + Inc(ARect.Top, FHeight); + end; +end; + +procedure TJvWizardPageHeader.AdjustTitleFont; +begin + if (FWizardPage <> nil) and FParentFont then + begin + if FTitle <> nil then + FTitle.AdjustFont(FWizardPage.Font); + if FSubtitle <> nil then + FSubtitle.AdjustFont(FWizardPage.Font); + end; +end; + +procedure TJvWizardPageHeader.SetParentFont(Value: Boolean); +begin + if FParentFont <> Value then + begin + FParentFont := Value; + AdjustTitleFont; + + // Setting back the value as AdjustTitleFont might change the font, thus + // trigerring this handler again. + FParentFont := Value; + end; +end; + +procedure TJvWizardPageHeader.VisibleChanged; +begin + inherited VisibleChanged; + if WizardPage <> nil then + WizardPage.Realign; +end; + +//=== { TJvWizardWaterMark } ================================================= + +constructor TJvWizardWaterMark.Create; +begin + inherited Create; + FAlign := alLeft; + Color := clActiveCaption; + FWidth := 164; + FBorderWidth := 1; + FImage := TJvWizardImage.Create; + FImage.OnChange := @ImageChanged; +end; + +destructor TJvWizardWaterMark.Destroy; +begin + FImage.Free; + inherited Destroy; +end; + +procedure TJvWizardWaterMark.SetBorderWidth(Value: Integer); +begin + if FBorderWidth <> Value then + begin + FBorderWidth := Value; + DoChange; + end; +end; + +procedure TJvWizardWaterMark.SetAlign(Value: TJvWizardLeftRight); +begin + if FAlign <> Value then + begin + FAlign := Value; + DoChange; + if WizardPage <> nil then + WizardPage.Realign; + end; +end; + +procedure TJvWizardWaterMark.SetWidth(Value: Integer); +begin + if FWidth <> Value then + begin + FWidth := Value; + DoChange; + end; +end; + +procedure TJvWizardWaterMark.PaintTo(ACanvas: TCanvas; var ARect: TRect); +var + R: TRect; + AHeight: Integer; +begin + if Visible then + begin + AHeight := ARect.Bottom - ARect.Top; + if FAlign = alLeft then + begin + R := Bounds(ARect.Left, ARect.Top, FWidth, AHeight); + Inc(ARect.Left, FWidth); + end + else // must be alRight + begin + R := Bounds(ARect.Right - FWidth, ARect.Top, FWidth, AHeight); + Dec(ARect.Right, FWidth); + end; + InflateRect(R, -FBorderWidth, -FBorderWidth); + with ACanvas do + begin + Brush.Style := bsSolid; + Brush.Color := Color; + FillRect(R); + end; + FImage.PaintTo(ACanvas, R); + end; +end; + +procedure TJvWizardWaterMark.ImageChanged(Sender: TObject); +begin + DoChange; +end; + +procedure TJvWizardWaterMark.VisibleChanged; +begin + inherited VisibleChanged; + if WizardPage <> nil then + WizardPage.Realign; +end; + +//=== { TJvWizardPagePanel } ================================================= + +constructor TJvWizardPagePanel.Create; +begin + inherited Create; + FBorderWidth := 7; + Color := clBtnFace; + Visible := False; +end; + +procedure TJvWizardPagePanel.PaintTo(ACanvas: TCanvas; var ARect: TRect); +begin + if Visible and (FBorderWidth > 0) then + begin + InflateRect(ARect, -FBorderWidth, -FBorderWidth); + JvWizardDrawBorderEdges(ACanvas, ARect, fsGroove, beAllEdges); + if Color <> clNone then // clNone means transparent + begin + InflateRect(ARect, -2, -2); + with ACanvas do + begin + Brush.Style := bsSolid; + Brush.Color := Color; + FillRect(ARect); + end; + end; + end; +end; + +procedure TJvWizardPagePanel.SetBorderWidth(Value: Word); +begin + if FBorderWidth <> Value then + begin + FBorderWidth := Value; + DoChange; + end; +end; + +//=== { TJvWizardCustomPage } ================================================ + +constructor TJvWizardCustomPage.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + Align := alClient; + ControlStyle := ControlStyle + [csAcceptsControls, csNoDesignVisible, csNoFocus, csDesignFixedBounds]; + Visible := False; + Color := clBtnFace; + FHeader := TJvWizardPageHeader.Create; + FHeader.WizardPage := Self; + FImage := TJvWizardImage.Create; + FImage.OnChange := @ImageChanged; + FPanel := TJvWizardPagePanel.Create; + FPanel.WizardPage := Self; + { try to avoid screen flicker, it paints its image + into memory, then move image memory to the screen at once. } + FEnabledButtons := bkAllButtons; + FVisibleButtons := [bkBack, bkNext, bkCancel]; + DoubleBuffered := True; + FEnableJumpToPage := True; +end; + +destructor TJvWizardCustomPage.Destroy; +begin + if FWizard <> nil then + FWizard.RemovePage(Self); + FPanel.Free; + FImage.Free; + FHeader.Free; + inherited Destroy; +end; + +procedure TJvWizardCustomPage.CreateParams(var Params: TCreateParams); +begin + inherited CreateParams(Params); + with Params.WindowClass do + Style := Style and not (CS_HREDRAW or CS_VREDRAW); +end; + +procedure TJvWizardCustomPage.AdjustClientRect(var Rect: TRect); +begin + inherited AdjustClientRect(Rect); + if FHeader.Visible then + Rect.Top := Rect.Top + FHeader.Height; +end; + +procedure TJvWizardCustomPage.EnableButton(AButton: TJvWizardButtonKind; AEnabled: Boolean); +var + BIsEnabled: Boolean; + ButtonSet: TJvWizardButtonSet; +begin + ButtonSet := [AButton]; + BIsEnabled := (ButtonSet * EnabledButtons) <> []; + if AEnabled <> BIsEnabled then + begin + if AEnabled then + EnabledButtons := EnabledButtons + ButtonSet + else + EnabledButtons := EnabledButtons - ButtonSet; + end; +end; + +procedure TJvWizardCustomPage.CMEnabledChanged(var Msg: TLMessage); +var + NextPage: TJvWizardCustomPage; +begin + inherited; + if FWizard <> nil then + begin + if FWizard.FRouteMap <> nil then + FWizard.FRouteMap.DoUpdatePage(Self); + if not ((csDesigning in ComponentState) or Enabled) and (FWizard.ActivePage = Self) then + begin + NextPage := FWizard.FindNextPage(PageIndex, 1, not (csDesigning in ComponentState)); + if NextPage = nil then + NextPage := FWizard.FindNextPage(PageIndex, -1, not (csDesigning in ComponentState)); + FWizard.SetActivePage(NextPage); + end; + end; +end; + +procedure TJvWizardCustomPage.CMTextChanged(var Msg: TLMessage); +begin + Invalidate; + if (FWizard <> nil) and (FWizard.FRouteMap <> nil) then + FWizard.FRouteMap.DoUpdatePage(Self); +end; + +procedure TJvWizardCustomPage.CMFontChanged(var Msg: TLMessage); +begin + FHeader.AdjustTitleFont; + inherited; +end; + +procedure TJvWizardCustomPage.SetWizard(AWizard: TJvWizard); +begin + if FWizard <> AWizard then + begin + if FWizard <> nil then + FWizard.RemovePage(Self); + Parent := AWizard; + if AWizard <> nil then + AWizard.InsertPage(Self); + end; +end; + +function TJvWizardCustomPage.GetPageIndex: Integer; +begin + if FWizard <> nil then + Result := FWizard.FPages.IndexOf(Self) + else + Result := -1; +end; + +procedure TJvWizardCustomPage.ReadState(Reader: TReader); +begin + inherited ReadState(Reader); + if Reader.Parent is TJvWizard then + Wizard := TJvWizard(Reader.Parent); +end; + +procedure TJvWizardCustomPage.SetPageIndex(const Value: Integer); +var + OldIndex: Integer; +begin + if (FWizard <> nil) and (Value >= 0) and (Value < FWizard.FPages.Count) then + begin + OldIndex := PageIndex; + FWizard.FPages.Move(OldIndex, Value); + if FWizard.FRouteMap <> nil then + FWizard.FRouteMap.DoMovePage(Self, OldIndex); + end; +end; + +procedure TJvWizardCustomPage.WMEraseBkgnd(var Msg: TLMEraseBkgnd); +begin + {$IFDEF JVCLThemesEnabledD6} + if StyleServices.Enabled then + inherited; + {$ENDIF JVCLThemesEnabledD6} + {$IFDEF COMPILER9_UP} + inherited; + Msg.Result := 0; + {$ELSE} + Msg.Result := 1; + {$ENDIF COMPILER9_UP} +end; + +procedure TJvWizardCustomPage.Paint; +var + ARect: TRect; +begin + if FDrawing then + Exit; + FDrawing := True; + try + ARect := ClientRect; + with Canvas do + begin + Brush.Style := bsSolid; + Brush.Color := Color; + FillRect(ARect); + end; + DrawPage(Canvas, ARect); + if Assigned(FOnPaintPage) and not (csDesigning in ComponentState) then + FOnPaintPage(Self, Canvas, ARect) + else + begin + { Paint the image first to prevent the image from covering + the panel. } + FImage.PaintTo(Canvas, ARect); + FPanel.PaintTo(Canvas, ARect); + end; + { display page caption at design time. } + if csDesigning in ComponentState then + begin + Canvas.Brush.Style := bsClear; + Canvas.Font.Assign(Font); + DrawText(Canvas.Handle, PChar(Caption), -1, ARect, + DT_SINGLELINE + DT_CENTER + DT_VCENTER); + end; + finally + FDrawing := False; + end; +end; + +procedure TJvWizardCustomPage.DrawPage(ACanvas: TCanvas; var ARect: TRect); +begin + { all derived page control should call this method to paint itsself + rather than call the overrided paint method. } +end; + +procedure TJvWizardCustomPage.Done; +begin + Refresh; // !!! Force the page to repaint itself immediately. + if Assigned(FOnPage) and Enabled and not ([csDesigning, csDestroying] * ComponentState = []) then + FOnPage(Self); +end; + +procedure TJvWizardCustomPage.Enter(const FromPage: TJvWizardCustomPage); +begin + if Assigned(FOnEnterPage) and Enabled and not ([csDesigning, csDestroying] * ComponentState = []) then + FOnEnterPage(Self, FromPage); +end; + +procedure TJvWizardCustomPage.ExitPage(const ToPage: TJvWizardCustomPage); +begin + if Assigned(FOnExitPage) and Enabled and ([csDesigning, csDestroying] * ComponentState = []) then + FOnExitPage(Self, ToPage); +end; + +procedure TJvWizardCustomPage.ImageChanged(Sender: TObject); +begin + Invalidate; +end; + +procedure TJvWizardCustomPage.SetEnabledButtons(Value: TJvWizardButtonSet); +begin + if FEnabledButtons <> Value then + begin + FEnabledButtons := Value; + if (FWizard <> nil) and (FWizard.FActivePage = Self) then + FWizard.UpdateButtonsStatus; + end; +end; + +procedure TJvWizardCustomPage.SetVisibleButtons(Value: TJvWizardButtonSet); +begin + if FVisibleButtons <> Value then + begin + FVisibleButtons := Value; + if (FWizard <> nil) and (FWizard.FActivePage = Self) then + begin + { if there is no buttons are visible, then we don't need + to display the button bar. } + if FWizard.AutoHideButtonBar then + begin + if FVisibleButtons = [] then + FWizard.ButtonBarHeight := 0 + else + FWizard.ButtonBarHeight := FWizard.CalculateButtonBarHeight; + end; + Invalidate; + end; + end; +end; + +function TJvWizardCustomPage.GetSubtitle: TJvWizardPageTitle; +begin + Result := Header.Subtitle; +end; + +function TJvWizardCustomPage.GetTitle: TJvWizardPageTitle; +begin + Result := Header.Title; +end; + +procedure TJvWizardCustomPage.SetSubtitle(const Value: TJvWizardPageTitle); +begin + Header.Subtitle := Value; +end; + +procedure TJvWizardCustomPage.SetTitle(const Value: TJvWizardPageTitle); +begin + Header.Title := Value; +end; + +//=== { TJvWizardWelcomePage } =============================================== + +constructor TJvWizardWelcomePage.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FWaterMark := TJvWizardWaterMark.Create; + FWaterMark.WizardPage := Self; + FHeader.FTitle.FText := RsWelcome; + // welcome pages don't have dividers by default +// FHeader.ShowDivider := False; + Color := clWindow; +end; + +destructor TJvWizardWelcomePage.Destroy; +begin + FWaterMark.Free; + inherited Destroy; +end; + +procedure TJvWizardWelcomePage.AdjustClientRect(var Rect: TRect); +begin + inherited AdjustClientRect(Rect); // !!! must call + if FWaterMark.Visible then + begin + if FWaterMark.Align = alLeft then + Rect.Left := Rect.Left + FWaterMark.Width + else + Rect.Right := Rect.Right - FWaterMark.Width; + end; +end; + +procedure TJvWizardWelcomePage.DrawPage(ACanvas: TCanvas; var ARect: TRect); +begin + FWaterMark.PaintTo(ACanvas, ARect); + FHeader.PaintTo(ACanvas, ARect); +end; + +//=== { TJvWizardInteriorPage } ============================================== + +procedure TJvWizardInteriorPage.DrawPage(ACanvas: TCanvas; var ARect: TRect); +begin + FHeader.PaintTo(ACanvas, ARect); +end; + +//=== { TJvWizardPageList } ================================================== + +destructor TJvWizardPageList.Destroy; +begin + FWizard := nil; + inherited Destroy; +end; + +function TJvWizardPageList.GetItems(Index: Integer): TJvWizardCustomPage; +begin + Result := TJvWizardCustomPage(inherited Items[Index]); +end; + +procedure TJvWizardPageList.Notify(Ptr: Pointer; Action: TListNotification); +begin + case Action of + lnAdded: + TJvWizardCustomPage(Ptr).FWizard := FWizard; + lnDeleted: + TJvWizardCustomPage(Ptr).FWizard := nil; + end; +end; + +//=== { TJvWizard } ========================================================== + +constructor TJvWizard.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + { In order to accept TJvWizardRouteMap control, we need to add + csAcceptsControls ControlStyle } + ControlStyle := ControlStyle + [csAcceptsControls]; + FPages := TJvWizardPageList.Create; + FPages.Wizard := Self; + Align := alClient; + FShowDivider := True; + FButtonBarHeight := CalculateButtonBarHeight; + FImageChangeLink := TChangeLink.Create; + FImageChangeLink.OnChange := @ImageListChange; + FAutoHideButtonBar := True; + CreateNavigateButtons; + FDefaultButtons := True; +end; + +destructor TJvWizard.Destroy; +var + I: Integer; +begin + DestroyNavigateButtons; + { !!! Reset wizard property value of all wizard pages FIRST, + so that when the actual wizard page control is freed, the page won't + call Wizard.RemovePage, otherwise it will cause AV, because at that + time FPages has already been destroyed. } + for I := 0 to FPages.Count - 1 do + TJvWizardCustomPage(FPages[I]).FWizard := nil; + FImageChangeLink.Free; + FPages.Free; + inherited Destroy; +end; + +class function TJvWizard.CalculateButtonBarHeight: Integer; +begin + Result := CalculateButtonHeight + Round(Screen.PixelsPerInch / ciDefaultPPI * 17); +end; + +class function TJvWizard.CalculateButtonHeight: Integer; +begin + Result := Round(Screen.PixelsPerInch / ciDefaultPPI * ciBaseButtonHeight); +end; + +class function TJvWizard.CalculateButtonPlacement: Integer; +begin + Result := (CalculateButtonBarHeight - CalculateButtonHeight) div 2; +end; + +procedure TJvWizard.Loaded; +begin + inherited Loaded; + RepositionButtons; + { When the wizard shows up, by default we display the first page. } + if FPages.Count > 0 then + SelectFirstPage; +end; + +function TJvWizard.GetButtonControlClass(AKind: TJvWizardButtonKind): TJvWizardButtonControlClass; +begin + case AKind of + bkStart: + Result := TJvWizardStartButton; + bkLast: + Result := TJvWizardLastButton; + bkBack: + Result := TJvWizardBackButton; + bkNext: + Result := TJvWizardNextButton; + bkFinish: + Result := TJvWizardFinishButton; + bkCancel: + Result := TJvWizardCancelButton; + bkHelp: + Result := TJvWizardHelpButton; + else + Result := TJvWizardButtonControl; + end; +end; + +procedure TJvWizard.CreateNavigateButtons; +var + AKind: TJvWizardButtonKind; + AButton: TJvWizardButtonControl; +begin + for AKind := Low(TJvWizardButtonKind) to High(TJvWizardButtonKind) do + begin + { Don't need to set width property } + AButton := GetButtonControlClass(AKind).Create(Self); + try + AButton.Parent := Self; + AButton.Height := CalculateButtonHeight; + AButton.Wizard := Self; + finally + FNavigateButtons[AKind] := TJvWizardNavigateButton.Create; + FNavigateButtons[AKind].Control := AButton; + end; + end; +end; + +procedure TJvWizard.DestroyNavigateButtons; +var + AKind: TJvWizardButtonKind; +begin + for AKind := Low(TJvWizardButtonKind) to High(TJvWizardButtonKind) do + FNavigateButtons[AKind].Free; +end; + +function TJvWizard.FindNextPage(PageIndex: Integer; const Step: Integer; + CheckDisable: Boolean): TJvWizardCustomPage; +begin + { !!! Only the Enabled property of the page can tell if it should be + ignore or skip. we can not use Visible property, because all pages are + invisible at startup until they are actived. } + Result := nil; + Assert(Step <> 0); + repeat + Inc(PageIndex, Step); + until (PageIndex < 0) or (PageIndex >= FPages.Count) or + TJvWizardCustomPage(FPages[PageIndex]).Enabled or not CheckDisable; + if csDesigning in ComponentState then + begin + if PageIndex < 0 then + PageIndex := FPages.Count - 1 + else + if PageIndex >= FPages.Count then + PageIndex := 0; + end; + if (PageIndex >= 0) and (PageIndex < FPages.Count) and + (TJvWizardCustomPage(FPages[PageIndex]).Enabled or not CheckDisable) then + Result := TJvWizardCustomPage(FPages[PageIndex]); +end; + +function TJvWizard.FindNextEnabledPage(PageIndex: Integer; const Step: Integer; + CheckDisable: Boolean): TJvWizardCustomPage; +begin + Result := FindNextPage(PageIndex, Step, CheckDisable); + if not (csDesigning in ComponentState) then + while (Result <> nil) and not Result.EnableJumpToPage do + Result := FindNextPage(Result.PageIndex, Step, CheckDisable); +end; + +procedure TJvWizard.SelectFirstPage; +var + AFirstPage: TJvWizardCustomPage; +begin + AFirstPage := FindNextEnabledPage(-1, 1, not (csDesigning in ComponentState)); + if AFirstPage <> nil then + begin + if not (csDesigning in ComponentState) and Assigned(FOnSelectFirstPage) then + FOnSelectFirstPage(Self, FActivePage, AFirstPage); + if AFirstPage <> nil then + SetActivePage(AFirstPage); + end; +end; + +procedure TJvWizard.SelectLastPage; +var + ALastPage: TJvWizardCustomPage; +begin + ALastPage := FindNextEnabledPage(FPages.Count, -1, not (csDesigning in ComponentState)); + if ALastPage <> nil then + begin + if not (csDesigning in ComponentState) and Assigned(FOnSelectLastPage) then + FOnSelectLastPage(Self, FActivePage, ALastPage); + if ALastPage <> nil then + SetActivePage(ALastPage); + end; +end; + +procedure TJvWizard.SelectNextPage; +var + ANextPage: TJvWizardCustomPage; +begin + ANextPage := FindNextEnabledPage(GetActivePageIndex, 1, not (csDesigning in ComponentState)); + if ANextPage <> nil then + begin + if not (csDesigning in ComponentState) and Assigned(FOnSelectNextPage) then + FOnSelectNextPage(Self, FActivePage, ANextPage); + if ANextPage <> nil then + SetActivePage(ANextPage); + end; +end; + +procedure TJvWizard.SelectPriorPage; +var + APriorPage: TJvWizardCustomPage; +begin + APriorPage := FindNextEnabledPage(GetActivePageIndex, -1, not (csDesigning in ComponentState)); + if APriorPage <> nil then + begin + if not (csDesigning in ComponentState) and Assigned(FOnSelectPriorPage) then + FOnSelectPriorPage(Self, FActivePage, APriorPage); + if APriorPage <> nil then + SetActivePage(APriorPage); + end; +end; + +function TJvWizard.IsFirstPage(const APage: TJvWizardCustomPage; CheckDisable: Boolean): Boolean; +var + AFirstPage: TJvWizardCustomPage; +begin + AFirstPage := FindNextPage(-1, 1, CheckDisable); + Result := (AFirstPage = nil) or (APage = AFirstPage); +end; + +function TJvWizard.IsLastPage(const APage: TJvWizardCustomPage; CheckDisable: Boolean): Boolean; +var + ALastPage: TJvWizardCustomPage; +begin + ALastPage := FindNextPage(FPages.Count, -1, CheckDisable); + Result := (ALastPage = nil) or (APage = ALastPage); +end; + +procedure TJvWizard.SetActivePage(Page: TJvWizardCustomPage); +begin + if not (csLoading in ComponentState) and + ((Page = nil) or ((Page.Wizard = Self) and ((csDesigning in ComponentState) or Page.Enabled))) then + begin + ChangeActivePage(Page); + end; +end; + +procedure TJvWizard.ChangeActivePage(Page: TJvWizardCustomPage); +var + ParentForm: TCustomForm; +begin + if FActivePage <> Page then + begin + if not (csDestroying in ComponentState) then + DoActivePageChanging(Page); + if Page = FActivePage then + Exit; + + ParentForm := GetParentForm(Self); + if (ParentForm <> nil) and (FActivePage <> nil) and + FActivePage.ContainsControl(ParentForm.ActiveControl) and FActivePage.CanFocus then + begin + ParentForm.ActiveControl := FActivePage; + end; + + if FActivePage <> nil then + begin + { FActivePage.Exit, called just before the page is hidden. } + FActivePage.ExitPage(Page); + FActivePage.Visible := False; + FActivePage.ControlStyle := FActivePage.ControlStyle + [csNoDesignVisible]; + end; + + { Just in case the new page is changed to be disabled again after + the above OnExitPage event is called. } + if (Page <> nil) and not (Page.Enabled or (csDesigning in ComponentState)) then + begin + if IsForward(FActivePage, Page) then + Page := FindNextPage(GetActivePageIndex) // try go forward + else + Page := FindNextPage(GetActivePageIndex, -1); // try go backward + end; + + if Page <> nil then + begin + { FActivePage.Enter, called before the page shows up. } + Page.Enter(FActivePage); + Page.BringToFront; + Page.Visible := True; + Page.ControlStyle := Page.ControlStyle - [csNoDesignVisible]; + if ParentForm <> nil then + begin + if Page.CanFocus then + ParentForm.ActiveControl := Page + else + if CanFocus then + ParentForm.ActiveControl := Self; + end; + end; + + FActivePage := Page; + if FRouteMap <> nil then + FRouteMap.DoActivatePage(FActivePage); + if AutoHideButtonBar then + begin + if (FActivePage <> nil) and (FActivePage.FVisibleButtons = []) then + ButtonBarHeight := 0 + else + ButtonBarHeight := CalculateButtonBarHeight; + end; + { At design time, if the Page's Enabled property set to False, + the following if block never gets called. } + if (ParentForm <> nil) and (FActivePage <> nil) and (ParentForm.ActiveControl = FActivePage) then + begin + FActivePage.SelectFirst; + FActivePage.Done; + end; + + if not (csDestroying in ComponentState) then + DoActivePageChanged; + end; +end; + +procedure TJvWizard.InsertPage(Page: TJvWizardCustomPage); +begin + FPages.Add(Page); + if FRouteMap <> nil then + FRouteMap.DoAddPage(Page); +end; + +procedure TJvWizard.RemovePage(Page: TJvWizardCustomPage); +var + NextPage: TJvWizardCustomPage; +begin + if ActivePage = Page then + NextPage := FindNextPage(Page.PageIndex, 1, not (csDesigning in ComponentState)) + else + NextPage := ActivePage; + + if NextPage = Page then + NextPage := nil; + if FRouteMap <> nil then + FRouteMap.DoDeletePage(Page); + FPages.Remove(Page); + SetActivePage(NextPage); + { !!! We must not call Page.Free, because page is the child + control of the wizard now, so when the wizard being destroy, this page + will be destroyed as well. } +end; + +function TJvWizard.GetActivePageIndex: Integer; +begin + if ActivePage <> nil then + Result := ActivePage.PageIndex + else + Result := -1; +end; + +procedure TJvWizard.SetActivePageIndex(Value: Integer); +begin + if (Value >= 0) and (Value < PageCount) then + ActivePage := TJvWizardCustomPage(FPages[Value]) + else + ActivePage := nil; +end; + +procedure TJvWizard.WMEraseBkgnd(var Msg: TLMEraseBkgnd); +begin + {$IFDEF JVCLThemesEnabledD6} + if StyleServices.Enabled then + inherited; + {$ENDIF JVCLThemesEnabledD6} + Msg.Result := 1; +end; + +procedure TJvWizard.Paint; +var + R: TRect; +begin + R := ClientRect; + if Color <> clNone then + begin + Canvas.Brush.Color := Color; + Canvas.Brush.Style := bsSolid; + Canvas.FillRect(R); + end; + if (FButtonBarHeight > CalculateButtonHeight) and FShowDivider then + begin + R.Top := R.Bottom - FButtonBarHeight; + JvWizardDrawBorderEdges(Canvas, R, fsGroove, [beTop]); + end; +end; + +procedure TJvWizard.SetShowDivider(Value: Boolean); +begin + if FShowDivider <> Value then + begin + FShowDivider := Value; + Invalidate; + end; +end; + +function TJvWizard.GetShowRouteMap: Boolean; +begin + if FRouteMap <> nil then + Result := FRouteMap.Visible + else + Result := False; +end; + +procedure TJvWizard.SetShowRouteMap(Value: Boolean); +begin + if FRouteMap <> nil then + FRouteMap.Visible := Value; +end; + +procedure TJvWizard.SetButtonBarHeight(Value: Integer); +begin + if FButtonBarHeight <> Value then + begin + FButtonBarHeight := Value; + Realign; + RepositionButtons; + Invalidate; + end; + { Whatever the ButtonBarHeight is changed or not, we need to + call UpdateButtonsStatus method anyway. } + UpdateButtonsStatus; +end; + +procedure TJvWizard.SetHeaderImages(Value: TCustomImageList); +begin + ReplaceImageListReference(Self, Value, FHeaderImages, FImageChangeLink); + if FActivePage <> nil then + FActivePage.Invalidate; +end; + +function TJvWizard.GetButtonClick(Index: Integer): TNotifyEvent; +begin + if FNavigateButtons[TJvWizardButtonKind(Index)].Control <> nil then + Result := FNavigateButtons[TJvWizardButtonKind(Index)].Control.OnClick + else + Result := nil; +end; + +procedure TJvWizard.SetButtonClick(Index: Integer; const Value: TNotifyEvent); +begin + if FNavigateButtons[TJvWizardButtonKind(Index)].Control <> nil then + FNavigateButtons[TJvWizardButtonKind(Index)].Control.OnClick := Value; +end; + +function TJvWizard.GetPageCount: Integer; +begin + Result := FPages.Count; +end; + +procedure TJvWizard.CMDesignHitTest(var Msg: TCMDesignHitTest); +var + Pt: TPoint; +begin + Pt := SmallPointToPoint(Msg.Pos); + if (FActivePage <> nil) and PtInRect(FActivePage.BoundsRect, Pt) then + Msg.Result := 1; +end; + +procedure TJvWizard.AdjustClientRect(var Rect: TRect); +begin + { All wizard's child controls (Pages, RouteMap, etc) whose align + property set to (alTop, alLeft, alTop, alBottom, alClient) will call + this procedure to adjust their bounds. All navigation buttons would not + call it because they do not have align set, so they can display at + the bottom of the wizard. } + inherited AdjustClientRect(Rect); + if FButtonBarHeight > CalculateButtonHeight then + Rect.Bottom := Rect.Bottom - FButtonBarHeight; +end; + +procedure TJvWizard.WMGetDlgCode(var Msg: TLMGetDlgCode); +begin + Msg.Result := DLGC_WANTALLKEYS or DLGC_WANTARROWS; +end; + +procedure TJvWizard.UpdateButtonsStatus; +var + AKind: TJvWizardButtonKind; + AEnabledButtonSet: TJvWizardButtonSet; + AVisibleButtonSet: TJvWizardButtonSet; +begin + if Parent = nil then + Exit; + AEnabledButtonSet := [bkCancel]; + AVisibleButtonSet := [bkBack, bkNext, bkCancel]; + if FActivePage <> nil then + begin + { By default, the Back button should be disabled for the first + page at run time } + if not (csDesigning in ComponentState) and IsFirstPage(FActivePage) then + Exclude(FActivePage.FEnabledButtons, bkBack); + AEnabledButtonSet := FActivePage.FEnabledButtons; + AVisibleButtonSet := FActivePage.FVisibleButtons; + if csDesigning in ComponentState then + begin + Include(AEnabledButtonSet, bkBack); + Include(AEnabledButtonSet, bkNext); + Include(AVisibleButtonSet, bkBack); + Include(AVisibleButtonSet, bkNext); + Exclude(AVisibleButtonSet, bkFinish); + end; + end; + { Change Buttons' status. } + for AKind := Low(TJvWizardButtonKind) to High(TJvWizardButtonKind) do + begin + FNavigateButtons[AKind].Control.Visible := AKind in AVisibleButtonSet; + FNavigateButtons[AKind].Control.Enabled := AKind in AEnabledButtonSet; + end; + { Set Default Button, Next Button has the higher priority than + the Finish Button. } + if (bkNext in AVisibleButtonSet) and (bkNext in AEnabledButtonSet) then + FNavigateButtons[bkNext].Control.Default := DefaultButtons + else + if (bkFinish in AVisibleButtonSet) and (bkFinish in AEnabledButtonSet) then + FNavigateButtons[bkFinish].Control.Default := DefaultButtons; +end; + +procedure TJvWizard.RepositionButtons; +var + ATop: Integer; + ALeft: Integer; + AButtonSet: TJvWizardButtonSet; + AButtonKind: TJvWizardButtonKind; + + procedure LocateButton(const AKind: TJvWizardButtonKind; const AOffset: Integer); + begin + if AKind in AButtonSet then + begin + with FNavigateButtons[AKind] do + begin + if FControl.Alignment = alRight then + ALeft := ALeft - FControl.Width; + FControl.SetBounds(ALeft, ATop, FControl.Width, CalculateButtonHeight); + if FControl.Alignment = alLeft then + ALeft := ALeft + FControl.Width; + end; + ALeft := ALeft + AOffset; + end; + end; + +begin + if Parent = nil then + Exit; + if FButtonBarHeight > CalculateButtonHeight then + begin + AButtonSet := [bkBack, bkNext, bkCancel]; + if FActivePage <> nil then + begin + AButtonSet := FActivePage.FVisibleButtons; + if csDesigning in ComponentState then + begin + Include(AButtonSet, bkBack); + Include(AButtonSet, bkNext); + Exclude(AButtonSet, bkFinish); + end; + end; + ATop := ClientRect.Bottom - FButtonBarHeight + CalculateButtonPlacement + 2; + { Position left side buttons } + ALeft := ClientRect.Left + CalculateButtonPlacement; + LocateButton(bkHelp, CalculateButtonPlacement + 2); + LocateButton(bkStart, 1); + LocateButton(bkLast, 0); + { Position right side buttons } + ALeft := ClientRect.Right - CalculateButtonPlacement; + if [bkNext, bkFinish] * AButtonSet = [bkNext, bkFinish] then + begin + LocateButton(bkCancel, -1); + LocateButton(bkFinish, -CalculateButtonPlacement - 2); + end + else + begin + LocateButton(bkCancel, -CalculateButtonPlacement - 2); + LocateButton(bkFinish, -1); + end; + LocateButton(bkNext, -2); + LocateButton(bkBack, 0); + end + else // Hide all buttons + begin + for AButtonKind := Low(TJvWizardButtonKind) to High(TJvWizardButtonKind) do + with FNavigateButtons[AButtonKind] do + FControl.SetBounds(0, 0, FControl.Width, 0); // Must keep the width + end; +end; + +procedure TJvWizard.GetChildren(Proc: TGetChildProc; Root: TComponent); +var + I: Integer; + Control: TControl; +begin + { Force the wizard to load its pages in page order. } + for I := 0 to FPages.Count - 1 do + Proc(TComponent(FPages[I])); + { Load other controls, otherwise, those controls won't show up in + the wizard. } + for I := 0 to ControlCount - 1 do + begin + Control := Controls[I]; + { Because all the pages are already loaded, so here we do NOT need to + load them again, otherwise it will cause 'duplicate component name' + error. } + if not (Control is TJvWizardCustomPage) and (Control.Owner = Root) then + Proc(Control); + end; +end; + +procedure TJvWizard.Notification(AComponent: TComponent; Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + if (Operation = opRemove) and (AComponent = FHeaderImages) then + SetHeaderImages(nil); +end; + +procedure TJvWizard.ImageListChange(Sender: TObject); +begin + if HandleAllocated and (Sender = FHeaderImages) and (FActivePage <> nil) then + FActivePage.Invalidate; +end; + +procedure TJvWizard.ShowControl(AControl: TControl); +begin + if (AControl is TJvWizardCustomPage) and (TJvWizardCustomPage(AControl).Wizard = Self) then + SetActivePage(TJvWizardCustomPage(AControl)); + inherited ShowControl(AControl); +end; + +procedure TJvWizard.Resize; +begin + RepositionButtons; + inherited Resize; +end; + +function TJvWizard.IsForward(const FromPage, ToPage: TJvWizardCustomPage): Boolean; +begin + if (FromPage <> nil) and (ToPage <> nil) and (FromPage.Wizard <> ToPage.Wizard) then + raise EJvWizardError.CreateRes(@RsEInvalidWizardPage); + Result := (FromPage = nil) or ((ToPage <> nil) and (FromPage.PageIndex < ToPage.PageIndex)); +end; + +procedure TJvWizard.SetAutoHideButtonBar(const Value: Boolean); +begin + if FAutoHideButtonBar <> Value then + begin + FAutoHideButtonBar := Value; + RepositionButtons; + UpdateButtonsStatus; + end; +end; + +function TJvWizard.GetWizardPages(Index: Integer): TJvWizardCustomPage; +begin + Result := TJvWizardCustomPage(Pages[Index]); +end; + +procedure TJvWizard.DoActivePageChanged; +begin + if Assigned(FOnActivePageChanged) then + FOnActivePageChanged(Self); +end; + +procedure TJvWizard.DoActivePageChanging(var ToPage: TJvWizardCustomPage); +begin + if Assigned(FOnActivePageChanging) then + FOnActivePageChanging(Self, ToPage); +end; + +procedure TJvWizard.SetDefaultButtons(const Value: Boolean); +begin + if Value <> FDefaultButtons then + begin + FDefaultButtons := Value; + UpdateButtonsStatus; + end; +end; + +function TJvWizard.GetNavigateButtons(Index: Integer): TJvWizardNavigateButton; +begin + Result := FNavigateButtons[TJvWizardButtonKind(Index)]; +end; + +procedure TJvWizard.SetNavigateButtons(Index: Integer; Value: TJvWizardNavigateButton); +begin + FNavigateButtons[TJvWizardButtonKind(Index)] := Value; +end; + +end. diff --git a/components/jvcllaz/run/JvWizard/jvwizardcommon.pas b/components/jvcllaz/run/JvWizard/jvwizardcommon.pas new file mode 100644 index 000000000..a9d3f081a --- /dev/null +++ b/components/jvcllaz/run/JvWizard/jvwizardcommon.pas @@ -0,0 +1,270 @@ +{----------------------------------------------------------------------------- +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/MPL-1.1.html + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: JvWizardCommom.PAS, released on 2001-12-23. + +The Initial Developer of the Original Code is William Yu Wei. +Portions created by William Yu Wei are Copyright (C) 2001 William Yu Wei. +All Rights Reserved. + +Contributor(s): +Peter Thörnqvist - converted to JVCL naming conventions on 2003-07-11 +Micha³ Gawrycki - Lazarus port (2019) + +You may retrieve the latest version of this file at the Project JEDI's JVCL home page, +located at http://jvcl.delphi-jedi.org + +Purpose: + All common functions and procedures which used by all components + +History: + 12/23/2001 First Create, introduce TKSide, TKSides, TJvWizardFrameStyle, + beAllSides, TKDeleteItemEvent + function KDrawSides, KDrawBevel, KDrawFrame + 12/25/2001 introduced TKMessageLevel + 01/04/2001 Add function KDrawBorderSides + +Known Issues: +-----------------------------------------------------------------------------} +// $Id$ + +unit JvWizardCommon; + +{$mode objfpc} +{$H+} + +interface + +uses + Controls, Graphics, Types, Classes, SysUtils, LCLIntf, LCLType, + JvResources; + +type + TBevelEdge = (beLeft, beTop, beRight, beBottom); + TBevelEdges = set of TBevelEdge; + +const + beAllEdges = [beLeft, beTop, beRight, beBottom]; + +type + TJvWizardFrameStyle = + (fsWindows, fsNone, fsFlat, fsGroove, fsBump, fsLowered, fsRaised); + TJvWizardImageAlignment = (iaLeft, iaRight, iaCenter, iaStretch); + TJvWizardImageLeftRight = iaLeft..iaRight; + TJvWizardImageLayout = (ilTop, ilBottom, ilCenter, ilStretch, ilTile); + EJvWizardError = class(Exception); + +function JvWizardDrawEdges(ACanvas: TCanvas; ABounds: TRect; + ULColor, LRColor: TColor; AEdges: TBevelEdges): TRect; + +function JvWizardDrawBorderEdges(ACanvas: TCanvas; ABounds: TRect; + AStyle: TJvWizardFrameStyle; AEdges: TBevelEdges): TRect; + +procedure JvWizardDrawImage(ACanvas: TCanvas; AGraphic: TGraphic; ARect: TRect; + Align: TJvWizardImageAlignment; ALayout: TJvWizardImageLayout); + +implementation + +const + { Frame Style Color constant arrays } + KULFrameColor: array [TJvWizardFrameStyle] of TColor = (clNone, clWindow, + clWindowFrame, clBtnShadow, clBtnHighlight, clBtnShadow, clBlack); + + KLRFrameColor: array [TJvWizardFrameStyle] of TColor = (clNone, clBtnFace, + clWindowFrame, clBtnHighlight, clBtnShadow, clBtnHighlight, clBtnFace); + +{----------------------------------------------------------------------------- + Procedure: JvWizardDrawEdges + Author: yuwei + Date: December 23, 2001 + Time: 17:22:42 + Purpose: Draw a frame with specified the borders on the specified bounds + of the canvas. + Arguments: + ACanvas: TCanvas; + the canvas where it draws the sides. + ABounds: TRect; + the bounds of the canvas for drawing. + ULColor: TColor; + the left and top side color. + LRColor: TColor; + the right and bottom side color. + ASides: TBevelEdges; + which sides it can draw on the canvas. + Result: + TRect: + The bounds within the sides after drawing. + See also: + + History: + --------------------------------------------------------------------------- + Date(mm/dd/yy) Comments + --------------------------------------------------------------------------- + 12/23/2001 First Release +-----------------------------------------------------------------------------} + +function JvWizardDrawEdges(ACanvas: TCanvas; ABounds: TRect; + ULColor, LRColor: TColor; AEdges: TBevelEdges): TRect; +begin + with ACanvas do + begin + Pen.Style := psSolid; + Pen.Mode := pmCopy; + Pen.Color := ULColor; + if beLeft in AEdges then + begin + MoveTo(ABounds.Left, ABounds.Top); + LineTo(ABounds.Left, ABounds.Bottom); + end; + if beTop in AEdges then + begin + MoveTo(ABounds.Left, ABounds.Top); + LineTo(ABounds.Right, ABounds.Top); + end; + Pen.Color := LRColor; + if beRight in AEdges then + begin + MoveTo(ABounds.Right - 1, ABounds.Top); + LineTo(ABounds.Right - 1, ABounds.Bottom); + end; + if beBottom in AEdges then + begin + MoveTo(ABounds.Left, ABounds.Bottom - 1); + LineTo(ABounds.Right, ABounds.Bottom - 1); + end; + end; + if beLeft in AEdges then + Inc(ABounds.Left); + if beTop in AEdges then + Inc(ABounds.Top); + if beRight in AEdges then + Dec(ABounds.Right); + if beBottom in AEdges then + Dec(ABounds.Bottom); + Result := ABounds; +end; + +function JvWizardDrawBorderEdges(ACanvas: TCanvas; ABounds: TRect; + AStyle: TJvWizardFrameStyle; AEdges: TBevelEdges): TRect; +var + ULColor, LRColor: TColor; + R: TRect; +begin + { Draw the Frame } + if not (AStyle in [fsNone, fsWindows]) then + begin + ULColor := KULFrameColor[AStyle]; + LRColor := KLRFrameColor[AStyle]; + if AStyle in [fsFlat] then + ABounds := JvWizardDrawEdges(ACanvas, ABounds, ULColor, LRColor, AEdges) + else + begin + R := ABounds; + Inc(R.Left); + Inc(R.Top); + JvWizardDrawEdges(ACanvas, R, LRColor, LRColor, AEdges); + OffsetRect(R, -1, -1); + JvWizardDrawEdges(ACanvas, R, ULColor, ULColor, AEdges); + if beLeft in AEdges then + Inc(ABounds.Left, 2); + if beTop in AEdges then + Inc(ABounds.Top, 2); + if beRight in AEdges then + Dec(ABounds.Right, 2); + if beBottom in AEdges then + Dec(ABounds.Bottom, 2); + end; + end; + Result := ABounds; +end; + +procedure JvWizardDrawTiled(ACanvas: TCanvas; AGraphic: TGraphic; ARect: TRect); +var + AWidth, AHeight: Integer; + Bmp: Graphics.TBitmap; +begin + + if not Assigned(AGraphic) or (AGraphic.Width = 0) or (AGraphic.Height = 0) then + raise EJvWizardError.CreateRes(@RsETilingError); + // Create a temporary bitmap to draw into. This is both to speed things up a bit + // and also to clip the image to the ARect param (using Draw doesn't clip the image, + // but it does support auto-detecting transparency) + Bmp := {Graphics.}TBitmap.Create; + try + Bmp.Width := ARect.Right - ARect.Left; + Bmp.Height := ARect.Bottom - ARect.Top; + Bmp.Canvas.Brush.Color := ACanvas.Brush.Color; + Bmp.Canvas.FillRect(Bmp.Canvas.ClipRect); + AWidth := 0; + while AWidth <= Bmp.Width do + begin + AHeight := 0; + while AHeight <= Bmp.Height do + begin + Bmp.Canvas.Draw(AWidth, AHeight, AGraphic); + Inc(AHeight, AGraphic.Height); + end; + Inc(AWidth, AGraphic.Width); + end; + BitBlt(ACanvas.Handle, ARect.Left, ARect.Top, Bmp.Width, Bmp.Height, + Bmp.Canvas.Handle, 0, 0, SRCCOPY); + finally + Bmp.Free; + end; +end; + +procedure JvWizardDrawImage(ACanvas: TCanvas; AGraphic: TGraphic; ARect: TRect; + Align: TJvWizardImageAlignment; ALayout: TJvWizardImageLayout); +var + Offset: TPoint; + AWidth, AHeight: Integer; +begin + if Assigned(AGraphic) then + begin + if ALayout = ilTile then + begin + JvWizardDrawTiled(ACanvas, AGraphic, ARect); + Exit; + end; + Offset := Point(0, 0); + AWidth := ARect.Right - ARect.Left; + AHeight := ARect.Bottom - ARect.Top; + if (Align in [iaCenter, iaRight]) and (AWidth > AGraphic.Width) then + begin + Offset.X := AWidth - AGraphic.Width; + if Align = iaCenter then + begin + Offset.X := Offset.X div 2; + ARect.Right := ARect.Right - Offset.X; + end; + end; + if (ALayout in [ilCenter, ilBottom]) and (AHeight > AGraphic.Height) then + begin + Offset.Y := AHeight - AGraphic.Height; + if ALayout = ilCenter then + begin + Offset.Y := Offset.Y div 2; + ARect.Bottom := ARect.Bottom - Offset.Y; + end; + end; + if (ALayout = ilTop) and (AHeight > AGraphic.Height) then + ARect.Bottom := ARect.Top + AGraphic.Height; + if (Align = iaLeft) and (AWidth > AGraphic.Width) then + ARect.Right := ARect.Left + AGraphic.Width; + ARect.Left := ARect.Left + Offset.X; + ARect.Top := ARect.Top + Offset.Y; + if (Align = iaStretch) or (ALayout = ilStretch) then + ACanvas.StretchDraw(ARect, AGraphic) + else + ACanvas.Draw(ARect.Left, ARect.Top, AGraphic); + end; +end; + +end. diff --git a/components/jvcllaz/run/JvWizard/jvwizardroutemaplist.pas b/components/jvcllaz/run/JvWizard/jvwizardroutemaplist.pas new file mode 100644 index 000000000..bda8efe5c --- /dev/null +++ b/components/jvcllaz/run/JvWizard/jvwizardroutemaplist.pas @@ -0,0 +1,564 @@ +{----------------------------------------------------------------------------- +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/MPL-1.1.html + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: JvWizardRouteMapList.PAS, released on 2004-02-14. + +The Initial Developer of the Original Code is Peter Thornqvist. +Portions created by Peter Thornqvist are Copyright (C) 2004 Peter Thornqvist + +Contributor(s): +MichaÅ‚ Gawrycki - Lazarus port (2019) + +You may retrieve the latest version of this file at the Project JEDI's JVCL home page, +located at http://jvcl.delphi-jedi.org + +Purpose: + Route map that displays pages as a list + +History: + +Known Issues: +-----------------------------------------------------------------------------} +// $Id$ + +unit JvWizardRouteMapList; + +{$mode objfpc} +{$H+} + +interface + +uses + Types, SysUtils, Classes, Graphics, Controls, Forms, LMessages, LCLIntf, LCLType, + JvTypes, JvJVCLUtils, JvWizard; + +type + TJvWizardDrawRouteMapListItem = procedure(Sender: TObject; ACanvas: TCanvas; + ARect: TRect; MousePos: TPoint; PageIndex: Integer; var DefaultDraw: Boolean) of object; + TRouteMapListItemText = (itNone, itCaption, itTitle, itSubtitle); + + TJvWizardRouteMapList = class(TJvWizardRouteMapControl) + private + FItemHeight: Integer; + FVertOffset: Integer; + FHorzOffset: Integer; + FClickable: Boolean; + FIncludeDisabled: Boolean; + FHotTrackFont: TFont; + FActiveFont: TFont; + FHotTrackCursor, FOldCursor: TCursor; + FOnDrawItem: TJvWizardDrawRouteMapListItem; + FAlignment: TAlignment; + FTextOffset: Integer; + FShowImages: Boolean; + FItemColor: TColor; + FRounded: Boolean; + FItemText: TRouteMapListItemText; + FHotTrack: Boolean; + FCurvature: Integer; + FHotTrackBorder: Integer; + FBorderColor: TColor; + FTextOnly: Boolean; + FHotTrackFontOptions: TJvTrackFontOptions; + FActiveFontOptions: TJvTrackFontOptions; + procedure SetItemHeight(const Value: Integer); + procedure SetHorzOffset(const Value: Integer); + procedure SetVertOffset(const Value: Integer); + procedure SetIncludeDisabled(const Value: Boolean); + procedure SetActiveFont(const Value: TFont); + procedure SetHotTrackFont(const Value: TFont); + procedure DoFontChange(Sender: TObject); + procedure SetAlignment(const Value: TAlignment); + procedure SetTextOffset(const Value: Integer); + procedure SetShowImages(const Value: Boolean); + procedure SetItemColor(const Value: TColor); + procedure SetRounded(const Value: Boolean); + procedure SetItemText(const Value: TRouteMapListItemText); + procedure SetCurvature(const Value: Integer); + procedure SetTextOnly(const Value: Boolean); + procedure SetBorderColor(Value: TColor); + procedure SetActiveFontOptions(const Value: TJvTrackFontOptions); + procedure SetHotTrackFontOptions(const Value: TJvTrackFontOptions); + function IsHotTrackFontStored: Boolean; + protected + procedure DrawPageItem(ACanvas: TCanvas; ARect: TRect; MousePos: TPoint; APageIndex: Integer); virtual; + procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; + function PageAtPos(Pt: TPoint): TJvWizardCustomPage; override; + procedure Paint; override; + procedure Loaded; override; + procedure CMCursorChanged(var Msg: TLMessage); message CM_CURSORCHANGED; + procedure CMFontChanged(var Msg: TLMessage); message CM_FONTCHANGED; + procedure CursorChanged; + procedure FontChanged; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + published + property ActiveFont: TFont read FActiveFont write SetActiveFont; + property ActiveFontOptions: TJvTrackFontOptions read FActiveFontOptions write SetActiveFontOptions default + DefaultTrackFontOptions; + property Alignment: TAlignment read FAlignment write SetAlignment default taCenter; + property Clickable: Boolean read FClickable write FClickable default True; + property Color default $00C08000; + property Curvature: Integer read FCurvature write SetCurvature default 9; + property Font; + property HorzOffset: Integer read FHorzOffset write SetHorzOffset default 8; + property HotTrackBorder: Integer read FHotTrackBorder write FHotTrackBorder default 2; + property HotTrackCursor: TCursor read FHotTrackCursor write FHotTrackCursor default crHandPoint; + property HotTrack: Boolean read FHotTrack write FHotTrack default True; + + property HotTrackFont: TFont read FHotTrackFont write SetHotTrackFont stored IsHotTrackFontStored; + property HotTrackFontOptions: TJvTrackFontOptions read FHotTrackFontOptions write SetHotTrackFontOptions default + DefaultTrackFontOptions; + property Image; + property TextOnly: Boolean read FTextOnly write SetTextOnly default False; + property IncludeDisabled: Boolean read FIncludeDisabled write SetIncludeDisabled default False; + property BorderColor: TColor read FBorderColor write SetBorderColor default clNavy; + property ItemColor: TColor read FItemColor write SetItemColor default clCream; + property ItemHeight: Integer read FItemHeight write SetItemHeight default 25; + property ItemText: TRouteMapListItemText read FItemText write SetItemText default itCaption; + property Rounded: Boolean read FRounded write SetRounded default False; + property ShowImages: Boolean read FShowImages write SetShowImages default False; + property TextOffset: Integer read FTextOffset write SetTextOffset default 8; + property VertOffset: Integer read FVertOffset write SetVertOffset default 8; + property OnDrawItem: TJvWizardDrawRouteMapListItem read FOnDrawItem write FOnDrawItem; + end; + +implementation + +constructor TJvWizardRouteMapList.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FActiveFont := TFont.Create; + FActiveFont.Style := [fsBold]; + FActiveFont.OnChange := @DoFontChange; + FHotTrackFont := TFont.Create; + FHotTrackFont.Color := clNavy; + FHotTrackFont.Style := [fsUnderline]; + FHotTrackFont.OnChange := @DoFontChange; + FActiveFontOptions := DefaultTrackFontOptions; + FHotTrackFontOptions := DefaultTrackFontOptions; + Color := $00C08000; + FHotTrackCursor := crHandPoint; + FVertOffset := 8; + FHorzOffset := 8; + FItemHeight := 25; + FClickable := True; + FAlignment := taCenter; + FTextOffset := 8; + FBorderColor := clNavy; + FItemColor := clCream; + FItemText := itCaption; + FHotTrack := True; + FCurvature := 9; + FHotTrackBorder := 2; + FTextOnly := False; +end; + +destructor TJvWizardRouteMapList.Destroy; +begin + FHotTrackFont.Free; + FActiveFont.Free; + inherited Destroy; +end; + +procedure TJvWizardRouteMapList.Loaded; +begin + inherited Loaded; + FOldCursor := Cursor; +end; + +procedure TJvWizardRouteMapList.MouseMove(Shift: TShiftState; + X, Y: Integer); +var + P: TJvWizardCustomPage; +begin + inherited MouseMove(Shift, X, Y); + if Clickable and HotTrack then + begin + P := PageAtPos(Point(X, Y)); + if (P <> nil) and P.Enabled then + begin + if Cursor <> FHotTrackCursor then + FOldCursor := Cursor; + Cursor := FHotTrackCursor; + Refresh; + end + else + if Cursor <> FOldCursor then + begin + Cursor := FOldCursor; + Refresh; + end; + end; +end; + +function TJvWizardRouteMapList.PageAtPos(Pt: TPoint): TJvWizardCustomPage; +var + R: TRect; + I: Integer; +begin + Result := nil; + if not Clickable then + Exit; + R := ClientRect; + InflateRect(R, -HorzOffset, -VertOffset); + R.Bottom := R.Top + ItemHeight; + for I := 0 to PageCount - 1 do + begin + if Pages[I].Enabled or IncludeDisabled then + begin + if PtInRect(R, Pt) then + begin + Result := Pages[I]; + Exit; + end; + OffsetRect(R, 0, ItemHeight); + end; + end; +end; + +procedure TJvWizardRouteMapList.Paint; +var + I: Integer; + R: TRect; + P: TPoint; +begin + Canvas.Brush.Style := bsSolid; + Canvas.Brush.Color := Color; + if BorderColor = clNone then + Canvas.Pen.Color := Color + else + Canvas.Pen.Color := BorderColor; + GetCursorPos(P); + P := ScreenToClient(P); + R := ClientRect; + if not HasPicture then + Canvas.Rectangle(R) + else + Image.PaintTo(Canvas, R); + if ItemHeight <= 0 then + Exit; + InflateRect(R, -HorzOffset, -VertOffset); + R.Bottom := R.Top + ItemHeight; + for I := 0 to PageCount - 1 do + if Pages[I].Enabled or IncludeDisabled then + begin + DrawPageItem(Canvas, R, P, I); + OffsetRect(R, 0, ItemHeight); + if R.Bottom >= ClientHeight - 2 then + Break; + end; +end; + +procedure TJvWizardRouteMapList.DrawPageItem(ACanvas: TCanvas; ARect: TRect; MousePos: TPoint; APageIndex: Integer); +const + cAlignment: array [TAlignment] of Cardinal = (DT_LEFT, DT_RIGHT, DT_CENTER); + cWordWrap: array [Boolean] of Cardinal = (DT_SINGLELINE, DT_WORDBREAK); +var + DefaultDraw: Boolean; + ATop, ALeft: Integer; + AOrigRect: TRect; + BkColor: TColor; + S: string; +begin + ACanvas.Lock; + try + AOrigRect := ARect; + ACanvas.Font := Font; + if Assigned(Wizard) and (Pages[APageIndex] = Wizard.ActivePage) then + ACanvas.Font := ActiveFont + else + if PtInRect(ARect, MousePos) and Pages[APageIndex].Enabled and HotTrack and Clickable then + ACanvas.Font := HotTrackFont + else + if not Pages[APageIndex].Enabled then + ACanvas.Font.Color := clGrayText; + + ACanvas.Brush.Color := ItemColor; + ACanvas.Pen.Color := Color; + DefaultDraw := True; + if Assigned(FOnDrawItem) then + FOnDrawItem(Self, ACanvas, ARect, MousePos, APageIndex, DefaultDraw); + if DefaultDraw then + begin + case ItemText of + itCaption: + S := Pages[APageIndex].Caption; + itTitle: + S := Pages[APageIndex].Title.Text; + itSubtitle: + S := Pages[APageIndex].Subtitle.Text; + end; + + if not TextOnly then + begin + if ItemColor = clNone then + ACanvas.Brush.Style := bsClear; + if Rounded then + ACanvas.RoundRect(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, Curvature, Curvature) + else + ACanvas.Rectangle(ARect); + if ShowImages and Assigned(Wizard) and Assigned(Wizard.HeaderImages) then + begin + ATop := ((ARect.Bottom - ARect.Top) - Wizard.HeaderImages.Height) div 2; + BkColor := ACanvas.Brush.Color; + case Alignment of + taLeftJustify: + begin + Wizard.HeaderImages.Draw(ACanvas, ARect.Left + 4, ARect.Top + ATop, Pages[APageIndex].Header.ImageIndex, Pages[APageIndex].Enabled); + Inc(ARect.Left, Wizard.HeaderImages.Width + 4); + end; + taRightJustify: + begin + Wizard.HeaderImages.Draw(ACanvas, ARect.Right - Wizard.HeaderImages.Width - 4, ARect.Top + ATop, + Pages[APageIndex].Header.ImageIndex, Pages[APageIndex].Enabled); + Dec(ARect.Right, Wizard.HeaderImages.Width + 4); + end; + taCenter: + begin + ALeft := ((ARect.Right - ARect.Left) - Wizard.HeaderImages.Width) div 2; + Inc(ARect.Top, 4); + Wizard.HeaderImages.Draw(ACanvas, ARect.Left + ALeft, ARect.Top + 8, + Pages[APageIndex].Header.ImageIndex, Pages[APageIndex].Enabled); + Inc(ARect.Top, Wizard.HeaderImages.Height); + // if ItemText = itSubtitle then + // Inc(ARect.Top, 16); + end; + end; + if not Pages[APageIndex].Enabled then + begin + // (p3) TImageList changes the canvas colors when drawing disabled images, so we reset them explicitly + SetBkColor(ACanvas.Handle, BkColor); + SetTextColor(ACanvas.Handle, ColorToRGB(clGrayText)); + end; + end; + end + else + ACanvas.Brush.Style := bsClear; + + case Alignment of + taLeftJustify: + Inc(ARect.Left, TextOffset); + taRightJustify: + Dec(ARect.Right, TextOffset); + taCenter: + InflateRect(ARect, -TextOffset div 2, -TextOffset div 2); + end; + if ItemText = itSubtitle then + begin + Inc(ARect.Top, TextOffset); + InflateRect(ARect, -TextOffset, 0); + end; + if (ItemText <> itNone) and ((ARect.Bottom - ARect.Top) > abs(ACanvas.Font.Height)) then + DrawText(ACanvas.Handle, PChar(S), Length(S), ARect, + cAlignment[Alignment] or cWordWrap[ItemText = itSubtitle] or DT_VCENTER or DT_EDITCONTROL or {DT_EXTERNALLEADING or} DT_END_ELLIPSIS); + if not TextOnly and HotTrack and (HotTrackBorder > 0) and PtInRect(AOrigRect, MousePos) then + begin + ACanvas.Brush.Style := bsClear; + ACanvas.Pen.Color := HotTrackFont.Color; + ACanvas.Pen.Width := HotTrackBorder; + if Rounded then + ACanvas.RoundRect(AOrigRect.Left, AOrigRect.Top, AOrigRect.Right, AOrigRect.Bottom, Curvature, Curvature) + else + ACanvas.Rectangle(AOrigRect); + ACanvas.Brush.Style := bsSolid; + ACanvas.Pen.Width := 1; + end; + end; + finally + ACanvas.Unlock; + end; +end; + +procedure TJvWizardRouteMapList.SetHorzOffset(const Value: Integer); +begin + if FHorzOffset <> Value then + begin + FHorzOffset := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetItemHeight(const Value: Integer); +begin + if FItemHeight <> Value then + begin + FItemHeight := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetVertOffset(const Value: Integer); +begin + if FVertOffset <> Value then + begin + FVertOffset := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetIncludeDisabled(const Value: Boolean); +begin + if FIncludeDisabled <> Value then + begin + FIncludeDisabled := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetActiveFont(const Value: TFont); +begin + FActiveFont.Assign(Value); +end; + +procedure TJvWizardRouteMapList.SetHotTrackFont(const Value: TFont); +begin + FHotTrackFont.Assign(Value); +end; + +procedure TJvWizardRouteMapList.DoFontChange(Sender: TObject); +begin + Invalidate; +end; + + + +procedure TJvWizardRouteMapList.CMCursorChanged(var Msg: TLMessage); +begin + inherited; + CursorChanged; +end; + +procedure TJvWizardRouteMapList.CMFontChanged(var Msg: TLMessage); +begin + inherited; + FontChanged; +end; + + + +procedure TJvWizardRouteMapList.SetAlignment(const Value: TAlignment); +begin + if FAlignment <> Value then + begin + FAlignment := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetTextOffset(const Value: Integer); +begin + if FTextOffset <> Value then + begin + FTextOffset := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetShowImages(const Value: Boolean); +begin + if FShowImages <> Value then + begin + FShowImages := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetItemColor(const Value: TColor); +begin + if FItemColor <> Value then + begin + FItemColor := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetRounded(const Value: Boolean); +begin + if FRounded <> Value then + begin + FRounded := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetItemText(const Value: TRouteMapListItemText); +begin + if FItemText <> Value then + begin + FItemText := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetCurvature(const Value: Integer); +begin + if FCurvature <> Value then + begin + FCurvature := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetActiveFontOptions(const Value: TJvTrackFontOptions); +begin + if FActiveFontOptions <> Value then + begin + FActiveFontOptions := Value; + UpdateTrackFont(ActiveFont, Font, FActiveFontOptions); + end; +end; + +procedure TJvWizardRouteMapList.SetHotTrackFontOptions(const Value: TJvTrackFontOptions); +begin + if FHotTrackFontOptions <> Value then + begin + FHotTrackFontOptions := Value; + UpdateTrackFont(HotTrackFont, Font, FHotTrackFontOptions); + end; +end; + +procedure TJvWizardRouteMapList.SetBorderColor(Value: TColor); +begin + if Value <> FBorderColor then + begin + FBorderColor := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.SetTextOnly(const Value: Boolean); +begin + if Value <> FTextOnly then + begin + FTextOnly := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapList.CursorChanged; +begin + if (Cursor <> FHotTrackCursor) and (Cursor <> FOldCursor) then + FOldCursor := Cursor; +end; + +procedure TJvWizardRouteMapList.FontChanged; +begin + UpdateTrackFont(HotTrackFont, Font, FHotTrackFontOptions); + UpdateTrackFont(ActiveFont, Font, FActiveFontOptions); +end; + +function TJvWizardRouteMapList.IsHotTrackFontStored: Boolean; +begin + Result := IsHotTrackFontDfmStored(HotTrackFont, Font, HotTrackFontOptions); +end; + +end. diff --git a/components/jvcllaz/run/JvWizard/jvwizardroutemapnodes.pas b/components/jvcllaz/run/JvWizard/jvwizardroutemapnodes.pas new file mode 100644 index 000000000..8302b5005 --- /dev/null +++ b/components/jvcllaz/run/JvWizard/jvwizardroutemapnodes.pas @@ -0,0 +1,397 @@ +{----------------------------------------------------------------------------- +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/MPL-1.1.html + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: JvWizardRouteMapNodes.PAS, released on 2002-02-05. + +The Initial Developer of the Original Code is Steve Forbes. +Portions created by Steve Forbes are Copyright (C) 2002 Steve Forbes. +All Rights Reserved. + +Contributor(s): +Peter Thörnqvist - converted to JVCL naming conventions on 2003-07-11 +S Steed. - added AllowClickableNodes property +Micha³ Gawrycki - Lazarus port (2019) + +You may retrieve the latest version of this file at the Project JEDI's JVCL home page, +located at http://jvcl.delphi-jedi.org + +Description: + Nodes style route map for TJvWizardRouteMap + +History: +10/14/2003 + Added option to allow user to turn off the clicking of the nodes + during runtime. S Steed. +05/02/2002 + Initial create + +Known Issues: +-----------------------------------------------------------------------------} +// $Id$ + +unit JvWizardRouteMapNodes; + +{$mode objfpc} +{$H+} + +interface + +uses + Graphics, Classes, LCLIntf, LCLType, + JvWizard; + +type + TJvWizardRouteMapNodes = class; + + TJvWizardRouteMapNodeColors = class(TPersistent) + private + FSelected: TColor; + FUnselected: TColor; + FDisabled: TColor; + FLine: TColor; + FRouteMap: TJvWizardRouteMapNodes; + protected + procedure SetLine(Value: TColor); + procedure SetSelected(Value: TColor); + procedure SetUnselected(Value: TColor); + procedure SetDisabled(Value: TColor); + procedure Changed; + public + constructor Create(ARouteMap: TJvWizardRouteMapNodes); + published + property Selected: TColor read FSelected write SetSelected default clLime; + property Unselected: TColor read FUnselected write SetUnselected default clWhite; + property Line: TColor read FLine write SetLine default clBtnShadow; + property Disabled: TColor read FDisabled write SetDisabled default clBtnFace; + end; + + TJvWizardRouteMapNodes = class(TJvWizardRouteMapControl) + private + FItemHeight: Integer; + FUsePageTitle: Boolean; + FNodeColors: TJvWizardRouteMapNodeColors; + FIndent: Integer; + FAllowClickableNodes: Boolean; + procedure SetItemHeight(Value: Integer); + procedure SetUsePageTitle(Value: Boolean); + procedure SetIndent(Value: Integer); + procedure SetAllowClickableNodes(const Value: Boolean); + protected + function PageAtPos(Pt: TPoint): TJvWizardCustomPage; override; + procedure Paint; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + published + property ItemHeight: Integer read FItemHeight write SetItemHeight default 20; + property AllowClickableNodes: Boolean read FAllowClickableNodes write SetAllowClickableNodes default True; // ss 10/14/2003 + property Align; + property Color default clBackground; + property Font; + property Image; + property Indent: Integer read FIndent write SetIndent default 8; + property NodeColors: TJvWizardRouteMapNodeColors read FNodeColors write FNodeColors; + property UsePageTitle: Boolean read FUsePageTitle write SetUsePageTitle default True; + property OnDisplaying; + end; + +implementation + +//=== { TJvWizardRouteMapNodeColors } ======================================== + +constructor TJvWizardRouteMapNodeColors.Create(ARouteMap: TJvWizardRouteMapNodes); +begin + inherited Create; + FRouteMap := ARouteMap; + FSelected := clLime; + FUnselected := clWhite; + FLine := clBtnShadow; + FDisabled := clBtnFace; +end; + +procedure TJvWizardRouteMapNodeColors.Changed; +begin + if Assigned(FRouteMap) then + FRouteMap.Invalidate; +end; + +procedure TJvWizardRouteMapNodeColors.SetDisabled(Value: TColor); +begin + if FDisabled <> Value then + begin + FDisabled := Value; + Changed; + end; +end; + +procedure TJvWizardRouteMapNodeColors.SetLine(Value: TColor); +begin + if FLine <> Value then + begin + FLine := Value; + Changed; + end; +end; + +procedure TJvWizardRouteMapNodeColors.SetSelected(Value: TColor); +begin + if FSelected <> Value then + begin + FSelected := Value; + Changed; + end; +end; + +procedure TJvWizardRouteMapNodeColors.SetUnselected(Value: TColor); +begin + if FUnselected <> Value then + begin + FUnselected := Value; + Changed; + end; +end; + +//=== { TJvWizardRouteMapNodes } ============================================= + +constructor TJvWizardRouteMapNodes.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FItemHeight := 20; + Color := clBackground; + Font.Color := clWhite; + FUsePageTitle := True; + FIndent := 8; + FAllowClickableNodes := True; // ss 10/14/2003 + FNodeColors := TJvWizardRouteMapNodeColors.Create(Self); +end; + +destructor TJvWizardRouteMapNodes.Destroy; +begin + FNodeColors.Free; + inherited Destroy; +end; + +function TJvWizardRouteMapNodes.PageAtPos(Pt: TPoint): TJvWizardCustomPage; +var + I, Count: Integer; + ARect: TRect; +begin + if AllowClickableNodes then // ss 10/14/2003 + begin + ARect := ClientRect; + InflateRect(ARect, -1, -1); + if PtInRect(ARect, Pt) then + begin + Count := PageCount; + ARect := Bounds(ARect.Left, ARect.Top + Trunc((FItemHeight - 12) / 2), + ARect.Right - ARect.Left, FItemHeight); + I := 0; + while I < Count do + begin + if CanDisplay(Pages[I]) then + begin + if PtInRect(ARect, Pt) then + begin + Result := Pages[I]; + Exit; + end; + OffsetRect(ARect, 0, FItemHeight); + end; + Inc(I); + end; + end; + end; + Result := nil; +end; + +procedure TJvWizardRouteMapNodes.Paint; +var + ARect, ATextRect, NodeRect: TRect; + I: Integer; + AColor: TColor; + AFont: TFont; + IsFirstPage, IsLastPage: Boolean; +begin + ARect := ClientRect; + with Canvas do + begin + Brush.Color := Color; + Brush.Style := bsSolid; + Pen.Color := clBtnShadow; + Pen.Width := 1; + Pen.Style := psSolid; + if not HasPicture then + Rectangle(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom) + else + Image.PaintTo(Canvas, ARect); + InflateRect(ARect, -1, -1); + AFont := TFont.Create; + try + AFont.Assign(Self.Font); + ARect := Bounds(ARect.Left + FIndent, ARect.Top + FIndent, + ARect.Right - ARect.Left - FIndent, FItemHeight); + for I := 0 to PageCount - 1 do + begin + IsFirstPage := Wizard.IsFirstPage(Pages[I], not (csDesigning in ComponentState)); + IsLastPage := Wizard.IsLastPage(Pages[I], not (csDesigning in ComponentState)); + if CanDisplay(Pages[I]) then + begin + AColor := Color; + if I = PageIndex then + begin + AFont.Color := Self.Font.Color; + AFont.Style := AFont.Style + [fsBold] + end + else + if not Pages[I].Enabled then + begin + AFont.Color := clBtnShadow; + AFont.Style := AFont.Style - [fsBold]; + end + else + if not Pages[I].EnableJumpToPage then // Nonn... + begin + AFont.Color := NodeColors.Disabled; + AFont.Style := AFont.Style - [fsBold]; // ... Nonn + end + else + begin + AFont.Color := Self.Font.Color; + AFont.Style := AFont.Style - [fsBold] + end; + + ATextRect := ARect; + if not (IsFirstPage or IsLastPage) then + ATextRect.Left := ATextRect.Left + 18; + + NodeRect := ATextRect; + NodeRect.Right := NodeRect.Left + 12; + NodeRect.Top := NodeRect.Top + Trunc((FItemHeight - 12) / 2); + NodeRect.Bottom := NodeRect.Top + 12; + + if not (IsFirstPage or IsLastPage) then + ATextRect.Left := ATextRect.Left + 20 + else + ATextRect.Left := ATextRect.Left + 18 + 20; + + try + Pen.Color := FNodeColors.Line; + if I = PageIndex then + Brush.Color := FNodeColors.Selected + else + if not Pages[I].EnableJumpToPage then // Nonn + Brush.Color := FNodeColors.Disabled // Nonn + else + if Pages[I].Enabled then + Brush.Color := FNodeColors.Unselected + else + Brush.Color := FNodeColors.Disabled; + Rectangle(NodeRect.Left, NodeRect.Top, NodeRect.Right, + NodeRect.Bottom); + + Brush.Color := FNodeColors.Line; + if IsFirstPage or IsLastPage then + begin + MoveTo(NodeRect.Right, NodeRect.Top + 5); + LineTo(NodeRect.Right + 13, NodeRect.Top + 5); + MoveTo(NodeRect.Right, NodeRect.Top + 6); + LineTo(NodeRect.Right + 13, NodeRect.Top + 6); + if IsFirstPage then + begin + MoveTo(NodeRect.Right + 11, NodeRect.Top + 6); + LineTo(NodeRect.Right + 11, ATextRect.Bottom); + MoveTo(NodeRect.Right + 12, NodeRect.Top + 6); + LineTo(NodeRect.Right + 12, ATextRect.Bottom); + end + else + begin + MoveTo(NodeRect.Right + 11, NodeRect.Top + 5); + LineTo(NodeRect.Right + 11, ATextRect.Top); + MoveTo(NodeRect.Right + 12, NodeRect.Top + 5); + LineTo(NodeRect.Right + 12, ATextRect.Top); + end; + end + else + begin + MoveTo(NodeRect.Left + 5, NodeRect.Top); + LineTo(NodeRect.Left + 5, ATextRect.Top - 1); + MoveTo(NodeRect.Left + 6, NodeRect.Top); + LineTo(NodeRect.Left + 6, ATextRect.Top - 1); + MoveTo(NodeRect.Left + 5, NodeRect.Bottom); + LineTo(NodeRect.Left + 5, ATextRect.Bottom + 1); + MoveTo(NodeRect.Left + 6, NodeRect.Bottom); + LineTo(NodeRect.Left + 6, ATextRect.Bottom + 1); + end; + + Brush.Color := AColor; + if not HasPicture then + FillRect(ATextRect) + else + SetBkMode(Canvas.Handle, TRANSPARENT); + Brush.Style := bsClear; + Font.Assign(AFont); + + if FUsePageTitle then + DrawText(Canvas.Handle, + PChar((Pages[I] as TJvWizardCustomPage).Header.Title.Text), -1, + ATextRect, DT_LEFT or DT_SINGLELINE or DT_VCENTER) + else + DrawText(Canvas.Handle, PChar(Pages[I].Caption), -1, ATextRect, + DT_LEFT or DT_SINGLELINE or DT_VCENTER); + + finally + OffsetRect(ARect, 0, FItemHeight); + end; + end; + end; + finally + AFont.Free; + end; + end; +end; + +procedure TJvWizardRouteMapNodes.SetItemHeight(Value: Integer); +begin + if FItemHeight <> Value then + begin + FItemHeight := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapNodes.SetUsePageTitle(Value: Boolean); +begin + if FUsePageTitle <> Value then + begin + FUsePageTitle := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapNodes.SetIndent(Value: Integer); +begin + if FIndent <> Value then + begin + FIndent := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapNodes.SetAllowClickableNodes( + const Value: Boolean); +begin + if FAllowClickableNodes <> Value then + begin + FAllowClickableNodes := Value; + Invalidate; + end; +end; + +end. diff --git a/components/jvcllaz/run/JvWizard/jvwizardroutemapsteps.pas b/components/jvcllaz/run/JvWizard/jvwizardroutemapsteps.pas new file mode 100644 index 000000000..54a7a51ea --- /dev/null +++ b/components/jvcllaz/run/JvWizard/jvwizardroutemapsteps.pas @@ -0,0 +1,459 @@ +{----------------------------------------------------------------------------- +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/MPL-1.1.html + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: JvWizardRouteMapSteps.PAS, released on 2002-02-11. + +The Initial Developer of the Original Code is Max Evans. +Portions created by Max Evans are Copyright (C) 2002 Max Evans + +Contributor(s): +MichaÅ‚ Gawrycki - Lazarus port (2019) + +You may retrieve the latest version of this file at the Project JEDI's JVCL home page, +located at http://jvcl.delphi-jedi.org + +Purpose: + Step style route map for TJvWizardRouteMap + +History: + +Known Issues: +-----------------------------------------------------------------------------} +// $Id$ + +unit JvWizardRouteMapSteps; + +{$mode objfpc} +{$H+} + +interface + +uses + Types, SysUtils, Classes, Graphics, Controls, Forms, LCLIntf, LCLType, + JvWizard; + +type + TJvWizardRouteMapSteps = class(TJvWizardRouteMapControl) + private + FIndent: Integer; + FNextStepText: string; + FActiveStepFormat: string; + FPreviousStepText: string; + FShowDivider: Boolean; + FShowNavigators: Boolean; + FShowNavigation: Boolean; + FMultiline: Boolean; + function GetActiveStepRect: TRect; + function GetPreviousStepRect: TRect; + function GetNextStepRect: TRect; + function GetPreviousArrowRect: TRect; + function GetNextArrowRect: TRect; + procedure SetIndent(const Value: Integer); + procedure SetNextStepText(const Value: string); + procedure SetActiveStepFormat(const Value: string); + procedure SetPreviousStepText(const Value: string); + procedure SetShowDivider(const Value: Boolean); + procedure SetShowNavigators(const Value: Boolean); + function DetectPageCount(var ActivePageIndex: Integer): Integer; // Add by Yu Wei + function DetectPage(const Pt: TPoint): TJvWizardCustomPage; // Add by Yu Wei + function StoreActiveStepFormat: Boolean; + function StoreNextStepText: Boolean; + function StorePreviousStepText: Boolean; + procedure SetShowNavigation(const Value: Boolean); + procedure SetMultiline(const Value: Boolean); + protected + procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; + function PageAtPos(Pt: TPoint): TJvWizardCustomPage; override; + procedure Paint; override; + public + constructor Create(AOwner: TComponent); override; + published + property Color default clBackground; + property Font; + property Image; + property Indent: Integer read FIndent write SetIndent default 5; + property PreviousStepText: string read FPreviousStepText write SetPreviousStepText stored StorePreviousStepText; + property ActiveStepFormat: string read FActiveStepFormat write SetActiveStepFormat stored StoreActiveStepFormat; + property Multiline: Boolean read FMultiline write SetMultiline default False; + property NextStepText: string read FNextStepText write SetNextStepText stored StoreNextStepText; + property ShowDivider: Boolean read FShowDivider write SetShowDivider default True; + property ShowNavigators: Boolean read FShowNavigators write SetShowNavigators default True; + property ShowNavigation: Boolean read FShowNavigation write SetShowNavigation default True; + end; + +implementation + +uses + JvResources; + +constructor TJvWizardRouteMapSteps.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FIndent := 5; + Color := clBackground; + Font.Color := clWhite; + FPreviousStepText := RsBackTo; + FActiveStepFormat := RsActiveStepFormat; + FNextStepText := RsNextStep; + FShowDivider := True; + FShowNavigators := True; + FShowNavigation := True; +end; + +function TJvWizardRouteMapSteps.DetectPage(const Pt: TPoint): TJvWizardCustomPage; +begin + if FShowNavigators then + begin + // Ignore all disabled pages at run time. + if PtInRect(GetPreviousArrowRect, Pt) then + begin + if (PageIndex < Wizard.PageCount) and (PageIndex > 0) and + not ((csDesigning in ComponentState) or (bkBack in Wizard.WizardPages[PageIndex].EnabledButtons)) then + Result := nil + else + Result := Wizard.FindNextPage(PageIndex, -1, not (csDesigning in ComponentState)); + end + else + if PtInRect(GetNextArrowRect, Pt) then + begin + if (PageIndex < Wizard.PageCount) and (PageIndex > 0) and + not ((csDesigning in ComponentState) or (bkNext in Wizard.WizardPages[PageIndex].EnabledButtons)) then + Result := nil + else + Result := Wizard.FindNextPage(PageIndex, 1, not (csDesigning in ComponentState)); + end + else + Result := nil; + end + else + begin + Result := nil; + end; +end; + +function TJvWizardRouteMapSteps.GetActiveStepRect: TRect; +begin + Result := Rect(Left + FIndent, (ClientHeight div 2 - Canvas.TextHeight('Wq')), + Width, ClientHeight div 2); +end; + +function TJvWizardRouteMapSteps.GetNextArrowRect: TRect; +begin + Result := Rect(Left + FIndent, Height - Indent - 32, Left + FIndent + 16, + (Height - FIndent) - 16); +end; + +function TJvWizardRouteMapSteps.GetNextStepRect: TRect; +begin + Result := Rect(Left + FIndent, Height - FIndent - 32, Width, + Height - FIndent - 32 + Canvas.TextHeight('Wq')); +end; + +function TJvWizardRouteMapSteps.DetectPageCount(var ActivePageIndex: Integer): Integer; +var + I: Integer; +begin + // Ignore all disabled pages at run time. + ActivePageIndex := 0; + Result := 0; + for I := 0 to PageCount - 1 do + begin + if (csDesigning in ComponentState) or Pages[I].Enabled then + begin + if I <= PageIndex then + Inc(ActivePageIndex); + Inc(Result); + end; + end; +end; + +function TJvWizardRouteMapSteps.GetPreviousArrowRect: TRect; +begin + Result := Rect(Left + FIndent, Top + FIndent, Left + FIndent + 16, + Top + FIndent + 16); +end; + +function TJvWizardRouteMapSteps.GetPreviousStepRect: TRect; +begin + Result := Rect(Left + FIndent, Top + FIndent, Width, + Top + FIndent + Canvas.TextHeight('Wq')); +end; + +procedure TJvWizardRouteMapSteps.MouseMove(Shift: TShiftState; X, Y: Integer); +var + Pt: TPoint; + APage: TJvWizardCustomPage; +begin + inherited MouseMove(Shift, X, Y); + if ShowNavigators and not (csDesigning in ComponentState) then + begin + Pt := Point(X, Y); + if PtInRect(ClientRect, Pt) then + begin + APage := DetectPage(Pt); + if Assigned(APage) then + Screen.Cursor := crHandPoint + else + Screen.Cursor := crDefault; + end + else + if Screen.Cursor = crHandPoint then + Screen.Cursor := crDefault; + end; +end; + +function TJvWizardRouteMapSteps.PageAtPos(Pt: TPoint): TJvWizardCustomPage; +begin + Result := DetectPage(Pt); +end; + +procedure TJvWizardRouteMapSteps.Paint; +var + LRect, TextRect, ArrowRect, DividerRect: TRect; + ActivePageIndex, TotalPageCount: Integer; + StepHeight: Integer; + APage: TJvWizardCustomPage; + S: string; + LDrawProperties: Cardinal; +begin + LRect := ClientRect; + TotalPageCount := DetectPageCount(ActivePageIndex); + Canvas.Brush.Color := Color; + if HasPicture then + Image.PaintTo(Canvas, LRect); + + TextRect := GetActiveStepRect; + LRect := TextRect; //Rect(TextRect.TopLeft, TextRect.BottomRight); + Canvas.Font.Assign(Font); + Canvas.Font.Style := [fsBold]; + Canvas.Brush.Style := bsClear; + + if Multiline then + begin + S := Pages[PageIndex].Caption; + Canvas.Font.Style := []; + StepHeight := DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, + DT_CALCRECT or DT_LEFT or DT_WORDBREAK); + TextRect.Right := LRect.Right; + OffsetRect(TextRect, 0, Round((-0.5) * StepHeight + Canvas.TextHeight('Wq'))); + end; + + Canvas.Font.Style := [fsBold]; + S := Format(ActiveStepFormat, [ActivePageIndex, TotalPageCount]); + if Multiline then + begin + LDrawProperties := DT_LEFT or DT_WORDBREAK; + end + else + begin + LDrawProperties := DT_LEFT or DT_SINGLELINE or DT_END_ELLIPSIS or DT_VCENTER; + end; + StepHeight := DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, + LDrawProperties); + + // Display Active Page Description + Canvas.Font.Style := []; + OffsetRect(TextRect, 0, StepHeight); + S := Pages[PageIndex].Caption; + if Multiline then + begin + LDrawProperties := DT_LEFT or DT_WORDBREAK; + end + else + begin + LDrawProperties := DT_LEFT or DT_SINGLELINE or DT_END_ELLIPSIS or DT_VCENTER; + end; + DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, LDrawProperties); + + Canvas.Font.Style := []; + if Self.ShowDivider then + begin + SetRect(DividerRect, Left + Indent, TextRect.Bottom + 5, Width - Indent, + TextRect.Bottom + 6); + DrawEdge(Canvas.Handle, DividerRect, EDGE_RAISED, BF_FLAT or BF_BOTTOM); + end; + + { do the previous step } + + // YW - Ignore all disabled pages at run time + APage := Wizard.FindNextPage(PageIndex, -1, not (csDesigning in ComponentState)); + if Assigned(APage) and (PageIndex <> -1) and ShowNavigation then + begin + TextRect := GetPreviousStepRect; + ArrowRect := GetPreviousArrowRect; + Canvas.Font.Style := []; + if ShowNavigators then + begin + if TextRect.Left + Indent + ArrowRect.Right - ArrowRect.Left < Width then + OffsetRect(TextRect, ArrowRect.Right, 0); + if (csDesigning in ComponentState) or (bkBack in Wizard.WizardPages[PageIndex].EnabledButtons) then + DrawFrameControl(Canvas.Handle, ArrowRect, DFC_SCROLL, + DFCS_SCROLLLEFT or DFCS_FLAT); + end; + + S := PreviousStepText; + StepHeight := DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, + DT_LEFT or DT_WORDBREAK or DT_END_ELLIPSIS); + + OffsetRect(TextRect, 0, StepHeight); + S := APage.Caption; + if Multiline then + begin + DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, + DT_CALCRECT or DT_LEFT or DT_WORDBREAK); + TextRect.Right := LRect.Right; + + LDrawProperties := DT_LEFT or DT_WORDBREAK; + end + else + begin + LDrawProperties := DT_SINGLELINE or DT_LEFT or DT_END_ELLIPSIS or DT_VCENTER; + end; + DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, LDrawProperties); + end; + + { do the next step } + + // YW - Ignore all disabled pages at run time + APage := Wizard.FindNextPage(PageIndex, 1, not (csDesigning in ComponentState)); + if Assigned(APage) and (PageIndex <> -1) and ShowNavigation then + begin + TextRect := GetNextStepRect; + ArrowRect := GetNextArrowRect; + Canvas.Font.Style := []; + if ShowNavigators then + begin + OffsetRect(TextRect, ArrowRect.Right, 0); + if (csDesigning in ComponentState) or (bkNext in Wizard.WizardPages[PageIndex].EnabledButtons) then + DrawFrameControl(Canvas.Handle, ArrowRect, DFC_SCROLL, + DFCS_SCROLLRIGHT or DFCS_FLAT); + end; + + if Multiline then + begin + S := APage.Caption; + StepHeight := DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, + DT_CALCRECT or DT_LEFT or DT_WORDBREAK); + TextRect.Right := LRect.Right; + OffsetRect(TextRect, 0, (-1) * StepHeight + Canvas.TextHeight('Wq')); + end; + + S := NextStepText; + StepHeight := DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, + DT_LEFT or DT_WORDBREAK); + + OffsetRect(TextRect, 0, StepHeight); + S := APage.Caption; + if Multiline then + begin + DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, + DT_CALCRECT or DT_LEFT or DT_WORDBREAK); + TextRect.Right := LRect.Right; + + LDrawProperties := DT_LEFT or DT_WORDBREAK; + end + else + begin + LDrawProperties := DT_SINGLELINE or DT_LEFT or DT_END_ELLIPSIS or DT_VCENTER; + end; + DrawText(Canvas.Handle, PChar(S), Length(S), TextRect, LDrawProperties); + end; +end; + +procedure TJvWizardRouteMapSteps.SetShowDivider(const Value: Boolean); +begin + if FShowDivider <> Value then + begin + FShowDivider := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapSteps.SetIndent(const Value: Integer); +begin + if FIndent <> Value then + begin + FIndent := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapSteps.SetMultiline(const Value: Boolean); +begin + if FMultiline <> Value then + begin + FMultiline := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapSteps.SetNextStepText(const Value: string); +begin + if FNextStepText <> Value then + begin + FNextStepText := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapSteps.SetActiveStepFormat(const Value: string); +begin + if FActiveStepFormat <> Value then + begin + FActiveStepFormat := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapSteps.SetPreviousStepText(const Value: string); +begin + if FPreviousStepText <> Value then + begin + FPreviousStepText := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapSteps.SetShowNavigators(const Value: Boolean); +begin + if FShowNavigators <> Value then + begin + if Screen.Cursor = crHandPoint then + Screen.Cursor := crDefault; + FShowNavigators := Value; + Invalidate; + end; +end; + +procedure TJvWizardRouteMapSteps.SetShowNavigation(const Value: Boolean); +begin + if Value <> FShowNavigation then + begin + FShowNavigation := Value; + Invalidate; + end; +end; + +function TJvWizardRouteMapSteps.StoreActiveStepFormat: Boolean; +begin + Result := ActiveStepFormat <> RsActiveStepFormat; +end; + +function TJvWizardRouteMapSteps.StoreNextStepText: Boolean; +begin + Result := NextStepText <> RsNextStep; +end; + +function TJvWizardRouteMapSteps.StorePreviousStepText: Boolean; +begin + Result := PreviousStepText <> RsBackTo; +end; + +end.