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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 |
+ | Chris Macksey |
+ | Wayne Niddery |
+ | Raymond J. Schappe |
+ | Theodore |
+ | Max Evans |
+ +---------------------------------------------------------------------------+
+ | 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 : |
+ | 1) ModalResult property is added for TJvWizardButton |
+ | 2) Width property is added for TJvWizardButton |
+ | |
+ | 02/12/2002 1) Suggested by : |
+ | 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 : |
+ | 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 : |
+ | 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 : |
+ | 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 : SelectPriorPage calls |
+ | OnSelectFirstPage event rather the OnSelectPriorPage. |
+ | 2) Suggested by : |
+ | FromPage parameters added for OnEnterPage event, |
+ | so the developers can detect from where it enters. |
+ | 3) Suggested by : |
+ | ToPage paramters added for OnExitPage event, so the |
+ | developers can detect to where it exits. |
+ | 4) Suggested by : |
+ | 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 |
+ | 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 |
+ | , 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 : |
+ | 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 for his great job !!!! |
+ | |
+ | 1) Move OnEnterPage, OnPage, OnExitPage event from TJvWizard |
+ | into TJvWizardCustomPage. |
+ | 2) TJvWizardPagePanel added, suggested by . |
+ | 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 . |
+ | 7) Handle Design time package and Run time package, |
+ | package file name convenstion suggested by |
+ | : |
+ | 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 |
+ | |
+ | 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 : |
+ | |
+ | 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 : |
+ | 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.