';
+ end;
+end;
+
+function SheetFuncName(AIndex: Word): String;
+begin
+ case AIndex of
+ 0 : result := 'COUNT';
+ 1 : Result := 'IF';
+ 2 : Result := 'ISNA';
+ 3 : Result := 'ISERROR';
+ 4 : Result := 'SUM';
+ 5 : Result := 'AVERAGE';
+ 6 : Result := 'MIN';
+ 7 : Result := 'MAX';
+ 8 : Result := 'ROW';
+ 9 : Result := 'COLUMN';
+ 10 : Result := 'NA';
+ 11 : Result := 'NPV';
+ 12 : Result := 'STDEV';
+ 13 : Result := 'DOLLAR';
+ 14 : Result := 'FIXED';
+ 15 : Result := 'SIN';
+ 16 : Result := 'COS';
+ 17 : Result := 'TAN';
+ 18 : Result := 'ATAN';
+ 19 : Result := 'PI';
+ 20 : Result := 'SQRT';
+ 21 : Result := 'EXP';
+ 22 : Result := 'LN';
+ 23 : Result := 'LOG10';
+ 24 : Result := 'ABS';
+ 25 : Result := 'INT';
+ 26 : Result := 'SIGN';
+ 27 : Result := 'ROUND';
+ 28 : Result := 'LOOKUP';
+ 29 : Result := 'INDEX';
+ 30 : Result := 'REPT';
+ 31 : Result := 'MID';
+ 32 : Result := 'LEN';
+ 33 : Result := 'VALUE';
+ 34 : Result := 'TRUE';
+ 35 : Result := 'FALSE';
+ 36 : Result := 'AND';
+ 37 : Result := 'OR';
+ 38 : Result := 'NOT';
+ 39 : Result := 'MOD';
+ 40 : Result := 'DCOUNT';
+ 41 : Result := 'DSUM';
+ 42 : Result := 'DAVERAGE';
+ 43 : Result := 'DMIN';
+ 44 : Result := 'DMAX';
+ 45 : Result := 'DSTDEV';
+ 46 : Result := 'VAR';
+ 47 : Result := 'DVAR';
+ 48 : Result := 'TEXT';
+ 49 : Result := 'LINEST';
+ 50 : Result := 'TREND';
+ 51 : Result := 'LOGEST';
+ 52 : Result := 'GROWTH';
+ 56 : Result := 'PV';
+ 57 : Result := 'FV';
+ 58 : Result := 'NPER';
+ 59 : Result := 'PMT';
+ 60 : Result := 'RATE';
+ 61 : Result := 'MIRR';
+ 62 : Result := 'IRR';
+ 63 : Result := 'RAND';
+ 64 : Result := 'MATCH';
+ 65 : Result := 'DATE';
+ 66 : Result := 'TIME';
+ 67 : Result := 'DAY';
+ 68 : Result := 'MONTH';
+ 69 : Result := 'YEAR';
+ 70 : Result := 'WEEKDAY';
+ 71 : Result := 'HOUR';
+ 72 : Result := 'MINUTE';
+ 73 : Result := 'SECOND';
+ 74 : Result := 'NOW';
+ 75 : Result := 'AREAS';
+ 76 : Result := 'ROWS';
+ 77 : Result := 'COLUMNS';
+ 78 : Result := 'OFFSET';
+ 82 : Result := 'SEARCH';
+ 83 : Result := 'TRANSPOSE';
+ 86 : Result := 'TYPE';
+ 97 : Result := 'ATAN2';
+ 98 : Result := 'ASIN';
+ 99 : Result := 'ACOS';
+ 100 : Result := 'CHOOSE';
+ 101 : Result := 'HLOOKUP';
+ 102 : Result := 'VLOOKUP';
+ 105 : Result := 'ISREF';
+ 109 : Result := 'LOG';
+ 111 : Result := 'CHAR';
+ 112 : Result := 'LOWER';
+ 113 : Result := 'UPPER';
+ 114 : Result := 'PROPER';
+ 115 : Result := 'LEFT';
+ 116 : Result := 'RIGHT';
+ 117 : Result := 'EXACT';
+ 118 : Result := 'TRIM';
+ 119 : Result := 'REPLACE';
+ 120 : Result := 'SUBSTITUTE';
+ 121 : Result := 'CODE';
+ 124 : Result := 'FIND';
+ 125 : Result := 'CELL';
+ 126 : Result := 'ISERR';
+ 127 : Result := 'ISTEXT';
+ 128 : Result := 'ISNUMBER';
+ 129 : Result := 'ISBLANK';
+ 130 : Result := 'T';
+ 131 : Result := 'N';
+ 140 : Result := 'DATEVALUE';
+ 141 : Result := 'TIMEVALUE';
+ 142 : Result := 'SLN';
+ 143 : Result := 'SYD';
+ 144 : Result := 'DDB';
+ 148 : Result := 'INDIRECT';
+ 162 : Result := 'CLEAN';
+ 163 : Result := 'MDETERM';
+ 164 : Result := 'MINVERSE';
+ 165 : Result := 'MMULT';
+ 167 : Result := 'IPMT';
+ 168 : Result := 'PPMT';
+ 169 : Result := 'COUNTA';
+ 183 : Result := 'PRODUCT';
+ 184 : Result := 'FACT';
+ 189 : Result := 'DPRODUCT';
+ 190 : Result := 'ISNONTEXT';
+ 193 : Result := 'STDEVP';
+ 194 : Result := 'VARP';
+ 195 : Result := 'DSTDEVP';
+ 196 : Result := 'DVARP';
+ 197 : Result := 'TRUNC';
+ 198 : Result := 'ISLOGICAL';
+ 199 : Result := 'DCOUNTA';
+ 204 : Result := 'YEN/USDOLLAR';
+ 205 : Result := 'FINDB';
+ 206 : Result := 'SEARCHB';
+ 207 : Result := 'REPLACEB';
+ 208 : Result := 'LEFTB';
+ 209 : Result := 'RIGHTB';
+ 210 : Result := 'MIDB';
+ 211 : Result := 'LENB';
+ 212 : Result := 'ROUNDUP';
+ 213 : Result := 'ROUNDDOWN';
+ 214 : Result := 'ASC';
+ 215 : Result := 'JIS / DBCS';
+ 216 : Result := 'RANK';
+ 219 : Result := 'ADDRESS';
+ 220 : Result := 'DAYS360';
+ 221 : Result := 'TODAY';
+ 222 : Result := 'VDB';
+ 227 : Result := 'MEDIAN';
+ 228 : Result := 'SUMPRODUCT';
+ 229 : Result := 'SINH';
+ 230 : Result := 'COSH';
+ 231 : Result := 'TANH';
+ 232 : Result := 'ASINH';
+ 233 : Result := 'ACOSH';
+ 234 : Result := 'ATANH';
+ 235 : Result := 'DGET';
+ 244 : Result := 'INFO';
+ 247 : Result := 'DB';
+ 252 : Result := 'FREQUENCY';
+ 261 : Result := 'ERROR.TYPE';
+ 269 : Result := 'AVEDEV';
+ 270 : Result := 'BETADIST';
+ 271 : Result := 'GAMMALN';
+ 272 : Result := 'BETAINV';
+ 273 : Result := 'BINOMDIST';
+ 274 : Result := 'CHIDIST';
+ 275 : Result := 'CHIINV';
+ 276 : Result := 'COMBIN';
+ 277 : Result := 'CONFIDENCE';
+ 278 : Result := 'CRITBINOM';
+ 279 : Result := 'EVEN';
+ 280 : Result := 'EXPONDIST';
+ 281 : Result := 'FDIST';
+ 282 : Result := 'FINV';
+ 283 : Result := 'FISHER';
+ 284 : Result := 'FISHERINV';
+ 285 : Result := 'FLOOR';
+ 286 : Result := 'GAMMADIST';
+ 287 : Result := 'GAMMAINV';
+ 288 : Result := 'CEILING';
+ 289 : Result := 'HYPGEOMDIST';
+ 290 : Result := 'LOGNORMDIST';
+ 291 : Result := 'LOGINV';
+ 292 : Result := 'NEGBINOMDIST';
+ 293 : Result := 'NORMDIST';
+ 294 : Result := 'NORMSDIST';
+ 295 : Result := 'NORMINV';
+ 296 : Result := 'NORMSINV';
+ 297 : Result := 'STANDARDIZE';
+ 298 : Result := 'ODD';
+ 299 : Result := 'PERMUT';
+ 300 : Result := 'POISSON';
+ 301 : Result := 'TDIST';
+ 302 : Result := 'WEIBULL';
+ 303 : Result := 'SUMXMY2';
+ 304 : Result := 'SUMX2MY2';
+ 305 : Result := 'SUMX2PY2';
+ 306 : Result := 'CHITEST';
+ 307 : Result := 'CORREL';
+ 308 : Result := 'COVAR';
+ 309 : Result := 'FORECAST';
+ 310 : Result := 'FTEST';
+ 311 : Result := 'INTERCEPT';
+ 312 : Result := 'PEARSON';
+ 313 : Result := 'RSQ';
+ 314 : Result := 'STEYX';
+ 315 : Result := 'SLOPE';
+ 316 : Result := 'TTEST';
+ 317 : Result := 'PROB';
+ 318 : Result := 'DEVSQ';
+ 319 : Result := 'GEOMEAN';
+ 320 : Result := 'HARMEAN';
+ 321 : Result := 'SUMSQ';
+ 322 : Result := 'KURT';
+ 323 : Result := 'SKEW';
+ 324 : Result := 'ZTEST';
+ 325 : Result := 'LARGE';
+ 326 : Result := 'SMALL';
+ 327 : Result := 'QUARTILE';
+ 328 : Result := 'PERCENTILE';
+ 329 : Result := 'PERCENTRANK';
+ 330 : Result := 'MODE';
+ 331 : Result := 'TRIMMEAN';
+ 332 : Result := 'TINV';
+ 336 : Result := 'CONCATENATE';
+ 337 : Result := 'POWER';
+ 342 : Result := 'RADIANS';
+ 343 : Result := 'DEGREES';
+ 344 : Result := 'SUBTOTAL';
+ 345 : Result := 'SUMIF';
+ 346 : Result := 'COUNTIF';
+ 347 : Result := 'COUNTBLANK';
+ 350 : Result := 'ISPMT';
+ 351 : Result := 'DATEDIF';
+ 352 : Result := 'DATESTRING';
+ 353 : Result := 'NUMBERSTRING';
+ 354 : Result := 'ROMAN';
+ 358 : Result := 'GETPIVOTDATA';
+ 359 : Result := 'HYPERLINK';
+ 360 : Result := 'PHONETIC';
+ 361 : Result := 'AVERAGEA';
+ 362 : Result := 'MAXA';
+ 363 : Result := 'MINA';
+ 364 : Result := 'STDEVPA';
+ 365 : Result := 'VARPA';
+ 366 : Result := 'STDEVA';
+ 367 : Result := 'VARA';
+ else Result := 'unknown';
+ end;
+end;
+
+end.
+
diff --git a/components/fpspreadsheet/reference/BIFFExplorer/behtml.pas b/components/fpspreadsheet/reference/BIFFExplorer/behtml.pas
new file mode 100644
index 000000000..71f255619
--- /dev/null
+++ b/components/fpspreadsheet/reference/BIFFExplorer/behtml.pas
@@ -0,0 +1,245 @@
+unit beHTML;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, Graphics;
+
+type
+ THTMLHeader = (h1, h2, h3, h4, h5);
+ THeaderColors = Array[THTMLHeader] of TColor;
+
+ THTMLDocument = class
+ private
+ FLines: TStrings;
+ FRawMode: Boolean;
+ FIndent: Integer;
+ function Indent: String;
+ function Raw(const AText: String): String;
+ function ColorToHTML(AColor: TColor): String;
+ public
+ constructor Create;
+ destructor Destroy; override;
+ procedure AddEmptyLine;
+ procedure AddListItem(const AText: String);
+ procedure AddHeader(AHeader: THTMLHeader; const AText: String);
+ procedure AddParagraph(const AText: String);
+ procedure BeginDocument(const ATitle: String; const AHeaderColors: THeaderColors;
+ ARawMode: Boolean=false);
+ procedure BeginBulletList;
+ procedure BeginNumberedList;
+ function Bold(const AText: String): String;
+ procedure EndDocument;
+ procedure EndBulletList;
+ procedure EndNumberedList;
+ function Hyperlink(const AText, ALink: String): String;
+ function Italic(const AText: String): String;
+ property Lines: TStrings read FLines;
+ end;
+
+implementation
+
+uses
+ StrUtils, LCLIntf;
+
+constructor THTMLDocument.Create;
+begin
+ inherited;
+ FLines := TStringList.Create;
+end;
+
+destructor THTMLDocument.Destroy;
+begin
+ FLines.Free;
+ inherited;
+end;
+
+procedure THTMLDocument.AddHeader(AHeader: THTMLHeader; const AText: String);
+begin
+ if FRawMode then
+ FLines.Add(Raw(AText))
+ else
+ FLines.Add(Format('%s%s', [Indent, ord(AHeader)+1, AText, ord(AHeader)+1]));
+end;
+
+ (*
+
+
+
+
+
+
+Title appears in the browser's title bar...
+
+
+
+
+
+Heading goes here...
+Enter your paragraph text here...
+
+
+ *)
+
+procedure THTMLDocument.BeginDocument(const ATitle: String;
+ const AHeaderColors: THeaderColors; ARawMode: Boolean = false);
+begin
+ FRawMode := ARawMode;
+ FLines.Clear;
+ if not FRawMode then begin
+ FLines.Add('');
+ FLines.Add('');
+ FLines.Add(' ');
+ FLines.Add(' ');
+ FLines.Add(' ' + ATitle + '');
+ FLines.Add(' ');
+ FLines.Add(' ');
+ FLines.Add(' ');
+ FIndent := 4;
+ end;
+end;
+
+procedure THTMLDocument.BeginBulletList;
+begin
+ if not FRawMode then begin
+ FLines.Add(Indent + '');
+ inc(FIndent, 2);
+ end;
+end;
+
+procedure THTMLDocument.BeginNumberedList;
+begin
+ if not FRawMode then begin
+ FLines.Add(Indent + '');
+ inc(FIndent, 2);
+ end;
+end;
+
+procedure THTMLDocument.AddEmptyLine;
+begin
+ if FRawMode then
+ FLines.Add('')
+ else
+ FLines.Add('
');
+end;
+
+procedure THTMLDocument.AddListItem(const AText: String);
+begin
+ if FRawMode then
+ FLines.Add('- ' + Raw(AText))
+ else
+ FLines.Add(Indent + '- ' + AText + '
');
+end;
+
+procedure THTMLDocument.AddParagraph(const AText: String);
+begin
+ if FRawMode then
+ FLines.Add(Raw(AText))
+ else
+ FLines.Add(Indent + '' + AText + '
');
+end;
+
+function THTMLDocument.Bold(const AText: String): String;
+begin
+ if FRawMode then
+ Result := AText
+ else
+ Result := '' + AText + '';
+end;
+
+function THTMLDocument.ColorToHTML(AColor: TColor): String;
+var
+ tmpRGB: LongInt;
+begin
+ tmpRGB := ColorToRGB(AColor) ;
+ Result := Format('#%.2x%.2x%.2x', [
+ GetRValue(tmpRGB),
+ GetGValue(tmpRGB),
+ GetBValue(tmpRGB)
+ ]) ;
+end;
+
+procedure THTMLDocument.EndDocument;
+begin
+ if not FRawMode then begin
+ FLines.Add(' ');
+ FLines.Add('');
+ end;
+end;
+
+procedure THTMLDocument.EndBulletList;
+begin
+ if not FRawMode then begin
+ dec(FIndent, 2);
+ FLines.Add(Indent + '
');
+ end;
+end;
+
+procedure THTMLDocument.EndNumberedList;
+begin
+ if not FRawMode then begin
+ dec(FIndent, 2);
+ FLines.Add(Indent + '');
+ end;
+end;
+
+function THTMLDocument.Hyperlink(const AText, ALink: String): String;
+begin
+ if FRawMode then
+ Result := Format('%s (%s)', [AText, ALink])
+ else
+ Result := Format('%s', [ALink, AText]);
+end;
+
+function THTMLDocument.Indent: String;
+begin
+ Result := DupeString(' ', FIndent);
+end;
+
+function THTMLDocument.Italic(const AText: String): String;
+begin
+ if FRawMode then
+ Result := AText
+ else
+ Result := '' + AText + '';
+end;
+
+function THTMLDocument.Raw(const AText: String): String;
+var
+ i, n: Integer;
+begin
+ Result := '';
+ if AText = '' then
+ exit;
+ n := Length(AText);
+ i := 1;
+ while (i <= n) do begin
+ if AText[i] = '<' then
+ repeat
+ inc(i);
+ until (i = n) or (AText[i] = '>')
+ else
+ Result := Result + AText[i];
+ inc(i);
+ end;
+end;
+
+end.
+
diff --git a/components/fpspreadsheet/reference/BIFFExplorer/bemain.lfm b/components/fpspreadsheet/reference/BIFFExplorer/bemain.lfm
new file mode 100644
index 000000000..3afa0069b
--- /dev/null
+++ b/components/fpspreadsheet/reference/BIFFExplorer/bemain.lfm
@@ -0,0 +1,1255 @@
+object MainForm: TMainForm
+ Left = 352
+ Height = 576
+ Top = 177
+ Width = 1089
+ Caption = 'BIFF Explorer'
+ ClientHeight = 556
+ ClientWidth = 1089
+ Menu = MainMenu
+ OnCloseQuery = FormCloseQuery
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ OnShow = FormShow
+ ShowHint = True
+ LCLVersion = '1.3'
+ object Splitter1: TSplitter
+ Left = 419
+ Height = 507
+ Top = 26
+ Width = 5
+ end
+ object ToolBar: TToolBar
+ Left = 0
+ Height = 26
+ Top = 0
+ Width = 1089
+ Caption = 'ToolBar'
+ Images = ImageList
+ TabOrder = 1
+ object ToolButton1: TToolButton
+ Left = 1
+ Top = 2
+ Action = AcFileOpen
+ DropdownMenu = RecentFilesPopupMenu
+ Style = tbsDropDown
+ end
+ object ToolButton2: TToolButton
+ Left = 64
+ Top = 2
+ Action = AcFileQuit
+ end
+ object ToolButton3: TToolButton
+ Left = 36
+ Top = 2
+ Action = AcFind
+ end
+ object ToolButton4: TToolButton
+ Left = 59
+ Top = 2
+ Width = 5
+ Caption = 'ToolButton4'
+ Style = tbsDivider
+ end
+ end
+ object DetailPanel: TPanel
+ Left = 424
+ Height = 507
+ Top = 26
+ Width = 665
+ Align = alClient
+ BevelOuter = bvNone
+ ClientHeight = 507
+ ClientWidth = 665
+ TabOrder = 2
+ object HexSplitter: TSplitter
+ Cursor = crVSplit
+ Left = 0
+ Height = 5
+ Top = 244
+ Width = 665
+ Align = alBottom
+ ResizeAnchor = akBottom
+ end
+ object HexPanel: TPanel
+ Left = 0
+ Height = 244
+ Top = 0
+ Width = 665
+ Align = alClient
+ Caption = 'HexPanel'
+ ClientHeight = 244
+ ClientWidth = 665
+ TabOrder = 1
+ object HexGrid: TStringGrid
+ Left = 1
+ Height = 242
+ Top = 1
+ Width = 398
+ Align = alClient
+ AutoFillColumns = True
+ ColCount = 17
+ DefaultColWidth = 28
+ ExtendedSelect = False
+ Options = [goFixedVertLine, goFixedHorzLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goThumbTracking, goSmoothScroll]
+ ParentFont = False
+ TabOrder = 0
+ TitleStyle = tsNative
+ OnClick = GridClick
+ OnPrepareCanvas = HexGridPrepareCanvas
+ OnSelection = HexGridSelection
+ ColWidths = (
+ 28
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 22
+ 36
+ )
+ Cells = (
+ 16
+ 1
+ 0
+ '0'
+ 2
+ 0
+ '1'
+ 3
+ 0
+ '2'
+ 4
+ 0
+ '3'
+ 5
+ 0
+ '4'
+ 6
+ 0
+ '5'
+ 7
+ 0
+ '6'
+ 8
+ 0
+ '7'
+ 9
+ 0
+ '8'
+ 10
+ 0
+ '9'
+ 11
+ 0
+ '10'
+ 12
+ 0
+ '11'
+ 13
+ 0
+ '12'
+ 14
+ 0
+ '13'
+ 15
+ 0
+ '14'
+ 16
+ 0
+ '15'
+ )
+ end
+ object AlphaGrid: TStringGrid
+ Left = 404
+ Height = 242
+ Top = 1
+ Width = 260
+ Align = alRight
+ AutoFillColumns = True
+ ColCount = 16
+ FixedCols = 0
+ Options = [goFixedVertLine, goFixedHorzLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goThumbTracking, goSmoothScroll]
+ ParentFont = False
+ TabOrder = 1
+ TitleStyle = tsNative
+ OnClick = GridClick
+ OnSelection = AlphaGridSelection
+ ColWidths = (
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ 16
+ )
+ Cells = (
+ 16
+ 0
+ 0
+ '0'
+ 1
+ 0
+ '1'
+ 2
+ 0
+ '2'
+ 3
+ 0
+ '3'
+ 4
+ 0
+ '4'
+ 5
+ 0
+ '5'
+ 6
+ 0
+ '6'
+ 7
+ 0
+ '7'
+ 8
+ 0
+ '8'
+ 9
+ 0
+ '9'
+ 10
+ 0
+ 'A'
+ 11
+ 0
+ 'B'
+ 12
+ 0
+ 'C'
+ 13
+ 0
+ 'D'
+ 14
+ 0
+ 'E'
+ 15
+ 0
+ 'F'
+ )
+ end
+ object HexDumpSplitter: TSplitter
+ Left = 399
+ Height = 242
+ Top = 1
+ Width = 5
+ Align = alRight
+ ResizeAnchor = akRight
+ end
+ end
+ object PageControl: TPageControl
+ Left = 0
+ Height = 258
+ Top = 249
+ Width = 665
+ ActivePage = PgValues
+ Align = alBottom
+ TabIndex = 1
+ TabOrder = 2
+ OnChange = PageControlChange
+ object PgAnalysis: TTabSheet
+ Caption = 'Analysis'
+ ClientHeight = 230
+ ClientWidth = 657
+ object AnalysisDetails: TMemo
+ Left = 428
+ Height = 230
+ Top = 0
+ Width = 229
+ Align = alRight
+ Font.CharSet = ANSI_CHARSET
+ Font.Height = -12
+ Font.Name = 'Courier New'
+ Font.Pitch = fpFixed
+ Font.Quality = fqDraft
+ ParentFont = False
+ ScrollBars = ssAutoBoth
+ TabOrder = 0
+ WordWrap = False
+ end
+ object DetailsSplitter: TSplitter
+ Left = 423
+ Height = 230
+ Top = 0
+ Width = 5
+ Align = alRight
+ ResizeAnchor = akRight
+ end
+ end
+ object PgValues: TTabSheet
+ Caption = 'Values'
+ ClientHeight = 230
+ ClientWidth = 657
+ object ValueGrid: TStringGrid
+ Left = 0
+ Height = 230
+ Top = 0
+ Width = 657
+ Align = alClient
+ ColCount = 3
+ DefaultColWidth = 100
+ FixedCols = 0
+ Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goColSizing, goSmoothScroll]
+ RowCount = 9
+ TabOrder = 0
+ TitleStyle = tsNative
+ ColWidths = (
+ 112
+ 142
+ 141
+ )
+ Cells = (
+ 3
+ 0
+ 0
+ 'Data type'
+ 1
+ 0
+ 'Value'
+ 2
+ 0
+ 'Offset range'
+ )
+ end
+ end
+ end
+ end
+ object TreePanel: TPanel
+ Left = 0
+ Height = 507
+ Top = 26
+ Width = 419
+ Align = alLeft
+ BevelOuter = bvNone
+ ClientHeight = 507
+ ClientWidth = 419
+ Constraints.MinWidth = 275
+ TabOrder = 3
+ object FindPanel: TPanel
+ Left = 0
+ Height = 36
+ Top = 471
+ Width = 419
+ Align = alBottom
+ BevelOuter = bvNone
+ ClientHeight = 36
+ ClientWidth = 419
+ TabOrder = 0
+ Visible = False
+ object BtnFindNext: TSpeedButton
+ Left = 240
+ Height = 22
+ Hint = 'Find next'
+ Top = 6
+ Width = 23
+ Action = AcFindNext
+ Flat = True
+ Glyph.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E297
+ 3A00D98E3300CB802900BC711D00AE631200A05509159B5005AE9B5005AEA055
+ 0915AE631200BC711D00CB802900D98E3300E2973A00FFFFFF00FFFFFF00E297
+ 3A00D98E3300CB802900BC711D00AE631215A75C0DAED38D19E6D38C18E6A75C
+ 0DAEAE631215BC711D00CB802900D98E3300E2973A00FFFFFF00FFFFFF00E297
+ 3A00D98E3300CB802900BC711D15B56A18AED69737E6F1B436FFF0B130FFD492
+ 2DE6B56A18AEBC711D15CB802900D98E3300E2973A00FFFFFF00FFFFFF00E297
+ 3A00D98E3300CB802915C37923AEDCA553E6E3B25DFFD3953BFFD3953BFFDFA9
+ 52FFD69A45E6C37923AECB802915D98E3300E2973A00FFFFFF00FFFFFF00E297
+ 3A00D98E3315D2872EAEE8B563E6F7CB7FFFEAAF63FFE0A559FFD69B4FFFD195
+ 49FFDDAC60FFDFA553E6D2872EAED98E3315E2973A00FFFFFF00FFFFFF00E297
+ 3A15DF9438AEF0BD69E6FEDE92FFFCD68AFFFCD68AFFFCD68AFFFCD68AFFFCD5
+ 89FFFCD589FFFDDA8EFFEFBA66E6DF9438AEE2973A15FFFFFF00FFFFFF00E69B
+ 3D33E89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D
+ 3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE69B3D33FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ }
+ end
+ object BtnFindPrev: TSpeedButton
+ Left = 216
+ Height = 22
+ Hint = 'Find previous'
+ Top = 6
+ Width = 23
+ Action = AcFindPrev
+ Flat = True
+ Glyph.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF009C51
+ 06999B5005CC9B5005CC9B5005CC9B5005CC9B5005CC9B5005CC9B5005CC9B50
+ 05CC9B5005CC9B5005CC9B5005CC9C510699FFFFFF00FFFFFF00FFFFFF00A55A
+ 0C5CA75C0DCCF9C966FFFAB827FFFBB71CFFFBB518FFFBB414FFFBB311FFFBB2
+ 0FFFFBB20EFFFBB516FFA75C0DCCA55A0C5CFFFFFF00FFFFFF00FFFFFF00A75C
+ 0D00B368175CB56A18CCF8CF80FFE6A53EFFDE9D2FFFDD9C2EFFDD9C2EFFDD9C
+ 2EFFE6AE47FFB56A18CCB368175CA75C0D00FFFFFF00FFFFFF00FFFFFF00A75C
+ 0D00B56A1800C177225CC37923CCFBD98DFFECB367FFE1A75BFFD79C50FFE7BC
+ 70FFC37923CCC177225CB56A1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C
+ 0D00B56A1800C3792300D0852D5CD2872ECCFEE195FFF8C77BFFFDDE92FFD287
+ 2ECCD0852D5CC3792300B56A1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C
+ 0D00B56A1800C3792300D2872E00DE93375CDF9438CCFFE599FFDF9438CCDE93
+ 375CD2872E00C3792300B56A1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C
+ 0D00B56A1800C3792300D2872E00DF943800E79C3E5CE89D3FCCE79C3E5CDF94
+ 3800D2872E00C3792300B56A1800A75C0D00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ }
+ end
+ object SpeedButton3: TSpeedButton
+ Left = 3
+ Height = 22
+ Hint = 'Close "find" panel'
+ Top = 6
+ Width = 23
+ Action = AcFindClose
+ Flat = True
+ Glyph.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00000072000000614800005FCC000061480000720000008200000082000000
+ 72000000614800005FCC0000614800007200FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF0000007548000072CC1111D8FF000072CC0000754800008200000082000000
+ 7548000072CC1111D8FF000072CC00007548FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00000082CC1111D0FF1111D0FF1111D0FF000082CC00008348000083480000
+ 82CC1111D0FF1111D0FF1111D0FF000082CCFFFFFF00FFFFFF00FFFFFF00FFFF
+ FF0000008748000087CC1111C4FF1111C4FF1111C4FF000087CC000087CC1111
+ C4FF1111C4FF1111C4FF000087CC00008748FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF000000870000008C4800008DCC1111B8FF1111B8FF1111B8FF1111B8FF1111
+ B8FF1111B8FF00008DCC00008C4800008700FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF000000870000008D0000009148000092CC1515AFFF1111ACFF1111ACFF1111
+ ACFF000092CC0000914800008D0000008700FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF000000A00000009B0000009848000097CC2525B4FF1111A2FF1111A2FF1414
+ A5FF000097CC0000984800009B000000A000FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF000000A00000009C4800009BCC5353DBFF2E2EB7FF3D3DC6FF3131BAFF1515
+ 9FFF1E1EA8FF00009BCC00009C480000A000FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF000000A1480000A0CC6767EFFF3636BEFF5E5EE6FF0000A0CC0000A0CC4F4F
+ D7FF3636BEFF4545CDFF0000A0CC0000A148FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF000000A3CC7676FEFF4C4CD4FF7272FAFF0000A3CC0000A3480000A3480000
+ A3CC6262EAFF4C4CD4FF5C5CE4FF0000A3CCFFFFFF00FFFFFF00FFFFFF00FFFF
+ FF000000A7480000A7CC7777FFFF0000A7CC0000A7480000A3000000A3000000
+ A7480000A7CC7070F8FF0000A7CC0000A748FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF000000A7000000AA480000AACC0000AA480000A7000000A3000000A3000000
+ A7000000AA480000AACC0000AA480000A700FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ }
+ end
+ object CbFind: TComboBox
+ Left = 28
+ Height = 23
+ Top = 5
+ Width = 183
+ ItemHeight = 15
+ OnChange = CbFindChange
+ OnKeyPress = CbFindKeyPress
+ TabOrder = 0
+ end
+ end
+ object BIFFTree: TVirtualStringTree
+ Left = 0
+ Height = 471
+ Top = 0
+ Width = 419
+ Align = alClient
+ ButtonStyle = bsTriangle
+ DefaultText = 'Node'
+ Header.AutoSizeIndex = 3
+ Header.Columns = <
+ item
+ Alignment = taRightJustify
+ CaptionAlignment = taRightJustify
+ MinWidth = 80
+ Options = [coAllowClick, coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus, coUseCaptionAlignment]
+ Position = 0
+ Text = 'Offset'
+ Width = 80
+ end
+ item
+ Alignment = taCenter
+ MinWidth = 60
+ Position = 1
+ Text = 'Record ID'
+ Width = 80
+ end
+ item
+ MinWidth = 80
+ Position = 2
+ Text = 'Record name'
+ Width = 130
+ end
+ item
+ MinWidth = 80
+ Position = 3
+ Text = 'Record description'
+ Width = 125
+ end>
+ Header.DefaultHeight = 24
+ Header.Height = 24
+ Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible]
+ HintMode = hmTooltip
+ PopupMenu = TreePopupMenu
+ TabOrder = 1
+ TreeOptions.AutoOptions = [toAutoDropExpand, toAutoScrollOnExpand, toAutoSpanColumns, toAutoTristateTracking, toAutoDeleteMovedNodes]
+ TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowRoot, toThemeAware, toUseBlendedImages]
+ TreeOptions.SelectionOptions = [toFullRowSelect]
+ OnBeforeCellPaint = BIFFTreeBeforeCellPaint
+ OnFocusChanged = BIFFTreeFocusChanged
+ OnFreeNode = BIFFTreeFreeNode
+ OnGetText = BIFFTreeGetText
+ OnPaintText = BIFFTreePaintText
+ OnGetNodeDataSize = BIFFTreeGetNodeDataSize
+ end
+ end
+ object StatusBar: TStatusBar
+ Left = 0
+ Height = 23
+ Top = 533
+ Width = 1089
+ Panels = <
+ item
+ Width = 120
+ end
+ item
+ Width = 180
+ end
+ item
+ Width = 150
+ end
+ item
+ Width = 180
+ end>
+ SimplePanel = False
+ end
+ object ImageList: TImageList
+ left = 80
+ top = 64
+ Bitmap = {
+ 4C69090000001000000010000000FFFFFF00FFFFFF000088CC610088CC810088
+ CC810088CC810088CC810088CC810088CC810088CC810088CC810088CC810088
+ CC810088CC610087CB00FFFFFF00FFFFFF00FFFFFF000087CA8388DCF4FF60C0
+ E9FF5FBFEAFF80D3F4FF9CE3FDFFA2E6FFFFA2E6FFFFA2E6FFFFA2E6FFFFA6EA
+ FFFF0087CA830087CA00FFFFFF00FFFFFF00FFFFFF000085C885ACF1FFFFABEF
+ FEFF95E2F8FF6EC9EDFF48A8D9FF98DCFEFF98DCFEFF98DCFEFF98DCFEFFA1E5
+ FFFF0085C8850085C800FFFFFF00FFFFFF00FFFFFF000084C587A9EEFDFFA4E9
+ FCFFA4E9FCFFAAEEFDFF42A1D1FF97DBFDFF97DBFDFF97DBFDFF97DBFDFF9FE3
+ FEFF0084C5870084C500FFFFFF00FFFFFF00FFFFFF000082C28AA6EBFCFFA1E6
+ FBFFA1E6FBFFA6EBFCFF3C9DCFFF96DAFCFF96DAFCFF96DAFCFF96DAFCFF9EE2
+ FDFF0082C28A0082C200FFFFFF00FFFFFF00FFFFFF00007FBF8DA3E8FBFF9DE3
+ F9FF9DE3F9FFA3E8FBFF3594C5FF94D8FAFF94D8FAFF94D8FAFF94D8FAFF9BDF
+ FCFF007FBF8D007FBE00FFFFFF00FFFFFF00FFFFFF00007DBB909EE5F9FF98DF
+ F6FF98DFF6FF9EE5F9FF3290C0FF92D6F8FF92D6F8FF92D6F8FF92D6F8FF99DD
+ FAFF007DBB90007DBB33FFFFFF00FFFFFF00FFFFFF00007BB8949BE1F7FF94DB
+ F4FF94DBF4FF9BE1F7FF308DBCFF90D4F6FF90D4F6FF90D4F6FF90D4F6FF97DB
+ F9FFFEFEFDFF007BB894FFFFFF00FFFFFF00FFFFFF000078B49797DEF6FF90D8
+ F2FF90D8F2FF97DEF6FF2D89B7FF8FD3F5FF8FD3F5FF8FD3F5FF8FD3F5FF95D9
+ F8FFF5F5EEFF0078B497FFFFFF00FFFFFF00FFFFFF000076B09B92DAF4FF8BD4
+ F0FF8BD4F0FF92DAF4FF2B85B3FF8DD1F3FF8DD1F3FF8DD1F3FF8DD1F3FF93D7
+ F6FFEBEBDDFF0076B09BFFFFFF00FFFFFF00FFFFFF000073AC9E8ED6F2FF87D0
+ EDFF87D0EDFF8ED6F2FF2882AFFF8BCFF1FF8BCFF1FF8BCFF1FF8BCFF1FF91D5
+ F5FFFEC941FF0073AC9EFFFFFF00FFFFFF00FFFFFF00006FA7A48AD3F0FF82CD
+ EBFF82CDEBFF8AD3F0FF267EABFF8ACEF0FF8ACEF0FF8ACEF0FF8ACEF0FF8FD3
+ F4FFF4B62EFF006FA7A4FFFFFF00FFFFFF00FFFFFF00006699B287D1EFFF7FCA
+ E9FF7FCAE9FF87D0EFFF267DA9FF8DD1F3FF8DD1F3FF8DD1F3FF8DD1F3FF90D4
+ F5FF006699B200679B3EFFFFFF00FFFFFF00FFFFFF00005E8D8E3591BDF169B8
+ DDFA81CBECFF84CEEEFF005C8BEF005D8CBE005D8CBE005D8CBE005D8CBE005D
+ 8CBE005E8D8E00669900FFFFFF00FFFFFF00FFFFFF00005D8C00006599500064
+ 97991C7AA9C052A5CDE0005B89C1005B8900005B8900005B8900005B8900005B
+ 8900005D8C0000669900FFFFFF00FFFFFF00FFFFFF00005D8C00006497000062
+ 9300005E8E30005C8C7C0059879200598700005B8900005B8900005B8900005B
+ 8900005D8C0000669900FFFFFF00003F9300003F9300003F9300003F9424003F
+ 948A003E93CC004095CC004095CC004095CC004095CC004095CC004095CC0040
+ 95CC004095CC00409599FFFFFF00003F9300003F9324003F938A0E4B9CD33F76
+ C0EC5D90D4FF3365A9FFA0A0A0FFA9A9A9FFA9A9A9FFAAAAAAFFACACACFFAEAE
+ AEFFB0B0B0FF003E93CCFFFFFF00003F938A0E4A9CD33E75BFEC5487CBFF3669
+ ADFF23569AFF3363A6FFA9A9A9FFBCBCBCFFBDBDBDFFBFBFBFFFC1C1C1FFC4C4
+ C4FFC7C7C7FF003C90CCFFFFFF00003D91CC5D90D4FF3568ACFF285B9FFF1A4D
+ 91FF4477BBFF3361A4FFA9A9A9FFBDBDBDFFBFBFBFFFC1C1C1FFC4C4C4FFC7C7
+ C7FFC9C9C9FF003A8DCCFFFFFF00003B8ECC588BCFFF1A4D91FF4376BAFF3265
+ A9FF4376BAFF335FA1FFAAAAAAFFBFBFBFFFC1C1C1FFC4C4C4FFC7C7C7FFC9C9
+ C9FFCCCCCCFF003789CCFFFFFF0000398BCC5588CCFF275A9EFF4174B8FF3164
+ A8FF4174B8FF335D9EFFACACACFFC1C1C1FFC4C4C4FFC7C7C7FFC9C9C9FFCCCC
+ CCFFD0D0D0FF003485CCFFFFFF00003688CC5386CAFF295CA0FF3F72B6FF3063
+ A7FF3F72B6FF335A9AFFAEAEAEFFC4C4C4FFC7C7C7FFC9C9C9FFCCCCCCFFD0D0
+ D0FFD3D3D3FF003181CCFFFFFF00003485CC5083C7FF1D5094FF3265A9FF2D60
+ A4FF3D70B4FF335897FFB0B0B0FFC7C7C7FFC9C9C9FFCCCCCCFFD0D0D0FFD3D3
+ D3FFD5D5D5FF002E7DCCFFFFFF00003181CC4C7FC3FFBBBBBBFF22518CFF2C5F
+ A3FF3B6EB2FF335593FFB3B3B3FFC9C9C9FFCCCCCCFFD0D0D0FFD3D3D3FFD5D5
+ D5FFD8D8D8FF002B78CCFFFFFF00002E7DCC497CC0FF09336FFF215090FF2B5E
+ A2FF396CB0FF335290FFB5B5B5FFCCCCCCFFD0D0D0FFD3D3D3FFD5D5D5FFD8D8
+ D8FFDBDBDBFF002774CCFFFFFF00002B79CC477ABEFF2C5FA3FF376AAEFF2B5E
+ A2FF376AAEFF33508CFFB8B8B8FFD0D0D0FFD3D3D3FFD5D5D5FFD8D8D8FFDBDB
+ DBFFDCDCDCFF00246FCCFFFFFF00002875CC4477BBFF2C5FA3FF3568ACFF2B5E
+ A2FF2E61A5FF334B87FFBBBBBBFFD3D3D3FFD5D5D5FFD8D8D8FFDBDBDBFFDCDC
+ DCFFDDDDDDFF001F68CCFFFFFF00002571CC4174B8FF2C5FA3FF2D60A4FF2356
+ 9AFF3D70B4FF334179FFBEBEBEFFD5D5D5FFD8D8D8FFDBDBDBFFDCDCDCFFDDDD
+ DDFFDDDDDDFF001258CCFFFFFF0000226DCC3F72B6FF225599FF3B6EB2FF2C51
+ 96EC0A1C60D3000749A4000648CC000648CC000648CC000648CC000648CC0006
+ 48CC000648CC00074A99FFFFFF00001B64CC4174B8FF2A5094EC0A1A5ED30008
+ 4A8A000648240006470000044500000445000004450000044500000445000004
+ 45000004450000064800FFFFFF0000105500000B4FCC0007498A000546240005
+ 4700000648000006470000044500000445000004450000044500000445000004
+ 45000004450000064800FFFFFF004E4E4E005151510054545411555555405555
+ 555A555555655555555A5555554054545411515151004E4E4E004E4E4E002957
+ 27000569000007710000FFFFFF004E4E4E005151512163605E62B1A3948BE6D5
+ C5AFF4EADFC7EDE3D9B5B6ACA28E63605E62515151214E4E4E004E4E4E004E4E
+ 4E004E4E4E004E4E4E00FFFFFF004D4D4D115F5D5A64D5C1AEA1EBD8C4C2F6EC
+ E2CDF6EDE4CEF6EDE4CEF6ECE2CDD9C8B8A4605D5B644D4D4D114C4C4C004C4C
+ 4C004C4C4C004C4C4C00FFFFFF0049494943AD9F918EE8D2BBC0F1E3D5C8F6ED
+ E4CEF6EDE4CEF6EDE4CEF6EDE4CEF2E4D6C8B0A4979149494943494949004949
+ 49004949490049494900FFFFFF0043434360E0CBB6ACE8D2BBC0E8D2BBC0E8D2
+ BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E4D3C1B243434360434343004343
+ 43004343430043434300FFFFFF003E3E3E6FE9D4BEBEE8D2BBC0E8D2BBC0F6ED
+ E4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEEDDBC8C53E3E3E6F3E3E3E003E3E
+ 3E003E3E3E003E3E3E00FFFFFF0038383865E1CFBCB1E8D2BBC0F6EDE4CEF6ED
+ E4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEE7D8CAB838383865383838003838
+ 38003838380038383800FFFFFF0031313149A89D9397EAD5BFC3F5E9DFCBF6ED
+ E4CEF6EDE4CEF6EDE4CEF6EDE4CEF6ECE2CEADA69E9D31313149313131003131
+ 31003131310031313100FFFFFF00262626143B3A3874D7C9BCAFF3E6D9CBF6ED
+ E4CEF6EDE4CEF6EDE4CEF7EFE6D1E4DED9C84544437D34343424383838003939
+ 39003A3A3A003C3C3C00FFFFFF001E1E1E001111112A2826257D9D9791A5EEE8
+ E3C4F9F3EDD6EFEAE5C5A3A09EA92827278AACACACFF373737753737371F3939
+ 39003A3A3A003C3C3C00FFFFFF001E1E1E000E0E0E0004040416040404560404
+ 04790404048704040479040404560404042A0F0F0F86B8B5B5FF4241417E3838
+ 382A3A3A3A003C3C3C00FFFFFF001E1E1E000E0E0E0004040400040404000404
+ 040004040400040404000404040004040400040404251A1A1A8FC8C1C1FF4F4D
+ 4D88393939383C3C3C00FFFFFF001E1E1E000E0E0E0004040400040404000404
+ 040004040400040404000404040004040400040404000404043328272799D9CE
+ CEFF605C5C913A3A3A4DFFFFFF001E1E1E000E0E0E0004040400040404000404
+ 0400040404000404040004040400040404000404040004040400040404443B38
+ 38A2E8D8D8FF32323276FFFFFF001E1E1E000E0E0E0004040400040404000404
+ 0400040404000404040004040400040404000404040004040400040404000404
+ 045C090909892525252CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A7000000AA480000
+ AACC0000AA480000A7000000A3000000A3000000A7000000AA480000AACC0000
+ AA480000A700FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A7480000A7CC7777
+ FFFF0000A7CC0000A7480000A3000000A3000000A7480000A7CC7070F8FF0000
+ A7CC0000A748FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A3CC7676FEFF4C4C
+ D4FF7272FAFF0000A3CC0000A3480000A3480000A3CC6262EAFF4C4CD4FF5C5C
+ E4FF0000A3CCFFFFFF00FFFFFF00FFFFFF00FFFFFF000000A1480000A0CC6767
+ EFFF3636BEFF5E5EE6FF0000A0CC0000A0CC4F4FD7FF3636BEFF4545CDFF0000
+ A0CC0000A148FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A00000009C480000
+ 9BCC5353DBFF2E2EB7FF3D3DC6FF3131BAFF15159FFF1E1EA8FF00009BCC0000
+ 9C480000A000FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A00000009B000000
+ 9848000097CC2525B4FF1111A2FF1111A2FF1414A5FF000097CC000098480000
+ 9B000000A000FFFFFF00FFFFFF00FFFFFF00FFFFFF000000870000008D000000
+ 9148000092CC1515AFFF1111ACFF1111ACFF1111ACFF000092CC000091480000
+ 8D0000008700FFFFFF00FFFFFF00FFFFFF00FFFFFF000000870000008C480000
+ 8DCC1111B8FF1111B8FF1111B8FF1111B8FF1111B8FF1111B8FF00008DCC0000
+ 8C4800008700FFFFFF00FFFFFF00FFFFFF00FFFFFF0000008748000087CC1111
+ C4FF1111C4FF1111C4FF000087CC000087CC1111C4FF1111C4FF1111C4FF0000
+ 87CC00008748FFFFFF00FFFFFF00FFFFFF00FFFFFF00000082CC1111D0FF1111
+ D0FF1111D0FF000082CC0000834800008348000082CC1111D0FF1111D0FF1111
+ D0FF000082CCFFFFFF00FFFFFF00FFFFFF00FFFFFF0000007548000072CC1111
+ D8FF000072CC00007548000082000000820000007548000072CC1111D8FF0000
+ 72CC00007548FFFFFF00FFFFFF00FFFFFF00FFFFFF0000007200000061480000
+ 5FCC00006148000072000000820000008200000072000000614800005FCC0000
+ 614800007200FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E69B3D33E89D3FCCE89D3FCCE89D
+ 3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D
+ 3FCCE89D3FCCE69B3D33FFFFFF00FFFFFF00E2973A15DF9438AEF0BD69E6FEDE
+ 92FFFCD68AFFFCD68AFFFCD68AFFFCD68AFFFCD589FFFCD589FFFDDA8EFFEFBA
+ 66E6DF9438AEE2973A15FFFFFF00FFFFFF00E2973A00D98E3315D2872EAEE8B5
+ 63E6F7CB7FFFEAAF63FFE0A559FFD69B4FFFD19549FFDDAC60FFDFA553E6D287
+ 2EAED98E3315E2973A00FFFFFF00FFFFFF00E2973A00D98E3300CB802915C379
+ 23AEDCA553E6E3B25DFFD3953BFFD3953BFFDFA952FFD69A45E6C37923AECB80
+ 2915D98E3300E2973A00FFFFFF00FFFFFF00E2973A00D98E3300CB802900BC71
+ 1D15B56A18AED69737E6F1B436FFF0B130FFD4922DE6B56A18AEBC711D15CB80
+ 2900D98E3300E2973A00FFFFFF00FFFFFF00E2973A00D98E3300CB802900BC71
+ 1D00AE631215A75C0DAED38D19E6D38C18E6A75C0DAEAE631215BC711D00CB80
+ 2900D98E3300E2973A00FFFFFF00FFFFFF00E2973A00D98E3300CB802900BC71
+ 1D00AE631200A05509159B5005AE9B5005AEA0550915AE631200BC711D00CB80
+ 2900D98E3300E2973A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A75C0D00B56A1800C3792300D287
+ 2E00DF943800E79C3E5CE89D3FCCE79C3E5CDF943800D2872E00C3792300B56A
+ 1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C0D00B56A1800C3792300D287
+ 2E00DE93375CDF9438CCFFE599FFDF9438CCDE93375CD2872E00C3792300B56A
+ 1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C0D00B56A1800C3792300D085
+ 2D5CD2872ECCFEE195FFF8C77BFFFDDE92FFD2872ECCD0852D5CC3792300B56A
+ 1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C0D00B56A1800C177225CC379
+ 23CCFBD98DFFECB367FFE1A75BFFD79C50FFE7BC70FFC37923CCC177225CB56A
+ 1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C0D00B368175CB56A18CCF8CF
+ 80FFE6A53EFFDE9D2FFFDD9C2EFFDD9C2EFFDD9C2EFFE6AE47FFB56A18CCB368
+ 175CA75C0D00FFFFFF00FFFFFF00FFFFFF00A55A0C5CA75C0DCCF9C966FFFAB8
+ 27FFFBB71CFFFBB518FFFBB414FFFBB311FFFBB20FFFFBB20EFFFBB516FFA75C
+ 0DCCA55A0C5CFFFFFF00FFFFFF00FFFFFF009C5106999B5005CC9B5005CC9B50
+ 05CC9B5005CC9B5005CC9B5005CC9B5005CC9B5005CC9B5005CC9B5005CC9B50
+ 05CC9C510699FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF004F4F4F005050500052525200535353005454
+ 54155555553E555555555555556355555563555555555555553E545454155353
+ 530052525200505050004F4F4F004F4F4F0050505000525252075353533D7373
+ 7378C8C8C8D2EAEAEAFFE6E6E6FFE6E6E6FFEAEAEAFFC7C7C7D2727272785353
+ 533D52525207505050004F4F4F004F4F4F00505050075151514D9F9F9FA1E6E6
+ E6FFD7B0A3FFD08C75FFCD6C4BFFCD6C4BFFD08C75FFD6AFA2FFE3E4E4FF9D9D
+ 9DA15151514D505050074F4F4F004E4E4E004E4E4E3F9D9D9DA2DFDFDFFFCB79
+ 5EFFDB7A58FFEE906EFFF49674FFF49573FFED8E6CFFDA7856FFCB795EFFDBDC
+ DCFF999999A24E4E4E3F4E4E4E004B4B4B176C6C6C7CDFE0E0FFC8755AFFE283
+ 61FFDC7A58FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2987FFFDF7E5CFFC875
+ 5AFFD8D8D8FF6969697C4B4B4B1748484842BEBFBFD4C9A295FFD57452FFE281
+ 5FFFD26C4AFFD5A291FFD5A291FFE6C2B6FFFFFFFFFFE0AD9CFFDF7C5AFFD16E
+ 4CFFC7A194FFB2B3B3D4484848424545455CDBDCDCFFC07C65FFDF805EFFCF69
+ 47FFCF6947FFCA6442FFC05937FFC28775FFCCCCCCFFBC8877FFAD4624FFC360
+ 3EFFC07C65FFCBCCCCFF4545455C4242426CCFCFCFFFBC5B3BFFDD7D5BFFC962
+ 40FFBD5330FFB44A26FFBC7259FFD1CFCFFFC7AEA5FFB24824FFB34925FFBD55
+ 32FFBC5B3BFFC3C3C3FF4242426C3E3E3E6ECCCCCCFFB95737FFD5714DFFBF50
+ 2AFFBD4E27FFB94B26FFDBDBDBFFDBDBDBFFB94C26FFBD4E27FFBD4E27FFC154
+ 2EFFB95737FFC0C0C0FF3E3E3E6E3A3A3A61D0CFCFFFB9745DFFCF643EFFC954
+ 2AFFC9542AFFC9542AFFBB4D27FFBB4D27FFC9542AFFC9542AFFC9542AFFC554
+ 2CFFB9745DFFC2C0C0FF3A3A3A6137373747ACAAAAD7C09789FFBF5631FFD85F
+ 33FFD55A2DFFCB542AFFEEEEEEFFEEEEEEFFCB542AFFD55A2DFFD55A2DFFBC4F
+ 29FFBF9588FFA29F9FD7373737473434341953515186D4CECEFFB35F44FFC957
+ 2FFFE16132FFD3592DFFEEEEEEFFEEEEEEFFD3592DFFE15F30FFC8532AFFB35F
+ 44FFD0C9C9FF5150508634343419303030002F2F2F48827E7EACDBD1D1FFAC57
+ 3CFFB6461FFFD6592AFFE56230FFE56230FFD6592AFFB6461FFFAC573CFFDACF
+ CFFF817C7CAC2F2F2F48303030002E2E2E002C2C2C092626265C807979AFE4D6
+ D6FFC69689FFAD644EFF943312FF943312FFAD644EFFC69689FFE3D6D6FF7F79
+ 79AF2626265C2C2C2C092E2E2E002E2E2E002C2C2C001E1E1E091717174F3D3A
+ 3A92B2A6A6DCEBDADAFFEBDADAFFEBDADAFFEBDADAFFB2A6A6DC3D3A3A921717
+ 174F1E1E1E092C2C2C002E2E2E002E2E2E002C2C2C001E1E1E00131313000D0D
+ 0D1D0B0B0B540B0B0B740B0B0B870B0B0B870B0B0B740B0B0B540D0D0D1D1313
+ 13001E1E1E002C2C2C002E2E2E00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF007A7A7A117C7C7C547C7C7C677C7C7C547A7A
+ 7A1177777700555555000000A2000000A200000099000000A6000000A7210000
+ A8A60000A8CC0000A8A60000A72165656557CACACAB8FDFDFDFFCACACAB86565
+ 65575B5B5B005555550016168E0000009FCC0000993300009E0000009FA73F3F
+ D5E87272FEFF3F3FD5E800009FA74545456FF2F2F2FFF2F2F2FFF2F2F2FF4545
+ 456F55555566555555662B2B7400000092B3000092CC00009200000092CC5656
+ F5FF5656F5FF5656F5FF000092CC2525255E9F9F9FBDE4E4E4FF9F9F9FBD2525
+ 255E474747005555550016167700000084CC00008B3300008600000084A71F1F
+ BEE83434EBFF1F1FBEE8000084A70E0E0E140B0B0B610B0B0B770B0B0B610E0E
+ 0E141010100055555500000080000000800000008B0000006E0000006B210000
+ 67A6000067CC000067A600006B21FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF007A7A7A117C7C7C547C7C7C677C7C7C547A7A
+ 7A1177777700555555005555550055555500EA846200EB856329EC8664D0EC86
+ 64FFEC8664D0EB856329FFFFFF0065656557CACACAB8FDFDFDFFCACACAB86565
+ 65575B5B5B0055555500555555005555550079605700E27C5AD0EEA891FFF7CE
+ C1FFEEA891FFE27C5AD0FFFFFF004545456FF2F2F2FFF2F2F2FFF2F2F2FF4545
+ 456F5454546654545466545454665454546654545466D46F4DFFF0C7BAFFF0C7
+ BAFFF0C7BAFFD46F4DFFFFFFFF002525255E9F9F9FBDE4E4E4FF9F9F9FBD2525
+ 255E45454500505050004C4C4C66505050006E554D00C4613FD0D7927BFFE8BF
+ B2FFD7927BFFC4613FD0FFFFFF000E0E0E140B0B0B610B0B0B770B0B0B610E0E
+ 0E1410101000414141004141416641414100B9563400B8553329B65331D0B653
+ 31FFB65331D0B8553329FFFFFF000B0B0B000606060006060600060606000B0B
+ 0B002323230035353500353535663535350077463500B6533100B3502E00B350
+ 2E00B3502E00B6533100FFFFFF000B0B0B000606060006060600060606000B0B
+ 0B00282828002828280028282866282828006E372600B1452300AE442200AE44
+ 2200AE442200B1452300FFFFFF000B0B0B000606060006060600060606001111
+ 11001A1A1A001A1A1A001A1A1A661A1A1A00B3462400B2462429B14523D0B145
+ 23FFB14523D0B2462429FFFFFF000B0B0B000606060006060600080808000F0F
+ 0F000F0F0F000F0F0F000F0F0F660A0A0A0034180F00BD4B29D0DB9078FFF7CE
+ C1FFDB9078FFBD4B29D0FFFFFF000B0B0B000606060006060600070707000707
+ 070007070700070707000606064D0505056605050566CC5331FFF0C7BAFFF0C7
+ BAFFF0C7BAFFCC5331FFFFFFFF000B0B0B000606060006060600070707000707
+ 0700070707000707070005050500030303003A1A1100DB5B39D0E4917AFFE8BF
+ B2FFE4917AFFDB5B39D0FFFFFF000B0B0B000606060006060600070707000707
+ 070007070700070707000505050003030300E5613F00E7624029E86341D0E863
+ 41FFE86341D0E7624029FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00
+ }
+ end
+ object MainMenu: TMainMenu
+ Images = ImageList
+ left = 168
+ top = 136
+ object MnuFile: TMenuItem
+ Caption = 'File'
+ object MnuFileOpen: TMenuItem
+ Action = AcFileOpen
+ Bitmap.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+ FF00005D8C000064970000629300005E8E30005C8C7C0059879200598700005B
+ 8900005B8900005B8900005B8900005D8C0000669900FFFFFF00FFFFFF00FFFF
+ FF00005D8C0000659950006497991C7AA9C052A5CDE0005B89C1005B8900005B
+ 8900005B8900005B8900005B8900005D8C0000669900FFFFFF00FFFFFF00FFFF
+ FF00005E8D8E3591BDF169B8DDFA81CBECFF84CEEEFF005C8BEF005D8CBE005D
+ 8CBE005D8CBE005D8CBE005D8CBE005E8D8E00669900FFFFFF00FFFFFF00FFFF
+ FF00006699B287D1EFFF7FCAE9FF7FCAE9FF87D0EFFF267DA9FF8DD1F3FF8DD1
+ F3FF8DD1F3FF8DD1F3FF90D4F5FF006699B200679B3EFFFFFF00FFFFFF00FFFF
+ FF00006FA7A48AD3F0FF82CDEBFF82CDEBFF8AD3F0FF267EABFF8ACEF0FF8ACE
+ F0FF8ACEF0FF8ACEF0FF8FD3F4FFF4B62EFF006FA7A4FFFFFF00FFFFFF00FFFF
+ FF000073AC9E8ED6F2FF87D0EDFF87D0EDFF8ED6F2FF2882AFFF8BCFF1FF8BCF
+ F1FF8BCFF1FF8BCFF1FF91D5F5FFFEC941FF0073AC9EFFFFFF00FFFFFF00FFFF
+ FF000076B09B92DAF4FF8BD4F0FF8BD4F0FF92DAF4FF2B85B3FF8DD1F3FF8DD1
+ F3FF8DD1F3FF8DD1F3FF93D7F6FFEBEBDDFF0076B09BFFFFFF00FFFFFF00FFFF
+ FF000078B49797DEF6FF90D8F2FF90D8F2FF97DEF6FF2D89B7FF8FD3F5FF8FD3
+ F5FF8FD3F5FF8FD3F5FF95D9F8FFF5F5EEFF0078B497FFFFFF00FFFFFF00FFFF
+ FF00007BB8949BE1F7FF94DBF4FF94DBF4FF9BE1F7FF308DBCFF90D4F6FF90D4
+ F6FF90D4F6FF90D4F6FF97DBF9FFFEFEFDFF007BB894FFFFFF00FFFFFF00FFFF
+ FF00007DBB909EE5F9FF98DFF6FF98DFF6FF9EE5F9FF3290C0FF92D6F8FF92D6
+ F8FF92D6F8FF92D6F8FF99DDFAFF007DBB90007DBB33FFFFFF00FFFFFF00FFFF
+ FF00007FBF8DA3E8FBFF9DE3F9FF9DE3F9FFA3E8FBFF3594C5FF94D8FAFF94D8
+ FAFF94D8FAFF94D8FAFF9BDFFCFF007FBF8D007FBE00FFFFFF00FFFFFF00FFFF
+ FF000082C28AA6EBFCFFA1E6FBFFA1E6FBFFA6EBFCFF3C9DCFFF96DAFCFF96DA
+ FCFF96DAFCFF96DAFCFF9EE2FDFF0082C28A0082C200FFFFFF00FFFFFF00FFFF
+ FF000084C587A9EEFDFFA4E9FCFFA4E9FCFFAAEEFDFF42A1D1FF97DBFDFF97DB
+ FDFF97DBFDFF97DBFDFF9FE3FEFF0084C5870084C500FFFFFF00FFFFFF00FFFF
+ FF000085C885ACF1FFFFABEFFEFF95E2F8FF6EC9EDFF48A8D9FF98DCFEFF98DC
+ FEFF98DCFEFF98DCFEFFA1E5FFFF0085C8850085C800FFFFFF00FFFFFF00FFFF
+ FF000087CA8388DCF4FF60C0E9FF5FBFEAFF80D3F4FF9CE3FDFFA2E6FFFFA2E6
+ FFFFA2E6FFFFA2E6FFFFA6EAFFFF0087CA830087CA00FFFFFF00FFFFFF00FFFF
+ FF000088CC610088CC810088CC810088CC810088CC810088CC810088CC810088
+ CC810088CC810088CC810088CC810088CC610087CB00FFFFFF00
+ }
+ end
+ object MnuFileReopen: TMenuItem
+ Caption = 'Recently opened files'
+ end
+ object MenuItem4: TMenuItem
+ Caption = '-'
+ end
+ object MnuFileQuit: TMenuItem
+ Action = AcFileQuit
+ Bitmap.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 200000000000000400006400000064000000000000000000000000105500000B
+ 4FCC0007498A0005462400054700000648000006470000044500000445000004
+ 45000004450000044500000445000004450000064800FFFFFF00001B64CC4174
+ B8FF2A5094EC0A1A5ED300084A8A000648240006470000044500000445000004
+ 45000004450000044500000445000004450000064800FFFFFF0000226DCC3F72
+ B6FF225599FF3B6EB2FF2C5196EC0A1C60D3000749A4000648CC000648CC0006
+ 48CC000648CC000648CC000648CC000648CC00074A99FFFFFF00002571CC4174
+ B8FF2C5FA3FF2D60A4FF23569AFF3D70B4FF334179FFBEBEBEFFD5D5D5FFD8D8
+ D8FFDBDBDBFFDCDCDCFFDDDDDDFFDDDDDDFF001258CCFFFFFF00002875CC4477
+ BBFF2C5FA3FF3568ACFF2B5EA2FF2E61A5FF334B87FFBBBBBBFFD3D3D3FFD5D5
+ D5FFD8D8D8FFDBDBDBFFDCDCDCFFDDDDDDFF001F68CCFFFFFF00002B79CC477A
+ BEFF2C5FA3FF376AAEFF2B5EA2FF376AAEFF33508CFFB8B8B8FFD0D0D0FFD3D3
+ D3FFD5D5D5FFD8D8D8FFDBDBDBFFDCDCDCFF00246FCCFFFFFF00002E7DCC497C
+ C0FF09336FFF215090FF2B5EA2FF396CB0FF335290FFB5B5B5FFCCCCCCFFD0D0
+ D0FFD3D3D3FFD5D5D5FFD8D8D8FFDBDBDBFF002774CCFFFFFF00003181CC4C7F
+ C3FFBBBBBBFF22518CFF2C5FA3FF3B6EB2FF335593FFB3B3B3FFC9C9C9FFCCCC
+ CCFFD0D0D0FFD3D3D3FFD5D5D5FFD8D8D8FF002B78CCFFFFFF00003485CC5083
+ C7FF1D5094FF3265A9FF2D60A4FF3D70B4FF335897FFB0B0B0FFC7C7C7FFC9C9
+ C9FFCCCCCCFFD0D0D0FFD3D3D3FFD5D5D5FF002E7DCCFFFFFF00003688CC5386
+ CAFF295CA0FF3F72B6FF3063A7FF3F72B6FF335A9AFFAEAEAEFFC4C4C4FFC7C7
+ C7FFC9C9C9FFCCCCCCFFD0D0D0FFD3D3D3FF003181CCFFFFFF0000398BCC5588
+ CCFF275A9EFF4174B8FF3164A8FF4174B8FF335D9EFFACACACFFC1C1C1FFC4C4
+ C4FFC7C7C7FFC9C9C9FFCCCCCCFFD0D0D0FF003485CCFFFFFF00003B8ECC588B
+ CFFF1A4D91FF4376BAFF3265A9FF4376BAFF335FA1FFAAAAAAFFBFBFBFFFC1C1
+ C1FFC4C4C4FFC7C7C7FFC9C9C9FFCCCCCCFF003789CCFFFFFF00003D91CC5D90
+ D4FF3568ACFF285B9FFF1A4D91FF4477BBFF3361A4FFA9A9A9FFBDBDBDFFBFBF
+ BFFFC1C1C1FFC4C4C4FFC7C7C7FFC9C9C9FF003A8DCCFFFFFF00003F938A0E4A
+ 9CD33E75BFEC5487CBFF3669ADFF23569AFF3363A6FFA9A9A9FFBCBCBCFFBDBD
+ BDFFBFBFBFFFC1C1C1FFC4C4C4FFC7C7C7FF003C90CCFFFFFF00003F9300003F
+ 9324003F938A0E4B9CD33F76C0EC5D90D4FF3365A9FFA0A0A0FFA9A9A9FFA9A9
+ A9FFAAAAAAFFACACACFFAEAEAEFFB0B0B0FF003E93CCFFFFFF00003F9300003F
+ 9300003F9300003F9424003F948A003E93CC004095CC004095CC004095CC0040
+ 95CC004095CC004095CC004095CC004095CC00409599FFFFFF00
+ }
+ end
+ end
+ object MnuRecord: TMenuItem
+ Caption = 'Record'
+ object MnuFind: TMenuItem
+ Action = AcFind
+ AutoCheck = True
+ Bitmap.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF001E1E1E000E0E
+ 0E00040404000404040004040400040404000404040004040400040404000404
+ 040004040400040404000404045C090909892525252CFFFFFF001E1E1E000E0E
+ 0E00040404000404040004040400040404000404040004040400040404000404
+ 040004040400040404443B3838A2E8D8D8FF32323276FFFFFF001E1E1E000E0E
+ 0E00040404000404040004040400040404000404040004040400040404000404
+ 04000404043328272799D9CECEFF605C5C913A3A3A4DFFFFFF001E1E1E000E0E
+ 0E00040404000404040004040400040404000404040004040400040404000404
+ 04251A1A1A8FC8C1C1FF4F4D4D88393939383C3C3C00FFFFFF001E1E1E000E0E
+ 0E000404041604040456040404790404048704040479040404560404042A0F0F
+ 0F86B8B5B5FF4241417E3838382A3A3A3A003C3C3C00FFFFFF001E1E1E001111
+ 112A2826257D9D9791A5EEE8E3C4F9F3EDD6EFEAE5C5A3A09EA92827278AACAC
+ ACFF373737753737371F393939003A3A3A003C3C3C00FFFFFF00262626143B3A
+ 3874D7C9BCAFF3E6D9CBF6EDE4CEF6EDE4CEF6EDE4CEF7EFE6D1E4DED9C84544
+ 437D3434342438383800393939003A3A3A003C3C3C00FFFFFF0031313149A89D
+ 9397EAD5BFC3F5E9DFCBF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6ECE2CEADA6
+ 9E9D3131314931313100313131003131310031313100FFFFFF0038383865E1CF
+ BCB1E8D2BBC0F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEE7D8
+ CAB83838386538383800383838003838380038383800FFFFFF003E3E3E6FE9D4
+ BEBEE8D2BBC0E8D2BBC0F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEEDDB
+ C8C53E3E3E6F3E3E3E003E3E3E003E3E3E003E3E3E00FFFFFF0043434360E0CB
+ B6ACE8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E4D3
+ C1B24343436043434300434343004343430043434300FFFFFF0049494943AD9F
+ 918EE8D2BBC0F1E3D5C8F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF2E4D6C8B0A4
+ 97914949494349494900494949004949490049494900FFFFFF004D4D4D115F5D
+ 5A64D5C1AEA1EBD8C4C2F6ECE2CDF6EDE4CEF6EDE4CEF6ECE2CDD9C8B8A4605D
+ 5B644D4D4D114C4C4C004C4C4C004C4C4C004C4C4C00FFFFFF004E4E4E005151
+ 512163605E62B1A3948BE6D5C5AFF4EADFC7EDE3D9B5B6ACA28E63605E625151
+ 51214E4E4E004E4E4E004E4E4E004E4E4E004E4E4E00FFFFFF004E4E4E005151
+ 510054545411555555405555555A555555655555555A55555540545454115151
+ 51004E4E4E004E4E4E00295727000569000007710000FFFFFF00
+ }
+ end
+ end
+ object MnuHelp: TMenuItem
+ Caption = 'Help'
+ object MenuItem2: TMenuItem
+ Action = AcAbout
+ Bitmap.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 20000000000000040000640000006400000000000000000000002E2E2E002C2C
+ 2C001E1E1E00131313000D0D0D1D0B0B0B540B0B0B740B0B0B870B0B0B870B0B
+ 0B740B0B0B540D0D0D1D131313001E1E1E002C2C2C002E2E2E002E2E2E002C2C
+ 2C001E1E1E091717174F3D3A3A92B2A6A6DCEBDADAFFEBDADAFFEBDADAFFEBDA
+ DAFFB2A6A6DC3D3A3A921717174F1E1E1E092C2C2C002E2E2E002E2E2E002C2C
+ 2C092626265C807979AFE4D6D6FFC69689FFAD644EFF943312FF943312FFAD64
+ 4EFFC69689FFE3D6D6FF7F7979AF2626265C2C2C2C092E2E2E00303030002F2F
+ 2F48827E7EACDBD1D1FFAC573CFFB6461FFFD6592AFFE56230FFE56230FFD659
+ 2AFFB6461FFFAC573CFFDACFCFFF817C7CAC2F2F2F4830303000343434195351
+ 5186D4CECEFFB35F44FFC9572FFFE16132FFD3592DFFEEEEEEFFEEEEEEFFD359
+ 2DFFE15F30FFC8532AFFB35F44FFD0C9C9FF515050863434341937373747ACAA
+ AAD7C09789FFBF5631FFD85F33FFD55A2DFFCB542AFFEEEEEEFFEEEEEEFFCB54
+ 2AFFD55A2DFFD55A2DFFBC4F29FFBF9588FFA29F9FD7373737473A3A3A61D0CF
+ CFFFB9745DFFCF643EFFC9542AFFC9542AFFC9542AFFBB4D27FFBB4D27FFC954
+ 2AFFC9542AFFC9542AFFC5542CFFB9745DFFC2C0C0FF3A3A3A613E3E3E6ECCCC
+ CCFFB95737FFD5714DFFBF502AFFBD4E27FFB94B26FFDBDBDBFFDBDBDBFFB94C
+ 26FFBD4E27FFBD4E27FFC1542EFFB95737FFC0C0C0FF3E3E3E6E4242426CCFCF
+ CFFFBC5B3BFFDD7D5BFFC96240FFBD5330FFB44A26FFBC7259FFD1CFCFFFC7AE
+ A5FFB24824FFB34925FFBD5532FFBC5B3BFFC3C3C3FF4242426C4545455CDBDC
+ DCFFC07C65FFDF805EFFCF6947FFCF6947FFCA6442FFC05937FFC28775FFCCCC
+ CCFFBC8877FFAD4624FFC3603EFFC07C65FFCBCCCCFF4545455C48484842BEBF
+ BFD4C9A295FFD57452FFE2815FFFD26C4AFFD5A291FFD5A291FFE6C2B6FFFFFF
+ FFFFE0AD9CFFDF7C5AFFD16E4CFFC7A194FFB2B3B3D4484848424B4B4B176C6C
+ 6C7CDFE0E0FFC8755AFFE28361FFDC7A58FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFE2987FFFDF7E5CFFC8755AFFD8D8D8FF6969697C4B4B4B174E4E4E004E4E
+ 4E3F9D9D9DA2DFDFDFFFCB795EFFDB7A58FFEE906EFFF49674FFF49573FFED8E
+ 6CFFDA7856FFCB795EFFDBDCDCFF999999A24E4E4E3F4E4E4E004F4F4F005050
+ 50075151514D9F9F9FA1E6E6E6FFD7B0A3FFD08C75FFCD6C4BFFCD6C4BFFD08C
+ 75FFD6AFA2FFE3E4E4FF9D9D9DA15151514D505050074F4F4F004F4F4F005050
+ 5000525252075353533D73737378C8C8C8D2EAEAEAFFE6E6E6FFE6E6E6FFEAEA
+ EAFFC7C7C7D2727272785353533D52525207505050004F4F4F004F4F4F005050
+ 50005252520053535300545454155555553E5555555555555563555555635555
+ 55555555553E545454155353530052525200505050004F4F4F00
+ }
+ end
+ end
+ end
+ object ActionList: TActionList
+ Images = ImageList
+ left = 168
+ top = 64
+ object AcFileOpen: TAction
+ Caption = 'Open'
+ Hint = 'Open xls file'
+ ImageIndex = 0
+ OnExecute = AcFileOpenExecute
+ ShortCut = 16463
+ end
+ object AcFileQuit: TAction
+ Caption = 'Quit'
+ Hint = 'Quit application'
+ ImageIndex = 1
+ OnExecute = AcFileQuitExecute
+ ShortCut = 32856
+ end
+ object AcFind: TAction
+ AutoCheck = True
+ Caption = 'Find'
+ Hint = 'Find record'
+ ImageIndex = 2
+ OnExecute = AcFindExecute
+ ShortCut = 16454
+ end
+ object AcFindClose: TAction
+ ImageIndex = 3
+ OnExecute = AcFindCloseExecute
+ end
+ object AcFindNext: TAction
+ ImageIndex = 4
+ OnExecute = AcFindNextExecute
+ end
+ object AcFindPrev: TAction
+ ImageIndex = 5
+ OnExecute = AcFindPrevExecute
+ end
+ object AcAbout: TAction
+ Caption = 'About...'
+ ImageIndex = 6
+ OnExecute = AcAboutExecute
+ end
+ object AcNodeExpand: TAction
+ Caption = 'Expand node'
+ Hint = 'Expand current node'
+ ImageIndex = 8
+ OnExecute = AcNodeExpandExecute
+ OnUpdate = AcNodeExpandUpdate
+ end
+ object AcNodeCollapse: TAction
+ Caption = 'Collapse node'
+ Hint = 'Collapse current node'
+ ImageIndex = 7
+ OnExecute = AcNodeCollapseExecute
+ OnUpdate = AcNodeCollapseUpdate
+ end
+ end
+ object OpenDialog: TOpenDialog
+ DefaultExt = '.xls'
+ Filter = 'Excel files (*.xls)|*.xls'
+ left = 160
+ top = 296
+ end
+ object RecentFilesPopupMenu: TPopupMenu
+ left = 160
+ top = 208
+ object MenuItem1: TMenuItem
+ Caption = 'New Item1'
+ end
+ end
+ object TreePopupMenu: TPopupMenu
+ Images = ImageList
+ left = 160
+ top = 392
+ object MenuItem3: TMenuItem
+ Action = AcNodeExpand
+ Bitmap.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000B0B0B000606
+ 060006060600070707000707070007070700070707000505050003030300E561
+ 3F00E7624029E86341D0E86341FFE86341D0E7624029FFFFFF000B0B0B000606
+ 0600060606000707070007070700070707000707070005050500030303003A1A
+ 1100DB5B39D0E4917AFFE8BFB2FFE4917AFFDB5B39D0FFFFFF000B0B0B000606
+ 060006060600070707000707070007070700070707000606064D050505660505
+ 0566CC5331FFF0C7BAFFF0C7BAFFF0C7BAFFCC5331FFFFFFFF000B0B0B000606
+ 060006060600080808000F0F0F000F0F0F000F0F0F000F0F0F660A0A0A003418
+ 0F00BD4B29D0DB9078FFF7CEC1FFDB9078FFBD4B29D0FFFFFF000B0B0B000606
+ 06000606060006060600111111001A1A1A001A1A1A001A1A1A661A1A1A00B346
+ 2400B2462429B14523D0B14523FFB14523D0B2462429FFFFFF000B0B0B000606
+ 060006060600060606000B0B0B00282828002828280028282866282828006E37
+ 2600B1452300AE442200AE442200AE442200B1452300FFFFFF000B0B0B000606
+ 060006060600060606000B0B0B00232323003535350035353566353535007746
+ 3500B6533100B3502E00B3502E00B3502E00B6533100FFFFFF000E0E0E140B0B
+ 0B610B0B0B770B0B0B610E0E0E1410101000414141004141416641414100B956
+ 3400B8553329B65331D0B65331FFB65331D0B8553329FFFFFF002525255E9F9F
+ 9FBDE4E4E4FF9F9F9FBD2525255E45454500505050004C4C4C66505050006E55
+ 4D00C4613FD0D7927BFFE8BFB2FFD7927BFFC4613FD0FFFFFF004545456FF2F2
+ F2FFF2F2F2FFF2F2F2FF4545456F545454665454546654545466545454665454
+ 5466D46F4DFFF0C7BAFFF0C7BAFFF0C7BAFFD46F4DFFFFFFFF0065656557CACA
+ CAB8FDFDFDFFCACACAB8656565575B5B5B005555550055555500555555007960
+ 5700E27C5AD0EEA891FFF7CEC1FFEEA891FFE27C5AD0FFFFFF007A7A7A117C7C
+ 7C547C7C7C677C7C7C547A7A7A1177777700555555005555550055555500EA84
+ 6200EB856329EC8664D0EC8664FFEC8664D0EB856329FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ }
+ end
+ object MenuItem5: TMenuItem
+ Action = AcNodeCollapse
+ Bitmap.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000E0E0E140B0B
+ 0B610B0B0B770B0B0B610E0E0E14101010005555550000008000000080000000
+ 8B0000006E0000006B21000067A6000067CC000067A600006B212525255E9F9F
+ 9FBDE4E4E4FF9F9F9FBD2525255E474747005555550016167700000084CC0000
+ 8B3300008600000084A71F1FBEE83434EBFF1F1FBEE8000084A74545456FF2F2
+ F2FFF2F2F2FFF2F2F2FF4545456F55555566555555662B2B7400000092B30000
+ 92CC00009200000092CC5656F5FF5656F5FF5656F5FF000092CC65656557CACA
+ CAB8FDFDFDFFCACACAB8656565575B5B5B005555550016168E0000009FCC0000
+ 993300009E0000009FA73F3FD5E87272FEFF3F3FD5E800009FA77A7A7A117C7C
+ 7C547C7C7C677C7C7C547A7A7A1177777700555555000000A2000000A2000000
+ 99000000A6000000A7210000A8A60000A8CC0000A8A60000A721FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ }
+ end
+ object MenuItem6: TMenuItem
+ Caption = '-'
+ end
+ object MenuItem7: TMenuItem
+ Action = AcFind
+ AutoCheck = True
+ Bitmap.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF001E1E1E000E0E
+ 0E00040404000404040004040400040404000404040004040400040404000404
+ 040004040400040404000404045C090909892525252CFFFFFF001E1E1E000E0E
+ 0E00040404000404040004040400040404000404040004040400040404000404
+ 040004040400040404443B3838A2E8D8D8FF32323276FFFFFF001E1E1E000E0E
+ 0E00040404000404040004040400040404000404040004040400040404000404
+ 04000404043328272799D9CECEFF605C5C913A3A3A4DFFFFFF001E1E1E000E0E
+ 0E00040404000404040004040400040404000404040004040400040404000404
+ 04251A1A1A8FC8C1C1FF4F4D4D88393939383C3C3C00FFFFFF001E1E1E000E0E
+ 0E000404041604040456040404790404048704040479040404560404042A0F0F
+ 0F86B8B5B5FF4241417E3838382A3A3A3A003C3C3C00FFFFFF001E1E1E001111
+ 112A2826257D9D9791A5EEE8E3C4F9F3EDD6EFEAE5C5A3A09EA92827278AACAC
+ ACFF373737753737371F393939003A3A3A003C3C3C00FFFFFF00262626143B3A
+ 3874D7C9BCAFF3E6D9CBF6EDE4CEF6EDE4CEF6EDE4CEF7EFE6D1E4DED9C84544
+ 437D3434342438383800393939003A3A3A003C3C3C00FFFFFF0031313149A89D
+ 9397EAD5BFC3F5E9DFCBF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6ECE2CEADA6
+ 9E9D3131314931313100313131003131310031313100FFFFFF0038383865E1CF
+ BCB1E8D2BBC0F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEE7D8
+ CAB83838386538383800383838003838380038383800FFFFFF003E3E3E6FE9D4
+ BEBEE8D2BBC0E8D2BBC0F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEEDDB
+ C8C53E3E3E6F3E3E3E003E3E3E003E3E3E003E3E3E00FFFFFF0043434360E0CB
+ B6ACE8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E4D3
+ C1B24343436043434300434343004343430043434300FFFFFF0049494943AD9F
+ 918EE8D2BBC0F1E3D5C8F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF2E4D6C8B0A4
+ 97914949494349494900494949004949490049494900FFFFFF004D4D4D115F5D
+ 5A64D5C1AEA1EBD8C4C2F6ECE2CDF6EDE4CEF6EDE4CEF6ECE2CDD9C8B8A4605D
+ 5B644D4D4D114C4C4C004C4C4C004C4C4C004C4C4C00FFFFFF004E4E4E005151
+ 512163605E62B1A3948BE6D5C5AFF4EADFC7EDE3D9B5B6ACA28E63605E625151
+ 51214E4E4E004E4E4E004E4E4E004E4E4E004E4E4E00FFFFFF004E4E4E005151
+ 510054545411555555405555555A555555655555555A55555540545454115151
+ 51004E4E4E004E4E4E00295727000569000007710000FFFFFF00
+ }
+ end
+ end
+end
diff --git a/components/fpspreadsheet/reference/BIFFExplorer/bemain.pas b/components/fpspreadsheet/reference/BIFFExplorer/bemain.pas
new file mode 100644
index 000000000..2449bd3c5
--- /dev/null
+++ b/components/fpspreadsheet/reference/BIFFExplorer/bemain.pas
@@ -0,0 +1,1144 @@
+unit beMain;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ ActnList, Classes, ComCtrls, ExtCtrls, Grids, Menus, StdCtrls, SysUtils,
+ FileUtil, Forms, Controls, Graphics, Dialogs, Buttons, VirtualTrees,
+ {$ifdef USE_NEW_OLE}
+ fpolebasic,
+ {$else}
+ fpolestorage,
+ {$endif}
+ fpSpreadsheet,
+ mrumanager, beBIFFGrid;
+
+type
+ { Virtual tree node data }
+ TBiffNodeData = class
+ Offset: Integer;
+ RecordID: Integer;
+ RecordName: String;
+ RecordDescription: String;
+ destructor Destroy; override;
+ end;
+
+
+ { TMainForm }
+ TMainForm = class(TForm)
+ AcFileOpen: TAction;
+ AcFileQuit: TAction;
+ AcFind: TAction;
+ AcFindNext: TAction;
+ AcFindPrev: TAction;
+ AcAbout: TAction;
+ AcFindClose: TAction;
+ AcNodeExpand: TAction;
+ AcNodeCollapse: TAction;
+ ActionList: TActionList;
+ BIFFTree: TVirtualStringTree;
+ CbFind: TComboBox;
+ HexGrid: TStringGrid;
+ ImageList: TImageList;
+ MainMenu: TMainMenu;
+ AnalysisDetails: TMemo;
+ MenuItem1: TMenuItem;
+ MenuItem3: TMenuItem;
+ MenuItem5: TMenuItem;
+ MenuItem6: TMenuItem;
+ MenuItem7: TMenuItem;
+ MnuFind: TMenuItem;
+ MnuRecord: TMenuItem;
+ MnuFileReopen: TMenuItem;
+ MenuItem4: TMenuItem;
+ MnuHelp: TMenuItem;
+ MenuItem2: TMenuItem;
+ MnuFileQuit: TMenuItem;
+ MnuFileOpen: TMenuItem;
+ MnuFile: TMenuItem;
+ OpenDialog: TOpenDialog;
+ PageControl: TPageControl;
+ DetailPanel: TPanel;
+ HexPanel: TPanel;
+ FindPanel: TPanel;
+ TreePopupMenu: TPopupMenu;
+ TreePanel: TPanel;
+ BtnFindNext: TSpeedButton;
+ BtnFindPrev: TSpeedButton;
+ RecentFilesPopupMenu: TPopupMenu;
+ SpeedButton3: TSpeedButton;
+ Splitter1: TSplitter;
+ HexSplitter: TSplitter;
+ AlphaGrid: TStringGrid;
+ HexDumpSplitter: TSplitter;
+ PgAnalysis: TTabSheet;
+ PgValues: TTabSheet;
+ DetailsSplitter: TSplitter;
+ StatusBar: TStatusBar;
+ ToolButton3: TToolButton;
+ ToolButton4: TToolButton;
+ ValueGrid: TStringGrid;
+ ToolBar: TToolBar;
+ ToolButton1: TToolButton;
+ ToolButton2: TToolButton;
+ procedure AcAboutExecute(Sender: TObject);
+ procedure AcFileOpenExecute(Sender: TObject);
+ procedure AcFileQuitExecute(Sender: TObject);
+ procedure AcFindCloseExecute(Sender: TObject);
+ procedure AcFindExecute(Sender: TObject);
+ procedure AcFindNextExecute(Sender: TObject);
+ procedure AcFindPrevExecute(Sender: TObject);
+ procedure AcNodeCollapseExecute(Sender: TObject);
+ procedure AcNodeCollapseUpdate(Sender: TObject);
+ procedure AcNodeExpandExecute(Sender: TObject);
+ procedure AcNodeExpandUpdate(Sender: TObject);
+ procedure AlphaGridSelection(Sender: TObject; aCol, aRow: Integer);
+ procedure BIFFTreeBeforeCellPaint(Sender: TBaseVirtualTree;
+ TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
+ CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
+ procedure BIFFTreeFocusChanged(Sender: TBaseVirtualTree;
+ Node: PVirtualNode; Column: TColumnIndex);
+ procedure BIFFTreeFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
+ procedure BIFFTreeGetNodeDataSize(Sender: TBaseVirtualTree;
+ var NodeDataSize: Integer);
+ procedure BIFFTreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
+ Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
+ procedure BIFFTreePaintText(Sender: TBaseVirtualTree;
+ const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
+ TextType: TVSTTextType);
+ procedure CbFindChange(Sender: TObject);
+ procedure CbFindKeyPress(Sender: TObject; var Key: char);
+ procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
+ procedure FormCreate(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure FormShow(Sender: TObject);
+ procedure GridClick(Sender: TObject);
+ procedure HexGridPrepareCanvas(sender: TObject; aCol, aRow: Integer;
+ aState: TGridDrawState);
+ procedure HexGridSelection(Sender: TObject; aCol, aRow: Integer);
+ procedure ListViewSelectItem(Sender: TObject; Item: TListItem;
+ Selected: Boolean);
+ procedure PageControlChange(Sender: TObject);
+
+ private
+ MemStream: TMemoryStream;
+ OLEStorage: TOLEStorage;
+ FFileName: String;
+ FFormat: TsSpreadsheetFormat;
+ FBuffer: TBIFFBuffer;
+ FCurrOffset: Integer;
+ FLockHexDumpGrids: Integer;
+ FAnalysisGrid: TBIFFGrid;
+ FMRUMenuManager : TMRUMenuManager;
+ procedure AddToHistory(const AText: String);
+ procedure AnalysisGridDetails(Sender: TObject; ADetails: TStrings);
+ procedure ExecFind(ANext, AKeep: Boolean);
+ function GetNodeData(ANode: PVirtualNode): TBiffNodeData;
+ function GetRecType: Word;
+ procedure LoadFile(const AFileName: String); overload;
+ procedure LoadFile(const AFileName: String; AFormat: TsSpreadsheetFormat); overload;
+ procedure MRUMenuManagerRecentFile(Sender:TObject; const AFileName:string);
+ procedure PopulateAnalysisGrid;
+ procedure PopulateHexDump;
+ procedure PopulateValueGrid;
+ procedure ReadCmdLine;
+ procedure ReadFromIni;
+ procedure ReadFromStream(AStream: TStream);
+ procedure UpdateCaption;
+ procedure WriteToIni;
+
+ public
+ procedure BeforeRun;
+ end;
+
+var
+ MainForm: TMainForm;
+
+implementation
+
+{$R *.lfm}
+
+uses
+ IniFiles, StrUtils, Math, lazutf8,
+ fpsUtils,
+ beUtils, beBIFFUtils, beAbout;
+
+const
+ VALUE_ROW_INDEX = 1;
+ VALUE_ROW_BYTE = 2;
+ VALUE_ROW_WORD = 3;
+ VALUE_ROW_DWORD = 4;
+ VALUE_ROW_QWORD = 5;
+ VALUE_ROW_DOUBLE = 6;
+ VALUE_ROW_ANSISTRING = 7;
+ VALUE_ROW_WIDESTRING = 8;
+
+ MAX_HISTORY = 16;
+
+
+{ Virtual tree nodes }
+type
+ TObjectNodeData = record
+ Data: TObject;
+ end;
+ PObjectNodeData = ^TObjectNodeData;
+
+
+{ TBiffNodeData }
+
+destructor TBiffNodeData.Destroy;
+begin
+ Finalize(RecordName);
+ Finalize(RecordDescription);
+ inherited;
+end;
+
+
+{ TMainForm }
+
+procedure TMainForm.AcAboutExecute(Sender: TObject);
+var
+ F: TAboutForm;
+begin
+ F := TAboutForm.Create(nil);
+ try
+ F.ShowModal;
+ finally
+ F.Free;
+ end;
+end;
+
+
+procedure TMainForm.AcFileOpenExecute(Sender: TObject);
+begin
+ with OpenDialog do begin
+ if Execute then LoadFile(FileName);
+ end;
+end;
+
+
+procedure TMainForm.AcFileQuitExecute(Sender: TObject);
+begin
+ Close;
+end;
+
+
+procedure TMainForm.AcFindCloseExecute(Sender: TObject);
+begin
+ AcFind.Checked := false;
+ FindPanel.Hide;
+end;
+
+
+procedure TMainForm.AcFindExecute(Sender: TObject);
+begin
+ if AcFind.Checked then begin
+ FindPanel.Show;
+ CbFind.SetFocus;
+ end else begin
+ FindPanel.Hide;
+ end;
+end;
+
+
+procedure TMainForm.AcFindNextExecute(Sender: TObject);
+begin
+ ExecFind(true, false);
+end;
+
+
+procedure TMainForm.AcFindPrevExecute(Sender: TObject);
+begin
+ ExecFind(false, false);
+end;
+
+
+procedure TMainForm.AcNodeCollapseExecute(Sender: TObject);
+var
+ node: PVirtualNode;
+begin
+ node := BiffTree.FocusedNode;
+ if node <> nil then begin
+ if BiffTree.GetNodeLevel(node) > 0 then
+ node := node^.Parent;
+ BiffTree.Expanded[node] := false;
+ end;
+end;
+
+procedure TMainForm.AcNodeCollapseUpdate(Sender: TObject);
+var
+ node: PVirtualNode;
+begin
+ node := BiffTree.FocusedNode;
+ if node <> nil then begin
+ if BiffTree.GetNodeLevel(node) > 0 then
+ node := node^.Parent;
+ end;
+ AcNodeCollapse.Enabled := (node <> nil) and BiffTree.Expanded[node];
+end;
+
+
+procedure TMainForm.AcNodeExpandExecute(Sender: TObject);
+var
+ node: PVirtualNode;
+begin
+ node := BiffTree.FocusedNode;
+ if node <> nil then begin
+ if BiffTree.GetNodeLevel(node) > 0 then
+ node := node^.Parent;
+ BiffTree.Expanded[node] := true;
+ end;
+end;
+
+
+procedure TMainForm.AcNodeExpandUpdate(Sender: TObject);
+var
+ node: PVirtualNode;
+begin
+ node := BiffTree.FocusedNode;
+ if node <> nil then begin
+ if BiffTree.GetNodeLevel(node) > 0 then
+ node := node^.Parent;
+ end;
+ AcNodeExpand.Enabled := (node <> nil) and not BiffTree.Expanded[node];
+end;
+
+procedure TMainForm.AddToHistory(const AText: String);
+begin
+ if (AText <> '') and (CbFind.Items.IndexOf(AText) = -1) then begin
+ CbFind.Items.Insert(0, AText);
+ while CbFind.Items.Count > MAX_HISTORY do
+ CbFind.Items.Delete(CbFind.Items.Count-1);
+ end;
+end;
+
+
+procedure TMainForm.AlphaGridSelection(Sender: TObject; aCol, aRow: Integer);
+begin
+ if FLockHexDumpGrids > 0 then
+ exit;
+ FCurrOffset := (ARow - AlphaGrid.FixedRows)*16 + (ACol - AlphaGrid.FixedCols);
+ if FCurrOffset < 0 then FCurrOffset := 0;
+ inc(FLockHexDumpGrids);
+ HexGrid.Col := aCol - AlphaGrid.FixedCols + HexGrid.FixedCols;
+ HexGrid.Row := aRow - AlphaGrid.FixedRows + HexGrid.FixedRows;
+ dec(FLockHexDumpGrids);
+ if FCurrOffset > -1 then
+ Statusbar.Panels[3].Text := Format('HexViewer offset: %d', [FCurrOffset])
+ else
+ Statusbar.Panels[3].Text := '';
+end;
+
+
+procedure TMainForm.AnalysisGridDetails(Sender: TObject; ADetails: TStrings);
+begin
+ AnalysisDetails.Lines.Assign(ADetails);
+end;
+
+
+procedure TMainForm.BeforeRun;
+begin
+ ReadFromIni;
+ ReadCmdLine;
+end;
+
+
+procedure TMainForm.BIFFTreeBeforeCellPaint(Sender: TBaseVirtualTree;
+ TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
+ CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
+var
+ s: String;
+begin
+ if (Sender.GetNodeLevel(Node) = 0) and (Column = 0) then begin
+ // Left-align parent nodes (column 0 is right-aligned)
+ BiffTreeGetText(Sender, Node, 0, ttNormal, s);
+ TargetCanvas.Font.Style := [fsBold];
+ ContentRect.Right := CellRect.Left + TargetCanvas.TextWidth(s) + 30;
+ end;
+end;
+
+
+procedure TMainForm.BIFFTreeFocusChanged(Sender: TBaseVirtualTree;
+ Node: PVirtualNode; Column: TColumnIndex);
+var
+ ptr: PObjectNodeData;
+ data: TBiffNodeData;
+ n: Word;
+begin
+ ptr := Sender.GetNodeData(Node);
+ data := TBiffNodeData(ptr^.Data);
+
+ // Move to start of record + 2 bytes to skip record type ID.
+ MemStream.Position := PtrInt(data.Offset) + 2;
+
+ // Read size of record
+ n := WordLEToN(MemStream.ReadWord);
+
+ // Read record data
+ SetLength(FBuffer, n);
+ if n > 0 then
+ MemStream.ReadBuffer(FBuffer[0], n);
+
+ // Update user interface
+ if (BiffTree.FocusedNode <> nil) and (BiffTree.GetNodeLevel(BiffTree.FocusedNode) > 0)
+ then begin
+ Statusbar.Panels[0].Text := Format('Record ID: $%.4x', [data.RecordID]);
+ Statusbar.Panels[1].Text := data.RecordName;
+ Statusbar.Panels[2].Text := Format('Record size: %d bytes', [n]);
+ Statusbar.Panels[3].Text := '';
+ end else begin
+ Statusbar.Panels[0].Text := '';
+ Statusbar.Panels[1].Text := data.RecordName;
+ Statusbar.Panels[2].Text := '';
+ Statusbar.Panels[3].Text := '';
+ end;
+ PopulateHexDump;
+ PageControlChange(nil);
+end;
+
+
+procedure TMainForm.BIFFTreeFreeNode(Sender: TBaseVirtualTree;
+ Node: PVirtualNode);
+var
+ ptr: PObjectNodeData;
+begin
+ ptr := BiffTree.GetNodeData(Node);
+ if ptr <> nil then
+ FreeAndNil(ptr^.Data);
+end;
+
+
+procedure TMainForm.BIFFTreeGetNodeDataSize(Sender: TBaseVirtualTree;
+ var NodeDataSize: Integer);
+begin
+ NodeDataSize := SizeOf(TObjectNodeData);
+end;
+
+
+procedure TMainForm.BIFFTreeGetText(Sender: TBaseVirtualTree;
+ Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
+ var CellText: String);
+var
+ ptr: PObjectNodeData;
+ data: TBiffNodeData;
+begin
+ CellText := '';
+ ptr := Sender.GetNodeData(Node);
+ if ptr <> nil then begin
+ data := TBiffNodeData(ptr^.Data);
+ case Sender.GetNodeLevel(Node) of
+ 0: if Column = 0 then
+ CellText := data.RecordName;
+ 1: case Column of
+ 0: CellText := IntToStr(data.Offset);
+ 1: CellText := Format('$%.4x', [data.RecordID]);
+ 2: CellText := data.RecordName;
+ 3: CellText := data.RecordDescription;
+ end;
+ end;
+ end;
+end;
+
+
+procedure TMainForm.BIFFTreePaintText(Sender: TBaseVirtualTree;
+ const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
+ TextType: TVSTTextType);
+begin
+ // Paint parent node in bold font.
+ if (Sender.GetNodeLevel(Node) = 0) and (Column = 0) then
+ TargetCanvas.Font.Style := [fsBold];
+end;
+
+
+procedure TMainForm.CbFindChange(Sender: TObject);
+begin
+ ExecFind(true, true);
+end;
+
+
+procedure TMainForm.CbFindKeyPress(Sender: TObject; var Key: char);
+begin
+ if Key = #13 then
+ ExecFind(true, false);
+end;
+
+
+procedure TMainForm.ExecFind(ANext, AKeep: Boolean);
+var
+ s: String;
+ node, node0: PVirtualNode;
+
+ function GetRecordname(ANode: PVirtualNode; UseLowercase: Boolean = true): String;
+ var
+ data: TBIffNodeData;
+ begin
+ data := GetNodeData(ANode);
+ if Assigned(data) then begin
+ if UseLowercase then
+ Result := lowercase(data.RecordName)
+ else
+ Result := data.RecordName;
+ end else
+ Result := '';
+ end;
+
+ function GetNextNode(ANode: PVirtualNode): PVirtualNode;
+ var
+ nextparent: PVirtualNode;
+ begin
+ Result := BiffTree.GetNextSibling(ANode);
+ if (Result = nil) and (ANode <> nil) then begin
+ nextparent := BiffTree.GetNextSibling(ANode^.Parent);
+ if nextparent = nil then
+ nextparent := BiffTree.GetFirst;
+ Result := BiffTree.GetFirstChild(nextparent);
+ end;
+ end;
+
+ function GetPrevNode(ANode: PVirtualNode): PVirtualNode;
+ var
+ prevparent: PVirtualNode;
+ begin
+ Result := BiffTree.GetPreviousSibling(ANode);
+ if (Result = nil) and (ANode <> nil) then begin
+ prevparent := BiffTree.GetPreviousSibling(ANode^.Parent);
+ if prevparent = nil then
+ prevparent := BiffTree.GetLast;
+ Result := BiffTree.GetLastChild(prevparent);
+ end;
+ end;
+
+begin
+ if CbFind.Text = '' then
+ exit;
+
+ s := Lowercase(CbFind.Text);
+ node0 := BiffTree.FocusedNode;
+ if node0 = nil then
+ node0 := BiffTree.GetFirst;
+ if BiffTree.GetNodeLevel(node0) = 0 then
+ node0 := BiffTree.GetFirstChild(node0);
+
+ if ANext then begin
+ if AKeep
+ then node := node0
+ else node := GetNextNode(node0);
+ repeat
+ if pos(s, GetRecordname(node)) > 0 then begin
+ BiffTree.FocusedNode := node;
+ BiffTree.Selected[node] := true;
+ BiffTree.ScrollIntoView(node, true);
+ AddToHistory(GetRecordname(node, false));
+ exit;
+ end;
+ node := GetNextNode(node);
+ until (node = node0) or (node = nil);
+ end else begin
+ if AKeep
+ then node := node0
+ else node := GetPrevNode(node0);
+ repeat
+ if pos(s, GetRecordName(node)) > 0 then begin
+ BiffTree.FocusedNode := node;
+ BiffTree.Selected[node] := true;
+ BiffTree.ScrollIntoView(node, true);
+ AddToHistory(GetRecordName(node, false));
+ exit;
+ end;
+ node := GetPrevNode(node);
+ until (node = node0) or (node = nil);
+ end;
+end;
+
+
+procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: boolean);
+begin
+ if CanClose then
+ try
+ WriteToIni;
+ except
+ MessageDlg('Could not write setting to configuration file.', mtError, [mbOK], 0);
+ end;
+end;
+
+
+procedure TMainForm.FormCreate(Sender: TObject);
+begin
+ FMRUMenuManager := TMRUMenuManager.Create(self);
+ with FMRUMenuManager do begin
+ Name := 'MRUMenuManager';
+ IniFileName := GetAppConfigFile(false);
+ IniSection := 'RecentFiles';
+ MaxRecent := 16;
+ MenuCaptionMask := '&%x - %s'; // & --> create hotkey
+ MenuItem := MnuFileReopen;
+ PopupMenu := RecentFilesPopupMenu;
+ OnRecentFile := @MRUMenuManagerRecentFile;
+ end;
+
+ HexGrid.ColWidths[HexGrid.ColCount-1] := 5;
+ HexGrid.DefaultRowHeight := HexGrid.Canvas.TextHeight('Tg') + 4;
+ AlphaGrid.DefaultRowHeight := HexGrid.DefaultRowHeight;
+ ValueGrid.DefaultRowHeight := HexGrid.DefaultRowHeight;
+ BiffTree.DefaultNodeHeight := HexGrid.DefaultRowHeight;
+ BiffTree.Header.DefaultHeight := HexGrid.DefaultRowHeight + 4;
+
+ FAnalysisGrid := TBIFFGrid.Create(self);
+ with FAnalysisGrid do begin
+ Parent := PgAnalysis;
+ Align := alClient;
+ DefaultRowHeight := HexGrid.DefaultRowHeight;
+ Options := Options + [goDrawFocusSelected];
+ TitleStyle := tsNative;
+ OnDetails := @AnalysisGridDetails;
+ end;
+
+ with ValueGrid do begin
+ ColCount := 3;
+ RowCount := VALUE_ROW_WIDESTRING+1;
+ Cells[0, 0] := 'Data type';
+ Cells[1, 0] := 'Value';
+ Cells[2, 0] := 'Offset range';
+ Cells[0, VALUE_ROW_INDEX] := 'Offset';
+ Cells[0, VALUE_ROW_BYTE] := 'Byte';
+ Cells[0, VALUE_ROW_WORD] := 'Word';
+ Cells[0, VALUE_ROW_DWORD] := 'DWord';
+ Cells[0, VALUE_ROW_QWORD] := 'QWord';
+ Cells[0, VALUE_ROW_DOUBLE] := 'Double';
+ Cells[0, VALUE_ROW_ANSISTRING] := 'AnsiString';
+ Cells[0, VALUE_ROW_WIDESTRING] := 'WideString';
+ end;
+end;
+
+
+procedure TMainForm.FormDestroy(Sender: TObject);
+begin
+ if MemStream <> nil then
+ FreeAndNil(MemStream);
+ if OLEStorage <> nil then
+ FreeAndNil(OLEStorage);
+end;
+
+
+procedure TMainForm.FormShow(Sender: TObject);
+begin
+ Width := Width + 1; // remove black rectangle next to ValueGrid
+ Width := Width - 1;
+end;
+
+
+function TMainForm.GetNodeData(ANode: PVirtualNode): TBiffNodeData;
+var
+ ptr: PObjectNodeData;
+begin
+ result := nil;
+ if ANode <> nil then begin
+ ptr := BiffTree.GetNodeData(ANode);
+ if ptr <> nil then Result := TBiffNodeData(ptr^.Data);
+ end;
+end;
+
+
+function TMainForm.GetRecType: Word;
+var
+ data: TBiffNodeData;
+begin
+ Result := Word(-1);
+ if BiffTree.FocusedNode <> nil then begin
+ data := GetNodeData(BiffTree.FocusedNode);
+ if data <> nil then begin
+ MemStream.Position := data.Offset;
+ Result := WordLEToN(MemStream.ReadWord);
+ end;
+ end;
+end;
+
+
+procedure TMainForm.GridClick(Sender: TObject);
+begin
+ if PageControl.ActivePage = PgValues then
+ PopulateValueGrid;
+end;
+
+
+procedure TMainForm.HexGridPrepareCanvas(sender: TObject; aCol, aRow: Integer;
+ aState: TGridDrawState);
+var
+ ts: TTextStyle;
+begin
+ ts := HexGrid.Canvas.TextStyle;
+ if ACol = 0 then
+ ts.Alignment := taRightJustify
+ else
+ ts.Alignment := taCenter;
+ ts.Opaque := false;
+ ts.Layout := tlCenter;
+ HexGrid.Canvas.TextStyle := ts;
+
+ ts.Alignment := taCenter;
+ AlphaGrid.Canvas.TextStyle := ts;
+end;
+
+
+procedure TMainForm.HexGridSelection(Sender: TObject; aCol, aRow: Integer);
+begin
+ if (FLockHexDumpGrids > 0) then
+ exit;
+ FCurrOffset := (ARow - HexGrid.FixedRows)*16 + (ACol - HexGrid.FixedCols);
+ if FCurrOffset < 0 then
+ FCurrOffset := 0;
+ inc(FLockHexDumpGrids);
+ AlphaGrid.Row := aRow - HexGrid.FixedRows + AlphaGrid.FixedRows;
+ AlphaGrid.Col := aCol - HexGrid.FixedCols + AlphaGrid.FixedCols;
+ dec(FLockHexDumpGrids);
+ if FCurrOffset > -1 then
+ Statusbar.Panels[3].Text := Format('HexViewer offset: %d', [FCurrOffset])
+ else
+ Statusbar.Panels[3].Text := '';
+end;
+
+
+procedure TMainForm.LoadFile(const AFileName: String);
+var
+ fmt: TsSpreadsheetFormat;
+ valid: Boolean;
+ excptn: Exception = nil;
+begin
+ if not FileExists(AFileName) then begin
+ MessageDlg(Format('File "%s" not found.', [AFileName]), mtError, [mbOK], 0);
+ exit;
+ end;
+
+ if not SameText(ExtractFileExt(AFileName), '.xls') then begin
+ MessageDlg('BIFFExplorer can only process binary Excel files (extension ".xls")',
+ mtError, [mbOK], 0);
+ exit;
+ end;
+
+ fmt := sfExcel8;
+ while True do begin
+ try
+ LoadFile(AFileName, fmt);
+ valid := True;
+ except
+ on E: Exception do begin
+ if fmt = sfExcel8 then excptn := E;
+ valid := False
+ end;
+ end;
+ if valid or (fmt = sfExcel2) then Break;
+ fmt := Pred(fmt);
+ end;
+
+ // A failed attempt to read a file should bring an exception, so re-raise
+ // the exception if necessary. We re-raise the exception brought by Excel 8,
+ // since this is the most common format
+ if (not valid) and (excptn <> nil) then
+ raise excptn;
+
+ FFormat := fmt;
+end;
+
+
+procedure TMainForm.LoadFile(const AFileName: String; AFormat: TsSpreadsheetFormat);
+var
+ OLEDocument: TOLEDocument;
+begin
+ if MemStream <> nil then
+ FreeAndNil(MemStream);
+
+ if OLEStorage <> nil then
+ FreeAndNil(OLEStorage);
+
+ MemStream := TMemoryStream.Create;
+
+ if AFormat = sfExcel2 then begin
+ MemStream.LoadFromFile(AFileName);
+ end else begin
+ OLEStorage := TOLEStorage.Create;
+
+ // Only one stream is necessary for any number of worksheets
+ OLEDocument.Stream := MemStream;
+ OLEStorage.ReadOLEFile(AFileName, OLEDocument, 'Workbook');
+
+ // Check if the operation succeded
+ if MemStream.Size = 0 then
+ raise Exception.Create('BIFF Explorer: Reading the OLE document failed');
+ end;
+
+ // Rewind the stream and read from it
+ MemStream.Position := 0;
+ FFileName := ExpandFileName(AFileName);
+ ReadFromStream(MemStream);
+
+ UpdateCaption;
+ FMRUMenuManager.AddToRecent(AFileName);
+end;
+
+
+procedure TMainForm.ListViewSelectItem(Sender: TObject; Item: TListItem;
+ Selected: Boolean);
+var
+ n: Word;
+begin
+ if Selected then begin
+ // Move to start of record + 2 bytes to skip record type ID.
+ MemStream.Position := PtrInt(Item.Data) + 2;
+
+ // Read size of record
+ n := WordLEToN(MemStream.ReadWord);
+
+ // Read record data
+ SetLength(FBuffer, n);
+ MemStream.ReadBuffer(FBuffer[0], n);
+
+ // Update user interface
+ Statusbar.Panels[0].Text := Format('Record ID: %s', [Item.SubItems[0]]);
+ Statusbar.Panels[1].Text := Item.SubItems[1];
+ Statusbar.Panels[2].Text := Format('Record size: %s bytes', [Item.SubItems[3]]);
+ PopulateHexDump;
+ PageControlChange(nil);
+ end;
+end;
+
+
+procedure TMainForm.MRUMenuManagerRecentFile(Sender: TObject;
+ const AFileName: string);
+begin
+ LoadFile(AFileName);
+end;
+
+
+procedure TMainForm.PopulateAnalysisGrid;
+begin
+ FAnalysisGrid.SetRecordType(GetRecType, FBuffer, FFormat);
+end;
+
+
+procedure TMainForm.PopulateHexDump;
+var
+ n: Word;
+ i,r,c, w: Integer;
+begin
+ n := Length(FBuffer);
+
+ // Prepare hex viewer rows...
+ r := HexGrid.FixedRows + n div 16;
+ if n mod 16 <> 0 then inc(r);
+ HexGrid.RowCount := r;
+ AlphaGrid.RowCount := r;
+ for i:=HexGrid.FixedRows to r-1 do begin
+ HexGrid.Rows[i].Clear;
+ HexGrid.Cells[0, i] := IntToStr((i - HexGrid.FixedRows)*16);
+ AlphaGrid.Rows[i].Clear;
+ end;
+
+ // ... width of first column, ...
+ w := HexGrid.Canvas.TextWidth(IntToStr(n)) + 4;
+ if w > HexGrid.DefaultColWidth then
+ HexGrid.ColWidths[0] := w;
+
+ // ... and cells
+ for i:=0 to Length(FBuffer)-1 do begin
+ c := i mod 16;
+ r := i div 16;
+ with HexGrid do
+ Cells[c+FixedCols, r+FixedRows] := Format('%.2x', [FBuffer[i]]);
+ with AlphaGrid do
+ if FBuffer[i] < 32 then
+ Cells[c+FixedCols, r+FixedRows] := '.'
+ else
+ Cells[c+FixedCols, r+FixedRows] := AnsiToUTF8(AnsiChar(FBuffer[i]));
+ end;
+
+ // Clear value grid
+ if PageControl.ActivePage = PgValues then
+ with ValueGrid do begin
+ Clean(1, 1, RowCount-1, ColCount-1, [gzNormal]);
+ end;
+
+ // Update status bar
+ HexGridSelection(nil, HexGrid.Col, HexGrid.Row);
+end;
+
+
+procedure TMainForm.PopulateValueGrid;
+var
+ buf: array[0..1023] of Byte;
+ w: word absolute buf;
+ dw: DWord absolute buf;
+ qw: QWord absolute buf;
+ dbl: double absolute buf;
+ idx: Integer;
+ i, j: Integer;
+ s: String;
+ sw: WideString;
+ ls: Integer;
+begin
+ idx := FCurrOffset;
+
+ i := ValueGrid.RowCount;
+ j := ValueGrid.ColCount;
+
+ ValueGrid.Cells[1, VALUE_ROW_INDEX] := IntToStr(idx);
+
+ if idx <= Length(FBuffer)-SizeOf(byte) then begin
+ ValueGrid.Cells[1, VALUE_ROW_BYTE] := IntToStr(FBuffer[idx]);
+ ValueGrid.Cells[2, VALUE_ROW_BYTE] := Format('%d ... %d', [idx, idx]);
+ end
+ else begin
+ ValueGrid.Cells[1, VALUE_ROW_BYTE] := '';
+ ValueGrid.Cells[2, VALUE_ROW_BYTE] := '';
+ end;
+
+ if idx <= Length(FBuffer)-SizeOf(word) then begin
+ buf[0] := FBuffer[idx];
+ buf[1] := FBuffer[idx+1];
+ ValueGrid.Cells[1, VALUE_ROW_WORD] := IntToStr(WordLEToN(w));
+ ValueGrid.Cells[2, VALUE_ROW_WORD] := Format('%d ... %d', [idx, idx+SizeOf(Word)-1]);
+ end else begin
+ ValueGrid.Cells[1, VALUE_Row_WORD] := '';
+ ValueGrid.Cells[2, VALUE_ROW_WORD] := '';
+ end;
+
+ if idx <= Length(FBuffer) - SizeOf(DWord) then begin
+ for i:=0 to SizeOf(DWord)-1 do buf[i] := FBuffer[idx+i];
+ ValueGrid.Cells[1, VALUE_ROW_DWORD] := IntToStr(DWordLEToN(dw));
+ ValueGrid.Cells[2, VALUE_ROW_DWORD] := Format('%d ... %d', [idx, idx+SizeOf(DWord)-1]);
+ end else begin
+ ValueGrid.Cells[1, VALUE_ROW_DWORD] := '';
+ ValueGrid.Cells[2, VALUE_ROW_DWORD] := '';
+ end;
+
+ if idx <= Length(FBuffer) - SizeOf(QWord) then begin
+ for i:=0 to SizeOf(QWord)-1 do buf[i] := FBuffer[idx+i];
+ ValueGrid.Cells[1, VALUE_ROW_QWORD] := Format('%d', [qw]);
+ ValueGrid.Cells[2, VALUE_ROW_QWORD] := Format('%d ... %d', [idx, idx+SizeOf(QWord)-1]);
+ end else begin
+ ValueGrid.Cells[1, VALUE_ROW_QWORD] := '';
+ ValueGrid.Cells[2, VALUE_ROW_QWORD] := '';
+ end;
+
+ if idx <= Length(FBuffer) - SizeOf(double) then begin
+ for i:=0 to SizeOf(double)-1 do buf[i] := FBuffer[idx+i];
+ ValueGrid.Cells[1, VALUE_ROW_DOUBLE] := Format('%f', [dbl]);
+ ValueGrid.Cells[2, VALUE_ROW_DOUBLE] := Format('%d ... %d', [idx, idx+SizeOf(Double)-1]);
+ end else begin
+ ValueGrid.Cells[1, VALUE_ROW_DOUBLE] := '';
+ ValueGrid.Cells[2, VALUE_ROW_DOUBLE] := '';
+ end;
+
+ if idx < Length(FBuffer) then begin
+ ls := FBuffer[idx];
+ SetLength(s, ls);
+ i := idx + 1;
+ j := 0;
+ while (i < Length(FBuffer)) and (j < Length(s)) do begin
+ inc(j);
+ s[j] := char(FBuffer[i]);
+ inc(i);
+ end;
+ SetLength(s, j);
+ ValueGrid.Cells[1, VALUE_ROW_ANSISTRING] := s;
+ ValueGrid.Cells[2, VALUE_ROW_ANSISTRING] := Format('%d ... %d', [idx, ls * SizeOf(char) + 1]);
+ end else begin
+ ValueGrid.Cells[1, VALUE_ROW_ANSISTRING] := '';
+ ValueGrid.Cells[2, VALUE_ROW_ANSISTRING] := '';
+ end;
+
+ if idx < Length(FBuffer) then begin
+ ls := FBuffer[idx];
+ SetLength(sw, ls);
+ j := 0;
+ i := idx + 2;
+ while (i < Length(FBuffer)-1) and (j < Length(sw)) do begin
+ buf[0] := FBuffer[i];
+ buf[1] := FBuffer[i+1];
+ inc(i, SizeOf(WideChar));
+ inc(j);
+ sw[j] := WideChar(w);
+ end;
+ SetLength(sw, j);
+ ValueGrid.Cells[1, VALUE_ROW_WIDESTRING] := UTF8Decode(sw);
+ ValueGrid.Cells[2, VALUE_ROW_WIDESTRING] := Format('%d ... %d', [idx, idx + ls*SizeOf(wideChar)+1]);
+ end else begin
+ ValueGrid.Cells[1, VALUE_ROW_WIDESTRING] := '';
+ ValueGrid.Cells[2, VALUE_ROW_WIDESTRING] := '';
+ end;
+end;
+
+
+procedure TMainForm.ReadCmdLine;
+begin
+ if ParamCount > 0 then
+ LoadFile(ParamStr(1));
+end;
+
+
+procedure TMainForm.ReadFromIni;
+var
+ ini: TCustomIniFile;
+ i: Integer;
+begin
+ ini := CreateIni;
+ try
+ ReadFormFromIni(ini, 'MainForm', self);
+
+ BiffTree.Width := ini.ReadInteger('MainForm', 'RecordList_Width', BiffTree.Width);
+ for i:=0 to BiffTree.Header.Columns.Count-1 do
+ BiffTree.Header.Columns[i].Width := ini.ReadInteger('MainForm',
+ Format('RecordList_ColWidth_%d', [i+1]), BiffTree.Header.Columns[i].Width);
+
+ ValueGrid.Height := ini.ReadInteger('MainForm', 'ValueGrid_Height', ValueGrid.Height);
+ for i:=0 to ValueGrid.ColCount-1 do
+ ValueGrid.ColWidths[i] := ini.ReadInteger('MainForm',
+ Format('ValueGrid_ColWidth_%d', [i+1]), ValueGrid.ColWidths[i]);
+
+ AlphaGrid.Width := ini.ReadInteger('MainForm', 'AlphaGrid_Width', AlphaGrid.Width);
+ for i:=0 to AlphaGrid.ColCount-1 do
+ AlphaGrid.ColWidths[i] := ini.ReadInteger('MainForm',
+ Format('AlphaGrid_ColWidth_%d', [i+1]), AlphaGrid.ColWidths[i]);
+
+ for i:=0 to FAnalysisGrid.ColCount-1 do
+ FAnalysisGrid.ColWidths[i] := ini.ReadInteger('MainForm',
+ Format('AnalysisGrid_ColWidth_%d', [i+1]), FAnalysisGrid.ColWidths[i]);
+
+ AnalysisDetails.Width := ini.ReadInteger('MainForm', 'AnalysisDetails_Width', AnalysisDetails.Width);
+
+ PageControl.Height := ini.ReadInteger('MainForm', 'PageControl_Height', PageControl.Height);
+ PageControl.ActivePageIndex := ini.ReadInteger('MainForm', 'PageIndex', PageControl.ActivePageIndex);
+ finally
+ ini.Free;
+ end;
+end;
+
+
+procedure TMainForm.ReadFromStream(AStream: TStream);
+var
+ recType: Word;
+ recSize: Word;
+ p: Cardinal;
+ p0: Cardinal;
+ s: String;
+ i: Integer;
+ node: PVirtualNode;
+ parentnode: PVirtualNode;
+ ptr: PObjectNodeData;
+ parentdata, data: TBiffNodeData;
+ w: word;
+ crs: TCursor;
+begin
+ crs := Screen.Cursor;
+ try
+ Screen.Cursor := crHourGlass;
+ BiffTree.Clear;
+ parentnode := nil;
+ AStream.Position := 0;
+ while AStream.Position < AStream.Size do begin
+ p := AStream.Position;
+ recType := WordLEToN(AStream.ReadWord);
+ recSize := WordLEToN(AStream.ReadWord);
+ s := RecTypeName(recType);
+ i := pos(':', s);
+ // in case of BOF record: create new parent node for this substream
+ if (recType = $0009) or (recType = $0209) or (recType = $0409) or (recType = $0809)
+ then begin
+ // Read info on substream beginning here
+ p0 := AStream.Position;
+ AStream.Position := AStream.Position + 2;
+ w := WordLEToN(AStream.ReadWord);
+ AStream.Position := p0;
+ parentdata := TBiffNodeData.Create;
+ parentdata.Offset := p;
+ parentdata.Recordname := BOFName(w);
+ // add parent node for this substream
+ parentnode := BIFFTree.AddChild(nil);
+ ptr := BIFFTree.GetNodeData(parentnode);
+ ptr^.Data := parentdata;
+ end;
+ // add node to parent node
+ data := TBiffNodeData.Create;
+ data.Offset := p;
+ data.RecordID := recType;
+ if i > 0 then begin
+ data.RecordName := copy(s, 1, i-1);
+ data.RecordDescription := copy(s, i+2, Length(s));
+ end else begin
+ data.RecordName := s;
+ data.RecordDescription := '';
+ end;
+ node := BIFFTree.AddChild(parentnode);
+ ptr := BIFFTree.GetNodeData(node);
+ ptr^.Data := data;
+ // advance stream pointer
+ AStream.Position := AStream.Position + recSize;
+ end;
+ // expand all parent nodes
+ node := BiffTree.GetFirst;
+ while node <> nil do begin
+ BiffTree.Expanded[node] := true;
+ node := BiffTree.GetNextSibling(node);
+ end;
+ // Select first node
+ BiffTree.FocusedNode := BiffTree.GetFirst;
+ BiffTree.Selected[BiffTree.FocusedNode] := true;
+
+ finally
+ Screen.Cursor := crs;
+ end;
+end;
+
+
+procedure TMainForm.PageControlChange(Sender: TObject);
+begin
+ if PageControl.ActivePage = PgAnalysis then
+ PopulateAnalysisGrid
+ else
+ if PageControl.ActivePage = PgValues then
+ PopulateValueGrid;
+end;
+
+
+procedure TMainForm.UpdateCaption;
+begin
+ Caption := Format('BIFF Explorer - "%s', [IfThen(FFileName <> '', FFileName, 'no file loaded')]);
+end;
+
+
+procedure TMainForm.WriteToIni;
+var
+ ini: TCustomIniFile;
+ i: Integer;
+begin
+ ini := CreateIni;
+ try
+ WriteFormToIni(ini, 'MainForm', self);
+
+ ini.WriteInteger('MainForm', 'RecordList_Width', BiffTree.Width);
+ for i:=0 to BiffTree.Header.Columns.Count-1 do
+ ini.WriteInteger('MainForm', Format('RecordList_ColWidth_%d', [i+1]), BiffTree.Header.Columns[i].Width);
+
+ ini.WriteInteger('MainForm', 'ValueGrid_Height', ValueGrid.Height);
+ for i:=0 to ValueGrid.ColCount-1 do
+ ini.WriteInteger('MainForm', Format('ValueGrid_ColWidth_%d', [i+1]), ValueGrid.ColWidths[i]);
+
+ ini.WriteInteger('MainForm', 'AlphaGrid_Width', AlphaGrid.Width);
+ for i:=0 to AlphaGrid.ColCount-1 do
+ ini.WriteInteger('MainForm', Format('AlphaGrid_ColWidth_%d', [i+1]), AlphaGrid.ColWidths[i]);
+
+ for i:=0 to FAnalysisGrid.ColCount-1 do
+ ini.WriteInteger('MainForm', Format('AnalysisGrid_ColWidth_%d', [i+1]), FAnalysisGrid.ColWidths[i]);
+
+ ini.WriteInteger('MainForm', 'AnalysisDetails_Width', AnalysisDetails.Width);
+
+ ini.WriteInteger('MainForm', 'PageIndex', PageControl.ActivePageIndex);
+ ini.WriteInteger('MainForm', 'PageControl_Height', PageControl.Height);
+ finally
+ ini.Free;
+ end;
+end;
+
+end.
+
diff --git a/components/fpspreadsheet/reference/BIFFExplorer/beutils.pas b/components/fpspreadsheet/reference/BIFFExplorer/beutils.pas
new file mode 100644
index 000000000..736ea8475
--- /dev/null
+++ b/components/fpspreadsheet/reference/BIFFExplorer/beutils.pas
@@ -0,0 +1,66 @@
+unit beUtils;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, IniFiles, Forms;
+
+function CreateIni : TCustomIniFile;
+procedure ReadFormFromIni(ini: TCustomIniFile; ASection: String; AForm: TCustomForm);
+procedure WriteFormToIni(ini: TCustomIniFile; ASection: String; AForm: TCustomForm);
+
+
+implementation
+
+function CreateIni : TCustomIniFile;
+var
+ cfg : string;
+begin
+ cfg := GetAppConfigDir(false);
+ if not DirectoryExists(cfg) then
+ CreateDir(cfg);
+ result := TMemIniFile.Create(GetAppConfigFile(false));
+end;
+
+procedure ReadFormFromIni(ini: TCustomIniFile; ASection: String; AForm: TCustomForm);
+var
+ L,T,W,H: Integer;
+ isMax: Boolean;
+begin
+ L := ini.ReadInteger(ASection, 'Left', AForm.Left);
+ T := Ini.ReadInteger(ASection, 'Top', AForm.Top);
+ W := ini.ReadInteger(ASection, 'Width', AForm.Width);
+ H := ini.ReadInteger(ASection, 'Height', AForm.Height);
+ isMax := ini.ReadBool(ASection, 'Maximized', AForm.WindowState = wsMaximized);
+ if W > Screen.Width then W := Screen.Width;
+ if H > Screen.Height then H := Screen.Height;
+ if L < 0 then L := 0;
+ if T < 0 then T := 0;
+ if L + W > Screen.Width then L := Screen.Width - W;
+ if T + H > Screen.Height then T := Screen.Height - H;
+ AForm.Left := L;
+ AForm.Top := T;
+ AForm.Width := W;
+ AForm.Height := H;
+ if IsMax then
+ AForm.WindowState := wsMaximized
+ else
+ AForm.WindowState := wsNormal;
+end;
+
+
+procedure WriteFormToIni(ini: TCustomIniFile; ASection: String; AForm: TCustomForm);
+begin
+ ini.WriteBool(ASection, 'Maximized', (AForm.WindowState = wsMaximized));
+ if AForm.WindowState = wsNormal then begin
+ ini.WriteInteger(ASection, 'Left', AForm.Left);
+ ini.WriteInteger(ASection, 'Top', AForm.Top);
+ ini.WriteInteger(ASection, 'Width', AForm.Width);
+ ini.WriteInteger(ASection, 'Height', AForm.Height);
+ end;
+end;
+
+end.
+
diff --git a/components/fpspreadsheet/reference/BIFFExplorer/mrumanager.pp b/components/fpspreadsheet/reference/BIFFExplorer/mrumanager.pp
new file mode 100644
index 000000000..847f886e9
--- /dev/null
+++ b/components/fpspreadsheet/reference/BIFFExplorer/mrumanager.pp
@@ -0,0 +1,485 @@
+{ MRU (Most Recent Used) menu item manager
+
+ Copyright (C) 2011 Michael Van Canneyt (michael@freepascal.org)
+ Modifications by Werner Pamler
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version with the following modification:
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent modules,and
+ to copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the terms
+ and conditions of the license of that module. An independent module is a
+ module which is not derived from or based on this library. If you modify
+ this library, you may extend this exception to your version of the library,
+ but you are not obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
+ for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ modified by wp
+}
+unit mrumanager;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, inifiles, menus;
+
+Type
+ { TRecentMenuItem }
+
+ TRecentMenuItem = Class(TMenuItem)
+ Private
+ FFileName : string;
+ Public
+ Property FileName : String Read FFileName;
+ end;
+ TRecentMenuItemClass = Class of TRecentMenuItem;
+
+ { TMRUMenuManager }
+
+ TOnRecentFileEvent = Procedure(Sender : TObject; Const AFileName : String) of object;
+
+ TMRUMenuManager = Class(TComponent)
+ Private
+ FIniFileName: String;
+ FIniSection: String;
+ FOnRecent: TOnRecentFileEvent;
+ FRecent : TStrings;
+ FMaxRecent : Integer;
+ FMenuCaptionMask : string;
+ FMIRecent : TMenuItem;
+ FPMRecent : TPopupMenu;
+ FMaxItemLength : integer;
+ procedure SetIniFileName(const AValue:string);
+ procedure SetIniSection(const AValue:string);
+ procedure SetMaxItemLength(const AValue:integer);
+ procedure SetMenuCaptionMask(const AValue:string);
+ procedure SetMIRecent(const AValue: TMenuItem);
+ procedure SetPMRecent(const AValue: TPopupMenu);
+ procedure SetRecent(const AValue: TStrings);
+ protected
+ // Overrides.
+ procedure Loaded; override;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ // Return default name and section if either is empty.
+ procedure GetFileNameAndSection(Var AFileName,ASection : String); virtual;
+ // Override if you want to load additional values.
+ procedure LoadFromIni(Ini: TCustomIniFile; ASection: String); virtual;
+ // Override if you want to write additional values.
+ procedure SaveToIni(Ini: TCustomIniFile; ASection: String); virtual;
+ // Called when menu item is clicked.
+ procedure DoOnRecentClick(Sender: TObject); virtual;
+ // Override this if you want to create a custom class of menu itel.
+ function CreateMenuItem(AOwner: TComponent): TRecentMenuItem; virtual;
+ // Create a menu caption. Default is index followed by filename.
+ // Override if you want to customize.
+ Function CreateMenuCaption(AIndex : Integer; Const AFileName : String) : String; virtual;
+ Public
+ Constructor Create(AOwner : TComponent);override;
+ Destructor Destroy; override;
+ // Load files from ini file AFileName in section ASection. Calls ShowRecentFiles
+ // Need for explicit call only when IniFileName='' and IniSection='' and class created at run-time
+ procedure LoadRecentFilesFromIni(const AFileName: string=''; const ASection: String='');
+ // Saves files to ini file AFileName in section ASection.
+ procedure SaveRecentFilesToIni(const AFileName: string=''; const ASection: String='');
+ // Add a filename to the list of files.
+ // If an existing file is added, it is moved first in the list.
+ // If MaxRecent is attained, the last one is removed.
+ // Calls ShowRecentFiles.
+ procedure AddToRecent(AFileName: String);
+ // Re-populate the menu.
+ procedure ShowRecentFiles;
+ Published
+ // Max. items to be kept in the list.
+ Property MaxRecent : Integer Read FMaxRecent write FMaxRecent;
+ // Menu item to create a submenu under. Existing items will be removed.
+ Property MenuItem : TMenuItem Read FMIRecent Write SetMIRecent;
+ // Popupmenu attached to a toolbar button. Existing items will be removed.
+ Property PopupMenu : TPopupMenu Read FPMRecent Write SetPMRecent;
+ // Default ini filename.
+ Property IniFileName : String Read FIniFileName Write SetIniFileName;
+ // Default ini section.
+ Property IniSection : String Read FIniSection Write SetIniSection;
+ // Maximum length of recent menu item
+ Property MaxItemLength : integer Read FMaxItemLength Write SetMaxItemLength default 80;
+ // Format mask for MenuCaption: first placeholder must be %d, second %s, e.g. '%d - %s'
+ Property MenuCaptionMask : string read FMenuCaptionMask Write SetMenuCaptionMask;
+ // Recent items. If adding manually to the list, ShowRecentFiles must be called manually.
+ Property Recent : TStrings Read FRecent Write SetRecent;
+ // Called when the user clicks an recent meu item.
+ Property OnRecentFile : TOnRecentFileEvent Read FOnRecent Write FOnRecent;
+ end;
+ EMRUManager = Class(Exception);
+
+Const
+ DefaultIniFile = 'recent.ini';
+ DefaultSection = 'Global';
+ KeyMaxRecent = 'MaxRecent';
+ KeyCount = 'Count';
+ KeyFile = 'File%d';
+
+implementation
+
+Resourcestring
+ SErrFailedToCreateDir = 'Failed to create directory "%s"';
+
+const
+ DEFAULT_MASK = '%d. %s';
+
+function MinimizeFileName(const AFileName:string; AMaxLen:integer) : string;
+
+ procedure SplitPath(const APath:String; Parts: TStrings);
+ { Splits the provided path into constituent folder names }
+ var
+ i, j : Integer;
+ begin
+ if APath = '' then exit;
+ if not Assigned(Parts) then exit;
+
+ i := Length(APath);
+ j := i;
+ while (i >= 1) do begin
+ if APath[i] = DirectorySeparator then begin
+ Parts.Insert(0, copy(APath, i+1, j-i));
+ j := i;
+ end;
+ dec(i);
+ end;
+ Parts.Insert(0, copy(APath, 1, j));
+ end;
+
+ function AddStringsFromTo(AList:TStrings; FromIndex,ToIndex:integer) : string;
+ var
+ i : integer;
+ begin
+ result := '';
+ for i:=FromIndex to ToIndex do
+ result := result + AList[i];
+ end;
+
+var
+ Parts : TStringList;
+ i : integer;
+ tmp : string;
+begin
+ result := AFileName;
+ if Length(AFileName) > AMaxLen then begin
+ Parts := TStringList.Create;
+ try
+ SplitPath(AFileName, Parts);
+ i := Parts.Count div 2;
+ while (i < Parts.Count) do begin
+ tmp := Format('%s...%s%s', [
+ AddStringsFromTo(Parts, 0, i-1),
+ DirectorySeparator,
+ AddStringsFromTo(Parts, i+1, Parts.Count-1)
+ ]);
+ if Length(tmp) < AMaxLen then begin
+ result := tmp;
+ exit;
+ end else
+ Parts.Delete(i);
+ i := Parts.Count div 2;
+ end;
+ result := ExtractFileName(AFileName);
+ finally
+ Parts.Free;
+ end;
+ end;
+end;
+
+procedure TMRUMenuManager.AddToRecent(AFileName : String);
+
+Var
+ I,J : Integer;
+ B : Boolean;
+
+begin
+ AFileName:=ExpandFileName(AFileName);
+ With FRecent do
+ begin
+ J:=IndexOf(AFileName);
+ If (J<>-1) then
+ begin
+ if (J>0) then
+ Exchange(0,J)
+ end
+ else
+ begin
+ While (Count>=FMaxRecent) do
+ Delete(Count-1);
+ Insert(0,AFileName)
+ end;
+ end;
+ ShowRecentFiles;
+end;
+
+function TMRUMenuManager.CreateMenuItem(AOwner :TComponent) : TRecentMenuItem;
+
+begin
+ Result:=TRecentMenuItem.Create(AOwner);
+end;
+
+function TMRUMenuManager.CreateMenuCaption(AIndex: Integer;
+ const AFileName: String): String;
+var
+ fn : string;
+ mask : string;
+begin
+ if FMaxItemLength > 0 then
+ fn := MinimizeFileName(AFileName, FMaxItemLength)
+ else
+ fn := AFileName;
+ if FMenuCaptionMask = '' then
+ mask := DEFAULT_MASK
+ else
+ mask := FMenuCaptionMask;
+ Result:=Format(mask, [AIndex+1,fn]);
+end;
+
+procedure TMRUMenuManager.ShowRecentFiles;
+
+Var
+ I : Integer;
+ M : TRecentMenuItem;
+
+begin
+ if Assigned(FMIRecent) then begin
+ FMIRecent.clear;
+ For I:=0 to FRecent.Count-1 do
+ begin
+ M:=CreateMenuItem(Self.Owner);
+ M.Caption:=CreateMenuCaption(I,FRecent[i]);
+ M.FFileName:=FRecent[i];
+ M.OnClick:=@DoOnRecentClick;
+ FMIRecent.Add(M);
+ end;
+ end;
+ if Assigned(FPMRecent) then begin
+ FPMRecent.Items.Clear;
+ for i:=0 to FRecent.Count-1 do
+ begin
+ M := CreateMenuItem(Self.Owner);
+ M.Caption := CreateMenuCaption(I, Recent[i]);
+ M.FFileName := FRecent[i];
+ M.OnClick := @DoOnRecentClick;
+ FPMRecent.Items.Add(M);
+ end;
+ end;
+end;
+
+procedure TMRUMenuManager.LoadFromIni(Ini : TCustomIniFile; ASection : String);
+
+Var
+ I,Count : Integer;
+ FN : String;
+
+begin
+ FRecent.Clear;
+ FMaxRecent:=Ini.ReadInteger(ASection,KeyMaxRecent,10);
+ Count:=Ini.ReadInteger(ASection,KeyCount,0);
+ For I:=1 to Count do
+ begin
+ FN:=Ini.ReadString(ASection,Format(KeyFile,[i]),'');
+ If (FN<>'') then
+ FRecent.Add(FN);
+ end;
+end;
+
+procedure TMRUMenuManager.GetFileNameAndSection(var AFileName, ASection: String);
+
+begin
+ if (AFileName='') then
+ begin
+ AFileName:=GetAppConfigDir(False);
+ AFileName:=IncludeTrailingPathDelimiter(AFileName)+DefaultIniFile;
+ end;
+ if (ASection='') then
+ ASection:=DefaultSection;
+end;
+
+procedure TMRUMenuManager.LoadRecentFilesFromIni(Const AFileName : string = ''; Const ASection : String = '');
+
+Var
+ DN,FN,Sec : String;
+ Ini : TIniFile;
+
+begin
+ FN:=AFileName;
+ Sec:=ASection;
+ GetFileNameAndSection(FN,Sec);
+ DN:=ExtractFilePath(FN);
+ If ForceDirectories(DN) then
+ begin
+ If FileExists(FN) then
+ begin
+ Ini:=TIniFile.Create(FN);
+ try
+ LoadFromIni(Ini,Sec);
+ finally
+ Ini.Free;
+ end;
+ end;
+ end;
+ ShowRecentFiles;
+end;
+
+procedure TMRUMenuManager.SaveToIni(Ini : TCustomIniFile; ASection : String);
+
+Var
+ I : Integer;
+begin
+ Ini.EraseSection(ASection);
+ Ini.WriteInteger(ASection,KeyMaxRecent,FMaxRecent);
+ Ini.WriteInteger(ASection,KeyCount,FRecent.Count);
+ For I:=0 to FRecent.Count-1 do
+ Ini.WriteString(ASection,Format(KeyFile,[i+1]),FRecent[i]);
+ Ini.UpdateFile;
+end;
+
+procedure TMRUMenuManager.SaveRecentFilesToIni(Const AFileName : string = ''; Const ASection : String = '');
+
+Var
+ DN,FN,Sec : String;
+ Ini : TMemIniFile;
+
+begin
+ FN:=AFileName;
+ Sec:=ASection;
+ GetFileNameAndSection(FN,Sec);
+ DN:=ExtractFilePath(FN);
+ If not ForceDirectories(DN) then
+ Raise EMRUManager.CreateFmt(SErrFailedToCreateDir,[DN]);
+ Ini:=TMemIniFile.Create(FN);
+ try
+ SaveToIni(Ini,Sec);
+ finally
+ Ini.Free;
+ end;
+end;
+
+procedure TMRUMenuManager.SetIniFileName(const AValue:string);
+begin
+ if AValue <> FIniFileName then begin
+ FIniFileName := AValue;
+ LoadRecentFilesFromIni(FIniFileName, FIniSection);
+ end;
+end;
+
+procedure TMRUMenuManager.SetIniSection(const AValue:string);
+begin
+ if AValue <> FIniSection then begin
+ FIniSection := AValue;
+ LoadRecentFilesFromini(FIniFileName, FIniSection);
+ end;
+end;
+
+procedure TMRUMenuManager.SetMaxItemLength(const AValue:integer);
+begin
+ if FMaxItemLength <> AValue then begin
+ FMaxItemLength := AValue;
+ ShowRecentFiles;
+ end;
+end;
+
+procedure TMRUMenuManager.SetMenuCaptionMask(const AValue:string);
+begin
+ if FMenuCaptionMask <> AValue then begin
+ FMenuCaptionMask := AValue;
+ ShowRecentFiles;
+ end;
+end;
+
+procedure TMRUMenuManager.SetMIRecent(const AValue: TMenuItem);
+begin
+ if FMIRecent=AValue then exit;
+ If Assigned(FMIRecent) then
+ FMIRecent.RemoveFreeNotification(Self);
+ FMIRecent:=AValue;
+ If Assigned(FMIRecent) then
+ FMIRecent.FreeNotification(Self);
+ ShowRecentFiles;
+end;
+
+procedure TMRUMenuManager.SetPMRecent(const AValue: TPopupMenu);
+begin
+ if FPMRecent=AValue then exit;
+ if Assigned(FPMRecent) then
+ FPMRecent.RemoveFreeNotification(self);
+ FPMRecent := AValue;
+ if Assigned(FPMRecent) then
+ FPMRecent.FreeNotification(self);
+ ShowRecentFiles;
+end;
+
+procedure TMRUMenuManager.SetRecent(const AValue: TStrings);
+begin
+ if FRecent=AValue then exit;
+ FRecent.Assign(AValue);
+ ShowRecentFiles;
+end;
+
+procedure TMRUMenuManager.loaded;
+begin
+ inherited loaded;
+ if (FRecent.Count>0) and (assigned(FMIRecent) or assigned(FPMRecent))then
+ LoadRecentFilesFromIni(FIniFileName, FIniSection);
+end;
+
+constructor TMRUMenuManager.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FRecent:=TStringList.Create;
+ FMaxItemLength := 80;
+ FMenuCaptionMask := DEFAULT_MASK;
+end;
+
+destructor TMRUMenuManager.Destroy;
+begin
+ SaveRecentFilesToIni(FIniFileName, FIniSection);
+ FreeAndNil(FRecent);
+ inherited Destroy;
+end;
+
+procedure TMRUMenuManager.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if (Operation = opRemove) then begin
+ if AComponent = FMIRecent then FMIRecent := nil;
+ if AComponent = FPMRecent then FPMRecent := nil;
+ end;
+ { original code - I think this is not correct:
+ inherited Notification(AComponent, Operation);
+ if (Operation=opRemove) and ((AComponent=FMIRecent) or (AComponent=FPMRecent)) then
+ exit;
+ }
+end;
+
+procedure TMRUMenuManager.DoOnRecentClick(Sender: TObject);
+Var
+ FN : String;
+begin
+ With (Sender as TRecentMenuItem) do
+ FN:=FileName;
+ if (FN<>'') and (OnRecentFile<>Nil) then
+ OnRecentFile(Self,FN);
+end;
+
+end.
+
diff --git a/components/fpspreadsheet/reference/BIFFExplorer/readme.txt b/components/fpspreadsheet/reference/BIFFExplorer/readme.txt
new file mode 100644
index 000000000..adeae1dc5
--- /dev/null
+++ b/components/fpspreadsheet/reference/BIFFExplorer/readme.txt
@@ -0,0 +1,18 @@
+BIFF Explorer
+--------------------------------------------------------------------------------
+
+"BIFF Explorer" is a tool to peek into the internal structure of a binary
+Excel file in biff format.
+
+It displays a list of the BIFF records contained in the xls file along with
+name and explanation as described in various documentation files (see "About").
+Selecting one of the records loads its bytes into a simple hex viewer; for the
+most important records I tried to decipher the contents of the hex values and
+display their meaning in a grid and a memo (page "Analysis"). For the other
+records select a byte in the hex viewer, and the program will display the
+contents of that byte and the following ones as integer, double, string
+(page "Values").
+
+For compiling, note that the program requires the package "VirtualTreeview-new"
+from ccr (which in turn requires the package "lclextensions" from
+http://code.google.com/p/luipack/downloads/list).