diff --git a/applications/spready/fpssylk.pas b/applications/spready/fpssylk.pas new file mode 100644 index 000000000..6ded4c683 --- /dev/null +++ b/applications/spready/fpssylk.pas @@ -0,0 +1,673 @@ +unit fpsSYLK; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + fpstypes, fpspreadsheet, fpsReaderWriter, xlsCommon; + +type + TsSYLKField = record + Name: Char; + Value: String; + end; + TsSYLKFields = array of TsSYLKField; + + + { TsSYLKReader } + + TsSYLKReader = class(TsCustomSpreadReader) + private + FWorksheetName: String; + FPointSeparatorSettings: TFormatSettings; + FDateMode: TDateMode; + protected + function GetFieldValue(const AFields: TsSYLKFields; AFieldName: Char): String; + procedure ProcessCell(const AFields: TsSYLKFields); + procedure ProcessFormat(const AFields: TsSYLKFields); + procedure ProcessLine(const ALine: String); + procedure ProcessRecord(ARecordType: String; const AFields: TsSYLKFields); + public + constructor Create(AWorkbook: TsWorkbook); override; + procedure ReadFromFile(AFileName: String; AParams: TsStreamParams = []); override; + procedure ReadFromStrings(AStrings: TStrings; AParams: TsStreamParams = []); override; + end; + + + { TsSYLKWriter } + TsSYLKWriter = class(TsCustomSpreadWriter) + private + FPointSeparatorSettings: TFormatSettings; + FDateMode: TDateMode; + FSheetIndex: Integer; + function GetFormatStr(ACell: PCell): String; + function GetFormulaStr(ACell: PCell): String; + protected + procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: Boolean; ACell: PCell); override; + procedure WriteCellToStream(AStream: TStream; ACell: PCell); override; + procedure WriteComment(AStream: TStream; ACell: PCell); override; + procedure WriteDateTime(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: TDateTime; ACell: PCell); override; + procedure WriteDimensions(AStream: TStream); + procedure WriteEndOfFile(AStream: TStream); + procedure WriteHeader(AStream: TStream); + procedure WriteLabel(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: string; ACell: PCell); override; + procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: double; ACell: PCell); override; + procedure WriteNumberFormatList(AStream: TStream); + procedure WriteOptions(AStream: TStream); + public + constructor Create(AWorkbook: TsWorkbook); override; + procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override; + end; + + TSYLKSettings = record + SheetIndex: Integer; // W + DateMode: TDateMode; // R/W + end; + +const + STR_FILEFORMAT_SYLK = 'SYLK'; + +var + {@@ Default settings for reading/writing of SYLK files } + SYLKSettings: TSYLKSettings = ( + SheetIndex: 0; + DateMode: dm1900 + ); + + {@@ File format identifier } + sfidSYLK: Integer; + +implementation + +uses + fpsRegFileFormats, fpsUtils, fpsNumFormat; + +{==============================================================================} +{ TsSYLKReader } +{==============================================================================} + +constructor TsSYLKReader.Create(AWorkbook: TsWorkbook); +begin + inherited Create(AWorkbook); + FWorksheetName := 'Sheet1'; // will be replaced by filename + FDateMode := SYLKSettings.DateMode; + FPointSeparatorSettings := DefaultFormatSettings; + FPointSeparatorSettings.DecimalSeparator := '.'; +end; + +function TsSYLKReader.GetFieldValue(const AFields: TsSYLKFields; + AFieldName: Char): String; +var + i: Integer; +begin + for i := 0 to Length(AFields)-1 do + if AFields[i].Name = AFieldName then begin + Result := AFields[i].Value; + exit; + end; + Result := ''; +end; + +procedure TsSYLKReader.ProcessCell(const AFields: TsSYLKFields); +var + row, col: Cardinal; + sval, expr: String; + val: Double; + cell: PCell; +begin + col := StrToInt(GetFieldValue(AFields, 'X')) - 1; + row := StrToInt(GetFieldValue(AFields, 'Y')) - 1; + cell := FWorksheet.GetCell(row, col); + + // Formula + expr := GetFieldValue(AFields, 'E'); // expression in R1C1 syntax + if expr <> '' then + begin + expr := 'A1'; // to do: Convert R1C1 expression to A1 expression! + FWorksheet.WriteFormula(cell, expr); // to do!!!! + exit; + end; + + // Value + sval := GetFieldValue(AFields, 'K'); + if sval <> '' then begin + if sval[1] = '"' then + begin + sval := UnquoteStr(sval); + if (sval = 'TRUE') or (sval = 'FALSE') then + FWorksheet.WriteBoolValue(cell, (sval = 'TRUE')) + else + FWorksheet.WriteText(cell, UnquoteStr(sval)) + // to do: error values + end else begin + val := StrToFloat(sval, FPointSeparatorSettings); + FWorksheet.WriteNumber(cell, val); + // to do: dates + end; + end; +end; + +procedure TsSYLKReader.ProcessFormat(const AFields: TsSYLKFields); +var + cell: PCell; + s, scol, srow, sval, scol1, scol2: String; + col, row, col1, col2: LongInt; + ch1, ch2: Char; + nf: TsNumberFormat; + decs: Integer; + ha: TsHorAlignment; + val: Double; + P: PChar; +begin + nf := nfGeneral; + ha := haDefault; + decs := 0; + + // Format + s := GetFieldValue(AFields, 'F'); + if s <> '' then + begin + ch1 := s[1]; + ch2 := s[Length(s)]; + sval := copy(s, 2, Length(s)); + + // Number format + case ch1 of + 'D': nf := nfGeneral; + 'C': nf := nfCurrency; + 'E': nf := nfExp; + 'F': nf := nfFixed; + 'G': nf := nfGeneral; + '$': ; // no idea what this is + '*': ; // no idea what this is + '%': nf := nfPercentage; + end; + + // Decimal places + TryStrtoInt(sval, decs); + + // Horizontal alignment + case ch2 of + 'D': ha := haDefault; + 'C': ha := haCenter; + 'G': ; // "Standard" ??? + 'L': ha := haLeft; + 'R': ha := haRight; + '-': ; // ??? + 'X': ; // "Fill" + end; + + // Determine whether the format applies to column, row or + + scol := GetFieldValue(AFields, 'C'); + // Column format, not supported yet + if scol <> '' then + exit; + + srow := GetFieldValue(AFields, 'R'); + // Row format, not yet supported + if srow <> '' then + exit; + + // Cell format + scol := GetFieldValue(AFields, 'X'); + srow := GetFieldValue(AFields, 'Y'); + if (scol <> '') and (srow <> '') then + begin + if not TryStrToInt(scol, col) then exit; + if not TryStrToInt(srow, row) then exit; + cell := FWorksheet.GetCell(row, col); + + FWorksheet.WriteNumberFormat(cell, nf, decs); + FWorksheet.WriteHorAlignment(cell, ha); + end; + end; + + // Column width + s := GetFieldValue(AFields, 'W'); + if s <> '' then + begin + scol1 := ''; + P := @s[1]; + while P^ <> ' ' do begin + scol1 := scol1 + P^; + inc(P); + end; + inc(P); + scol2 := ''; + while (P^ <> ' ') do begin + scol2 := scol2 + P^; + inc(P); + end; + inc(P); + sval := ''; + while (P^ <> #0) do begin + sval := sval + P^; + inc(P); + end; + if TryStrToInt(scol1, col1) and + TryStrToInt(scol2, col2) and + TryStrToFloat(sval, val, FPointSeparatorSettings) then + begin + for col := col1-1 to col2-1 do + FWorksheet.WriteColWidth(col, val, suChars); + end; + end; +end; + +procedure TsSYLKReader.ProcessLine(const ALine: String); +var + P: PChar; + i: Integer; + rtd, fval: String; + ftd: Char; + fields: TsSYLKFields; + + procedure StoreField(AName: Char; const AValue: String); + begin + if i >= Length(fields) then SetLength(fields, Length(fields)+100); + fields[i].Name := AName; + fields[i].Value := AValue; + inc(i); + end; + +begin + // Get record type + rtd := ''; + P := @ALine[1]; + while (P^ <> ';') do begin + rtd := rtd + P^; + inc(P); + end; + inc(P); + + if rtd = 'C' then + ftd := 'C'; + + // Get fields + SetLength(fields, 100); + i := 0; + while (P^ <> #0) do begin + ftd := P^; + inc(P); + fval := ''; + while (P^ <> #0) do begin + case P^ of + ';' : begin + inc(P); + if P^ = ';' then begin + fval := fval + P^; + end else + begin + StoreField(ftd, fval); + break; + end; + end; + else fval := fval + P^; + inc(P); + end; + end; + end; + + if fval <> '' then + StoreField(ftd, fval); + + // Process record + SetLength(fields, i); + ProcessRecord(rtd, fields); +end; + +procedure TsSYLKReader.ProcessRecord(ARecordType: String; + const AFields: TsSYLKFields); +begin + case ARecordType of + 'ID': ; // Begin of file - nothing to do for us + 'C' : ProcessCell(AFields); // Content record + 'F' : ProcessFormat(AFields); // Format record + 'E' : ; // End of file + end; +end; + +procedure TsSYLKReader.ReadFromFile(AFileName: String; + AParams: TsStreamParams = []); +begin + FWorksheetName := ChangeFileExt(ExtractFileName(AFileName), ''); + inherited ReadFromFile(AFilename, AParams); +end; + +procedure TsSYLKReader.ReadFromStrings(AStrings: TStrings; + AParams: TsStreamParams = []); +var + i: Integer; +begin + Unused(AParams); + + // Create worksheet + FWorksheet := FWorkbook.AddWorksheet(FWorksheetName, true); + + for i:=0 to AStrings.Count-1 do + ProcessLine(AStrings[i]); +end; + + +{==============================================================================} +{ TsSYLKWriter } +{==============================================================================} + +constructor TsSYLKWriter.Create(AWorkbook: TsWorkbook); +begin + inherited Create(AWorkbook); + FDateMode := SYLKSettings.DateMode; + FSheetIndex := SYLKSettings.SheetIndex; + FPointSeparatorSettings := DefaultFormatSettings; + FPointSeparatorSettings.DecimalSeparator := '.'; +end; + +function TsSYLKWriter.GetFormatStr(ACell: PCell): String; +var + cellFmt: PsCellFormat; + ch1, ch2: Char; + decs: String; + nfp: TsNumFormatParams; + style: String; + fnt: TsFont; +begin + Result := ''; + cellFmt := FWorkbook.GetPointerToCellFormat(ACell^.FormatIndex); + if cellFmt <> nil then + begin + // Number format --> field ";P" + ch1 := 'G'; // general number format + decs := '0'; // decimal places + if (uffNumberFormat in cellFmt^.UsedFormattingFields) then begin + Result := Result + Format(';P%d', [cellFmt^.NumberFormatIndex+1]); // +1 because of General format not in list + nfp := FWorkbook.GetNumberFormat(cellFmt^.NumberFormatIndex); + case nfp.Sections[0].NumFormat of + nfFixed : ch1 := 'F'; + nfCurrency : ch1 := 'C'; + nfPercentage : ch1 := '%'; + nfExp : ch1 := 'E'; + else ch1 := 'G'; + end; + decs := IntToStr(nfp.Sections[0].Decimals); + end else + Result := Result + ';P0'; + + // Horizontal alignment + old-style number format --> field ";F" + ch2 := 'D'; // default alignment + if (uffHorAlign in cellFmt^.UsedFormattingFields) then + case cellFmt^.HorAlignment of + haLeft : ch2 := 'L'; + haCenter: ch2 := 'C'; + haRight : ch2 := 'R'; + end; + Result := Result + ';F' + ch1 + decs + ch2; + + // Font style, Borders, background --> field ";S" + style := ''; + if (uffFont in cellFmt^.UsedFormattingFields) then + begin + fnt := FWorkbook.GetFont(cellFmt^.FontIndex); + if (fssBold in fnt.Style) then style := style + 'D'; + if (fssItalic in fnt.Style) then style := style + 'I'; + end; + if (uffBorder in cellFmt^.UsedFormattingFields) then + begin + if (cbWest in cellFmt^.Border) then style := style + 'L'; + if (cbEast in cellFmt^.Border) then style := style + 'R'; + if (cbNorth in cellFmt^.Border) then style := style + 'T'; + if (cbSouth in cellFmt^.Border) then style := style + 'B'; + end; + if (uffBackground in cellFmt^.UsedFormattingFields) then + style := style + 'S'; + + if style <> '' then + Result := Result + ';S' + style; + end; + + Result := 'F' + Result + Format(';Y%d;X%d', [ACell^.Row+1, ACell^.Col+1]); +end; + +function TsSYLKWriter.GetFormulaStr(ACell: PCell): String; +begin + if HasFormula(ACell) then + Result := ';E' + FWorksheet.ConvertFormulaDialect(ACell, fdExcelR1C1) else + Result := ''; +end; + +{@@ ---------------------------------------------------------------------------- + Writes a boolean value. + In the first line, we write the format code -- see GetFormatStr + In the second line, we write a "C" record containing the fields + - ";X" cell column index (1-based) + - ";Y" cell row index (1-based) + - ";K" boolean value as TRUE or FALSE, no quotes + - ";E" formula in R1C1 syntax, if available -- see GetFormulaStr +-------------------------------------------------------------------------------} +procedure TsSYLKWriter.WriteBool(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: Boolean; ACell: PCell); +const + BOOLSTR: Array[boolean] of String = ('FALSE', 'TRUE'); +var + sval: String; + sfmt: String; +begin + // Format codes + sfmt := GetFormatStr(ACell); + if sfmt <> '' then + sfmt := sfmt + LineEnding; + + // Cell coordinates, value, formula + sval := Format('C;Y$d;X%d;K%s', [ARow+1, ACol+1, BOOLSTR[AValue]]) + GetFormulaStr(ACell); + + // Write out + AppendToStream(AStream, sval + sfmt + LineEnding); +end; + +procedure TsSYLKWriter.WriteCellToStream(AStream: TStream; ACell: PCell); +begin + case ACell^.ContentType of + cctBool: + WriteBool(AStream, ACell^.Row, ACell^.Col, ACell^.BoolValue, ACell); + cctDateTime: + WriteDateTime(AStream, ACell^.Row, ACell^.Col, ACell^.DateTimeValue, ACell); + cctEmpty: + WriteBlank(AStream, ACell^.Row, ACell^.Col, ACell); + cctError: + WriteError(AStream, ACell^.Row, ACell^.Col, ACell^.ErrorValue, ACell); + cctNumber: + WriteNumber(AStream, ACell^.Row, ACell^.Col, ACell^.NumberValue, ACell); + cctUTF8String: + WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.UTF8StringValue, ACell); + end; + if FWorksheet.HasComment(ACell) then + WriteComment(AStream, ACell); +end; + +{@@ ---------------------------------------------------------------------------- + Writes a comment record. This is a "C" record containing the fields + - ";X" cell column index (1-based) + - ";Y" cell row index (1-based) + - ";A" comment text, not quoted +-------------------------------------------------------------------------------} +procedure TsSYLKWriter.WriteComment(AStream: TStream; ACell: PCell); +var + comment: String; +begin + comment := FWorksheet.ReadComment(ACell); + if comment <> '' then + AppendToStream(AStream, Format( + 'C;Y%d;X%d;A%s' + LineEnding, [ACell^.Row+1, ACell^.Col+1, comment])); +end; + +{@@ ---------------------------------------------------------------------------- + Writes a date/time value. The date/time cell is just an ordinary number cell, + just formatted with a date/time format. +-------------------------------------------------------------------------------} +procedure TsSYLKWriter.WriteDateTime(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: TDateTime; ACell: PCell); +var + DateSerial: double; +begin + DateSerial := ConvertDateTimeToExcelDateTime(AValue, FDateMode); + WriteNumber(AStream, ARow, ACol, DateSerial, ACell); +end; + +{@@ ---------------------------------------------------------------------------- + Writes out the size of the worksheet (row and column count) + In SYLK, this is a "B" record followed by the fields ";Y" and ";X" containing + the row and column counts. +-------------------------------------------------------------------------------} +procedure TsSYLKWriter.WriteDimensions(AStream: TStream); +begin + AppendToStream(AStream, Format( + 'B;Y%d;X%d;D%d %d %d %d' + LineEnding, [ + FWorksheet.GetLastRowIndex+1, FWorksheet.GetLastColIndex+1, + FWorksheet.GetFirstRowIndex, FWorksheet.GetFirstColIndex, + FWorksheet.GetLastRowIndex, FWorksheet.GetLastColIndex + ])); +end; + +{@@ ---------------------------------------------------------------------------- + Writes out an "E" record which is the last record of a SYLK file +-------------------------------------------------------------------------------} +procedure TsSYLKWriter.WriteEndOfFile(AStream: TStream); +begin + AppendToStream(AStream, + 'E' + LineEnding); +end; + +procedure TsSYLKWriter.WriteHeader(AStream: TStream); +begin + AppendToStream(AStream, + 'ID;PFPS' + LineEnding); // ID + generating app ("FPS" = FPSpreadsheet) +end; + +{@@ ---------------------------------------------------------------------------- + Writes a text value. + In the first line, we write the format code -- see GetFormatStr + In the second line, we write a "C" record containing the fields + - ";X" cell column index (1-based) + - ";Y" cell row index (1-based) + - ";K" text value in double quotes + - ";E" formula in R1C1 syntax, if available -- see GetFormulaStr +-------------------------------------------------------------------------------} +procedure TsSYLKWriter.WriteLabel(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: String; ACell: PCell); +var + sval: String; + sfmt: String; +begin + // Format codes + sfmt := GetFormatStr(ACell); + if sfmt <> '' then + sfmt := sfmt + LineEnding; + + // Cell coordinates, value, formula + sval := Format('C;Y%d;X%d;K"%s"', [ARow+1, ACol+1, AValue]) + GetFormulaStr(ACell); + + // Write out + AppendToStream(AStream, sfmt + sval + LineEnding); +end; + +{@@ ---------------------------------------------------------------------------- + Writes a number value. + In the first line, we write the format code -- see GetFormatStr + In the second line, we write a "C" record containing the fields + - ";X" cell column index (1-based) + - ";Y" cell row index (1-based) + - ";K" number value as unformatted string + - ";E" formula in R1C1 syntax, if available -- see GetFormulaStr +-------------------------------------------------------------------------------} +procedure TsSYLKWriter.WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: double; ACell: PCell); +var + sval: String; + sfmt: String; +begin + // Format codes + sfmt := GetFormatStr(ACell); + if sfmt <> '' then + sfmt := sfmt + LineEnding; + + // Cell coordinates, value, formula + sval := Format('C;Y%d;X%d;K%g', [ARow+1, ACol+1, AValue], FPointSeparatorSettings); + sval := sval + GetFormulaStr(ACell); + + // Write out + AppendToStream(AStream, sfmt + sval + LineEnding); +end; + +{@@ ---------------------------------------------------------------------------- + Writes the list of number formats. + In SYLK, this is a sequence of "P" records. Each record contains the Excel + format string with field identifier ";P" +-------------------------------------------------------------------------------} +procedure TsSYLKWriter.WriteNumberFormatList(AStream: TStream); +var + nfp: TsNumFormatParams; + nfs: String; + i, j: Integer; +begin + AppendToStream(AStream, + 'P;PGeneral' + LineEnding); + + for i:=0 to FWorkbook.GetNumberFormatCount-1 do begin + nfp := FWorkbook.GetNumberFormat(i); + nfs := BuildFormatStringFromSection(nfp.Sections[0]); + for j:=1 to High(nfp.Sections) do + nfs := nfs + ';;' + BuildFormatStringFromSection(nfp.Sections[j]); + AppendToStream(AStream, + 'P;P' + nfs + LineEnding); + end; +end; + +procedure TsSYLKWriter.WriteOptions(AStream: TStream); +var + dateModeStr: String; + A1ModeStr: String; +begin + A1ModeStr := ';L'; // Display formulas in A1 mode. + + case FDateMode of // Datemode 1900 or 1904 + dm1900: dateModeStr := ';V0'; + dm1904: dateModeStr := ';V4'; + end; + + AppendToStream(AStream, + 'O' + A1ModeStr + dateModeStr + LineEnding + ); +end; + +procedure TsSYLKWriter.WriteToStream(AStream: TStream; + AParams: TsStreamParams = []); +begin + Unused(AParams); + if (FSheetIndex < 0) or (FSheetIndex >= FWorkbook.GetWorksheetCount) then + raise Exception.Create('[TsSYLKWriter.WriteToStream] Non-existing worksheet.'); + + FWorksheet := FWorkbook.GetWorksheetByIndex(FSheetIndex); + + WriteHeader(AStream); + WriteNumberFormatList(AStream); + WriteDimensions(AStream); + WriteOptions(AStream); + WriteCellsToStream(AStream, FWorksheet.Cells); + WriteEndOfFile(AStream); +end; + +initialization + + sfidSYLK := RegisterSpreadFormat(sfUser, + TsSYLKReader, TsSYLKWriter, + STR_FILEFORMAT_SYLK, 'SYLK', ['.slk', '.sylk'] + ); + +end. + diff --git a/applications/spready/readme.txt b/applications/spready/readme.txt new file mode 100644 index 000000000..c58bfe6d5 --- /dev/null +++ b/applications/spready/readme.txt @@ -0,0 +1,2 @@ +spready is a relatively complex demonstration of the fpspreadsheet library +and its visual controls. diff --git a/applications/spready/sabout.lfm b/applications/spready/sabout.lfm new file mode 100644 index 000000000..eeb6fabee --- /dev/null +++ b/applications/spready/sabout.lfm @@ -0,0 +1,140 @@ +object AboutForm: TAboutForm + Left = 338 + Height = 294 + Top = 153 + Width = 375 + BorderStyle = bsSizeToolWin + Caption = 'About Spready' + ClientHeight = 294 + ClientWidth = 375 + Color = clWindow + Constraints.MinHeight = 275 + Constraints.MinWidth = 330 + OnCreate = FormCreate + Position = poMainFormCenter + LCLVersion = '1.7' + object Panel1: TPanel + Left = 0 + Height = 90 + Top = 0 + Width = 375 + Align = alTop + BevelOuter = bvNone + ClientHeight = 90 + ClientWidth = 375 + Color = clWindow + ParentColor = False + TabOrder = 0 + object IconImage: TImage + Left = 8 + Height = 64 + Top = 16 + Width = 64 + end + object BtnClose: TButton + AnchorSideTop.Control = Panel1 + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = Panel1 + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = IconImage + AnchorSideBottom.Side = asrBottom + Left = 292 + Height = 29 + Top = 51 + Width = 75 + Anchors = [akRight, akBottom] + BorderSpacing.Right = 8 + Cancel = True + Caption = 'Close' + Default = True + ModalResult = 1 + TabOrder = 0 + end + object LblVersion: TLabel + AnchorSideLeft.Control = IconImage + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Side = asrBottom + AnchorSideBottom.Control = IconImage + AnchorSideBottom.Side = asrBottom + Left = 84 + Height = 15 + Top = 65 + Width = 54 + Anchors = [akLeft, akBottom] + BorderSpacing.Left = 12 + Caption = 'LblVersion' + Font.Color = clNavy + ParentColor = False + ParentFont = False + end + object Image1: TImage + AnchorSideLeft.Control = IconImage + AnchorSideLeft.Side = asrBottom + AnchorSideBottom.Control = LblVersion + Left = 84 + Height = 44 + Top = 21 + Width = 156 + Anchors = [akLeft, akBottom] + AutoSize = True + BorderSpacing.Left = 12 + Picture.Data = { + 1754506F727461626C654E6574776F726B47726170686963B805000089504E47 + 0D0A1A0A0000000D494844520000009C0000002C08060000009072D138000000 + 097048597300000EC300000EC301C76FA8640000056A4944415478DAED5CDB6D + 5B310CF5000182204FE7A30B74824EE00D324137F002052E50B46EF2D311BA42 + 47E80CDDA15BB8396804B034251D52F73A06C20F02ADE32B51D4111F47BC5EED + F7FB554ACAB1248DF016377DF5695FE4E6E6DBF6A4007777F7B879566ABABCDC + FD948A42CECFBFFCC6E7507ABD7E7A9F9B99800B030E4003A034C85A929B9980 + 0B01EEFA7AF7DD03B4045C022E0C3828A08104003E7BBC87F5FAF183147CF7E2 + E2EBAF045C022E04B8FBFBA77752198089C9CDF0DCD5D5EE476E6602CE053819 + 4ACFCE3EFF0190728312708B014E1609005F6E4E026E51C0BDA6222909B8045C + 02EE78211505C3B116890A184507F246492A23ACA31A1E9D03B928C6F2AEEFF6 + F6F12388ED51BDA41E18136BD51C671917FC67C4BE18DB22E8B14E6DEFD65E48 + D601EB8EE82275D0766EF26F00C292804305CC90CB6C056CCD813548C030BC21 + 40517B460A0CCB82C1C36DB2E30A2A6BEA8D89F594FDEC1DFE110C68A6433FDF + FC3204C65F0270001BB3A91E8FA4E780B7F012D55ED29BF10211129D8D30D223 + 3102CFDC0BA9725FBC7497E4712DDB50C42F4E5C248434C0309545C1605618B1 + 3C536FF1B539A0BF9C0360B7C6D29EC2D2CDF2563D8F6490E807EB857D35787A + F995D603D1C2F248F8AC44121D51AC39F4B89E7DEE311DAEAB2D7C1EE5E66AE3 + 794F700BF8DAF81E7A479FFCDE73F0FC6CE829A0646C2737ACE53DB5F7663CA2 + E50D2DC0E14046A29CB6A17569D0BABCAFE63E11E045F314BDF81610A261295A + 30C9E4B8E57D3D9CA6CEA16A373D525FFC9B1D5FEF69CD8B46EC211D55ED19D7 + 203A77F194D4FA790F60F50D083B079B061C9E4CEE390D8E39725D23E9DEF40E + A127B1D79EB9B687FA7BCC7E4930D7745AB15EC6EA87F3A03FEA79ACF0513BF5 + 3AA446AA3C8F6E1A1CA3792ECB93497DBDD485D6B9E534744ECC1EBEA653F028 + 0B835AC0C304BD4B7E8FF291536F25E711DEC8AB5BD4D3604DB0273C09361D21 + D9B2AD0508F93D2F85E2217E6564E91D60991F36D39EC809C486EB5CA0A7D028 + BBCD3C1F9D23425B58D29BB310C9A3634ADB2F654BB608B03D7DDDF90CB97EA3 + 8C9F12707122B978ACDE98C7B0A5A7A1C393920CE71B1A7409B8FE2D40B9C62A + E4B4CEFD4E0970B278A8E5661294BDB46218708709BD9D388F18894DCEE700DC + 9C97D93A24FD6B68ED1716A70438234FDDD4F69FBA753956F7C188912255AA67 + 0EE9A5BD45034BE778AA664F0EE7ED5BF454A9D63A34DF28FFC6E8F22A80F31A + 89A501A280831197E89251C9FD1421BA7B55AA07C81677C8D8491FF89ACD99D7 + 1166081BFF1B8809775EEE88BD4C8E022E42722E15AAF55D76252FDC46F93FA6 + 2861F334095E969E095FC1D492E2DA66792984887147C2F6487BD05CDC236CC7 + 5C3DE943CEEA6B75CF44F6A1CC27531196833C3050ADE380F10CACF76195D4EE + DFD395E1059CBEC2630F5FEB8D35DDCCD8F39CECE5BAE5A97AFAD6DAC1583B59 + 5C5B246235C31E0C0950F5DE47650C6A75721443E9D88FFF6B00046E33DCD59B + D5855B3B14F0165247E640CA2648ED3D0A18643ED95A87F672561B96E804DECA + F1E6C875A3B733B3F0511130781A1D5F366AB334BDE16D0A65F8474F83642958 + D875E808C0761247ED546B68F5E4BCD593C60A50CF4C682D92011DBC0CFB4339 + 73F069588BE7FA89494118D0C974C1B30EEB9AB1424A4F73D84947016FBE5B25 + 2CA10806D313C07825D4BA905D5924E602F0F48B2A98C3DB4F3F27815BF4B252 + 87975F8C9A3C2FBC582F0A95B4458F135987754F0BDDAD9465C44E3A24BBF7E8 + 2DBC9A96329FF4DE5948C0A5CC2A11323B019712BD377F1825C8137029A18221 + 4A8E27E052429D2FD197E413702947F36E09B8148AEC3D7C3738FE03E209B814 + 5707F4E8EFCD24E05268C0CDF1E34609B894EE5BFD233FF1F16A804B4981FC05 + 9DCF04A745BF70B30000000049454E44AE426082 + } + end + end + object Bevel1: TBevel + Left = 0 + Height = 6 + Top = 90 + Width = 375 + Align = alTop + Shape = bsTopLine + end +end diff --git a/applications/spready/sabout.pas b/applications/spready/sabout.pas new file mode 100644 index 000000000..310235630 --- /dev/null +++ b/applications/spready/sabout.pas @@ -0,0 +1,130 @@ +unit sAbout; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, IpHtml, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, + ExtCtrls, StdCtrls; + +type + + { TAboutForm } + + TAboutForm = class(TForm) + Bevel1: TBevel; + BtnClose: TButton; + IconImage: TImage; + Image1: TImage; + LblVersion: TLabel; + Panel1: TPanel; + procedure FormCreate(Sender: TObject); + procedure HTMLViewerHotClick(Sender: TObject); + private + { private declarations } + FHTMLViewer: TIpHtmlPanel; + public + { public declarations } + end; + +var + AboutForm: TAboutForm; + +implementation + +{$R *.lfm} + +uses + LCLIntf, Types, resource, versiontypes, versionresource; + +const + LE = LineEnding; + + HTMLStr = + ' '+ LE + + ''+LE+ + '' + LE + + ' ' + LE + + ' ' + LE + + '' + LE + + '

Compiler and libaries:

' + LE + + ' ' + LE + + '

Icons:

' + LE + + ' ' + LE + + '' + LE + + ''; + + +function ResourceVersionInfo: String; +var + Stream: TResourceStream; + vr: TVersionResource; + fi: TVersionFixedInfo; +begin + Result := ''; + try + { This raises an exception if version info has not been incorporated into the + binary (Lazarus Project -> Project Options -> Version Info -> Version numbering). } + Stream:= TResourceStream.CreateFromID(HINSTANCE, 1, PChar(RT_VERSION)); + try + vr := TVersionResource.Create; + try + vr.SetCustomRawDataStream(Stream); + fi := vr.FixedInfo; + Result := Format('%d.%d', [ + fi.FileVersion[0], fi.FileVersion[1] + ]); + vr.SetCustomRawDataStream(nil) + finally + vr.Free + end; + finally + Stream.Free + end; + except + end; +end; + +procedure TAboutForm.FormCreate(Sender: TObject); +var + sz: TSize; +begin + sz.cx := 64; //128; + sz.cy := 64; //128; + + IconImage.Picture.Icon := Application.Icon; + IconImage.Picture.Icon.Current := Application.Icon.GetBestIndexForSize(sz); //4; + LblVersion.Caption := 'Version ' + ResourceVersionInfo; + + FHTMLViewer := TIpHtmlPanel.Create(self); + FHTMLViewer.Parent := self; + FHTMLViewer.Align := alClient; + FHTMLViewer.DefaultFontSize := 9; + FHTMLViewer.OnHotClick := @HTMLViewerHotClick; + FHTMLViewer.SetHtmlFromStr(HTMLStr); +end; + +procedure TAboutForm.HTMLViewerHotClick(Sender: TObject); +begin + OpenURL((Sender as TIpHtmlPanel).HotURL); +end; + + +end. + diff --git a/applications/spready/scolwidthform.lfm b/applications/spready/scolwidthform.lfm new file mode 100644 index 000000000..d41ddf893 --- /dev/null +++ b/applications/spready/scolwidthform.lfm @@ -0,0 +1,109 @@ +object ColWidthForm: TColWidthForm + Left = 479 + Height = 178 + Top = 289 + Width = 349 + HorzScrollBar.Page = 320 + HorzScrollBar.Range = 320 + VertScrollBar.Page = 141 + VertScrollBar.Range = 141 + BorderStyle = bsDialog + Caption = 'ColWidthForm' + ClientHeight = 178 + ClientWidth = 349 + OnCreate = FormCreate + Position = poMainFormCenter + LCLVersion = '1.7' + object ButtonPanel1: TButtonPanel + Left = 6 + Height = 34 + Top = 138 + Width = 337 + OKButton.Name = 'OKButton' + OKButton.DefaultCaption = True + HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True + CloseButton.Name = 'CloseButton' + CloseButton.Caption = 'Close' + CloseButton.DefaultCaption = False + CancelButton.Name = 'CancelButton' + CancelButton.DefaultCaption = True + TabOrder = 0 + ShowButtons = [pbOK, pbCancel] + end + object EdColWidth: TFloatSpinEdit + AnchorSideLeft.Control = LblColWidth + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = RbCustom + AnchorSideTop.Side = asrBottom + Left = 124 + Height = 23 + Top = 94 + Width = 74 + Alignment = taRightJustify + BorderSpacing.Left = 24 + BorderSpacing.Top = 24 + BorderSpacing.Bottom = 24 + Increment = 1 + MaxValue = 100 + MinValue = 0 + TabOrder = 1 + Value = 15 + end + object LblColWidth: TLabel + AnchorSideTop.Control = EdColWidth + AnchorSideTop.Side = asrCenter + Left = 24 + Height = 15 + Top = 98 + Width = 76 + BorderSpacing.Left = 24 + BorderSpacing.Bottom = 24 + Caption = 'Column width' + ParentColor = False + end + object CbUnits: TComboBox + AnchorSideLeft.Control = EdColWidth + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = EdColWidth + AnchorSideTop.Side = asrCenter + Left = 206 + Height = 23 + Top = 94 + Width = 114 + BorderSpacing.Left = 8 + ItemHeight = 15 + OnChange = CbUnitsChange + Style = csDropDownList + TabOrder = 2 + end + object RbDefault: TRadioButton + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = Owner + Left = 24 + Height = 19 + Top = 24 + Width = 58 + BorderSpacing.Left = 24 + BorderSpacing.Top = 24 + Caption = 'Default' + OnChange = ColWidthTypeChanged + TabOrder = 3 + end + object RbCustom: TRadioButton + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = RbDefault + AnchorSideTop.Side = asrBottom + Left = 24 + Height = 19 + Top = 51 + Width = 62 + BorderSpacing.Left = 24 + BorderSpacing.Top = 8 + Caption = 'Custom' + Checked = True + OnChange = ColWidthTypeChanged + TabOrder = 4 + TabStop = True + end +end diff --git a/applications/spready/scolwidthform.pas b/applications/spready/scolwidthform.pas new file mode 100644 index 000000000..e764093c3 --- /dev/null +++ b/applications/spready/scolwidthform.pas @@ -0,0 +1,139 @@ +unit sColWidthForm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ButtonPanel, + StdCtrls, Spin, ExtCtrls, fpsTypes, fpspreadsheet; + +type + + { TColWidthForm } + + TColWidthForm = class(TForm) + ButtonPanel1: TButtonPanel; + CbUnits: TComboBox; + EdColWidth: TFloatSpinEdit; + LblColWidth: TLabel; + RbDefault: TRadioButton; + RbCustom: TRadioButton; + procedure CbUnitsChange(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure ColWidthTypeChanged(Sender: TObject); + private + FWorkbook: TsWorkbook; + FOldUnits: TsSizeUnits; + function GetColWidth: Single; + function GetColWidthType: TsColWidthType; + function GetUnits: TsSizeUnits; + procedure SetColWidth(AValue: Single); + procedure SetColWidthType(AValue: TsColWidthType); + procedure SetUnits(AValue: TsSizeUnits); + procedure SetWorkbook(AValue: TsWorkbook); + protected + + public + procedure SetData(AWorkbook: TsWorkbook; AColWidth: single; + AColWidthType: TsColWidthType); + property ColWidth: Single read GetColWidth; + property ColWidthType: TsColWidthType read GetColWidthType; + property Units: TsSizeUnits read GetUnits; + end; + +var + ColWidthForm: TColWidthForm; + +implementation + +{$R *.lfm} + +{ TColWidthForm } + +procedure TColWidthForm.CbUnitsChange(Sender: TObject); +begin + if FWorkbook <> nil then + EdColWidth.Value := FWorkbook.ConvertUnits(EdColWidth.Value, FOldUnits, GetUnits); + FOldUnits := GetUnits; +end; + +procedure TColWidthForm.FormCreate(Sender: TObject); +begin + CbUnits.Items.Clear; + CbUnits.Items.AddObject('Characters', TObject(PtrInt(ord(suChars)))); + CbUnits.Items.AddObject('mm', TObject(PtrInt(ord(suMillimeters)))); + CbUnits.Items.AddObject('cm', TObject(PtrInt(ord(suCentimeters)))); + CbUnits.Items.AddObject('Points', TObject(PtrInt(ord(suPoints)))); + CbUnits.Items.AddObject('Inches', TObject(PtrInt(ord(suInches)))); +end; + +function TColWidthForm.GetColWidth: Single; +begin + Result := EdColWidth.Value; +end; + +function TColWidthForm.GetColWidthType: TsColWidthType; +begin + if RbDefault.Checked then + Result := cwtDefault + else + Result := cwtCustom; +end; + +function TColWidthForm.GetUnits: TsSizeUnits; +begin + if CbUnits.ItemIndex = -1 then + Result := FWorkbook.Units else + Result := TsSizeUnits(IntPtr(CbUnits.Items.Objects[CbUnits.ItemIndex])); +end; + +procedure TColWidthForm.ColWidthTypeChanged(Sender: TObject); +begin + LblColWidth.Enabled := RbCustom.Checked; + EdColWidth.Enabled := RbCustom.Checked; + CbUnits.Enabled := RbCustom.Checked; +end; + +procedure TColWidthForm.SetData(AWorkbook: TsWorkbook; AColWidth: Single; + AColWidthType: TsColWidthType); +begin + SetWorkbook(AWorkbook); + SetColWidth(AColWidth); + SetUnits(AWorkbook.Units); + SetColWidthType(AColWidthType); +end; + +procedure TColWidthForm.SetColWidth(AValue: Single); +begin + EdColWidth.Value := AValue; +end; + +procedure TColWidthForm.SetColWidthType(AValue: TsColWidthType); +begin + RbDefault.Checked := AValue = cwtDefault; + RbCustom.Checked := AValue = cwtCustom; + ColWidthTypeChanged(nil); +end; + +procedure TColWidthForm.SetUnits(AValue: TsSizeUnits); +var + i: Integer; +begin + FOldUnits := GetUnits; + for i:=0 to CbUnits.Items.Count-1 do + if TsSizeUnits(IntPtr(CbUnits.Items.Objects[i])) = AValue then + begin + CbUnits.ItemIndex := i; + exit; + end; +end; + +procedure TColWidthForm.SetWorkbook(AValue: TsWorkbook); +begin + FWorkbook := AValue; + FOldUnits := FWorkbook.Units; +end; + +end. + diff --git a/applications/spready/scsvparamsform.lfm b/applications/spready/scsvparamsform.lfm new file mode 100644 index 000000000..78a484a1c --- /dev/null +++ b/applications/spready/scsvparamsform.lfm @@ -0,0 +1,554 @@ +object CSVParamsForm: TCSVParamsForm + Left = 638 + Height = 555 + Top = 250 + Width = 470 + BorderStyle = bsDialog + Caption = 'Parameters for comma-delimited files' + ClientHeight = 555 + ClientWidth = 470 + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + Position = poMainFormCenter + LCLVersion = '1.5' + object ButtonPanel: TButtonPanel + Left = 6 + Height = 34 + Top = 515 + Width = 458 + OKButton.Name = 'OKButton' + OKButton.DefaultCaption = True + HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True + CloseButton.Name = 'CloseButton' + CloseButton.DefaultCaption = True + CancelButton.Name = 'CancelButton' + CancelButton.DefaultCaption = True + TabOrder = 0 + ShowButtons = [pbOK, pbCancel] + end + object PageControl: TPageControl + Left = 8 + Height = 499 + Top = 8 + Width = 454 + ActivePage = PgGeneralParams + Align = alClient + BorderSpacing.Around = 8 + MultiLine = True + TabIndex = 0 + TabOrder = 1 + Options = [nboMultiLine] + object PgGeneralParams: TTabSheet + Caption = 'General' + ClientHeight = 471 + ClientWidth = 446 + object LblQuoteChar: TLabel + Left = 16 + Height = 15 + Top = 84 + Width = 88 + Caption = 'Quote character:' + FocusControl = CbQuoteChar + ParentColor = False + end + object CbQuoteChar: TComboBox + Left = 156 + Height = 23 + Top = 80 + Width = 275 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'none' + 'double ( " )' + 'single ( '' )' + ) + Style = csDropDownList + TabOrder = 2 + Text = 'none' + end + object CbDelimiter: TComboBox + Left = 156 + Height = 23 + Top = 16 + Width = 275 + ItemHeight = 15 + ItemIndex = 4 + Items.Strings = ( + 'Comma ( , )' + 'Semicolon ( ; )' + 'Colon ( : )' + 'Bar ( | )' + 'TAB' + ) + Style = csDropDownList + TabOrder = 0 + Text = 'TAB' + end + object Label3: TLabel + Left = 16 + Height = 15 + Top = 19 + Width = 96 + Caption = 'Column delimiter:' + FocusControl = CbDelimiter + ParentColor = False + end + object Label4: TLabel + Left = 16 + Height = 15 + Top = 51 + Width = 65 + Caption = 'Line ending:' + FocusControl = CbLineEnding + ParentColor = False + end + object CbLineEnding: TComboBox + Left = 156 + Height = 23 + Top = 48 + Width = 275 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'System' + 'CR+LF (Windows)' + 'CR (Mac)' + 'LF (Unix/Linux/OS X/BSD)' + ) + Style = csDropDownList + TabOrder = 1 + Text = 'System' + end + object RgDetectContentType: TRadioGroup + Left = 16 + Height = 80 + Top = 156 + Width = 415 + AutoFill = True + Caption = 'Conversion of strings after reading' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 1 + ClientHeight = 60 + ClientWidth = 411 + ItemIndex = 1 + Items.Strings = ( + 'Do not convert, strings are sufficient' + 'Try to convert strings to content types' + ) + TabOrder = 3 + end + object LbEncoding: TLabel + Left = 16 + Height = 15 + Top = 116 + Width = 87 + Caption = 'String encoding:' + FocusControl = CbEncoding + ParentColor = False + end + object CbEncoding: TComboBox + Left = 156 + Height = 23 + Top = 112 + Width = 275 + DropDownCount = 32 + ItemHeight = 15 + Style = csDropDownList + TabOrder = 4 + end + end + object PgNumberParams: TTabSheet + Caption = 'Number cells' + ClientHeight = 471 + ClientWidth = 446 + object CbAutoDetectNumberFormat: TCheckBox + Left = 16 + Height = 19 + Top = 16 + Width = 200 + Caption = 'Try to auto-detect number format' + Checked = True + State = cbChecked + TabOrder = 0 + end + object EdNumFormat: TEdit + Left = 232 + Height = 23 + Top = 140 + Width = 194 + TabOrder = 3 + end + object LblNumFormat: TLabel + Left = 17 + Height = 15 + Top = 144 + Width = 182 + Caption = 'Format string for writing numbers:' + FocusControl = EdNumFormat + ParentColor = False + end + object LblNumFormatInfo: TLabel + Left = 232 + Height = 80 + Top = 176 + Width = 194 + AutoSize = False + BorderSpacing.Left = 8 + BorderSpacing.Right = 8 + BorderSpacing.Around = 8 + Caption = 'If empty, numbers are written in the same format as they appear in the worksheet.' + FocusControl = EdNumFormat + ParentColor = False + WordWrap = True + end + object LblDecimalSeparator: TLabel + Left = 16 + Height = 15 + Top = 59 + Width = 98 + Caption = 'Decimal separator:' + FocusControl = CbDecimalSeparator + ParentColor = False + end + object CbDecimalSeparator: TComboBox + Left = 232 + Height = 23 + Top = 56 + Width = 194 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'like spreadsheet' + 'Period ( . )' + 'Comma ( , )' + ) + TabOrder = 1 + Text = 'like spreadsheet' + end + object LblThousandSeparator: TLabel + Left = 16 + Height = 15 + Top = 91 + Width = 108 + Caption = 'Thousand separator:' + FocusControl = CbThousandSeparator + ParentColor = False + end + object CbThousandSeparator: TComboBox + Left = 232 + Height = 23 + Top = 88 + Width = 194 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'like spreadsheet' + 'Period ( . )' + 'Comma ( , )' + 'Space ( )' + ) + TabOrder = 2 + Text = 'like spreadsheet' + end + end + object PgCurrency: TTabSheet + Caption = 'Currency cells' + ClientHeight = 471 + ClientWidth = 446 + object LblCurrencySymbol: TLabel + Left = 16 + Height = 15 + Top = 20 + Width = 93 + Caption = 'Currency symbol:' + FocusControl = EdCurrencySymbol + ParentColor = False + end + object EdCurrencySymbol: TEdit + Left = 232 + Height = 23 + Top = 16 + Width = 194 + OnEnter = DateTimeFormatChange + TabOrder = 0 + Text = 'like spreadsheet' + end + end + object PgDateTimeParams: TTabSheet + Caption = 'Date/time cells' + ClientHeight = 471 + ClientWidth = 446 + object LblNumFormat1: TLabel + Left = 16 + Height = 15 + Top = 20 + Width = 128 + Caption = 'Long date format string:' + ParentColor = False + end + object LblNumFormat2: TLabel + Left = 16 + Height = 15 + Top = 52 + Width = 129 + Caption = 'Short date format string:' + ParentColor = False + end + object LblDecimalSeparator1: TLabel + Left = 16 + Height = 15 + Top = 83 + Width = 79 + Caption = 'Date separator:' + FocusControl = CbDateSeparator + ParentColor = False + end + object CbDateSeparator: TComboBox + Left = 232 + Height = 23 + Top = 80 + Width = 194 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'like spreadsheet' + 'Dot ( . )' + 'Dash ( - )' + 'Slash ( / )' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 2 + Text = 'like spreadsheet' + end + object LblNumFormat3: TLabel + Left = 16 + Height = 15 + Top = 268 + Width = 129 + Caption = 'Long time format string:' + ParentColor = False + end + object LblNumFormat4: TLabel + Left = 16 + Height = 15 + Top = 300 + Width = 130 + Caption = 'Short time format string:' + ParentColor = False + end + object LblDecimalSeparator2: TLabel + Left = 16 + Height = 15 + Top = 331 + Width = 82 + Caption = 'Time separator:' + FocusControl = CbTimeSeparator + ParentColor = False + end + object CbTimeSeparator: TComboBox + Left = 232 + Height = 23 + Top = 328 + Width = 194 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'like spreadsheet' + 'Dot ( . )' + 'Dash ( - )' + 'Slash ( / )' + 'Colon ( : )' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 5 + Text = 'like spreadsheet' + end + object LblLongMonthNames: TLabel + Left = 16 + Height = 15 + Top = 116 + Width = 107 + Caption = 'Long month names:' + ParentColor = False + end + object LblShortMonthNames: TLabel + Left = 16 + Height = 15 + Top = 148 + Width = 108 + Caption = 'Short month names:' + ParentColor = False + end + object LblLongDayNames: TLabel + Left = 16 + Height = 15 + Top = 180 + Width = 90 + Caption = 'Long day names:' + ParentColor = False + end + object LblShortDayNames: TLabel + Left = 16 + Height = 15 + Top = 212 + Width = 91 + Caption = 'Short day names:' + ParentColor = False + end + object CbLongDateFormat: TComboBox + Left = 232 + Height = 23 + Top = 16 + Width = 194 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'like spreadsheet' + 'ddd, d/mm/yyyy' + 'ddd, d/mmm/yyyy' + 'dddd, d/mm/yyyy' + 'dddd, d/mmm/yyyy' + 'd/mm/yyyy' + 'dd/mm/yyyy' + 'dddd, mm/d/yyyy' + 'dddd, mmm/d/yyyy' + 'mm/d/yyyy' + 'mm/dd/yyyy' + 'yyyy/mm/dd' + 'yyyy/mm/d' + 'yyyy/mmm/d' + 'yyyy/mmmm/d' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 0 + Text = 'like spreadsheet' + end + object CbShortDateFormat: TComboBox + Left = 232 + Height = 23 + Top = 48 + Width = 194 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'like spreadsheet' + 'd/m/yy' + 'd/mm/yy' + 'd/mm/yyyy' + 'm/d/yy' + 'mm/d/yy' + 'mm/d/yyyy' + 'yy/m/d' + 'yy/mm/d' + 'yyyy/mm/d' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 1 + Text = 'like spreadsheet' + end + object CbLongTimeFormat: TComboBox + Left = 232 + Height = 23 + Top = 264 + Width = 194 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'like spreadsheet' + 'h:n:s' + 'h:nn:ss' + 'hh:nn:ss' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 3 + Text = 'like spreadsheet' + end + object CbShortTimeFormat: TComboBox + Left = 232 + Height = 23 + Top = 296 + Width = 194 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'like spreadsheet' + 'h:n' + 'h:nn' + 'hh:nn' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 4 + Text = 'like spreadsheet' + end + object GroupBox1: TGroupBox + Left = 17 + Height = 58 + Top = 366 + Width = 409 + Caption = 'Sample' + ClientHeight = 38 + ClientWidth = 405 + TabOrder = 6 + object LblDateTimeSample: TLabel + Left = 7 + Height = 20 + Top = 2 + Width = 388 + Alignment = taCenter + Anchors = [akTop, akLeft, akRight] + AutoSize = False + Caption = 'sample' + ParentColor = False + end + end + end + object PgBoolParams: TTabSheet + Caption = 'Boolean cells' + ClientHeight = 471 + ClientWidth = 446 + object EdTRUE: TEdit + Left = 16 + Height = 23 + Top = 40 + Width = 131 + TabOrder = 0 + end + object EdFALSE: TEdit + Left = 176 + Height = 23 + Top = 40 + Width = 131 + TabOrder = 1 + end + object Label1: TLabel + Left = 19 + Height = 15 + Top = 16 + Width = 81 + Caption = 'Text for "TRUE"' + ParentColor = False + end + object Label2: TLabel + Left = 179 + Height = 15 + Top = 16 + Width = 85 + Caption = 'Text for "FALSE"' + ParentColor = False + end + end + end +end diff --git a/applications/spready/scsvparamsform.pas b/applications/spready/scsvparamsform.pas new file mode 100644 index 000000000..d5b36df7f --- /dev/null +++ b/applications/spready/scsvparamsform.pas @@ -0,0 +1,594 @@ +unit sCSVParamsForm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, + ButtonPanel, ExtCtrls, ComCtrls, StdCtrls, + fpsCSV, + sCtrls; + +type + + { TCSVParamsForm } + + TCSVParamsForm = class(TForm) + ButtonPanel: TButtonPanel; + CbAutoDetectNumberFormat: TCheckBox; + CbLongDateFormat: TComboBox; + CbLongTimeFormat: TComboBox; + CbEncoding: TComboBox; + EdCurrencySymbol: TEdit; + CbShortTimeFormat: TComboBox; + CbShortDateFormat: TComboBox; + CbDecimalSeparator: TComboBox; + CbDateSeparator: TComboBox; + CbTimeSeparator: TComboBox; + CbThousandSeparator: TComboBox; + CbLineEnding: TComboBox; + CbQuoteChar: TComboBox; + CbDelimiter: TComboBox; + EdTRUE: TEdit; + EdFALSE: TEdit; + EdNumFormat: TEdit; + GroupBox1: TGroupBox; + Label1: TLabel; + Label2: TLabel; + Label3: TLabel; + Label4: TLabel; + LblDateTimeSample: TLabel; + LblDecimalSeparator: TLabel; + LblDecimalSeparator1: TLabel; + LblDecimalSeparator2: TLabel; + LblCurrencySymbol: TLabel; + LbEncoding: TLabel; + LblShortMonthNames: TLabel; + LblLongDayNames: TLabel; + LblShortDayNames: TLabel; + LblNumFormat1: TLabel; + LblNumFormat2: TLabel; + LblNumFormat3: TLabel; + LblNumFormat4: TLabel; + LblLongMonthNames: TLabel; + LblThousandSeparator: TLabel; + LblNumFormat: TLabel; + LblQuoteChar: TLabel; + LblNumFormatInfo: TLabel; + PageControl: TPageControl; + PgGeneralParams: TTabSheet; + PgNumberParams: TTabSheet; + PgDateTimeParams: TTabSheet; + PgBoolParams: TTabSheet; + RgDetectContentType: TRadioGroup; + PgCurrency: TTabSheet; + procedure DateTimeFormatChange(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); + procedure FormCreate(Sender: TObject); + private + { private declarations } + FSampleDateTime: TDateTime; + FDateFormatSample: String; + FTimeFormatSample: String; + FEdLongMonthNames: TMonthDayNamesEdit; + FEdShortMonthNames: TMonthDayNamesEdit; + FEdLongDayNames: TMonthDayNamesEdit; + FEdShortDayNames: TMonthDayNamesEdit; + procedure DateSeparatorToFormatSettings(var ASettings: TFormatSettings); + procedure DecimalSeparatorToFormatSettings(var ASettings: TFormatSettings); +// function GetCurrencySymbol: String; + procedure ThousandSeparatorToFormatSettings(var ASettings: TFormatSettings); + procedure TimeSeparatorToFormatSettings(var ASettings: TFormatSettings); + public + { public declarations } + procedure GetParams(var AParams: TsCSVParams); + procedure SetParams(const AParams: TsCSVParams); + end; + +var + CSVParamsForm: TCSVParamsForm; + +implementation + +{$R *.lfm} + +uses + LConvEncoding, fpsUtils; + +resourcestring + rsLikeSpreadsheet = 'like spreadsheet'; + +var + CSVParamsPageIndex: Integer = 0; + + +{ TCSVParamsForm } + +procedure TCSVParamsForm.DateSeparatorToFormatSettings(var ASettings: TFormatSettings); +begin + case CbDateSeparator.ItemIndex of + 0: ASettings.DateSeparator := #0; + 1: ASettings.DateSeparator := '.'; + 2: ASettings.DateSeparator := '-'; + 3: ASettings.DateSeparator := '/'; + else ASettings.DateSeparator := CbDateSeparator.Text[1]; + end; +end; + +procedure TCSVParamsForm.DecimalSeparatorToFormatSettings(var ASettings: TFormatSettings); +begin + case CbDecimalSeparator.ItemIndex of + 0: ASettings.DecimalSeparator := #0; + 1: ASettings.DecimalSeparator := '.'; + 2: ASettings.DecimalSeparator := ','; + else ASettings.DecimalSeparator := CbDecimalSeparator.Text[1]; + end; +end; + +procedure TCSVParamsForm.DateTimeFormatChange(Sender: TObject); +var + fs: TFormatSettings; + ctrl: TWinControl; + dt: TDateTime; + arr: Array[1..12] of String; + i: Integer; +begin + fs := UTF8FormatSettings; + if CbLongDateFormat.ItemIndex <> 0 then + fs.LongDateFormat := CbLongDateFormat.Text; + if CbShortDateFormat.ItemIndex <> 0 then + fs.ShortDateFormat := CbShortDateFormat.Text; + if CbLongTimeFormat.ItemIndex <> 0 then + fs.LongTimeFormat := CbLongTimeFormat.Text; + if CbShortTimeFormat.ItemIndex <> 0 then + fs.ShortTimeFormat := CbShortTimeFormat.Text; + if CbDateSeparator.ItemIndex <> 0 then + DateSeparatorToFormatSettings(fs); + if CbTimeSeparator.ItemIndex <> 0 then + TimeSeparatorToFormatSettings(fs); + + if FEdLongMonthNames.Text <> rsLikeSpreadsheet then begin + arr[1] := ''; // to silence the compiler + FEdLongMonthNames.GetNames(arr); + for i:=1 to 12 do + if arr[i] <> '' then fs.LongMonthNames[i] := arr[i]; + end; + if FEdShortMonthNames.Text <> rsLikeSpreadsheet then begin + FEdShortMonthNames.GetNames(arr); + for i:=1 to 12 do + if arr[i] <> '' then fs.ShortMonthNames[i] := arr[i]; + end; + if FEdLongDayNames.Text <> rsLikeSpreadsheet then begin + FEdLongDayNames.GetNames(arr); + for i:=1 to 7 do + if arr[i] <> '' then fs.LongDayNames[i] := arr[i]; + end; + if FEdShortDayNames.Text <> rsLikeSpreadsheet then begin + FEdShortDayNames.GetNames(arr); + for i:=1 to 7 do + if arr[i] <> '' then fs.ShortDayNames[i] := arr[i]; + end; + + dt := FSampleDateTime; + ctrl := ActiveControl; + if (ctrl = CbLongDateFormat) then + begin + FDateFormatSample := fs.LongDateFormat; + LblDateTimeSample.Caption := FormatDateTime(FDateFormatSample, dt, fs); + end + else + if (ctrl = CbShortDateFormat) then + begin + FDateFormatSample := fs.ShortDateFormat; + LblDateTimeSample.Caption := FormatDateTime(FDateFormatSample, dt, fs); + end + else + if (ctrl = CbDateSeparator) then + LblDateTimeSample.Caption := FormatDateTime(FDateFormatSample, dt, fs) + else + if (ctrl = CbLongTimeFormat) then + begin + FTimeFormatSample := fs.LongTimeFormat; + LblDateTimeSample.Caption := FormatDateTime(FTimeFormatSample, dt, fs); + end + else + if (ctrl = CbShortTimeFormat) then + begin + FTimeFormatSample := fs.ShortTimeFormat; + LblDateTimeSample.Caption := FormatDateTime(FTimeFormatSample, dt, fs); + end + else + if (ctrl = CbTimeSeparator) then + LblDateTimeSample.Caption := FormatDateTime(FTimeFormatSample, dt, fs) + else + LblDateTimeSample.Caption := FormatDateTime('c', dt, fs); + + Application.ProcessMessages; +end; + +procedure TCSVParamsForm.FormCloseQuery(Sender: TObject; var CanClose: boolean); +begin + Unused(Sender, CanClose); + CSVParamsPageIndex := PageControl.ActivePageIndex; +end; + +procedure TCSVParamsForm.FormCreate(Sender: TObject); +begin + PageControl.ActivePageIndex := CSVParamsPageIndex; + + // Populate encoding combobox. Done in code because of the conditional define. + with CbEncoding.Items do begin + Add('automatic / UTF8'); + Add('UTF8'); + Add('UTF8 with BOM'); + Add('ISO_8859_1 (Central Europe)'); + Add('ISO_8859_15 (Western European languages)'); + Add('ISO_8859_2 (Eastern Europe)'); + Add('CP1250 (Central Europe)'); + Add('CP1251 (Cyrillic)'); + Add('CP1252 (Latin 1)'); + Add('CP1253 (Greek)'); + Add('CP1254 (Turkish)'); + Add('CP1255 (Hebrew)'); + Add('CP1256 (Arabic)'); + Add('CP1257 (Baltic)'); + Add('CP1258 (Vietnam)'); + Add('CP437 (DOS central Europe)'); + Add('CP850 (DOS western Europe)'); + Add('CP852 (DOS central Europe)'); + Add('CP866 (DOS and Windows console''s cyrillic)'); + Add('CP874 (Thai)'); + {$IFNDEF DisableAsianCodePages} + // Asian encodings + Add('CP932 (Japanese)'); + Add('CP936 (Chinese)'); + Add('CP949 (Korea)'); + Add('CP950 (Chinese Complex)'); + {$ENDIF} + Add('KOI8 (Russian cyrillic)'); + Add('UCS2LE (UCS2-LE 2byte little endian)'); + Add('UCS2BE (UCS2-BE 2byte big endian)'); + end; + CbEncoding.ItemIndex := 0; + + FEdLongMonthNames := TMonthDayNamesEdit.Create(self); + with FEdLongMonthNames do + begin + Parent := PgDateTimeParams; + Left := CbDateSeparator.Left; + Top := CbDateSeparator.Top + 32; + {$IFDEF LCL_FULLVERSION AND LCL_FULLVERSION > 1020600} + Width := CbDateSeparator.Width; + {$ELSE} + Width := CbDateSeparator.Width - Button.Width; + {$ENDIF} + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + TabOrder := CbDateSeparator.TabOrder + 1; + end; + LblLongMonthNames.FocusControl := FEdLongMonthNames; + + FEdShortMonthNames := TMonthDayNamesEdit.Create(self); + with FEdShortMonthNames do + begin + Parent := PgDateTimeParams; + Left := CbDateSeparator.Left; + Top := CbDateSeparator.Top + 32*2; + Width := FEdLongMonthNames.Width; + TabOrder := CbDateSeparator.TabOrder + 2; + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + end; + LblShortMonthNames.FocusControl := FEdShortMonthNames; + + FEdLongDayNames := TMonthDayNamesEdit.Create(self); + with FEdLongDayNames do + begin + Parent := PgDateTimeParams; + Left := CbDateSeparator.Left; + Top := CbDateSeparator.Top + 32*3; + Width := FEdLongMonthNames.Width; + TabOrder := CbDateSeparator.TabOrder + 3; + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + end; + LblLongDayNames.FocusControl := FEdLongDayNames; + + FEdShortDayNames := TMonthDayNamesEdit.Create(self); + with FEdShortDayNames do + begin + Parent := PgDateTimeParams; + Left := CbDateSeparator.Left; + Top := CbDateSeparator.Top + 32*4; + Width := FEdLongMonthNames.Width; + TabOrder := CbDateSeparator.TabOrder + 4; + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + end; + LblShortDayNames.FocusControl := FEdShortDayNames; + + FDateFormatSample := UTF8FormatSettings.LongDateFormat; + FTimeFormatSample := UTF8FormatSettings.LongTimeFormat; + FSampleDateTime := now(); +end; + +procedure TCSVParamsForm.GetParams(var AParams: TsCSVParams); +var + s: String; +begin + // Line endings + case CbLineEnding.ItemIndex of + 0: AParams.LineEnding := leSystem; + 1: AParams.LineEnding := leCRLF; + 2: AParams.LineEnding := leCR; + 3: AParams.LineEnding := leLF; + end; + + // Column delimiter + case CbDelimiter.ItemIndex of + 0: AParams.Delimiter := ','; + 1: AParams.Delimiter := ';'; + 2: AParams.Delimiter := ':'; + 3: AParams.Delimiter := '|'; + 4: AParams.Delimiter := #9; + end; + + // Quote character + case CbQuoteChar.ItemIndex of + 0: AParams.QuoteChar := #0; + 1: AParams.QuoteChar := '"'; + 2: AParams.QuoteChar := ''''; + end; + + // Encoding + if CbEncoding.ItemIndex = 0 then + AParams.Encoding := '' + else if CbEncoding.ItemIndex = 1 then + AParams.Encoding := EncodingUTF8BOM + else + begin + s := CbEncoding.Items[CbEncoding.ItemIndex]; + AParams.Encoding := Copy(s, 1, Pos(' ', s)-1); + end; + + // Detect content type and convert + AParams.DetectContentType := RgDetectContentType.ItemIndex <> 0; + + // Auto-detect number format + AParams.AutoDetectNumberFormat := CbAutoDetectNumberFormat.Checked; + + // Number format + AParams.NumberFormat := EdNumFormat.Text; + + // Decimal separator + DecimalSeparatorToFormatSettings(AParams.FormatSettings); + + // Thousand separator + ThousandSeparatorToFormatSettings(AParams.FormatSettings); + + // Currency symbol + if (EdCurrencySymbol.Text = '') or (EdCurrencySymbol.Text = rsLikeSpreadsheet) then + AParams.FormatSettings.CurrencyString := '' + else + AParams.FormatSettings.CurrencyString := EdCurrencySymbol.Text; + + // Long date format string + if (CbLongDateFormat.ItemIndex = 0) or (CbLongDateFormat.Text = '') then + AParams.FormatSettings.LongDateFormat := '' + else + AParams.FormatSettings.LongDateFormat := CbLongDateFormat.Text; + + // Short date format string + if (CbShortDateFormat.ItemIndex = 0) or (CbShortDateFormat.Text = '') then + AParams.FormatSettings.ShortDateFormat := '' + else + AParams.FormatSettings.ShortDateFormat := CbShortDateFormat.Text; + + // Date separator + DateSeparatorToFormatSettings(AParams.FormatSettings); + + // Long month names + FEdLongMonthNames.GetNames(AParams.FormatSettings.LongMonthNames); + + // Short month names + FEdShortMonthNames.GetNames(AParams.FormatSettings.ShortMonthNames); + + // Long day names + FEdLongDayNames.GetNames(AParams.FormatSettings.LongDayNames); + + // Short day names + FEdShortDayNames.GetNames(AParams.FormatSettings.ShortDayNames); + + // Long time format string + if CbLongTimeFormat.ItemIndex = 0 then + AParams.FormatSettings.LongTimeFormat := '' + else + AParams.FormatSettings.LongTimeFormat := CbLongTimeFormat.Text; + + // Short time format string + if CbShortTimeFormat.ItemIndex = 0 then + AParams.FormatSettings.ShortTimeFormat := '' + else + AParams.FormatSettings.ShortTimeFormat := CbShortTimeFormat.Text; + + // Time separator + TimeSeparatorToFormatSettings(AParams.FormatSettings); + + // Text for "TRUE" + AParams.TrueText := EdTRUE.Text; + + // Test for "FALSE" + AParams.FalseText := EdFALSE.Text; +end; + +procedure TCSVParamsForm.SetParams(const AParams: TsCSVParams); +var + s: String; + i: Integer; +begin + // Line endings + case AParams.LineEnding of + leSystem: CbLineEnding.ItemIndex := 0; + leCRLF : CbLineEnding.ItemIndex := 1; + leCR : CbLineEnding.ItemIndex := 2; + leLF : CbLineEnding.ItemIndex := 3; + end; + + // Column delimiter + case AParams.Delimiter of + ',' : CbDelimiter.ItemIndex := 0; + ';' : CbDelimiter.ItemIndex := 1; + ':' : CbDelimiter.ItemIndex := 2; + '|' : CbDelimiter.ItemIndex := 3; + #9 : CbDelimiter.ItemIndex := 4; + end; + + // Quote character + case AParams.QuoteChar of + #0 : CbQuoteChar.ItemIndex := 0; + '"' : CbQuoteChar.ItemIndex := 1; + '''' : CbQuoteChar.ItemIndex := 2; + end; + + // String encoding + if AParams.Encoding = '' then + CbEncoding.ItemIndex := 0 + else if AParams.Encoding = EncodingUTF8BOM then + CbEncoding.ItemIndex := 1 + else + for i:=1 to CbEncoding.Items.Count-1 do + begin + s := CbEncoding.Items[i]; + if SameText(AParams.Encoding, Copy(s, 1, Pos(' ', s)-1)) then + begin + CbEncoding.ItemIndex := i; + break; + end; + end; + + // Detect content type + RgDetectContentType.ItemIndex := ord(AParams.DetectContentType); + + // Auto-detect number format + CbAutoDetectNumberFormat.Checked := AParams.AutoDetectNumberFormat; + + // Number format + EdNumFormat.Text := AParams.NumberFormat; + + // Decimal separator + case AParams.FormatSettings.DecimalSeparator of + #0 : CbDecimalSeparator.ItemIndex := 0; + '.' : CbDecimalSeparator.ItemIndex := 1; + ',' : CbDecimalSeparator.ItemIndex := 2; + else CbDecimalSeparator.Text := AParams.FormatSettings.DecimalSeparator; + end; + + // Thousand separator + case AParams.FormatSettings.ThousandSeparator of + #0 : CbThousandSeparator.ItemIndex := 0; + '.' : CbThousandSeparator.ItemIndex := 1; + ',' : CbThousandSeparator.ItemIndex := 2; + ' ' : CbThousandSeparator.ItemIndex := 3; + else CbThousandSeparator.Text := AParams.FormatSettings.ThousandSeparator; + end; + + // Currency symbol + if AParams.FormatSettings.CurrencyString = '' then + EdCurrencySymbol.Text := rsLikeSpreadsheet + else + EdCurrencySymbol.Text := AParams.FormatSettings.CurrencyString; + + // Long date format + if AParams.FormatSettings.LongDateFormat = '' then + CbLongDateFormat.ItemIndex := 0 + else + CbLongDateFormat.Text := AParams.FormatSettings.LongDateFormat; + + // Short date format + if AParams.FormatSettings.ShortDateFormat = '' then + CbShortDateFormat.ItemIndex := 0 + else + CbShortDateFormat.Text := AParams.FormatSettings.ShortDateFormat; + + // Date separator + case AParams.FormatSettings.DateSeparator of + #0 : CbDateSeparator.ItemIndex := 0; + '.' : CbDateSeparator.ItemIndex := 1; + '-' : CbDateSeparator.ItemIndex := 2; + '/' : CbDateSeparator.ItemIndex := 3; + else CbDateSeparator.Text := AParams.FormatSettings.DateSeparator; + end; + + // Long month names + FEdLongMonthNames.SetNames(AParams.FormatSettings.LongMonthNames, 12, false, rsLikeSpreadsheet); + + // Short month names + FEdShortMonthNames.SetNames(AParams.FormatSettings.ShortMonthNames, 12, true, rsLikeSpreadsheet); + + // Long day names + FEdLongDayNames.SetNames(AParams.FormatSettings.LongDayNames, 7, false, rsLikeSpreadsheet); + + // Short month names + FEdShortDayNames.SetNames(AParams.FormatSettings.ShortDayNames, 7, true, rsLikeSpreadsheet); + + // Long time format + if AParams.FormatSettings.LongTimeFormat = '' then + CbLongTimeFormat.ItemIndex := 0 + else + CbLongTimeFormat.Text := AParams.FormatSettings.LongTimeFormat; + + // Short time format + if AParams.FormatSettings.ShortTimeFormat = '' then + CbShortTimeFormat.ItemIndex := 0 + else + CbShortTimeFormat.Text := AParams.FormatSettings.ShortTimeFormat; + + // Time separator + case AParams.FormatSettings.TimeSeparator of + #0 : CbTimeSeparator.ItemIndex := 0; + '.' : CbTimeSeparator.ItemIndex := 1; + '-' : CbTimeSeparator.ItemIndex := 2; + '/' : CbTimeSeparator.ItemIndex := 3; + ':' : CbTimeSeparator.ItemIndex := 4; + else CbTimeSeparator.Text := AParams.FormatSettings.TimeSeparator; + end; + + // Text for "TRUE" + EdTRUE.Text := AParams.TrueText; + + // Test for "FALSE" + EdFALSE.Text := AParams.FalseText; + + // Update date/time sample display + DateTimeFormatChange(nil); +end; + +procedure TCSVParamsForm.ThousandSeparatorToFormatSettings(var ASettings: TFormatSettings); +begin + case CbThousandSeparator.ItemIndex of + 0: ASettings.ThousandSeparator := #0; + 1: ASettings.ThousandSeparator := '.'; + 2: ASettings.ThousandSeparator := ','; + 3: ASettings.ThousandSeparator := ' '; + else ASettings.ThousandSeparator := CbThousandSeparator.Text[1]; + end; +end; + +procedure TCSVParamsForm.TimeSeparatorToFormatSettings(var ASettings: TFormatSettings); +begin + case CbTimeSeparator.ItemIndex of + 0: ASettings.TimeSeparator := #0; + 1: ASettings.TimeSeparator := '.'; + 2: ASettings.TimeSeparator := '-'; + 3: ASettings.TimeSeparator := '/'; + 4: ASettings.TimeSeparator := ':'; + else ASettings.TimeSeparator := CbTimeSeparator.Text[1]; + end; +end; + +//initialization +// {$I scsvparamsform.lrs} + +end. + diff --git a/applications/spready/sctrls.pas b/applications/spready/sctrls.pas new file mode 100644 index 000000000..680e37138 --- /dev/null +++ b/applications/spready/sctrls.pas @@ -0,0 +1,326 @@ +unit sCtrls; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Controls, StdCtrls, Grids, EditBtn, Forms; + +type + { TMonthDayNamesEdit } + TMonthDayNamesEdit = class(TEditButton) + private + FEmptyString: String; + FCount: Integer; + FShortnames: Boolean; + procedure ButtonClickHandler(Sender: TObject); + function CreateMonthDayNamesEditor(var AGrid: TStringGrid): TForm; + protected + public + constructor Create(AOwner: TComponent); override; + procedure GetNames(var ANamesArray); + procedure SetNames(const ANamesArray; ACount: Integer; IsShortNames: Boolean; + const AEmptyString: String); + end; + + { TFormatSeparatorCombo } + TFormatSeparatorKind = (skDecimal, skThousand, skDate, skTime, skList); + + TFormatSeparatorCombo = class(TCombobox) + private + FKind: TFormatSeparatorKind; + function GetSeparator: Char; + procedure SetSeparator(AValue: Char); + procedure SetSeparatorKind(AValue: TFormatSeparatorKind); + public + property Separator: Char read GetSeparator write SetSeparator; + property SeparatorKind: TFormatSeparatorKind read FKind write SetSeparatorKind; + end; + + +implementation + +uses + Math, ButtonPanel, fpsUtils; + +{@@ ---------------------------------------------------------------------------- + Concatenates the day names specified in ADayNames to a single string. If all + daynames are empty AEmptyStr is returned + + @param ADayNames Array[1..7] of day names as used in the Formatsettings + @param AEmptyStr Is returned if all day names are empty + @return String having all day names concatenated and separated by the + DefaultFormatSettings.ListSeparator +-------------------------------------------------------------------------------} +function DayNamesToString(const ADayNames: TWeekNameArray; + const AEmptyStr: String): String; +var + i: Integer; + isEmpty: Boolean; +begin + isEmpty := true; + for i:=1 to 7 do + if ADayNames[i] <> '' then + begin + isEmpty := false; + break; + end; + + if isEmpty then + Result := AEmptyStr + else + begin + Result := ADayNames[1]; + for i:=2 to 7 do + Result := Result + DefaultFormatSettings.ListSeparator + ' ' + ADayNames[i]; + end; +end; + +{@@ ---------------------------------------------------------------------------- + Concatenates the month names specified in AMonthNames to a single string. + If all month names are empty AEmptyStr is returned + + @param AMonthNames Array[1..12] of month names as used in the Formatsettings + @param AEmptyStr Is returned if all month names are empty + @return String having all month names concatenated and separated by the + DefaultFormatSettings.ListSeparator +-------------------------------------------------------------------------------} +function MonthNamesToString(const AMonthNames: TMonthNameArray; + const AEmptyStr: String): String; +var + i: Integer; + isEmpty: Boolean; +begin + isEmpty := true; + for i:=1 to 12 do + if AMonthNames[i] <> '' then + begin + isEmpty := false; + break; + end; + + if isEmpty then + Result := AEmptyStr + else + begin + Result := AMonthNames[1]; + for i:=2 to 12 do + Result := Result + DefaultFormatSettings.ListSeparator + ' ' + AMonthNames[i]; + end; +end; + +{ TMonthDayNamesEdit } + +constructor TMonthDayNamesEdit.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + Button.Caption := '...'; + OnButtonClick := @ButtonClickHandler; +end; + +procedure TMonthDayNamesEdit.ButtonClickHandler(Sender: TObject); +var + F: TForm; + i: Integer; + grid: TStringGrid = nil; + names: TMonthNameArray; // can hold day and month names as well +begin + F := CreateMonthDayNamesEditor(grid); + try + if F.ShowModal = mrOK then + begin + for i:=1 to 12 do + names[i] := ''; + for i:=1 to grid.RowCount-1 do + names[i] := grid.Cells[1, i]; + SetNames(names, FCount, FShortNames, FEmptyString); + end; + finally + F.Free; + end; +end; + +function TMonthDayNamesEdit.CreateMonthDayNamesEditor(var AGrid: TStringGrid): TForm; +var + btnPanel: TButtonPanel; + i: Integer; + R: TRect; + Pt: TPoint; + w: Integer; + names: TMonthNameArray; // has space for both months and days... +begin + Result := TForm.Create(nil); + btnPanel := TButtonPanel.Create(Result); + with btnPanel do begin + Parent := Result; + ShowButtons := [pbOK, pbCancel]; + end; + AGrid := TStringGrid.Create(Result); + with AGrid do begin + Parent := Result; + Align := alClient; + BorderSpacing.Around := 8; + TitleStyle := tsNative; + Options := Options + [goEditing, goAlwaysShowEditor] - [goVertLine]; + DefaultColWidth := 150; + AutoFillColumns := true; + ColCount := 2; + RowCount := FCount+1; + if FCount = 12 then + begin + Cells[0, 1] := 'January'; + Cells[0, 2] := 'February'; + Cells[0, 3] := 'March'; + Cells[0, 4] := 'April'; + Cells[0, 5] := 'May'; + Cells[0, 6] := 'June'; + Cells[0, 7] := 'July'; + Cells[0, 8] := 'August'; + Cells[0, 9] := 'September'; + Cells[0,10] := 'October'; + Cells[0,11] := 'November'; + Cells[0,12] := 'December'; + if FShortNames then + Cells[1, 0] := 'Short month names' + else + Cells[1, 0] := 'Long month names'; + end else + begin + Cells[0, 1] := 'Sunday'; + Cells[0, 2] := 'Monday'; + Cells[0, 3] := 'Tuesday'; + Cells[0, 4] := 'Wesdnesday'; + Cells[0, 5] := 'Thursday'; + Cells[0, 6] := 'Friday'; + Cells[0, 7] := 'Saturday'; + if FShortNames then + Cells[1, 0] := 'Short day names' + else + Cells[1, 0] := 'Long day names'; + end; + names[1] := ''; // to silence the compiler... + GetNames(names); + w := 0; + for i:=1 to FCount do + begin + Cells[1, i] := TMonthNameArray(names)[i]; + w := Max(w, Canvas.TextWidth(Cells[0, i])); + end; + ColWidths[0] := w + 16; + ColWidths[1] := 2*w; + R := CellRect(ColCount-1, RowCount-1); + end; + Pt := Result.ScreenToClient(AGrid.ClientToScreen(R.BottomRight)); + Result.Width := AGrid.width + AGrid.BorderSpacing.Around*2 + 5; + Result.Height := Pt.Y + btnPanel.Height + AGrid.BorderSpacing.Around*2 - 6; + Result.Position := poMainFormCenter; + Result.ActiveControl := AGrid; +end; + +procedure TMonthDayNamesEdit.GetNames(var ANamesArray); +{ Not very nice code here: will crash if a TWeekNameArray is passed as ANameArray, + but the edit stores month data! Watch out... } +var + L: TStringList; + i: Integer; +begin + for i:=1 to FCount do + TMonthNameArray(ANamesArray)[i] := ''; + if Text <> FEmptyString then + begin + L := TStringList.Create; + try + L.Delimiter := DefaultFormatSettings.ListSeparator; + L.DelimitedText := Text; + for i:=0 to L.Count-1 do + if i < L.Count then + TMonthNameArray(ANamesArray)[i+1] := L[i]; + finally + L.Free; + end; + end; +end; + +procedure TMonthDayNamesEdit.SetNames(const ANamesArray; ACount: Integer; + IsShortNames: Boolean; const AEmptyString: String); +begin + if not ACount in [7, 12] then + raise Exception.Create('[TMonthDayNameEdit] Array length can only be 7 or 12.'); + + FCount := ACount; + FEmptyString := AEmptyString; + FShortNames := IsShortNames; + + case FCount of + 7: Text := DayNamesToString(TWeekNameArray(ANamesArray), AEmptyString); + 12: Text := MonthNamesToString(TMonthNameArray(ANamesArray), AEmptyString); + else raise Exception.Create('[TMonthDayNameEdit] Array length can only be 7 or 12.'); + end; +end; + + +{ TFormatSeparatorCombo } + +function TFormatSeparatorCombo.GetSeparator: Char; +begin + if ItemIndex = -1 then + begin + if Text = '' then + Result := #0 + else + Result := Text[1]; + end else + Result := Char(PtrInt(items.Objects[ItemIndex])); +end; + +procedure TFormatSeparatorCombo.SetSeparator(AValue: Char); +var + i: Integer; +begin + i := Items.IndexOfObject(TObject(PtrInt(ord(AValue)))); + if i = -1 then + Text := AValue + else + ItemIndex := i; +end; + +procedure TFormatSeparatorCombo.SetSeparatorKind(AValue: TFormatSeparatorKind); +begin + FKind := AValue; + Items.BeginUpdate; + try + case FKind of + skDecimal, skThousand: + begin + Items.AddObject('Dot ( . )', TObject(PtrInt(ord('.')))); + Items.AddObject('Comma ( , )', TObject(PtrInt(ord(',')))); + if FKind = skThousand then + Items.AddObject('Space ( )', TObject(PtrInt(ord(' ')))); + end; + skDate, skTime: + begin + Items.AddObject('Dot ( . )', TObject(PtrInt(ord('.')))); + Items.AddObject('Dash ( - )', TObject(PtrInt(ord('-')))); + Items.AddObject('Slash ( / )', TObject(PtrInt(ord('/')))); + if FKind = skTime then + Items.AddObject('Colon ( : )', TObject(PtrInt(ord(':')))); + end; + skList: + begin + Items.AddObject('Dot ( . )', TObject(PtrInt(ord('.')))); + Items.AddObject('Comma ( , )', TObject(PtrInt(ord(',')))); + Items.AddObject('Semicolon ( ; )', TObject(PtrInt(ord(';')))); + Items.AddObject('Colon ( : )', TObject(PtrInt(ord(':')))); + Items.AddObject('Bar ( | )', TObject(PtrInt(ord('|')))); + Items.AddObject('Slash ( / )', TObject(PtrInt(ord('/')))); + Items.AddObject('Backslash ( \ )', TObject(PtrInt(ord('\')))); + end; + end; + finally + Items.EndUpdate; + end; +end; + +end. + diff --git a/applications/spready/scurrencyform.lfm b/applications/spready/scurrencyform.lfm new file mode 100644 index 000000000..86b255151 --- /dev/null +++ b/applications/spready/scurrencyform.lfm @@ -0,0 +1,172 @@ +object CurrencyForm: TCurrencyForm + Left = 544 + Height = 288 + Top = 339 + Width = 245 + BorderStyle = bsDialog + Caption = 'Currency symbols' + ClientHeight = 288 + ClientWidth = 245 + OnCreate = FormCreate + ShowHint = True + LCLVersion = '1.5' + object LblInfo: TLabel + Left = 4 + Height = 15 + Top = 4 + Width = 237 + Align = alTop + BorderSpacing.Around = 4 + Caption = 'These strings indicate currencies:' + ParentColor = False + WordWrap = True + end + object CurrencyListbox: TListBox + Left = 4 + Height = 223 + Top = 23 + Width = 237 + Align = alClient + BorderSpacing.Around = 4 + ItemHeight = 0 + TabOrder = 0 + end + object ButtonPanel: TPanel + Left = 0 + Height = 38 + Top = 250 + Width = 245 + Align = alBottom + ClientHeight = 38 + ClientWidth = 245 + FullRepaint = False + TabOrder = 1 + object BtnOK: TBitBtn + Left = 77 + Height = 25 + Hint = 'Accept changes and close' + Top = 8 + Width = 75 + Anchors = [akTop, akRight] + DefaultCaption = True + Kind = bkOK + ModalResult = 1 + OnClick = BtnOKClick + TabOrder = 0 + end + object BtnCancel: TBitBtn + Left = 157 + Height = 25 + Hint = 'Discard changes and close' + Top = 8 + Width = 83 + Anchors = [akTop, akRight] + DefaultCaption = True + Kind = bkCancel + ModalResult = 2 + TabOrder = 1 + end + object ButtonBevel: TBevel + Left = 5 + Height = 3 + Top = 1 + Width = 235 + Align = alTop + BorderSpacing.Left = 4 + BorderSpacing.Right = 4 + Shape = bsTopLine + end + object BtnAdd: TBitBtn + Left = 8 + Height = 25 + Hint = 'Add a currency symbol' + Top = 8 + Width = 27 + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0041924E233D8F497D3A8C44DB368940F332873CF32F84 + 37DB2C81337D287F3023FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0049995853459653E6419950FF7DC28FFF96D0A6FF96CFA6FF78BE + 89FF368D42FF2C8134E6297F3053FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00519F61534D9C5DF464B478FFA8DBB5FF87CC98FF66BC7DFF64BA7CFF86CB + 98FFA5D9B4FF58AA6BFF2C8134F4297F3053FFFFFF00FFFFFF00FFFFFF0059A6 + 6B2256A366E56AB97DFFA8DBB2FF60BC77FF5CBA73FF59B870FF59B56FFF58B5 + 6FFF5BB774FFA5D9B3FF5AAA6CFF2C8234E5297F3022FFFFFF00FFFFFF005DA9 + 707E53AB68FFAADDB4FF64C179FF5FBE71FF60BC77FFFFFFFFFFFFFFFFFF59B8 + 70FF58B56EFF5CB774FFA6DAB4FF388F43FF2C82347EFFFFFF00FFFFFF0061AC + 75DB8ACC98FF89D396FF6BC67AFF63C170FF55AB65FFFFFFFFFFFFFFFFFF59B8 + 70FF59B870FF5BB972FF85CC97FF7BBE8DFF308539DBFFFFFF00FFFFFF0065AF + 7AF6A9DDB3FF7DCF8AFF75CC81FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF59B870FF67BE7DFF9CD4ABFF34883DF6FFFFFF00FFFFFF0069B2 + 7EF6B6E2BEFF8BD597FF7AC986FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF59B870FF69C17EFF9DD4AAFF388B42F6FFFFFF00FFFFFF006DB5 + 83DBACDDB6FFA6DFAFFF81CB8CFF7CC986FF6EBD79FFFFFFFFFFFFFFFFFF5BAC + 6AFF60BC77FF5CBA73FF8BD199FF80C592FF3C8E47DBFFFFFF00FFFFFF0070B8 + 877E85C797FFD2EED7FF95D9A0FF8AD394FF7FC889FFFFFFFFFFFFFFFFFF79CD + 85FF6BC37CFF6FC77EFFACDFB5FF459E57FF40914C7EFFFFFF00FFFFFF0073BA + 8A2270B887E5AADAB7FFD8F1DCFF92D89DFF88CD93FF84CC8EFF8BD496FF8AD4 + 95FF83D28EFFAFE0B7FF6BB97DFF489856E544945122FFFFFF00FFFFFF00FFFF + FF0073BB8B5370B887F4AFDCBBFFDCF2E0FFB6E4BDFF9BDBA5FF96D9A0FFA5DF + AFFFC0E8C5FF79C28AFF509E5FF44C9B5B53FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0073BB8B5371B887E694CEA4FFC3E6CBFFCFEBD4FFC9E9CEFFAFDD + B8FF6DB97FFF58A569E654A16553FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0074BB8B2371B9887D6EB684DB6AB380F367B17CF363AE + 77DB60AB737D5CA86E23FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = BtnAddClick + Spacing = 0 + TabOrder = 2 + end + object BtnDelete: TBitBtn + Left = 40 + Height = 25 + Hint = 'Delete selected currency symbol' + Top = 8 + Width = 27 + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF003F54C3233A50C27D3853BEDB3551BDF3304BBCF32E4E + B8DB2B4CB77D2748B523FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF004658C8534255C6E63C52CCFF757AE8FF8F92EEFF8F92EEFF7178 + E4FF334DC1FF2B4AB7E6294BB553FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF004D5ACD534959CBF45C65E0FFA1A6F5FF7E86EFFF5B63E9FF595DE7FF7D84 + EEFF9EA0F4FF515DD7FF2B4AB7F4294BB553FFFFFF00FFFFFF00FFFFFF00545F + D2225361CFE5616BE3FFA1ACF5FF545FECFF505CEAFF4D59E9FF4E59E6FF4C56 + E6FF5056E6FF9EA2F4FF5460D6FF2A4AB8E5294BB522FFFFFF00FFFFFF005860 + D47E4B56DBFFA2ABF6FF5664F0FF5266EEFF4D59E9FF4D59E9FF4D59E9FF4D59 + E9FF4C58E6FF525AE6FF9FA3F5FF3450C4FF2A4AB87EFFFFFF00FFFFFF005C62 + D7DB818CEEFF7E91F7FF5D73F3FF4D59E9FF4D59E9FF4D59E9FF4D59E9FF4D59 + E9FF4D59E9FF4F5BE9FF7B83F0FF757BE2FF2E4BBADBFFFFFF00FFFFFF005F63 + DAF6A1ABF7FF7086F8FF6882F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF4D59E9FF5C66EAFF969CF1FF3250BCF6FFFFFF00FFFFFF006469 + DBF6AFB9F9FF7F93FAFF7085F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF4D59E9FF5E6AEEFF969DF1FF364FBEF6FFFFFF00FFFFFF00676A + DEDBA5AFF5FF9DABFAFF778CF0FF545FECFF545FECFF545FECFF545FECFF545F + ECFF545FECFF6377F2FF818EF4FF787FE9FF3A53C0DBFFFFFF00FFFFFF006A69 + E07E7D83EAFFCDD4FCFF8B9DFAFF7E93F7FF758AEEFF6C84F6FF6C84F6FF6C84 + F6FF6C84F6FF6379F3FFA4AFF8FF3E4FD0FF3E54C27EFFFFFF00FFFFFF006C6C + E1226A69E0E5A3A7F3FFD4DBFDFF879AFAFF7F91F0FF7A8EF1FF7F94F8FF7E92 + F9FF768CF8FFA8B6F8FF636EE3FF4557C7E54156C522FFFFFF00FFFFFF00FFFF + FF006D6CE3536A69E0F4AAADF2FFD8DCFDFFAEBAFAFF91A3FAFF8B9DFAFF9CA9 + FBFFBAC7FCFF707BE9FF4C5BCCF44858CA53FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF006D6CE3536A6ADFE68E93EDFFBEC3F8FFCCD3F9FFC4CBF9FFAAB4 + F4FF6670E2FF535ED1E6505DCE53FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF006D6DE2236B6AE17D686ADDDB6364DCF36164DAF35D63 + D9DB5B63D67D5862D423FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = BtnDeleteClick + Spacing = 0 + TabOrder = 3 + end + end +end diff --git a/applications/spready/scurrencyform.pas b/applications/spready/scurrencyform.pas new file mode 100644 index 000000000..48c596d71 --- /dev/null +++ b/applications/spready/scurrencyform.pas @@ -0,0 +1,100 @@ +unit scurrencyform; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, + ExtCtrls, Buttons; + +type + + { TCurrencyForm } + + TCurrencyForm = class(TForm) + ButtonBevel: TBevel; + BtnAdd: TBitBtn; + BtnCancel: TBitBtn; + BtnDelete: TBitBtn; + BtnOK: TBitBtn; + CurrencyListbox: TListBox; + LblInfo: TLabel; + ButtonPanel: TPanel; + procedure BtnAddClick(Sender: TObject); + procedure BtnDeleteClick(Sender: TObject); + procedure BtnOKClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + private + { private declarations } + function GetCurrencySymbol: String; + procedure SetCurrencySymbol(const AValue: String); + public + { public declarations } + property CurrencySymbol: String read GetCurrencySymbol write SetCurrencySymbol; + end; + +var + CurrencyForm: TCurrencyForm; + +implementation + +{$R *.lfm} + +uses + fpsCurrency; + + +{ TCurrencyForm } + +procedure TCurrencyForm.BtnAddClick(Sender: TObject); +var + s: String; + i: Integer; +begin + s := InputBox('Input', 'Currency symbol:', ''); + if s <> '' then begin + i := CurrencyListbox.Items.IndexOf(s); + if i = -1 then + i := CurrencyListbox.Items.Add(s); + CurrencyListbox.ItemIndex := i; + end; +end; + +procedure TCurrencyForm.BtnDeleteClick(Sender: TObject); +begin + if CurrencyListbox.ItemIndex > -1 then + CurrencyListbox.Items.Delete(CurrencyListbox.ItemIndex); +end; + +procedure TCurrencyForm.BtnOKClick(Sender: TObject); +begin + RegisterCurrencies(CurrencyListbox.Items, true); +end; + +procedure TCurrencyForm.FormCreate(Sender: TObject); +begin + GetRegisteredCurrencies(CurrencyListbox.Items); + CurrencyListbox.ItemIndex := CurrencyListbox.Items.Count-1; +end; + +function TCurrencyForm.GetCurrencySymbol: String; +var + index: Integer; +begin + index := CurrencyListbox.ItemIndex; + if index > -1 then + Result := CurrencyListbox.Items[index] + else + Result := ''; +end; + +procedure TCurrencyForm.SetCurrencySymbol(const AValue: String); +begin + CurrencyListbox.ItemIndex := CurrencyListbox.Items.IndexOf(AValue); +end; + +end. + + + diff --git a/applications/spready/sformatsettingsform.lfm b/applications/spready/sformatsettingsform.lfm new file mode 100644 index 000000000..387df0b60 --- /dev/null +++ b/applications/spready/sformatsettingsform.lfm @@ -0,0 +1,394 @@ +object FormatSettingsForm: TFormatSettingsForm + Left = 417 + Height = 494 + Top = 229 + Width = 470 + BorderStyle = bsDialog + Caption = 'Workbook format settings' + ClientHeight = 494 + ClientWidth = 470 + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + Position = poMainFormCenter + ShowHint = True + LCLVersion = '1.5' + object PageControl: TPageControl + Left = 8 + Height = 438 + Top = 8 + Width = 454 + ActivePage = PgCurrency + Align = alClient + BorderSpacing.Around = 8 + TabIndex = 1 + TabOrder = 0 + OnChange = PageControlChange + object PgNumber: TTabSheet + Caption = 'Number' + ClientHeight = 410 + ClientWidth = 446 + object LblDecimalSeparator: TLabel + Left = 16 + Height = 15 + Top = 19 + Width = 98 + Caption = 'Decimal separator:' + ParentColor = False + end + object LblThousandSeparator: TLabel + Left = 16 + Height = 15 + Top = 51 + Width = 108 + Caption = 'Thousand separator:' + ParentColor = False + end + object Label1: TLabel + Left = 4 + Height = 15 + Top = 391 + Width = 438 + Align = alBottom + BorderSpacing.Around = 4 + Caption = 'The current workbook is automatically updated to these settings.' + ParentColor = False + WordWrap = True + end + object Bevel3: TBevel + Left = 0 + Height = 3 + Top = 384 + Width = 446 + Align = alBottom + Shape = bsBottomLine + end + end + object PgCurrency: TTabSheet + Caption = 'Currency' + ClientHeight = 410 + ClientWidth = 446 + object LblCurrencySymbol: TLabel + Left = 16 + Height = 15 + Top = 20 + Width = 93 + Caption = 'Currency symbol:' + FocusControl = EdCurrencySymbol + ParentColor = False + end + object EdCurrencySymbol: TEdit + Left = 200 + Height = 23 + Top = 16 + Width = 202 + Anchors = [akTop, akLeft, akRight] + OnChange = EdCurrencySymbolChange + TabOrder = 0 + end + object LblCurrencySymbol1: TLabel + Left = 16 + Height = 15 + Top = 52 + Width = 132 + Caption = 'Currency decimal places:' + FocusControl = EdCurrencyDecimals + ParentColor = False + end + object EdCurrencyDecimals: TSpinEdit + Left = 200 + Height = 23 + Top = 48 + Width = 66 + TabOrder = 1 + end + object LblPosCurrencyFormat: TLabel + Left = 16 + Height = 15 + Top = 84 + Width = 135 + Caption = 'Format of positive values:' + FocusControl = CbPosCurrencyFormat + ParentColor = False + end + object CbPosCurrencyFormat: TComboBox + Left = 200 + Height = 23 + Top = 80 + Width = 231 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + Style = csDropDownList + TabOrder = 2 + end + object LblNegCurrencyFormat: TLabel + Left = 16 + Height = 15 + Top = 116 + Width = 139 + Caption = 'Format of negative values:' + FocusControl = CbNegCurrencyFormat + ParentColor = False + end + object CbNegCurrencyFormat: TComboBox + Left = 200 + Height = 23 + Top = 112 + Width = 231 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + Style = csDropDownList + TabOrder = 3 + end + object Label2: TLabel + Left = 4 + Height = 15 + Top = 391 + Width = 438 + Align = alBottom + BorderSpacing.Around = 4 + Caption = 'These settings are only respected in new cells.' + ParentColor = False + WordWrap = True + end + object Bevel2: TBevel + Left = 0 + Height = 3 + Top = 384 + Width = 446 + Align = alBottom + Shape = bsBottomLine + end + object BtnCurrency: TBitBtn + Left = 406 + Height = 25 + Top = 15 + Width = 25 + Caption = '...' + OnClick = BtnCurrencyClick + TabOrder = 4 + end + end + object PgDateTime: TTabSheet + Caption = 'Date/time' + ClientHeight = 401 + ClientWidth = 446 + object LblNumFormat1: TLabel + Left = 16 + Height = 20 + Top = 20 + Width = 160 + Caption = 'Long date format string:' + ParentColor = False + end + object CbLongDateFormat: TComboBox + Left = 200 + Height = 23 + Top = 16 + Width = 231 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'ddd, d/mm/yyyy' + 'ddd, d/mmm/yyyy' + 'dddd, d/mm/yyyy' + 'dddd, d/mmm/yyyy' + 'd/mm/yyyy' + 'dd/mm/yyyy' + 'dddd, mm/d/yyyy' + 'dddd, mmm/d/yyyy' + 'mm/d/yyyy' + 'mm/dd/yyyy' + 'yyyy/mm/dd' + 'yyyy/mm/d' + 'yyyy/mmm/d' + 'yyyy/mmmm/d' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 0 + Text = 'ddd, d/mm/yyyy' + end + object LblNumFormat2: TLabel + Left = 16 + Height = 20 + Top = 52 + Width = 162 + Caption = 'Short date format string:' + ParentColor = False + end + object CbShortDateFormat: TComboBox + Left = 200 + Height = 23 + Top = 48 + Width = 231 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'd/m/yy' + 'd/mm/yy' + 'd/mm/yyyy' + 'm/d/yy' + 'mm/d/yy' + 'mm/d/yyyy' + 'yy/m/d' + 'yy/mm/d' + 'yyyy/mm/d' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 1 + Text = 'd/m/yy' + end + object LblDateSeparator: TLabel + Left = 16 + Height = 20 + Top = 83 + Width = 102 + Caption = 'Date separator:' + ParentColor = False + end + object LblLongMonthNames: TLabel + Left = 16 + Height = 20 + Top = 116 + Width = 130 + Caption = 'Long month names:' + ParentColor = False + end + object LblShortMonthNames: TLabel + Left = 16 + Height = 20 + Top = 148 + Width = 132 + Caption = 'Short month names:' + ParentColor = False + end + object LblLongDayNames: TLabel + Left = 16 + Height = 20 + Top = 180 + Width = 111 + Caption = 'Long day names:' + ParentColor = False + end + object LblShortDayNames: TLabel + Left = 16 + Height = 20 + Top = 212 + Width = 113 + Caption = 'Short day names:' + ParentColor = False + end + object LblNumFormat3: TLabel + Left = 16 + Height = 20 + Top = 252 + Width = 160 + Caption = 'Long time format string:' + ParentColor = False + end + object LblNumFormat4: TLabel + Left = 16 + Height = 20 + Top = 284 + Width = 162 + Caption = 'Short time format string:' + ParentColor = False + end + object LblTimeSeparator: TLabel + Left = 16 + Height = 20 + Top = 315 + Width = 103 + Caption = 'Time separator:' + ParentColor = False + end + object CbLongTimeFormat: TComboBox + Left = 200 + Height = 23 + Top = 248 + Width = 231 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + ItemIndex = 1 + Items.Strings = ( + 'h:n:s' + 'h:nn:ss' + 'hh:nn:ss' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 2 + Text = 'h:nn:ss' + end + object CbShortTimeFormat: TComboBox + Left = 200 + Height = 23 + Top = 280 + Width = 231 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + ItemIndex = 1 + Items.Strings = ( + 'h:n' + 'h:nn' + 'hh:nn' + ) + OnChange = DateTimeFormatChange + OnEnter = DateTimeFormatChange + TabOrder = 3 + Text = 'h:nn' + end + object Label3: TLabel + Left = 4 + Height = 40 + Top = 357 + Width = 438 + Align = alBottom + BorderSpacing.Around = 4 + Caption = 'Only the date and time separator are automatically respected by the workbook; the other settings are considered only for new cells.' + ParentColor = False + WordWrap = True + end + object Bevel1: TBevel + Left = 0 + Height = 3 + Top = 350 + Width = 446 + Align = alBottom + Shape = bsBottomLine + end + end + end + object ButtonPanel: TButtonPanel + Left = 6 + Height = 34 + Top = 454 + Width = 458 + OKButton.Name = 'OKButton' + OKButton.DefaultCaption = True + OKButton.OnClick = OKButtonClick + HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True + CloseButton.Name = 'CloseButton' + CloseButton.DefaultCaption = True + CancelButton.Name = 'CancelButton' + CancelButton.DefaultCaption = True + TabOrder = 1 + ShowButtons = [pbOK, pbCancel] + object LblDateTimeSample: TLabel + Left = 6 + Height = 36 + Top = 2 + Width = 287 + Anchors = [akTop, akLeft, akRight] + AutoSize = False + Caption = 'sample' + Layout = tlCenter + ParentColor = False + WordWrap = True + end + end +end diff --git a/applications/spready/sformatsettingsform.pas b/applications/spready/sformatsettingsform.pas new file mode 100644 index 000000000..5b464abf0 --- /dev/null +++ b/applications/spready/sformatsettingsform.pas @@ -0,0 +1,470 @@ +unit sFormatsettingsForm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, + ButtonPanel, ComCtrls, StdCtrls, Spin, ExtCtrls, Buttons, sCtrls; + +type + { TFormatSettingsForm } + + TFormatSettingsForm = class(TForm) + Bevel1: TBevel; + Bevel2: TBevel; + Bevel3: TBevel; + BtnCurrency: TBitBtn; + ButtonPanel: TButtonPanel; + CbLongDateFormat: TComboBox; + CbLongTimeFormat: TComboBox; + CbPosCurrencyFormat: TComboBox; + CbNegCurrencyFormat: TComboBox; + CbShortDateFormat: TComboBox; + CbShortTimeFormat: TComboBox; + EdCurrencySymbol: TEdit; + EdCurrencyDecimals: TSpinEdit; + Label1: TLabel; + Label2: TLabel; + Label3: TLabel; + LblCurrencySymbol: TLabel; + LblCurrencySymbol1: TLabel; + LblDateTimeSample: TLabel; + LblDecimalSeparator: TLabel; + LblDateSeparator: TLabel; + LblTimeSeparator: TLabel; + LblLongDayNames: TLabel; + LblLongMonthNames: TLabel; + LblNumFormat1: TLabel; + LblNumFormat2: TLabel; + LblNumFormat3: TLabel; + LblNumFormat4: TLabel; + LblPosCurrencyFormat: TLabel; + LblNegCurrencyFormat: TLabel; + LblShortDayNames: TLabel; + LblShortMonthNames: TLabel; + LblThousandSeparator: TLabel; + PageControl: TPageControl; + PgCurrency: TTabSheet; + PgDateTime: TTabSheet; + PgNumber: TTabSheet; + procedure BtnCurrencyClick(Sender: TObject); + procedure DateTimeFormatChange(Sender: TObject); + procedure EdCurrencySymbolChange(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); + procedure FormCreate(Sender: TObject); + procedure OKButtonClick(Sender: TObject); + procedure PageControlChange(Sender: TObject); + private + FSampleDateTime: TDateTime; + FDateFormatSample: String; + FTimeFormatSample: String; + FEdLongMonthNames: TMonthDayNamesEdit; + FEdShortMonthNames: TMonthDayNamesEdit; + FEdLongDayNames: TMonthDayNamesEdit; + FEdShortDayNames: TMonthDayNamesEdit; + FCbDecimalSeparator: TFormatSeparatorCombo; + FCbThousandSeparator: TFormatSeparatorCombo; + FCbDateSeparator: TFormatSeparatorCombo; + FCbTimeSeparator: TFormatSeparatorCombo; + function GetFormatSettings: TFormatSettings; + procedure SetFormatSettings(const AValue: TFormatSettings); + function ValidData(out AControl: TWinControl; out AMsg: String): Boolean; + public + { public declarations } + property FormatSettings: TFormatSettings read GetFormatSettings write SetFormatSettings; + end; + +var + FormatSettingsForm: TFormatSettingsForm; + + +implementation + +{$R *.lfm} + +uses + fpsUtils, fpsNumFormat, + sCurrencyForm; + +const + CURR_VALUE = 100.0; + +var + PageIndex: Integer = 0; // stores the previously selected page index (to open the form always with previously used page) + + +{ TFormatSettingsForm } + +procedure TFormatSettingsForm.DateTimeFormatChange(Sender: TObject); +var + fs: TFormatSettings; + ctrl: TWinControl; + dt: TDateTime; + s: String; +begin + fs := GetFormatSettings; + dt := FSampleDateTime; + ctrl := ActiveControl; + + if (ctrl = CbLongDateFormat) then + begin + FDateFormatSample := fs.LongDateFormat; + s := FormatDateTime(FDateFormatSample, dt, fs); + LblDateTimeSample.Caption := 'Sample date:'#13 + s; + end + else + if (ctrl = CbShortDateFormat) then + begin + FDateFormatSample := fs.ShortDateFormat; + s := FormatDateTime(FDateFormatSample, dt, fs); + LblDateTimeSample.Caption := 'Sample date:'#13 + s; + end + else + if (ctrl = FCbDateSeparator) then begin + s := FormatDateTime(FDateFormatSample, dt, fs); + LblDateTimeSample.Caption := 'Sample date:'#13 + s; + end + else + if (ctrl = CbLongTimeFormat) then + begin + FTimeFormatSample := fs.LongTimeFormat; + s := FormatDateTime(FTimeFormatSample, dt, fs); + LblDateTimeSample.Caption := 'Sample time:'#13 + s; + end + else + if (ctrl = CbShortTimeFormat) then + begin + FTimeFormatSample := fs.ShortTimeFormat; + s := FormatDateTime(FTimeFormatSample, dt, fs); + LblDateTimeSample.Caption := 'Sample time:'#13 + s; + end + else + if (ctrl = FCbTimeSeparator) then + begin + s := FormatDateTime(FTimeFormatSample, dt, fs); + LblDateTimeSample.Caption := 'Sample time:'#13 + s; + { + end + else + begin + s := AnsiToUTF8(FormatDateTime('c', dt, fs)); + LblDateTimeSample.Caption := 'Sample date/time:'#13 + s; + } + end; + + LblDateTimeSample.Visible := (PageControl.Activepage = PgDateTime) and + ((FDateFormatSample <> '') or (FTimeFormatSample <> '')); +// Application.ProcessMessages; +end; + +procedure TFormatSettingsForm.BtnCurrencyClick(Sender: TObject); +var + F: TCurrencyForm; +begin + F := TCurrencyForm.Create(nil); + try + F.CurrencySymbol := EdCurrencySymbol.Text; + if F.ShowModal = mrOK then + EdCurrencySymbol.Text := F.CurrencySymbol; + finally + F.Free; + end; +end; + +procedure TFormatSettingsForm.EdCurrencySymbolChange(Sender: TObject); +var + currSym: String; +begin + currSym := EdCurrencySymbol.Text; + BuildCurrencyFormatList(CbPosCurrencyFormat.Items, true, CURR_VALUE, currSym); + BuildCurrencyFormatList(CbNegCurrencyFormat.Items, false, CURR_VALUE, currSym); +end; + +procedure TFormatSettingsForm.FormCloseQuery(Sender: TObject; + var CanClose: boolean); +begin + Unused(Sender, CanClose); + PageIndex := PageControl.ActivePageIndex; +end; + +procedure TFormatSettingsForm.FormCreate(Sender: TObject); +const + DROPDOWN_COUNT = 32; +var + w: Integer; +begin + PageControl.ActivePageIndex := PageIndex; + + CbLongDateFormat.DropdownCount := DROPDOWN_COUNT; + CbShortDateFormat.DropdownCount := DROPDOWN_COUNT; + CbLongTimeFormat.DropdownCount := DROPDOWN_COUNT; + CbShortTimeFormat.DropdownCount := DROPDOWN_COUNT; + CbPosCurrencyFormat.DropdownCount := DROPDOWN_COUNT; + CbNegCurrencyFormat.DropdownCount := DROPDOWN_COUNT; + + w := CbLongDateFormat.Width; + FCbDecimalSeparator := TFormatSeparatorCombo.Create(self); + with FCbDecimalSeparator do + begin + Parent := PgNumber; + Left := CbLongDateFormat.Left; + Width := w; + Top := CbLongDateFormat.Top; + TabOrder := 0; + SeparatorKind := skDecimal; + end; + LblDecimalSeparator.FocusControl := FCbDecimalSeparator; + + FCbThousandSeparator := TFormatSeparatorCombo.Create(self); + with FCbThousandSeparator do + begin + Parent := PgNumber; + Left := FCbDecimalSeparator.Left; + Width := w; + Top := FCBDecimalSeparator.Top + 32; + TabOrder := FCbDecimalSeparator.TabOrder + 1; + SeparatorKind := skThousand; + end; + LblThousandSeparator.FocusControl := FCbThousandSeparator; + + FCbDateSeparator := TFormatSeparatorCombo.Create(self); + with FCbDateSeparator do + begin + Parent := PgDateTime; + Left := CbShortDateFormat.Left; + Width := w; + Top := CbShortDateFormat.Top + 32; + TabOrder := CbShortDateFormat.TabOrder + 1; + SeparatorKind := skDate; + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + end; + LblDateSeparator.FocusControl := FCbDateSeparator; + + FEdLongMonthNames := TMonthDayNamesEdit.Create(self); + with FEdLongMonthNames do + begin + Parent := PgDateTime; + Left := CbShortDateFormat.Left; + {$IFDEF LCL_FULLVERSION AND LCL_FULLVERSION > 1020600} + Width := w; + {$ELSE} + Width := w - Button.Width; + {$ENDIF} + Top := CbShortDateFormat.Top + 32*2; + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + TabOrder := CbShortDateFormat.TabOrder + 2; + end; + LblLongMonthNames.FocusControl := FEdLongMonthNames; + + FEdShortMonthNames := TMonthDayNamesEdit.Create(self); + with FEdShortMonthNames do + begin + Parent := PgDateTime; + Left := CbShortDateFormat.Left; + Width := FEdLongMonthNames.Width; + Top := CbShortDateFormat.Top + 32*3; + TabOrder := CbShortDateFormat.TabOrder + 3; + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + end; + LblShortMonthNames.FocusControl := FEdShortMonthNames; + + FEdLongDayNames := TMonthDayNamesEdit.Create(self); + with FEdLongDayNames do + begin + Parent := PgDateTime; + Left := CbShortDateformat.Left; + Width := FEdLongMonthNames.Width; + Top := CbShortDateFormat.Top + 32*4; + TabOrder := CbShortDateFormat.TabOrder + 4; + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + end; + LblLongDayNames.FocusControl := FEdLongDayNames; + + FEdShortDayNames := TMonthDayNamesEdit.Create(self); + with FEdShortDayNames do + begin + Parent := PgDateTime; + Left := CbShortDateFormat.Left; + Width := FEdLongMonthNames.Width; + Top := CbShortDateFormat.Top + 32*5; + TabOrder := CbShortDateFormat.TabOrder + 5; + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + end; + LblShortDayNames.FocusControl := FEdShortDayNames; + + FCbTimeSeparator := TFormatSeparatorCombo.Create(self); + with FCbTimeSeparator do + begin + Parent := PgDateTime; + Left := CbShortTimeFormat.Left; + Width := w; + Top := CbShortTimeFormat.Top + 32; + TabOrder := CbShortTimeFormat.TabOrder + 1; + SeparatorKind := skTime; + OnChange := @DateTimeFormatChange; + OnEnter := @DateTimeFormatChange; + end; + LblTimeSeparator.FocusControl := FCbTimeSeparator; + + FDateFormatSample := ''; + FTimeFormatSample := ''; + FSampleDateTime := now(); + + LblDateTimeSample.Visible := false; + + // Published property not available in old Laz versions + EdCurrencyDecimals.Alignment := taRightJustify; +end; + +procedure TFormatSettingsForm.OKButtonClick(Sender: TObject); +var + msg: String; + C: TWinControl; + cParent: TWinControl; +begin + if not ValidData(C, msg) then + begin + cParent := C.Parent; + while (cParent <> nil) and not (cParent is TTabSheet) do + cParent := cParent.Parent; + PageControl.ActivePage := cParent as TTabSheet; + if C.CanFocus then C.SetFocus; + MessageDlg(msg, mtError, [mbOK], 0); + ModalResult := mrNone; + end; +end; + +procedure TFormatSettingsForm.PageControlChange(Sender: TObject); +begin + LblDateTimeSample.Visible := (PageControl.Activepage = PgDateTime) and + ((FDateFormatSample <> '') or (FTimeFormatSample <> '')); +end; + +function TFormatSettingsForm.GetFormatSettings: TFormatSettings; +begin + Result := DefaultFormatSettings; + + // --- Number format parameters -- + // Decimal separator + Result.DecimalSeparator := FCbDecimalSeparator.Separator; + // Thousand separator + Result.ThousandSeparator := FCbThousandSeparator.Separator; + + // --- Currency format parameters --- + // Currency symbol + Result.CurrencyString := EdCurrencySymbol.Text; + // Currency decimal places + Result.CurrencyDecimals := EdCurrencyDecimals.Value; + // Positive currency format + Result.CurrencyFormat := CbPosCurrencyFormat.ItemIndex; + // Negative currency format + Result.NegCurrFormat := CbNegCurrencyFormat.ItemIndex; + + // --- Date format parameters --- + // Long date format string + Result.LongDateFormat := CbLongDateFormat.Text; + // Short date format string + Result.ShortDateFormat := CbShortDateFormat.Text; + // Date separator + Result.DateSeparator := FCbDateSeparator.Separator; + // Long month names + FEdLongMonthNames.GetNames(Result.LongMonthNames); + // Short month names + FEdShortMonthNames.GetNames(Result.ShortMonthNames); + // Long day names + FEdLongDayNames.GetNames(Result.LongDayNames); + // Short day names + FEdShortDayNames.GetNames(Result.ShortDayNames); + + // --- Time format parameters --- + // Long time format string + Result.LongTimeFormat := CbLongTimeFormat.Text; + // Short time format string + Result.ShortTimeFormat := CbShortTimeFormat.Text; + // Time separator + Result.TimeSeparator := FCbTimeSeparator.Separator; +end; + +procedure TFormatSettingsForm.SetFormatSettings(const AValue: TFormatSettings); +var + i: Integer; +begin + // --- Number format parameters --- + FCbDecimalSeparator.Separator := AValue.DecimalSeparator; + FCbThousandSeparator.Separator := AValue.ThousandSeparator; + + // --- Currency format parameters --- + // Currency symbol + EdCurrencySymbol.Text := AValue.CurrencyString; + // Currency decimal places + EdCurrencyDecimals.Value := AValue.CurrencyDecimals; + // Positive currency format + CbPosCurrencyFormat.ItemIndex := AValue.CurrencyFormat; + // Negative currency format + CbNegCurrencyFormat.ItemIndex := AValue.NegCurrFormat; + + // --- Date format parameters --- + // Long date format string + i := CbLongDateFormat.Items.IndexOf(AValue.LongDateFormat); + if i = -1 then + CbLongDateFormat.ItemIndex := CbLongDateFormat.Items.Add(AValue.LongDateFormat) + else + CbLongDateFormat.ItemIndex := i; + // Short date format string + i := CbShortDateFormat.Items.IndexOf(AValue.ShortDateFormat); + if i = -1 then + CbShortDateFormat.ItemIndex := CbShortDateFormat.items.Add(AValue.ShortDateFormat) + else + CbShortDateFormat.ItemIndex := i; + // Date separator + FCbDateSeparator.Separator := AValue.DateSeparator; + // Long month names + FEdLongMonthNames.SetNames(AValue.LongMonthNames, 12, false, 'Error'); + // Short month names + FEdShortMonthNames.SetNames(AValue.ShortMonthNames, 12, true, 'Error'); + // Long day names + FEdLongDayNames.SetNames(AValue.LongDayNames, 7, false, 'Error'); + // Short month names + FEdShortDayNames.SetNames(AValue.ShortDayNames, 7, true, 'Error'); + + // --- Time format parameters --- + + // Long time format string + i := CbLongTimeFormat.items.IndexOf(AValue.LongTimeFormat); + if i = -1 then + CbLongTimeFormat.ItemIndex := CbLongTimeFormat.Items.Add(AValue.LongTimeFormat) + else + CbLongTimeFormat.ItemIndex := i; + // Short time format string + i := cbShortTimeFormat.Items.IndexOf(AValue.ShortTimeFormat); + if i = -1 then + CbShortTimeFormat.itemIndex := CbShortTimeFormat.Items.Add(AValue.ShortTimeFormat); + // Time separator + FCbTimeSeparator.Separator := AValue.TimeSeparator; +end; + +function TFormatSettingsForm.ValidData(out AControl: TWinControl; + out AMsg: String): Boolean; +begin + Result := false; + if FCbDecimalSeparator.Separator = FCbThousandSeparator.Separator then + begin + AControl := FCbDecimalSeparator; + AMsg := 'Decimal and thousand separators cannot be the same.'; + exit; + end; + Result := true; +end; + +//initialization +// {$I sformatsettingsform.lrs} + +end. + diff --git a/applications/spready/shyperlinkform.lfm b/applications/spready/shyperlinkform.lfm new file mode 100644 index 000000000..1656fe515 --- /dev/null +++ b/applications/spready/shyperlinkform.lfm @@ -0,0 +1,813 @@ +object HyperlinkForm: THyperlinkForm + Left = 327 + Height = 386 + Top = 259 + Width = 498 + Caption = 'Hyperlink' + ClientHeight = 386 + ClientWidth = 498 + OnCreate = FormCreate + ShowHint = True + LCLVersion = '1.5' + object ButtonPanel1: TButtonPanel + Left = 6 + Height = 34 + Top = 346 + Width = 486 + OKButton.Name = 'OKButton' + OKButton.DefaultCaption = True + OKButton.OnClick = OKButtonClick + HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True + CloseButton.Name = 'CloseButton' + CloseButton.DefaultCaption = True + CancelButton.Name = 'CancelButton' + CancelButton.DefaultCaption = True + TabOrder = 0 + ShowButtons = [pbOK, pbCancel] + end + object Panel2: TPanel + Left = 75 + Height = 340 + Top = 0 + Width = 423 + Align = alClient + BevelOuter = bvNone + ClientHeight = 340 + ClientWidth = 423 + TabOrder = 1 + object Notebook: TNotebook + Left = 4 + Height = 246 + Top = 4 + Width = 415 + PageIndex = 2 + Align = alClient + BorderSpacing.Around = 4 + TabOrder = 0 + TabStop = True + object PgInternal: TPage + object GroupBox2: TGroupBox + Left = 0 + Height = 80 + Top = 0 + Width = 415 + Align = alTop + Caption = 'Target within current workbook' + ClientHeight = 60 + ClientWidth = 411 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + object CbWorksheets: TComboBox + Left = 8 + Height = 23 + Top = 24 + Width = 210 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + OnChange = UpdateHyperlinkInfo + ParentFont = False + Style = csDropDownList + TabOrder = 0 + end + object Label5: TLabel + Left = 8 + Height = 15 + Top = 6 + Width = 59 + Caption = 'Worksheet:' + ParentColor = False + ParentFont = False + end + object Label6: TLabel + Left = 226 + Height = 15 + Top = 8 + Width = 66 + Anchors = [akTop, akRight] + Caption = 'Cell address:' + ParentColor = False + ParentFont = False + end + object CbCellAddress: TComboBox + Left = 226 + Height = 23 + Top = 24 + Width = 176 + Anchors = [akTop, akRight] + ItemHeight = 15 + OnChange = UpdateHyperlinkInfo + OnEditingDone = CbCellAddressEditingDone + ParentFont = False + TabOrder = 1 + end + end + end + object PgFile: TPage + object GbFileName: TGroupBox + Left = 0 + Height = 64 + Top = 0 + Width = 407 + Align = alTop + BorderSpacing.Right = 8 + BorderSpacing.Bottom = 8 + Caption = 'File / Document' + ClientHeight = 44 + ClientWidth = 403 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + object CbFileName: TComboBox + Left = 8 + Height = 23 + Top = 8 + Width = 307 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + OnChange = UpdateHyperlinkInfo + OnEditingDone = CbFileNameEditingDone + ParentFont = False + TabOrder = 0 + end + object BtnBrowseFile: TButton + Left = 320 + Height = 23 + Top = 8 + Width = 75 + Anchors = [akTop, akRight] + Caption = 'Browse...' + OnClick = BtnBrowseFileClick + ParentFont = False + TabOrder = 1 + end + end + object GbFileBookmark: TGroupBox + Left = 0 + Height = 64 + Top = 72 + Width = 407 + Align = alTop + BorderSpacing.Right = 8 + BorderSpacing.Bottom = 8 + Caption = 'Bookmark within document' + ClientHeight = 44 + ClientWidth = 403 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 1 + object CbFileBookmark: TComboBox + Left = 8 + Height = 23 + Top = 8 + Width = 387 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + OnChange = UpdateHyperlinkInfo + OnDropDown = CbFileBookmarkDropDown + ParentFont = False + TabOrder = 0 + end + end + end + object PgInternet: TPage + object GbInternetLinkType: TGroupBox + Left = 0 + Height = 64 + Top = 0 + Width = 407 + Align = alTop + BorderSpacing.Right = 8 + Caption = 'Type of link' + ClientHeight = 44 + ClientWidth = 403 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + object RbHTTP: TRadioButton + Left = 11 + Height = 19 + Top = 7 + Width = 42 + Caption = 'http' + Checked = True + OnChange = HTTP_FTP_Change + ParentFont = False + TabOrder = 1 + TabStop = True + end + object RbFTP: TRadioButton + Left = 77 + Height = 19 + Top = 7 + Width = 35 + Caption = 'ftp' + OnChange = HTTP_FTP_Change + ParentFont = False + TabOrder = 0 + end + end + object InternetNotebook: TNotebook + Left = 0 + Height = 182 + Top = 64 + Width = 415 + PageIndex = 1 + Align = alClient + TabOrder = 1 + TabStop = True + object PgHTTP: TPage + object GbHttp: TGroupBox + Left = 0 + Height = 144 + Top = 8 + Width = 407 + Align = alTop + BorderSpacing.Top = 8 + BorderSpacing.Right = 8 + Caption = 'Bookmark within document' + ClientHeight = 124 + ClientWidth = 403 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + object CbHttpAddress: TComboBox + Left = 8 + Height = 23 + Top = 32 + Width = 384 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + OnEditingDone = CbHttpAddressEditingDone + ParentFont = False + TabOrder = 0 + end + object EdHttpBookmark: TEdit + Left = 8 + Height = 23 + Top = 86 + Width = 384 + ParentFont = False + TabOrder = 1 + end + object LblHttpAddress: TLabel + Left = 8 + Height = 15 + Top = 8 + Width = 121 + Caption = 'URL of web document;' + FocusControl = CbHttpAddress + ParentColor = False + ParentFont = False + end + object LblHttpBookmark: TLabel + Left = 8 + Height = 15 + Top = 64 + Width = 151 + Caption = 'Bookmark within document:' + FocusControl = EdHttpBookmark + ParentColor = False + ParentFont = False + end + end + end + object PfFTP: TPage + object GbFtp: TGroupBox + Left = 0 + Height = 144 + Top = 8 + Width = 407 + Align = alTop + BorderSpacing.Top = 8 + BorderSpacing.Right = 8 + Caption = 'ftp server' + ClientHeight = 124 + ClientWidth = 403 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + object CbFtpServer: TComboBox + Left = 8 + Height = 23 + Top = 32 + Width = 384 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + OnEditingDone = CbFtpServerEditingDone + ParentFont = False + TabOrder = 0 + end + object Label1: TLabel + Left = 8 + Height = 15 + Top = 10 + Width = 35 + Caption = 'Server:' + ParentColor = False + ParentFont = False + end + object LblFtpUserName: TLabel + Left = 8 + Height = 15 + Top = 64 + Width = 59 + Caption = 'User name:' + FocusControl = CbFtpUsername + ParentColor = False + ParentFont = False + end + object CbFtpUsername: TComboBox + Left = 8 + Height = 23 + Top = 86 + Width = 190 + ItemHeight = 15 + ParentFont = False + TabOrder = 1 + end + object LblFtpPassword: TLabel + Left = 208 + Height = 15 + Top = 64 + Width = 53 + Caption = 'Password:' + FocusControl = CbFtpPassword + ParentColor = False + ParentFont = False + end + object CbFtpPassword: TComboBox + Left = 208 + Height = 23 + Top = 86 + Width = 182 + ItemHeight = 15 + ParentFont = False + TabOrder = 2 + end + end + end + end + end + object PgMail: TPage + object GbMailRecipient: TGroupBox + Left = 0 + Height = 60 + Top = 0 + Width = 415 + Align = alTop + BorderSpacing.Bottom = 8 + Caption = 'Mail address of recipient' + ClientHeight = 40 + ClientWidth = 411 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + object CbMailRecipient: TComboBox + Left = 8 + Height = 23 + Top = 6 + Width = 397 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + OnEditingDone = CbMailRecipientEditingDone + ParentFont = False + TabOrder = 0 + end + end + object GroupBox8: TGroupBox + Left = 0 + Height = 60 + Top = 68 + Width = 415 + Align = alTop + BorderSpacing.Bottom = 8 + Caption = 'Subject' + ClientHeight = 40 + ClientWidth = 411 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 1 + object EdMailSubject: TEdit + Left = 8 + Height = 23 + Top = 6 + Width = 397 + Anchors = [akTop, akLeft, akRight] + OnChange = UpdateHyperlinkInfo + ParentFont = False + TabOrder = 0 + end + end + end + end + object HyperlinkInfo: TLabel + Left = 8 + Height = 15 + Top = 321 + Width = 407 + Align = alBottom + BorderSpacing.Left = 8 + BorderSpacing.Top = 8 + BorderSpacing.Right = 8 + BorderSpacing.Bottom = 4 + Caption = 'HyperlinkInfo' + ParentColor = False + WordWrap = True + end + object Bevel1: TBevel + Left = 4 + Height = 3 + Top = 310 + Width = 415 + Align = alBottom + BorderSpacing.Left = 4 + BorderSpacing.Right = 4 + Shape = bsBottomLine + end + object GroupBox6: TGroupBox + Left = 0 + Height = 56 + Top = 254 + Width = 415 + Align = alBottom + BorderSpacing.Right = 8 + Caption = 'Cell tooltip' + ClientHeight = 36 + ClientWidth = 411 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 1 + object EdTooltip: TEdit + Left = 8 + Height = 23 + Top = 3 + Width = 392 + Anchors = [akTop, akLeft, akRight] + ParentFont = False + TabOrder = 0 + Text = 'EdTooltip' + end + end + end + object ToolBar: TToolBar + Left = 4 + Height = 336 + Top = 4 + Width = 67 + Align = alLeft + AutoSize = True + BorderSpacing.Around = 4 + ButtonHeight = 56 + ButtonWidth = 64 + Caption = 'ToolBar' + Color = clWindow + EdgeBorders = [ebLeft, ebTop, ebRight, ebBottom] + EdgeInner = esNone + Images = Images + ParentColor = False + ParentFont = False + ShowCaptions = True + TabOrder = 2 + Wrapable = False + object TbInternal: TToolButton + Left = 2 + Top = 1 + AllowAllUp = True + Caption = 'internal' + Down = True + ImageIndex = 0 + OnClick = ToolButtonClick + end + object TbFile: TToolButton + Tag = 1 + Left = 2 + Top = 57 + AllowAllUp = True + Caption = 'File' + ImageIndex = 1 + OnClick = ToolButtonClick + end + object TbInternet: TToolButton + Tag = 2 + Left = 2 + Top = 113 + AllowAllUp = True + Caption = 'Internet' + ImageIndex = 2 + OnClick = ToolButtonClick + end + object TbMail: TToolButton + Tag = 3 + Left = 2 + Top = 169 + AllowAllUp = True + Caption = 'Mail' + ImageIndex = 3 + OnClick = ToolButtonClick + end + end + object Images: TImageList + Height = 24 + Width = 24 + left = 48 + top = 296 + Bitmap = { + 4C69040000001800000018000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF007E7E54007F7F554D7F7F55667F7F55667F7F + 55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F + 55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F + 55667F7F55667F7F554DFFFFFF007E7E54007E7E5467FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF7D7D5467FFFFFF007C7C52007C7C5268FFFFFFFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFEFEFFFEFE + FEFFFFFFFFFF7B7B5268FFFFFF007A7A51007A7A5168FEFEFDFFFDFDFCFFFFCC + 44FFFECB43FFFECB43FFFDCA42FFFCC941FFFAC73FFFF9C63EFFF8C53DFFF6C3 + 3CFFF5C23AFFF4C139FFF3C038FFF1BE36FFF0BD35FFEFBC34FFEFBC34FFFDFD + FCFFFEFEFDFF79795069FFFFFF0078784F0078784F69FEFEFCFFFCFCFAFFFFCC + 44FFFFEE88FFFEED87FFFDCA42FFFCEB85FFFBEA84FFF9C63EFFF8E781FFF6E5 + 80FFF5C23AFFF4E37DFFF2E17BFFF1BE36FFF0DF79FFEFDE78FFEFBC34FFFCFC + FAFFFEFEFCFF76764E6AFFFFFF0076764D0076764D6AFDFDFAFFFBFBF8FFFFCC + 44FFFFEE88FFFEED87FFFDCA42FFFCEB85FFFBEA84FFF9C63EFFF8E781FFF6E5 + 80FFF5C23AFFF4E37DFFF2E17BFFF1BE36FFF0DF79FFEFDE78FFEFBC34FFFBFB + F8FFFDFDFAFF74744B6BFFFFFF0073734B0073734B6BFDFDF9FFFAFAF6FFFFCC + 44FFFECB43FFFECB43FFF5CE64FFEBD285FFE9D083FFE8CF82FFE7CE81FFE5CC + 80FFE4CB7EFFE3CA7DFFE2C97CFFE0C77AFFDFC679FFDEC578FFDEC578FFFAFA + F6FFFDFDF9FF7171496CFFFFFF00717149007171496CFCFCF8FFF8F8F4FFFFCC + 44FFFFEE88FFFEED87FFECD286FFFCFCFAFFFCFCFAFFD7D7C6FFFCFCFAFFFCFC + FAFFD3D3C2FFFCFCFAFFFCFCFAFFCFCFBEFFFCFCFAFFFCFCFAFFCDCDBCFFF8F8 + F4FFFCFCF8FF6E6E466DFFFFFF006E6E46006E6E466DFBFBF6FFF7F7F1FFFFCC + 44FFFFEE88FFFEED87FFECD286FFFBFBF8FFFBFBF8FFD7D7C6FFFBFBF8FFFBFB + F8FFD3D3C2FFFBFBF8FFFBFBF8FFCFCFBEFFFBFBF8FFFBFBF8FFCDCDBCFFF7F7 + F1FFFBFBF6FF6A6A436EFFFFFF006B6B44006B6B446EFAFAF4FFF5F5EFFFFFCC + 44FFFECB43FFFECB43FFECD286FFDADAC9FFD8D8C7FFDFDFD0FFD6D6C5FFD4D4 + C3FFDCDCCEFFD2D2C1FFD1D1C0FFD9D9CBFFCECEBDFFCDCDBCFFCDCDBCFFF5F5 + EFFFFAFAF4FF67674070FFFFFF00686841006868416FFAFAF2FFF4F4ECFFFFCC + 44FFFFEE88FFFEED87FFECD286FFFAFAF6FFFAFAF6FFD7D7C6FFFAFAF6FFFAFA + F6FFD3D3C2FFFAFAF6FFFAFAF6FFCFCFBEFFFAFAF6FFFAFAF6FFCDCDBCFFF4F4 + ECFFFAFAF2FF63633D71FFFFFF0065653F0065653F70F9F9F0FFF2F2E9FFFFCC + 44FFFFEE88FFFEED87FFECD286FFF9F9F4FFF9F9F4FFD7D7C6FFF9F9F4FFF9F9 + F4FFD3D3C2FFF9F9F4FFF9F9F4FFCFCFBEFFF9F9F4FFF9F9F4FFCDCDBCFFF2F2 + E9FFF9F9F0FF60603A73FFFFFF0062623C0062623C72F8F8EEFFF0F0E6FFFFCC + 44FFFECB43FFFECB43FFECD286FFDADAC9FFD8D8C7FFDDDDCEFFD6D6C5FFD4D4 + C3FFDBDBCCFFD2D2C1FFD1D1C0FFD8D8C9FFCECEBDFFCDCDBCFFCDCDBCFFF0F0 + E6FFF8F8EEFF5C5C3674FFFFFF005F5F39005F5F3973F7F7ECFFEFEFE4FFFFCC + 44FFFFEE88FFFEED87FFECD286FFF7F7F2FFF7F7F2FFD7D7C6FFF7F7F2FFF7F7 + F2FFD3D3C2FFF7F7F2FFF7F7F2FFCFCFBEFFF7F7F2FFF7F7F2FFCDCDBCFFEFEF + E4FFF7F7ECFF58583375FFFFFF005C5C36005C5C3674F6F6EBFFEDEDE1FFFFCC + 44FFFFEE88FFFEED87FFECD286FFF6F6F1FFF6F6F1FFD7D7C6FFF6F6F1FFF6F6 + F1FFD3D3C2FFF6F6F1FFF6F6F1FFCFCFBEFFF6F6F1FFF6F6F1FFCDCDBCFFEDED + E1FFF6F6EBFF55553077FFFFFF005959340059593475F6F6E9FFECECDFFFFFCC + 44FFFECB43FFFECB43FFECD286FFDADAC9FFD8D8C7FFD7D7C6FFD6D6C5FFD4D4 + C3FFD3D3C2FFD2D2C1FFD1D1C0FFCFCFBEFFCECEBDFFCDCDBCFFCDCDBCFFECEC + DFFFF6F6E9FF50502B79FFFFFF005656310056563177F5F5E7FFEAEADDFFEAEA + DDFFEAEADDFFEAEADDFFEAEADDFFEAEADDFFEAEADDFFEAEADDFFEAEADDFFEAEA + DDFFEAEADDFFEAEADDFFEAEADDFFEAEADDFFEAEADDFFEAEADDFFEAEADDFFEAEA + DDFFF5F5E7FF42421F7FFFFFFF0052522E0052522E78F4F4E6FFE9E9DBFFE9E9 + DBFFE9E9DBFFE9E9DBFFEFEFE0FFF4F4E6FFF4F4E6FFF4F4E6FFF4F4E6FFF4F4 + E6FFF4F4E6FFF4F4E6FFF4F4E6FFF4F4E6FFF4F4E6FFF4F4E6FFF4F4E6FFF4F4 + E6FFFAFAEBFF34341384FFFFFF00494925004949257CF4F4E5FFE8E8D9FFE8E8 + D9FFE8E8D9FFE8E8D9FFF4F4E5FFAAAA99FFAAAA99FFAAAA99FFAAAA99FFAAAA + 99FFAAAA99FFAAAA99FF29290988292909882929098829290988292909882929 + 0988292909882A2A0A66FFFFFF003C3C1A003C3C1A80F5F5E5FFE7E7D7FFE7E7 + D7FFE7E7D7FFE7E7D7FFF5F5E5FF67674FC5F5F5E5FFE7E7D7FFE7E7D7FFE7E7 + D7FFE7E7D7FFF5F5E5FF2323048A262607002727070027270700272707002727 + 07002727070029290900FFFFFF000D0D050031311174D4D4C0DCF4F4E3FFF3F3 + E2FFF3F3E2FFF4F4E3FFD4D4C0DC2323048AD0D0BDDEF4F4E3FFF3F3E2FFF3F3 + E2FFF4F4E3FFD0D0BDDE23230479090901000000000000000000000000000000 + 00000000000000000000FFFFFF0000000011171705402727097B282809882828 + 098828280988282809882727097B1A1A035F2222047C2323048A2323048A2323 + 048A2323048A2222047C1212024C0000002F000000280000001F000000160000 + 000D0000000600000001FFFFFF000000000000000012000000190000001A0000 + 001A0000001A0000001A0000001A0000001A0000001A0000001A0000001A0000 + 001A0000001A0000001A0000001A0000001800000014000000100000000B0000 + 00070000000300000001FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000088CB000088CB000088 + CC410088CC810088CC810088CC810088CC810088CC810088CC810088CC810088 + CC810088CC810088CC810088CC810088CC810088CC810088CC810088CC610088 + CB000088CB00FFFFFF00FFFFFF00FFFFFF00FFFFFF000087CB000087CB000087 + CB826FCCECE092E1F7FFADF1FFFFAEF2FFFFAEF2FFFFAEF2FFFFAEF2FFFFAEF2 + FFFFAEF2FFFFAEF2FFFFAEF2FFFFAEF2FFFFAEF2FFFFB1F5FFFF0087CB820087 + CB000087CB00FFFFFF00FFFFFF00FFFFFF00FFFFFF000086C9000086C9000086 + C983B0F5FFFF91E1F6FF5DC0E7FF72CCEEFF8CDCF6FFA6ECFEFFA8EDFEFFA8ED + FEFFA8EDFEFFA8EDFEFFA8EDFEFFA8EDFEFFA8EDFEFFADF2FFFF0086C9830086 + C9000086C900FFFFFF00FFFFFF00FFFFFF00FFFFFF000085C8000085C8000085 + C885ADF1FFFFABEFFEFFACF1FEFF8FDFF5FF69C7EAFF59BCE6FF76C9E6FFA6EB + FDFFA6EBFDFFA6EBFDFFA6EBFDFFA6EBFDFFA6EBFDFFABF0FEFF0085C8850085 + C8000085C800FFFFFF00FFFFFF00FFFFFF00FFFFFF000084C6000084C6000084 + C687ABEFFEFFA6EAFDFFA6EAFDFFA9EEFDFFADF1FEFFA1EAFAFF4FAFD8FF9BDC + EEFFA2E6F9FFA4E9FCFFA4E9FCFFA4E9FCFFA4E9FCFFA9EEFDFF0084C6870084 + C6000084C600FFFFFF00FFFFFF00FFFFFF00FFFFFF000083C4000083C4000083 + C489A8EEFDFFA3E9FCFFA3E9FCFFA3E9FCFFA3E9FCFFADF2FEFF49AEDAFF91CF + E1FF91CFE1FF97D8EBFF9FE4F7FFA1E6FAFFA1E6FAFFA6EBFCFF0083C4890083 + C4000083C400FFFFFF00FFFFFF00FFFFFF00FFFFFF000081C2000081C2000081 + C28BA6ECFCFFA1E7FBFFA1E7FBFFA1E7FBFFA1E7FBFFABF0FDFF41A5D2FF8ECD + E0FF8ECDE0FF8ECDE0FF96D9EDFF9EE4F9FF9EE4F9FFA4E9FBFF0081C28B0081 + C2000081C200FFFFFF00FFFFFF00FFFFFF00FFFFFF000080C0000080C0000080 + C08DA4E9FBFF9EE4F9FF9EE4F9FF9EE4F9FF9EE4F9FFA9EEFCFF3A9BC7FF8ACA + DEFF8ACADEFF8ACADEFF92D6EBFF9AE1F7FF9AE1F7FFA0E6F9FF0080C08D0080 + C0000080C000FFFFFF00FFFFFF00FFFFFF00FFFFFF00007EBD00007EBD00007E + BD8FA1E7FAFF9BE2F8FF9BE2F8FF9BE2F8FF9BE2F8FFA7ECFCFF3696C2FF88C7 + DDFF88C7DDFF88C7DDFF90D3EAFF97DEF6FF97DEF6FF9DE4F9FF007EBD8F007E + BD00007DBB00FFFFFF00FFFFFF00FFFFFF00FFFFFF00007DBB00007DBB00007D + BB919EE5F9FF98DFF6FF98DFF6FF98DFF6FF98DFF6FFA4EAFBFF3393BFFF84C5 + DBFF84C5DBFF84C5DBFF8CD0E8FF93DBF4FF93DBF4FF9AE1F7FF007DBB91007D + BB33007BB800FFFFFF00FFFFFF00FFFFFF00FFFFFF00007BB800007BB800007B + B8949CE3F8FF95DDF5FF95DDF5FF95DDF5FF95DDF5FFA2E8FAFF318FBCFF81C2 + D9FF81C2D9FF81C2D9FF89CDE6FF90D8F2FF90D8F2FF90D8F2FF90D8F2FF007B + B894007BB834FFFFFF00FFFFFF00FFFFFF00FFFFFF000079B6000079B6000079 + B69699E0F6FF92DAF3FF92DAF3FF92DAF3FF92DAF3FF9FE5F9FF2E8CB8FF7EBF + D8FF7EBFD8FF7EBFD8FF85CAE4FF8CD5F0FF8CD5F0FF8CD5F0FFFEFEFDFF8CD5 + F0FF0079B696FFFFFF00FFFFFF00FFFFFF00FFFFFF000077B3000077B3000077 + B39996DEF6FF8FD8F2FF8FD8F2FF8FD8F2FF8FD8F2FF9CE3F9FF2B88B5FF7BBD + D6FF7BBDD6FF7BBDD6FF82C8E2FF89D2EEFF89D2EEFF89D2EEFFF8F8F3FF89D2 + EEFF0077B399FFFFFF00FFFFFF00FFFFFF00FFFFFF000076B0000076B0000076 + B09B93DBF4FF8CD5F0FF8CD5F0FF8CD5F0FF8CD5F0FF9AE0F8FF2986B2FF78BA + D5FF78BAD5FF78BAD5FF7FC5E1FF85CFEDFF85CFEDFF85CFEDFFF0F0E6FF85CF + EDFF0076B09BFFFFFF00FFFFFF00FFFFFF00FFFFFF000074AE000074AE000074 + AE9E90D8F3FF89D2EEFF89D2EEFF89D2EEFF89D2EEFF97DEF7FF2682AFFF75B8 + D3FF75B8D3FF75B8D3FF7CC3DFFF82CDEBFF82CDEBFF82CDEBFFE9E9DBFF82CD + EBFF0074AE9EFFFFFF00FFFFFF00FFFFFF00FFFFFF000072AB000072AB000072 + ABA08ED6F2FF86D0EDFF86D0EDFF86D0EDFF86D0EDFF95DCF6FF257FACFF72B5 + D2FF72B5D2FF72B5D2FF79C0DEFF7FCAEAFF7FCAEAFF7FCAEAFFFEC941FF7FCA + EAFF0072ABA0FFFFFF00FFFFFF00FFFFFF00FFFFFF00006EA600006EA600006E + A6A58BD4F0FF83CEEBFF83CEEBFF83CEEBFF83CEEBFF93DAF5FF237DA9FF70B4 + D0FF70B4D0FF70B4D0FF77BEDCFF7DC8E8FF7DC8E8FF7DC8E8FFF4B62EFF7DC8 + E8FF006EA6A5FFFFFF00FFFFFF00FFFFFF00FFFFFF00001B280000679B000067 + 9BAF89D2F0FF81CBEAFF81CBEAFF81CBEAFF81CBEAFF91D8F5FF217AA6FF6EB2 + CFFF6EB2CFFF6EB2CFFF75BCDBFF7BC6E7FF7BC6E7FF7BC6E7FF7BC6E7FF0067 + 9BAF00689D3DFFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000001925000061 + 91B887D0EFFF7EC9E9FF7EC9E9FF7EC9E9FF7EC9E9FF8ED6F4FF227AA5FF74B6 + D4FF74B6D4FF74B6D4FF7BC1E1FF81CBECFF81CBECFF81CBECFF006191B80049 + 6E41001A2600FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000011000000260045 + 689C3590BCF269B8DCFA82CCECFF7CC7E8FF7CC7E8FF8CD4F4FF005C8BEF004F + 77C6004F77C6004F77C6005885C2005B8AC0005B8AC0005B8AC00045689C0000 + 002300000010FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000009000000130000 + 001A005C8A5B0062939F368FBAD16BBADEED80CAEBFF8BD3F3FF005884C70000 + 0031000000310000001F0000001A0000001A0000001A0000001A0000001A0000 + 001200000008FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000 + 0000005D8C0000649700006191530060909E1B76A3C551A2CAE2005A88C20000 + 001A000000070000000000000000000000000000000000000000000000000000 + 000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000 + 0000005D8C000064970000609000005E8E00005C8A31005B897E005986930000 + 0007000000000000000000000000000000000000000000000000000000000000 + 000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CF7A0200CF7A0200CF7A0200D47E + 0200DC830300E2880300E58A0313E68B034EE78B0388E78B03A6E78B03B8E78B + 03B8E78B03A6E78B0388E68B034EE58A0313E2880300DC830300D47E0200CF7A + 0200CF7A0200CF7A0200FFFFFF00FFFFFF00CF7A0200CF7A0200CF7A0200D47E + 0200DC83030DE0870363E38F13B5EDB459D5F7DCA4EBFBECC5F7FCF3D3FDFCF4 + D4FDFCEEC7F7F7DCA4EBEDB459D5E38F13B5E0870363DC83030DD47E0200CF7A + 0200CF7A0200CF7A0200FFFFFF00FFFFFF00CF7A0200CF7A0200CF7A0200D47E + 021CD780039DE1A146D7EBC68CF7E9C48EFFEAC792FFF0D19EFFF2D4A2FFEFD5 + A8FFFFFAD7FFFFFAD4FFFFFAD4FFFBEDC2F7E8B25BD7D780039DD47E021CCF7A + 0200CF7A0200CF7A0200FFFFFF00FFFFFF00C3710200C5730200CB77021CCF7E + 0CAEE7BD78E5EDCC90FFEBC788FFF7E7BBFFF9EDC5FFF1D29FFFF8DBA5FFF2D7 + A8FFFCF4D2FFFFFAD6FFFFF9D1FFFFF8CBFFFFF9CDFFEDC986E5CF7E0CAECB77 + 021CC5730200C3710200FFFFFF00FFFFFF00B6680200BA6B020DC070039FE8C3 + 82E5E1B570FFE0AD5FFFF1D9A2FFFFF7CCFFFFF7D0FFF5E0B2FFF1D199FFEED1 + A0FFEDD4AAFFFFF7D0FFFFF7CCFFFFF6C6FFFFF5BFFFFFF5C1FFE8C382E5C070 + 039FBA6B020DB6680200FFFFFF00FFFFFF00B0640200B3660266D19C50D9E2BA + 7AFFE6BE76FFE1B771FFFAE6AFFFFFF0BFFFF7E2B2FFE9C487FFE6BE81FFFDEE + C4FFFAEABEFFFAE7B9FFFFEFBDFFFFEFB9FFFFEDB4FFFFECAFFFFFEEB7FFD29E + 52D9B3660266B0640200FFFFFF00FFFFFF00A75D0114AE670EBCD7A866F8D498 + 3AFFE8BD6EFFD49F52FFFCE0A2FFF1D194FFDAA85EFFE5B86AFFDEB16DFFFFEA + B5FFFFE9B4FFE0B87BFFD4A25CFFF9DD9FFFFFE5A4FFFFE4A1FFFADB98FFD09E + 5DF8AB630ABCA75D0114FFFFFF00FFFFFF009B530153BB833DDBCB903DFFD599 + 38FFD79C3AFFD49A3EFFE3B364FFD59F4AFFDDA84FFFDEAB53FFD7A457FFFDDC + 9BFFE9BF7CFFE1B266FFCD9441FFEDC27AFFFFDA92FFF0C67DFFFFD98FFFE1B0 + 66FFB4782EDB9B530153FFFFFF00FFFFFF00914D0190C79355EFE9B160FFDA9F + 47FFD39633FFD59934FFD49836FFD59B39FFD89D3CFFD89E3EFFD1973CFFD79F + 4BFFC98D38FFC58731FFCF9344FFFFCF82FFFFCF80FFD29547FFCE913FFFE2AA + 56FFC48E46EF914D0190FFFFFF00FFFFFF00894700B2F2C07AF8F7BB67FFD797 + 41FFCC8C2AFFD0922DFFD1922DFFD1932EFFD19430FFD19430FFD19430FFCB8C + 2EFFDFA24EFFFFC571FFFFC470FFFCC16DFFDC9E4DFFFFC46FFFC48325FFCB8B + 29FFCD9848F8894700B2FFFFFF00FFFFFF00834200C6D89C54FEC6802CFFE19B + 44FFCE8A2DFFCD8A26FFCE8C26FFCE8C27FFCE8C27FFCE8C27FFCE8C27FFCB88 + 2AFFEDA951FFF2AD57FFFFBB62FFEEA852FFBC7720FFC17E20FFC58222FFCA88 + 24FFD39943FE834200C6FFFFFF00FFFFFF00804000C7C6873DFEC37C21FFE89D + 41FFCB8327FFCB8722FFCC8822FFCC8822FFCC8822FFCC8822FFCC8822FFC985 + 22FFC98224FFBD751EFFE2973FFFFFB354FFC88026FFC57F22FFE79C40FFC67E + 26FFC98C39FE804000C7FFFFFF00FFFFFF00814000B3E59F4FF8C47D1EFFC882 + 20FFCB8521FFCE8822FFCE8823FFCE8823FFCE8823FFCE8924FFCE8924FFCE89 + 24FFCC8623FFC17A1FFFF4A344FFFFAD4BFFC47A22FFCB7F27FFFFAD4AFFFBAA + 48FFD99546F8814000B3FFFFFF00FFFFFF0083420092BF7B32F0CB8220FFD088 + 22FFD08823FFD08823FFD18924FFD18A25FFD18A26FFD18A26FFD18B26FFD18B + 26FFCF8725FFD6892DFFFFAB47FFEE9C3DFFBB701BFFF39F3EFFFFAA45FFFFAA + 45FFDC9544F083420092FFFFFF00FFFFFF0088450054A36018DED48A28FFD488 + 23FFD48924FFD58A25FFD58B27FFD68C29FFD68E2CFFD78E2EFFD78F2FFFD78F + 2FFFD68D2DFFD2882AFFC77C23FFCC7F25FFDA8A2FFFFFAC46FFFFAB46FFFFAE + 4AFFB57024DE88450054FFFFFF00FFFFFF008F4A0014944E04C1D3882DF9DA89 + 24FFDA8A26FFDB8C29FFDC8E2DFFDC9132FFDD9337FFDE953AFFDE963CFFDE96 + 3CFFDE953AFFDD9337FFDC9032FFD28329FFF0A242FFFFB14AFFFFB049FFF3AA + 4CF9975107C18F4A0014FFFFFF00FFFFFF00954E0000974F006AB56A16DFE18D + 2BFFE18C28FFE28F2EFFE39336FFE4973FFFE59C46FFE69F4CFFE6A04FFFE6A0 + 4FFFE69F4CFFE59C46FFE4973FFFD98932FFF0A84BFFFFB954FFFFBA56FFC07A + 26DF974F006A954E0000FFFFFF00FFFFFF00995000009B52000E9F5500A7CC7A + 20EAE78F2FFFE89235FFEA9840FFEB9F4DFFECA558FFEDA960FFEDAC64FFEDAC + 64FFEDA960FFECA558FFEB9F4DFFE0903DFFF1B057FFFFC362FFDA983EEA9F55 + 00A79B52000E99500000FFFFFF00FFFFFF00A2560000A3570000A75A001DAB5D + 03B7D27E22EAEE973DFFEF9D49FFF0A558FFF1AD66FFF2B16EFFF2B473FFF2B4 + 73FFF2B16EFFF1AD66FFF0A558FFE69446FFF3BA66FFDEA145EAAC6005B7A75A + 001DA3570000A2560000FFFFFF00FFFFFF00552E0000552E0000552E0000AE5E + 001DB06000A7CB771ADFEC9A46F8F5A95EFFF5AF6AFFF6B474FFF6B779FFF6B7 + 79FFF6B474FFF5AF6AFFF5A95EFFE59244F8CA822ADFB06000A7AE5E001D552E + 0000552E0000552E0000FFFFFF00FFFFFF000000000000000000000000010000 + 00022E1900119A55006EBB6906C2CF7E23DEE6994BF0F0A963F8F7B271FEF7B2 + 71FEF0A963F8E6994BF0CF7E23DEBA6806C29C56006D2E190011000000020000 + 00010000000000000000FFFFFF00FFFFFF000000000000000000000000030000 + 000C0000001A00000024371F00376E3D006DAB5F009CB96600B5BC6800C7BC68 + 00C7B96600B5AB5F009C6E3D006D371F003700000024000000190000000C0000 + 00020000000000000000FFFFFF00FFFFFF000000000000000000000000020000 + 000800000011000000180000001A0000001A0000001A0000001A0000001A0000 + 001A0000001A0000001A0000001A0000001A0000001800000011000000080000 + 00010000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF007E7E54007F7F554D7F7F55667F7F55667F7F + 55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F + 55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F + 55667F7F55667F7F554D7E7E54007D7D53007D7D5367E0E0CFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFE0E0CFFF7D7D53677D7D53007A7A51007A7A5168F5F5F0FFDBDBCAFFFEFE + FDFFFEFEFDFFFEFEFDFFFEFEFDFFFEFEFDFFFEFEFDFFFEFEFDFFFEFEFDFFFEFE + FDFFFEFEFDFFFEFEFDFFFEFEFDFFFEFEFDFFFEFEFDFFFEFEFDFFFEFEFDFFDBDB + CAFFF5F5F0FF7A7A51687A7A510077774E0077774E69FDFDFAFFEEEEE5FFD5D5 + C4FFFCFCFAFFFCFCFAFFFCFCFAFFFCFCFAFFFCFCFAFFFCFCFAFFFCFCFAFFFCFC + FAFFFCFCFAFFFCFCFAFFFCFCFAFFFCFCFAFFFCFCFAFFFCFCFAFFD5D5C4FFEEEE + E5FFFDFDFAFF77774E6977774E0074744C0074744C6BFDFDFAFFF8F8F3FFE6E6 + DAFFCFCFBEFFFBFBF7FFFBFBF7FFFBFBF7FFFBFBF7FFFBFBF7FFFBFBF7FFFBFB + F7FFFBFBF7FFFBFBF7FFFBFBF7FFFBFBF7FFFBFBF7FFCFCFBEFFE6E6DAFFF8F8 + F3FFFDFDFAFF74744C6B74744C00717148007171486CFCFCF8FFF9F9F4FFF4F4 + EEFFDEDED0FFC9C9B8FFF9F9F4FFF9F9F4FFF9F9F4FFF9F9F4FFF9F9F4FFF9F9 + F4FFF9F9F4FFF9F9F4FFF9F9F4FFF9F9F4FFC9C9B8FFDEDED0FFF4F4EEFFF9F9 + F4FFFCFCF8FF7171486C717148006D6D45006D6D456DFBFBF5FFF6F6F0FFF6F6 + F0FFF1F1E8FFD9D9C9FFC4C4B3FFF6F6F0FFF6F6F0FFF6F6F0FFF6F6F0FFF6F6 + F0FFF6F6F0FFF6F6F0FFF6F6F0FFC4C4B3FFD9D9C9FFF1F1E8FFF6F6F0FFF6F6 + F0FFFBFBF5FF6D6D456D6D6D4500696942006969426FFAFAF2FFF4F4ECFFF4F4 + ECFFF4F4ECFFEEEEE4FFD6D6C5FFBEBEADFFF4F4ECFFF4F4ECFFF4F4ECFFF4F4 + ECFFF4F4ECFFF4F4ECFFBEBEADFFD6D6C5FFEEEEE4FFF4F4ECFFF4F4ECFFF4F4 + ECFFFAFAF2FF6969426F6969420065653E0065653E71F9F9F0FFF2F2E9FFF2F2 + E9FFF2F2E9FFF2F2E9FFE8E8DBFFD5D5C4FFB9B9A8FFF2F2E9FFF2F2E9FFF2F2 + E9FFF2F2E9FFB9B9A8FFD5D5C4FFE8E8DBFFF2F2E9FFF2F2E9FFF2F2E9FFF2F2 + E9FFF9F9F0FF65653E7165653E0061613A0061613A72F8F8EDFFF0F0E5FFF0F0 + E5FFF0F0E5FFEBEBDFFFDBDBCAFFECECE0FFD7D7C8FFB3B3A2FFF0F0E5FFF0F0 + E5FFB3B3A2FFD7D7C8FFECECE0FFDBDBCAFFEBEBDFFFF0F0E5FFF0F0E5FFF0F0 + E5FFF8F8EDFF61613A7261613A005C5C37005C5C3774F6F6EBFFEDEDE1FFEDED + E1FFE8E8DBFFD8D8C7FFEDEDE1FFEDEDE1FFEBEBDEFFD8D8C9FFAEAE9DFFAEAE + 9DFFD8D8C9FFEBEBDEFFEDEDE1FFEDEDE1FFD8D8C7FFE8E8DBFFEDEDE1FFEDED + E1FFF6F6EBFF5C5C37745C5C37005858330058583376F5F5E8FFEBEBDEFFE5E5 + D7FFD5D5C4FFEBEBDEFFEBEBDEFFEBEBDEFFEBEBDEFFEAEADDFFD9D9CAFFD9D9 + CAFFEAEADDFFEBEBDEFFEBEBDEFFEBEBDEFFEBEBDEFFD5D5C4FFE5E5D7FFEBEB + DEFFF5F5E8FF585833765858330054542F0054542F77F4F4E6FFE3E3D5FFD3D3 + C2FFE9E9DBFFE9E9DBFFE9E9DBFFE9E9DBFFE9E9DBFFE9E9DBFFE9E9DBFFE9E9 + DBFFE9E9DBFFE9E9DBFFE9E9DBFFE9E9DBFFE9E9DBFFE9E9DBFFD3D3C2FFE3E3 + D5FFF4F4E6FF54542F7754542F00494926004949267BEEEEDEFFD0D0BFFFE8E8 + D8FFE8E8D8FFE8E8D8FFE8E8D8FFE8E8D8FFE8E8D8FFE8E8D8FFE8E8D8FFE8E8 + D8FFE8E8D8FFE8E8D8FFE8E8D8FFE8E8D8FFE8E8D8FFE8E8D8FFE8E8D8FFD0D0 + BFFFEEEEDEFF4949267B494926000F0F070038381782CECEBDFFF3F3E2FFF3F3 + E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3 + E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3 + E2FFCECEBDFF383817820F0F0700000000102121096C2A2A0B872A2A0B872A2A + 0B872A2A0B872A2A0B872A2A0B872A2A0B872A2A0B872A2A0B872A2A0B872A2A + 0B872A2A0B872A2A0B872A2A0B872A2A0B872A2A0B872A2A0B872A2A0B872A2A + 0B872A2A0B872121096B0000000E0000000800000011000000190000001A0000 + 001A0000001A0000001A0000001A0000001A0000001A0000001A0000001A0000 + 001A0000001A0000001A0000001A0000001A0000001A0000001A0000001A0000 + 001A000000170000000E00000007FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00 + } + end + object OpenDialog: TOpenDialog + Filter = 'All files (*.*)|*.*' + left = 128 + top = 296 + end +end diff --git a/applications/spready/shyperlinkform.pas b/applications/spready/shyperlinkform.pas new file mode 100644 index 000000000..30ca3fd62 --- /dev/null +++ b/applications/spready/shyperlinkform.pas @@ -0,0 +1,550 @@ +unit sHyperlinkForm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ButtonPanel, + ExtCtrls, Buttons, StdCtrls, ComCtrls, + fpsTypes, fpspreadsheet; + +type + + { THyperlinkForm } + + THyperlinkForm = class(TForm) + Bevel1: TBevel; + BtnBrowseFile: TButton; + ButtonPanel1: TButtonPanel; + CbFtpServer: TComboBox; + CbFtpUsername: TComboBox; + CbFtpPassword: TComboBox; + CbHttpAddress: TComboBox; + CbFileBookmark: TComboBox; + CbWorksheets: TComboBox; + CbCellAddress: TComboBox; + CbFileName: TComboBox; + CbMailRecipient: TComboBox; + EdHttpBookmark: TEdit; + EdTooltip: TEdit; + EdMailSubject: TEdit; + GroupBox2: TGroupBox; + GbFileName: TGroupBox; + GbInternetLinkType: TGroupBox; + GbHttp: TGroupBox; + GbMailRecipient: TGroupBox; + GroupBox6: TGroupBox; + GbFileBookmark: TGroupBox; + GroupBox8: TGroupBox; + GbFtp: TGroupBox; + Images: TImageList; + HyperlinkInfo: TLabel; + Label1: TLabel; + LblFtpUserName: TLabel; + LblFtpPassword: TLabel; + LblHttpAddress: TLabel; + Label5: TLabel; + Label6: TLabel; + LblHttpBookmark: TLabel; + Notebook: TNotebook; + InternetNotebook: TNotebook; + OpenDialog: TOpenDialog; + PgHTTP: TPage; + PfFTP: TPage; + PgInternal: TPage; + PgFile: TPage; + PgInternet: TPage; + PgMail: TPage; + Panel2: TPanel; + RbFTP: TRadioButton; + RbHTTP: TRadioButton; + ToolBar: TToolBar; + TbInternal: TToolButton; + TbFile: TToolButton; + TbInternet: TToolButton; + TbMail: TToolButton; + procedure BtnBrowseFileClick(Sender: TObject); + procedure CbCellAddressEditingDone(Sender: TObject); + procedure CbFileBookmarkDropDown(Sender: TObject); + procedure CbFileNameEditingDone(Sender: TObject); + procedure CbFtpServerEditingDone(Sender: TObject); + procedure CbHttpAddressEditingDone(Sender: TObject); + procedure CbMailRecipientEditingDone(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure OKButtonClick(Sender: TObject); + procedure HTTP_FTP_Change(Sender: TObject); + procedure ToolButtonClick(Sender: TObject); + procedure UpdateHyperlinkInfo(Sender: TObject); + private + { private declarations } + FWorkbook: TsWorkbook; + FWorksheet: TsWorksheet; + function GetHyperlinkTarget: String; + function GetHyperlinkTooltip: String; + procedure SetHyperlinkKind(AValue: Integer); + procedure SetHyperlinkTarget(const AValue: String); + procedure SetHyperlinkTooltip(const AValue: String); + procedure SetInternetLinkKind(AValue: Integer); + procedure SetWorksheet(AWorksheet: TsWorksheet); + protected + function GetHyperlinkKind: Integer; + function ValidData(out AControl: TWinControl; out AMsg: String): Boolean; + public + { public declarations } + procedure GetHyperlink(out AHyperlink: TsHyperlink); + procedure SetHyperlink(AWorksheet: TsWorksheet; const AHyperlink: TsHyperlink); + end; + +var + HyperlinkForm: THyperlinkForm; + +implementation + +{$R *.lfm} + +uses + URIParser, LazFileUtils, + fpsUtils; + +const + TAG_INTERNAL = 0; + TAG_FILE = 1; + TAG_INTERNET = 2; + TAG_MAIL = 3; + + TAG_HTTP = 0; + TAG_FTP = 1; + +{ THyperlinkForm } + +procedure THyperlinkForm.BtnBrowseFileClick(Sender: TObject); +begin + with OpenDialog do begin + Filename := CbFileName.Text; + if Execute then begin + InitialDir := ExtractFileDir(FileName); + CbFileName.Text := FileName; + if (CbFileName.Text <> '') and (CbFileName.Items.IndexOf(FileName) = -1) then + CbFilename.Items.Insert(0, FileName); + end; + end; +end; + +procedure THyperlinkForm.CbCellAddressEditingDone(Sender: TObject); +begin + CbCellAddress.Text := Uppercase(CbCellAddress.Text); +end; + +procedure THyperlinkForm.CbFileBookmarkDropDown(Sender: TObject); +var + ext: String; + wb: TsWorkbook; + ws: TsWorksheet; + i: Integer; +begin + CbFileBookmark.Items.Clear; + if FileExists(CbFilename.Text) then begin + ext := Lowercase(ExtractFileExt(CbFileName.Text)); + if (ext = '.xls') or (ext = '.xlsx') or (ext = '.ods') then begin + wb := TsWorkbook.Create; + try + wb.ReadFromFile(CbFileName.Text); + for i:=0 to wb.GetWorksheetCount-1 do + begin + ws := wb.GetWorksheetByIndex(i); + CbFileBookmark.Items.Add(ws.Name); + end; + finally + wb.Free; + end; + end; + end; +end; + +procedure THyperlinkForm.CbFileNameEditingDone(Sender: TObject); +begin + if (CbFilename.Text <> '') and + (CbFilename.Items.IndexOf(CbFilename.Text) = -1) + then + CbFileName.Items.Insert(0, CbFileName.Text); +end; + +procedure THyperlinkForm.CbFtpServerEditingDone(Sender: TObject); +begin + if (CbFtpServer.Text <> '') and + (CbFtpServer.Items.IndexOf(CbFtpServer.Text) = -1) + then + CbFtpServer.Items.Insert(0, CbFtpServer.Text); +end; + +procedure THyperlinkForm.CbHttpAddressEditingDone(Sender: TObject); +begin + if (CbHttpAddress.Text <> '') and + (CbHttpAddress.Items.Indexof(CbHttpAddress.Text) = -1) + then + CbHttpAddress.Items.Insert(0, CbHttpAddress.Text); +end; + +procedure THyperlinkForm.CbMailRecipientEditingDone(Sender: TObject); +begin + if (CbMailRecipient.Text <> '') and + (CbMaiLRecipient.Items.IndexOf(CbMailRecipient.Text) = -1) + then + CbMailRecipient.Items.Insert(0, CbMailRecipient.Text); +end; + +procedure THyperlinkForm.FormCreate(Sender: TObject); +begin + HTTP_FTP_Change(nil); +end; + +procedure THyperlinkForm.GetHyperlink(out AHyperlink: TsHyperlink); +begin + AHyperlink.Target := GetHyperlinkTarget; + AHyperlink.Tooltip := GetHyperlinkTooltip; +end; + +function THyperlinkForm.GetHyperlinkKind: Integer; +begin + for Result := 0 to Toolbar.ButtonCount-1 do + if Toolbar.Buttons[Result].Down then + exit; + Result := -1; +end; + +function THyperlinkForm.GetHyperlinkTarget: String; +begin + Result := ''; + case GetHyperlinkKind of + TAG_INTERNAL: + begin //internal + if (CbWorksheets.ItemIndex > 0) and (CbCellAddress.Text <> '') then + Result := '#' + CbWorksheets.Text + '!' + Uppercase(CbCellAddress.Text) + else if (CbWorksheets.ItemIndex > 0) then + Result := '#' + CbWorksheets.Text + '!' + else if (CbCellAddress.Text <> '') then + Result := '#' + Uppercase(CbCellAddress.Text); + end; + + TAG_FILE: + begin // File + if FileNameIsAbsolute(CbFilename.Text) then + Result := FilenameToURI(CbFilename.Text) + else + Result := CbFilename.Text; + if CbFileBookmark.Text <> '' then + Result := Result + '#' + CbFileBookmark.Text; + end; + + TAG_INTERNET: + begin // Internet link + if RbHttp.Checked and (CbHttpAddress.Text <> '') then + begin + if pos('http', Lowercase(CbHttpAddress.Text)) = 1 then + Result := CbHttpAddress.Text + else + Result := 'http://' + CbHttpAddress.Text; + if EdHttpBookmark.Text <> '' then + Result := Result + '#' + EdHttpBookmark.Text; + end else + if RbFtp.Checked and (CbFtpServer.Text <> '') then + begin + if (CbFtpUsername.Text <> '') and (CbFtpPassword.Text <> '') then + Result := Format('ftp://%s:%s@%s', [CbFtpUsername.Text, CbFtpPassword.Text, CbFtpServer.Text]) + else + if (CbFtpUsername.Text <> '') and (CbFtpPassword.Text = '') then + Result := Format('ftp://%s@%s', [CbFtpUsername.Text , CbFtpServer.Text]) + else + Result := 'ftp://anonymous@' + CbFtpServer.Text; + end; + end; + + TAG_MAIL: + begin // Mail + if EdMailSubject.Text <> '' then + Result := Format('mailto:%s?subject=%s', [CbMailRecipient.Text, EdMailSubject.Text]) + else + Result := Format('mailto:%s', [CbMailRecipient.Text]); + end; + end; +end; + +function THyperlinkForm.GetHyperlinkTooltip: String; +begin + Result := EdTooltip.Text; +end; + +procedure THyperlinkForm.OKButtonClick(Sender: TObject); +var + C: TWinControl; + msg: String; +begin + if not ValidData(C, msg) then begin + C.SetFocus; + MessageDlg(msg, mtError, [mbOK], 0); + ModalResult := mrNone; + end; +end; + +procedure THyperlinkForm.HTTP_FTP_Change(Sender: TObject); +begin + if RbHTTP.Checked then + InternetNotebook.PageIndex := 0; + if RbFTP.Checked then + InternetNotebook.PageIndex := 1; + UpdateHyperlinkInfo(nil); +end; + +procedure THyperlinkForm.SetHyperlink(AWorksheet: TsWorksheet; + const AHyperlink: TsHyperlink); +begin + SetWorksheet(AWorksheet); + SetHyperlinkTarget(AHyperlink.Target); + SetHyperlinkTooltip(AHyperlink.Tooltip); +end; + +procedure THyperlinkForm.SetHyperlinkKind(AValue: Integer); +var + i: Integer; +begin + for i:=0 to Toolbar.ButtonCount-1 do + Toolbar.Buttons[i].Down := (AValue = Toolbar.Buttons[i].Tag); + Notebook.PageIndex := AValue; +end; + +procedure THyperlinkForm.SetHyperlinkTarget(const AValue: String); +var + u: TURI; + sheet: TsWorksheet; + c,r: Cardinal; + i, idx: Integer; + p: Integer; + fn, bm: String; +begin + if AValue = '' then + begin + CbWorksheets.ItemIndex := 0; + CbCellAddress.Text := ''; + + CbMailRecipient.Text := ''; + EdMailSubject.Text := ''; + + UpdateHyperlinkInfo(nil); + exit; + end; + + // Internal link + if pos('#', AValue) = 1 then begin + SetHyperlinkKind(TAG_INTERNAL); + if FWorkbook.TryStrToCell(Copy(AValue, 2, Length(AValue)), sheet, r, c) then + begin + if (sheet = nil) or (sheet = FWorksheet) then + CbWorksheets.ItemIndex := 0 + else + begin + idx := 0; + for i:=1 to CbWorksheets.Items.Count-1 do + if CbWorksheets.Items[i] = sheet.Name then + begin + idx := i; + break; + end; + CbWorksheets.ItemIndex := idx; + end; + CbCellAddress.Text := GetCellString(r, c); + UpdateHyperlinkInfo(nil); + end else begin + HyperlinkInfo.Caption := AValue; + MessageDlg(Format('Sheet not found in hyperlink "%s"', [AValue]), mtError, + [mbOK], 0); + end; + exit; + end; + + // external links + u := ParseURI(AValue); + + // File with absolute path + if SameText(u.Protocol, 'file') then + begin + SetHyperlinkKind(TAG_FILE); + UriToFilename(AValue, fn); + CbFilename.Text := fn; + CbFileBookmark.Text := u.Bookmark; + UpdateHyperlinkInfo(nil); + exit; + end; + + // Mail + if SameText(u.Protocol, 'mailto') then + begin + SetHyperlinkKind(TAG_MAIL); + CbMailRecipient.Text := u.Document; + if CbMailRecipient.Items.IndexOf(u.Document) = -1 then + CbMailRecipient.Items.Insert(0, u.Document); + if (u.Params <> '') then + begin + p := pos('subject=', u.Params); + if p <> 0 then + EdMailSubject.Text := copy(u.Params, p+Length('subject='), MaxInt); + end; + UpdateHyperlinkInfo(nil); + exit; + end; + + // http + if SameText(u.Protocol, 'http') or SameText(u.Protocol, 'https') then + begin + SetHyperlinkKind(TAG_INTERNET); + SetInternetLinkKind(TAG_HTTP); + CbHttpAddress.Text := u.Host; + EdHttpBookmark.Text := u.Bookmark; + UpdateHyperlinkInfo(nil); + exit; + end; + + // ftp + if SameText(u.Protocol, 'ftp') then + begin + SetHyperlinkKind(TAG_INTERNET); + SetInternetLinkKind(TAG_FTP); + CbFtpServer.Text := u.Host; + CbFtpUserName.text := u.UserName; + CbFtpPassword.Text := u.Password; + UpdateHyperlinkInfo(nil); + exit; + end; + + // If we get there it must be a local file with relative path + SetHyperlinkKind(TAG_FILE); + SplitHyperlink(AValue, fn, bm); + CbFileName.Text := fn; + CbFileBookmark.Text := bm; + UpdateHyperlinkInfo(nil); +end; + +procedure THyperlinkForm.SetHyperlinkTooltip(const AValue: String); +begin + EdTooltip.Text := AValue; +end; + +procedure THyperlinkForm.SetInternetLinkKind(AValue: Integer); +begin + RbHttp.Checked := AValue = TAG_HTTP; + RbFtp.Checked := AValue = TAG_FTP; + InternetNotebook.PageIndex := AValue; +end; + +procedure THyperlinkForm.SetWorksheet(AWorksheet: TsWorksheet); +var + i: Integer; +begin + FWorksheet := AWorksheet; + if FWorksheet = nil then + raise Exception.Create('[THyperlinkForm.SetWorksheet] Worksheet cannot be nil.'); + FWorkbook := FWorksheet.Workbook; + + CbWorksheets.Items.Clear; + CbWorksheets.Items.Add('(current worksheet)'); + for i:=0 to FWorkbook.GetWorksheetCount-1 do + CbWorksheets.Items.Add(FWorkbook.GetWorksheetByIndex(i).Name); +end; + +procedure THyperlinkForm.ToolButtonClick(Sender: TObject); +var + i: Integer; +begin + Notebook.PageIndex := TToolButton(Sender).Tag; + for i:=0 to Toolbar.ButtonCount-1 do + Toolbar.Buttons[i].Down := Toolbar.Buttons[i].Tag = TToolbutton(Sender).Tag; + UpdateHyperlinkInfo(nil); +end; + +procedure THyperlinkForm.UpdateHyperlinkInfo(Sender: TObject); +var + s: String; +begin + s := GetHyperlinkTarget; + if s = '' then s := #32; + HyperlinkInfo.Caption := s; +end; + +function THyperlinkForm.ValidData(out AControl: TWinControl; + out AMsg: String): Boolean; +var + r,c: Cardinal; +begin + Result := false; + AMsg := ''; + AControl := nil; + + case GetHyperlinkKind of + TAG_INTERNAL: + begin + if CbCellAddress.Text = '' then + begin + AMsg := 'No cell address specified.'; + AControl := CbCellAddress; + exit; + end; + if not ParseCellString(CbCellAddress.Text, r, c) then + begin + AMsg := Format('"%s" is not a valid cell address.', [CbCellAddress.Text]); + AControl := CbCellAddress; + exit; + end; + if (CbWorksheets.Items.IndexOf(CbWorksheets.Text) = -1) and (CbWorksheets.ItemIndex <> 0) then + begin + AMsg := Format('Worksheet "%s" does not exist.', [CbWorksheets.Text]); + AControl := CbWorksheets; + exit; + end; + end; + + TAG_FILE: + begin + if CbFilename.Text = '' then + begin + AMsg := 'No filename specified.'; + AControl := CbFileName; + exit; + end; + end; + + TAG_INTERNET: + if RbHttp.Checked then + begin + if CbHttpAddress.Text = '' then + begin + AMsg := 'URL of web site not specified.'; + AControl := CbHttpAddress; + exit; + end; + end else + if RbFtp.Checked then + begin + if CbFtpServer.Text = '' then + begin + AMsg := 'Ftp server not specified.'; + AControl := CbFtpServer; + exit; + end; + end; + + TAG_MAIL: + begin + if CbMailRecipient.Text = '' then + begin + AMsg := 'No mail recipient specified.'; + AControl := CbMailRecipient; + exit; + end; + // Check e-mail address here also! + end; + end; + Result := true; +end; + +end. + diff --git a/applications/spready/smain.lfm b/applications/spready/smain.lfm new file mode 100644 index 000000000..6490caab4 --- /dev/null +++ b/applications/spready/smain.lfm @@ -0,0 +1,4869 @@ +object MainForm: TMainForm + Left = 267 + Height = 709 + Top = 152 + Width = 1120 + Caption = 'spready' + ClientHeight = 689 + ClientWidth = 1120 + Menu = MainMenu + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnShow = FormShow + ShowHint = True + LCLVersion = '1.7' + object WorkbookTabControl: TsWorkbookTabControl + Left = 0 + Height = 606 + Top = 83 + Width = 792 + TabIndex = 0 + Tabs.Strings = ( + 'Sheet1' + ) + Align = alClient + TabOrder = 0 + WorkbookSource = WorkbookSource + object WorksheetGrid: TsWorksheetGrid + Left = 2 + Height = 581 + Top = 23 + Width = 788 + AutoCalc = True + FrozenCols = 0 + FrozenRows = 0 + ReadFormulas = True + TextOverflow = True + WorkbookSource = WorkbookSource + Align = alClient + AutoAdvance = aaDown + ColCount = 27 + DefaultColWidth = 64 + DefaultRowHeight = 22 + Font.Color = clBlack + Font.Height = -13 + Font.Name = 'Arial' + MouseWheelOption = mwGrid + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSizing, goColSizing, goEditing, goThumbTracking, goDblClickAutoSize, goCellHints] + ParentFont = False + RowCount = 101 + TabOrder = 1 + TitleFont.Color = clBlack + TitleFont.Height = -13 + TitleFont.Name = 'Arial' + TitleStyle = tsNative + OnClickHyperlink = WorksheetGridClickHyperlink + OnMouseWheel = WorksheetGridMouseWheel + end + end + object InspectorTabControl: TTabControl + Left = 797 + Height = 606 + Top = 83 + Width = 323 + MultiLine = True + OnChange = InspectorTabControlChange + TabIndex = 0 + Tabs.Strings = ( + 'Workbook' + 'Worksheet' + 'Cell values' + 'Cell properties' + 'Row' + 'Column' + ) + Align = alRight + TabOrder = 1 + Visible = False + object Inspector: TsSpreadsheetInspector + Left = 2 + Height = 561 + Top = 43 + Width = 319 + Align = alClient + DefaultColWidth = 100 + MouseWheelOption = mwGrid + RowCount = 33 + TabOrder = 1 + TitleStyle = tsNative + OnEnter = InspectorEnter + OnExit = InspectorExit + DisplayOptions = [doColumnTitles] + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing, goAlwaysShowEditor, goThumbTracking, goCellHints, goTruncCellHints, goCellEllipsis] + Strings.Strings = ( + 'FileName=' + 'FileFormat=(unknown)' + 'ActiveWorksheet=Sheet1' + 'Options=boAutoCalc, boCalcBeforeSaving, boReadFormulas' + '(-) FormatSettings=' + ' ThousandSeparator=.' + ' DecimalSeparator=,' + ' ListSeparator=;' + ' DateSeparator=.' + ' TimeSeparator=:' + ' ShortDateFormat=dd.MM.yy' + ' LongDateFormat=dd.MMM.yyyy' + ' ShortTimeFormat=hh:nn' + ' LongTimeFormat=hh:nn:ss' + ' TimeAMString=' + ' TimePMString=' + ' ShortMonthNames=Jan, Feb, Mrz, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez' + ' LongMontNames=Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember' + ' ShortMonthNames=So, Mo, Di, Mi, Do, Fr, Sa' + ' LongMontNames=Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag' + ' CurrencyString=€' + ' PosCurrencyFormat=3' + ' NegCurrencyFormat=8' + ' TwoDigitYearCenturyWindow=50' + '(-) Images=' + '(-) Fonts=' + ' Font0=Arial; size 10; black' + ' Font1=Arial; size 10; blue; underline' + ' Font2=Arial; size 10; black; bold' + ' Font3=Arial; size 10; black; italic' + '(-) Cell formats=' + ' CellFormat0=nfGeneral' + ) + TitleCaptions.Strings = ( + 'Properties' + 'Values' + ) + WorkbookSource = WorkbookSource + Mode = imWorkbook + ExtendedColSizing = True + ColWidths = ( + 159 + 160 + ) + end + end + object InspectorSplitter: TSplitter + Left = 792 + Height = 606 + Top = 83 + Width = 5 + Align = alRight + ResizeAnchor = akRight + Visible = False + end + object ToolBar1: TToolBar + Left = 0 + Height = 26 + Top = 24 + Width = 1120 + AutoSize = True + ButtonHeight = 26 + ButtonWidth = 24 + Caption = 'ToolBar1' + EdgeBorders = [] + Images = ImageList + TabOrder = 3 + object ToolButton6: TToolButton + Left = 280 + Top = 0 + Action = AcFontBold + end + object ToolButton7: TToolButton + Left = 304 + Top = 0 + Action = AcFontItalic + end + object ToolButton8: TToolButton + Left = 328 + Top = 0 + Action = AcFontUnderline + end + object ToolButton10: TToolButton + Left = 376 + Height = 26 + Top = 0 + Width = 5 + Caption = 'ToolButton10' + Style = tbsDivider + end + object ToolButton11: TToolButton + Left = 352 + Top = 0 + Action = AcFontStrikeout + end + object ToolButton12: TToolButton + Left = 381 + Top = 0 + Action = AcHorAlignLeft + end + object ToolButton13: TToolButton + Left = 405 + Top = 0 + Action = AcHorAlignCenter + end + object ToolButton14: TToolButton + Left = 429 + Top = 0 + Action = AcHorAlignRight + end + object ToolButton15: TToolButton + Left = 453 + Height = 26 + Top = 0 + Width = 5 + Caption = 'ToolButton15' + Style = tbsDivider + end + object ToolButton16: TToolButton + Left = 458 + Top = 0 + Action = AcVertAlignTop + end + object ToolButton17: TToolButton + Left = 482 + Top = 0 + Action = AcVertAlignCenter + end + object ToolButton18: TToolButton + Left = 506 + Top = 0 + Action = AcVertAlignBottom + end + object ToolButton19: TToolButton + Left = 530 + Height = 26 + Top = 0 + Width = 5 + Caption = 'ToolButton19' + Style = tbsDivider + end + object ToolButton20: TToolButton + Left = 564 + Top = 0 + Action = AcNumFormatCustom + DropdownMenu = PuNumFormat + ImageIndex = 15 + Marked = True + Style = tbsDropDown + end + object ToolButton21: TToolButton + Left = 624 + Top = 0 + Action = AcNumFormatCustom + DropdownMenu = PuCurrencyFormat + ImageIndex = 17 + Style = tbsDropDown + end + object ToolButton22: TToolButton + Left = 600 + Top = 0 + Action = AcNumFormatPercentage + end + object ToolButton23: TToolButton + Left = 896 + Height = 26 + Top = 0 + Width = 5 + Caption = 'ToolButton23' + Style = tbsDivider + end + object ToolButton24: TToolButton + Left = 660 + Top = 0 + Action = AcNumFormatCustom + DropdownMenu = PuDateFormat + ImageIndex = 18 + Style = tbsDropDown + end + object ToolButton25: TToolButton + Left = 696 + Top = 0 + Action = AcNumFormatCustom + DropdownMenu = PuTimeFormat + ImageIndex = 19 + Style = tbsDropDown + end + object ToolButton26: TToolButton + Left = 732 + Top = 0 + Action = AcDecDecimals + end + object ToolButton27: TToolButton + Left = 756 + Top = 0 + Action = AcIncDecimals + end + object ToolButton29: TToolButton + Left = 30 + Hint = 'Cell font dialog' + Top = 0 + Action = AcCellFontDialog + end + object ToolButton30: TToolButton + Left = 785 + Hint = 'Background color dialog' + Top = 0 + Action = AcBackgroundColorDialog + end + object ToolButton31: TToolButton + Left = 855 + Height = 26 + Top = 0 + Width = 5 + Caption = 'ToolButton31' + Style = tbsDivider + end + object TbBorders: TToolButton + Left = 860 + Hint = 'Top border' + Top = 0 + Caption = 'Top' + DropdownMenu = PuBorders + ImageIndex = 26 + Style = tbsDropDown + end + object ToolButton3: TToolButton + Left = 780 + Height = 26 + Top = 0 + Width = 5 + Caption = 'ToolButton3' + Style = tbsDivider + end + object ToolButton5: TToolButton + Left = 901 + Top = 0 + Action = AcMergeCells + end + object ToolButton36: TToolButton + Left = 535 + Top = 0 + Action = AcWordWrap + end + object ToolButton37: TToolButton + Left = 1 + Top = 0 + Action = AcCopyFormat + end + object ToolButton38: TToolButton + Left = 25 + Height = 26 + Top = 0 + Width = 5 + Caption = 'ToolButton38' + Style = tbsDivider + end + object FontnameCombo: TsCellCombobox + Left = 54 + Height = 23 + Hint = 'Cell font name' + Top = 0 + Width = 130 + CellFormatItem = cfiFontName + WorkbookSource = WorkbookSource + DropDownCount = 24 + ItemIndex = 44 + TabOrder = 0 + Text = 'Arial' + end + object FontsizeCombo: TsCellCombobox + Left = 184 + Height = 23 + Hint = 'Cell font size' + Top = 0 + Width = 48 + CellFormatItem = cfiFontSize + WorkbookSource = WorkbookSource + DropDownCount = 24 + ItemIndex = 2 + TabOrder = 1 + Text = '10' + end + object FontColorCombobox: TsCellCombobox + Left = 232 + Height = 24 + Hint = 'Font color' + Top = 0 + Width = 48 + CellFormatItem = cfiFontColor + ColorRectOffset = 3 + ColorRectWidth = -1 + WorkbookSource = WorkbookSource + OnAddColors = ColorComboboxAddColors + DropDownCount = 24 + ItemIndex = 0 + TabOrder = 2 + end + object BackgroundColorCombobox: TsCellCombobox + Left = 809 + Height = 24 + Hint = 'Background color' + Top = 0 + Width = 46 + CellFormatItem = cfiBackgroundColor + ColorRectOffset = 3 + ColorRectWidth = -1 + WorkbookSource = WorkbookSource + OnAddColors = ColorComboboxAddColors + DropDownCount = 24 + ItemIndex = 0 + TabOrder = 3 + end + object ToolButton45: TToolButton + Left = 559 + Height = 26 + Top = 0 + Width = 5 + Caption = 'ToolButton45' + Style = tbsDivider + end + end + object ToolBar2: TToolBar + Left = 0 + Height = 24 + Top = 0 + Width = 1120 + AutoSize = True + ButtonHeight = 24 + ButtonWidth = 24 + Caption = 'ToolBar2' + EdgeBorders = [] + Images = ImageList + TabOrder = 4 + object ToolButton32: TToolButton + Left = 179 + Top = 0 + Action = AcAddWorksheet + end + object ToolButton33: TToolButton + Left = 203 + Top = 0 + Action = AcDeleteWorksheet + end + object ToolButton34: TToolButton + Left = 227 + Top = 0 + Action = acRenameWorksheet + end + object ToolButton1: TToolButton + Left = 357 + Height = 24 + Top = 0 + Width = 5 + Caption = 'ToolButton1' + Style = tbsDivider + end + object ToolButton2: TToolButton + Left = 545 + Top = 0 + Action = AcFileExit + end + object tbFileOpen: TToolButton + Left = 25 + Top = 0 + Action = AcFileOpen + DropdownMenu = PuRecentFiles + Style = tbsDropDown + end + object ToolButton28: TToolButton + Left = 251 + Height = 24 + Top = 0 + Width = 5 + Caption = 'ToolButton28' + Style = tbsDivider + end + object ToolButton35: TToolButton + Left = 61 + Top = 0 + Action = AcFileSaveAs + end + object ToolButton39: TToolButton + Left = 256 + Top = 0 + Action = AcColAdd + end + object ToolButton40: TToolButton + Left = 280 + Top = 0 + Action = AcColDelete + end + object ToolButton41: TToolButton + Left = 309 + Top = 0 + Action = AcRowAdd + end + object ToolButton42: TToolButton + Left = 333 + Top = 0 + Action = AcRowDelete + end + object ToolButton43: TToolButton + Left = 174 + Height = 24 + Top = 0 + Width = 5 + Caption = 'ToolButton43' + Style = tbsDivider + end + object ToolButton44: TToolButton + Left = 304 + Height = 24 + Top = 0 + Width = 5 + Caption = 'ToolButton44' + Style = tbsDivider + end + object ToolButton46: TToolButton + Left = 90 + Top = 0 + Action = AcCopyToClipboard + end + object ToolButton47: TToolButton + Left = 114 + Top = 0 + Action = AcCutToClipboard + end + object ToolButton48: TToolButton + Left = 138 + Top = 0 + Action = AcPasteAllFromClipboard + DropdownMenu = PuPaste + Style = tbsDropDown + end + object ToolButton49: TToolButton + Left = 85 + Height = 24 + Top = 0 + Width = 5 + Caption = 'ToolButton49' + Style = tbsDivider + end + object TbCommentAdd: TToolButton + Left = 362 + Top = 0 + Action = AcCommentNew + end + object TbCommentDelete: TToolButton + Left = 386 + Top = 0 + Action = AcCommentEdit + end + object TbCommentEdit: TToolButton + Left = 410 + Top = 0 + Action = AcCommentDelete + end + object ToolButton52: TToolButton + Left = 434 + Height = 24 + Top = 0 + Width = 5 + Caption = 'ToolButton52' + Style = tbsDivider + end + object ToolButton50: TToolButton + Left = 439 + Top = 0 + Action = AcHyperlinkNew + end + object ToolButton51: TToolButton + Left = 463 + Top = 0 + Action = AcHyperlinkEdit + end + object ToolButton53: TToolButton + Left = 487 + Top = 0 + Action = AcHyperlinkDelete + end + object ToolButton54: TToolButton + Left = 511 + Height = 24 + Top = 0 + Width = 5 + Caption = 'ToolButton54' + Style = tbsDivider + end + object ToolButton4: TToolButton + Left = 516 + Top = 0 + Action = AcSearch + end + object ToolButton55: TToolButton + Left = 540 + Height = 24 + Top = 0 + Width = 5 + Caption = 'ToolButton55' + Style = tbsDivider + end + object ToolButton9: TToolButton + Left = 1 + Top = 0 + Action = AcFileNew + end + end + object ToolBar3: TToolBar + Left = 0 + Height = 28 + Top = 50 + Width = 1120 + AutoSize = True + Caption = 'ToolBar3' + Constraints.MinHeight = 28 + EdgeBorders = [ebBottom] + TabOrder = 5 + object Panel2: TPanel + Left = 1 + Height = 26 + Top = 0 + Width = 138 + Align = alLeft + BevelOuter = bvNone + ClientHeight = 26 + ClientWidth = 138 + TabOrder = 0 + object CellIndicator: TsCellIndicator + Left = 0 + Height = 23 + Top = 0 + Width = 138 + Align = alTop + TabOrder = 0 + Text = 'A1' + WorkbookSource = WorkbookSource + end + end + object CellEdit: TsCellEdit + Left = 144 + Height = 23 + Top = 0 + Width = 974 + Align = alClient + BorderSpacing.Right = 2 + BorderSpacing.Bottom = 3 + TabOrder = 1 + WantReturns = False + WorkbookSource = WorkbookSource + end + object Splitter2: TSplitter + Left = 139 + Height = 26 + Top = 0 + Width = 5 + end + end + object Splitter3: TSplitter + Cursor = crVSplit + Left = 0 + Height = 5 + Top = 78 + Width = 1120 + Align = alTop + ResizeAnchor = akTop + end + object WorkbookSource: TsWorkbookSource + AutoDetectFormat = False + FileFormat = sfUser + Options = [boAutoCalc, boCalcBeforeSaving, boReadFormulas] + left = 176 + top = 160 + end + object OpenDialog: TOpenDialog + DefaultExt = '.xls' + Filter = 'All spreadsheet files|*.xls;*.xlsx;*.ods;*.csv|All Excel files (*.xls, *.xlsx)|*.xls;*.xlsx|Excel XML spreadsheet (*.xlsx)|*.xlsx|Excel XP/2003 XML spreadsheet (*.xml)|*.xml|Excel 97-2003 spreadsheets (*.xls)|*.xls|Excel 5 spreadsheet (*.xls)|*.xls|Excel 2.1 spreadsheets (*.xls)|*.xls|LibreOffice/OpenOffice spreadsheet (*.ods)|*.ods|HTML files (*.html; *.htm)|*.html;*.htm|Comma-separated text files (*.csv; *.txt)|*.csv;*.txt' + Options = [ofExtensionDifferent, ofEnableSizing, ofViewDetail] + left = 312 + top = 160 + end + object ActionList: TActionList + Images = ImageList + OnUpdate = ActionListUpdate + left = 176 + top = 248 + object AcAddWorksheet: TsWorksheetAddAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Add worksheet' + Hint = 'Add empty worksheet' + ImageIndex = 1 + NameMask = 'Sheet%d' + end + object AcDeleteWorksheet: TsWorksheetDeleteAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Delete worksheet...' + Hint = 'Delete worksheet' + ImageIndex = 2 + end + object acRenameWorksheet: TsWorksheetRenameAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Rename...' + Hint = 'Rename worksheet' + ImageIndex = 3 + end + object AcFontBold: TsFontStyleAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Bold' + Hint = 'Bold' + ImageIndex = 4 + FontStyle = fssBold + end + object AcFontItalic: TsFontStyleAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Italic' + Hint = 'Italic' + ImageIndex = 5 + FontStyle = fssItalic + end + object AcFontUnderline: TsFontStyleAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Underline' + Hint = 'Underline' + ImageIndex = 6 + FontStyle = fssUnderline + end + object AcFontStrikeout: TsFontStyleAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Strikeout' + Hint = 'Strikeout' + ImageIndex = 7 + FontStyle = fssStrikeOut + end + object AcVertAlignTop: TsVertAlignmentAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Top' + Hint = 'Top-aligned text' + ImageIndex = 11 + VertAlignment = vaTop + end + object AcVertAlignCenter: TsVertAlignmentAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Center' + Hint = 'Vertically centered text' + ImageIndex = 12 + VertAlignment = vaCenter + end + object AcVertAlignBottom: TsVertAlignmentAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Bottom' + Hint = 'Bottom-aligned text' + ImageIndex = 13 + VertAlignment = vaBottom + end + object AcHorAlignLeft: TsHorAlignmentAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Left' + Hint = 'Left-aligned text' + ImageIndex = 8 + HorAlignment = haLeft + end + object AcHorAlignCenter: TsHorAlignmentAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Center' + Hint = 'Centered text' + ImageIndex = 9 + HorAlignment = haCenter + end + object AcHorAlignRight: TsHorAlignmentAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Right' + Hint = 'Right-aligned text' + ImageIndex = 10 + HorAlignment = haRight + end + object AcWordWrap: TsWordwrapAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Word-wrap' + Hint = 'Word-wrapped text' + ImageIndex = 24 + end + object AcTextRotHor: TsTextRotationAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Horizontal text' + end + object AcTextRot90CW: TsTextRotationAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '90° clockwise' + Hint = '90° clockwise rotated text' + TextRotation = rt90DegreeClockwiseRotation + end + object AcTextRot90CCW: TsTextRotationAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '90° counter-clockwise' + Hint = '90° counter-clockwise rotated text' + TextRotation = rt90DegreeCounterClockwiseRotation + end + object AcTextRotStacked: TsTextRotationAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Stacked' + Hint = 'Vertically stacked horizontal letters' + TextRotation = rtStacked + end + object AcNumFormatCustom: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Custom...' + Hint = 'Custom number format' + NumberFormat = nfCustom + OnGetNumberFormatString = AcNumFormatCustomGetNumberFormatString + end + object AcNumFormatGeneral: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'General' + Hint = 'General format' + end + object AcNumFormatFixed: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Fixed' + Hint = 'Fixed decimals format' + NumberFormat = nfFixed + end + object AcNumFormatFixedTh: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Fixed w/thousand separator' + Hint = 'Fixed decimal count with thousand separator' + NumberFormat = nfFixedTh + end + object AcNumFormatPercentage: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Percent' + Hint = 'Percent format' + ImageIndex = 16 + NumberFormat = nfPercentage + end + object AcNumFormatCurrency: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Currency' + Hint = 'Currency format' + NumberFormat = nfCurrency + end + object AcNumFormatCurrencyRed: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Currency (red)' + Hint = 'Currency format (negative values in red)' + NumberFormat = nfCurrencyRed + end + object AcNumFormatExp: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Exponential' + Hint = 'Exponential format' + NumberFormat = nfExp + end + object AcNumFormatFraction1: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Fraction (1 digit)' + NumberFormat = nfFraction + NumberFormatString = '# ?/?' + end + object AcNumFormatFraction2: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Fraction (2 digits)' + NumberFormat = nfFraction + NumberFormatString = '# ??/??' + end + object AcNumFormatFraction3: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Fraction (3 digits)' + NumberFormat = nfFraction + NumberFormatString = '# ???/???' + end + object AcNumFormatDateTime: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Date/time' + Hint = 'Date and time' + NumberFormat = nfShortDateTime + end + object AcNumFormatLongDate: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Long date' + Hint = 'Long date format' + NumberFormat = nfLongDate + end + object AcNumFormatShortDate: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Short date' + Hint = 'Short date format' + NumberFormat = nfShortDate + end + object AcNumFormatDayMonth: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Day and month' + Hint = 'Day and month only' + NumberFormat = nfDayMonth + end + object AcNumFormatMonthYear: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Month and year' + Hint = 'Month and year only' + NumberFormat = nfMonthYear + end + object AcNumFormatLongTime: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Long time' + Hint = 'Long time foramt' + NumberFormat = nfLongTime + end + object AcNumFormatShortTime: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Short time' + Hint = 'Short time format' + NumberFormat = nfShortTime + end + object AcNumFormatLongTimeAM: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Long time AM/PM' + Hint = 'Long 12-hour time format' + NumberFormat = nfLongTimeAM + end + object AcNumFormatShortTimeAM: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Short time AM/PM' + Hint = 'Short 12-hour time format' + NumberFormat = nfShortTimeAM + end + object AcNumFormatTimeInterval: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Time interval' + Hint = 'Time interval format' + NumberFormat = nfTimeInterval + end + object AcNumFormatText: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Text' + Hint = 'Text format' + NumberFormat = nfText + end + object AcViewInspector: TAction + Category = 'View' + AutoCheck = True + Caption = 'Inspector' + OnExecute = AcViewInspectorExecute + end + object AcRowAdd: TAction + Category = 'Worksheet' + Caption = 'Add row' + Hint = 'Add row' + ImageIndex = 48 + OnExecute = AcRowAddExecute + end + object AcColAdd: TAction + Category = 'Worksheet' + Caption = 'Add column' + Hint = 'Add column' + ImageIndex = 47 + OnExecute = AcColAddExecute + end + object AcRowDelete: TAction + Category = 'Worksheet' + Caption = 'Delete row' + Hint = 'Delete row' + ImageIndex = 50 + OnExecute = AcRowDeleteExecute + end + object AcColDelete: TAction + Category = 'Worksheet' + Caption = 'Delete column' + Hint = 'Delete column' + ImageIndex = 49 + OnExecute = AcColDeleteExecute + end + object AcSettingsFormatSettings: TAction + Category = 'Settings' + Caption = 'Number format settings...' + Hint = 'Define number format settings' + OnExecute = AcSettingsFormatSettingsExecute + end + object AcSettingsCSVParams: TAction + Category = 'Settings' + Caption = 'CSV parameters...' + Hint = 'Parameters for CSV files' + OnExecute = AcSettingsCSVParamsExecute + end + object AcSettingsCurrency: TAction + Category = 'Settings' + Caption = 'Currency symbols...' + Hint = 'Define currency symbols' + OnExecute = AcSettingsCurrencyExecute + end + object AcSearch: TAction + Category = 'Edit' + Caption = 'Search...' + Hint = 'Search for cells' + ImageIndex = 70 + OnExecute = AcSearchExecute + ShortCut = 16454 + end + object AcShowGridLines: TAction + Category = 'View' + AutoCheck = True + Caption = 'Grid lines' + Checked = True + OnExecute = AcShowGridLinesExecute + OnUpdate = AcShowGridLinesUpdate + end + object AcShowHeaders: TAction + Category = 'View' + AutoCheck = True + Caption = 'Show column/row headers' + Checked = True + OnExecute = AcShowHeadersExecute + OnUpdate = AcShowHeadersUpdate + end + object AcFrozenRows: TAction + Category = 'Worksheet' + AutoCheck = True + Caption = 'Frozen rows' + OnExecute = AcFrozenRowsExecute + OnUpdate = AcFrozenRowsUpdate + end + object AcFrozenCols: TAction + Category = 'Worksheet' + AutoCheck = True + Caption = 'Frozen columns' + OnExecute = AcFrozenColsExecute + OnUpdate = AcFrozenColsUpdate + end + object AcWorksheetRTL: TAction + Category = 'Worksheet' + AutoCheck = True + Caption = 'Text direction inverted' + OnExecute = AcWorksheetRTLExecute + OnUpdate = AcWorksheetRTLUpdate + end + object AcIncDecimals: TsDecimalsAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'More decimals' + ImageIndex = 21 + end + object AcDecDecimals: TsDecimalsAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Less decimals' + ImageIndex = 20 + Delta = -1 + end + object AcCellFontDialog: TsFontDialogAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Cell font...' + Hint = 'Cell font' + ImageIndex = 14 + Dialog.MinFontSize = 0 + Dialog.MaxFontSize = 0 + end + object AcBackgroundColorDialog: TsBackgroundColorDialogAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Background color...' + Hint = 'Background color' + ImageIndex = 22 + Dialog.Color = clBlack + Dialog.CustomColors.Strings = ( + 'ColorA=000000' + 'ColorB=000080' + 'ColorC=008000' + 'ColorD=008080' + 'ColorE=800000' + 'ColorF=800080' + 'ColorG=808000' + 'ColorH=808080' + 'ColorI=C0C0C0' + 'ColorJ=0000FF' + 'ColorK=00FF00' + 'ColorL=00FFFF' + 'ColorM=FF0000' + 'ColorN=FF00FF' + 'ColorO=FFFF00' + 'ColorP=FFFFFF' + 'ColorQ=C0DCC0' + 'ColorR=F0CAA6' + 'ColorS=F0FBFF' + 'ColorT=A4A0A0' + ) + end + object AcCellBorderNone: TsNoCellBordersAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '(none)' + Hint = 'No borders' + ImageIndex = 26 + end + object AcCellBorderTop: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = True + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = False + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Top' + Hint = 'Top border' + ImageIndex = 31 + end + object AcCellBorderInnerHor: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = False + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = True + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Inner horizontal' + Hint = 'Inner horizontal border' + ImageIndex = 38 + end + object AcCellBorderBottom: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = True + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Bottom' + Hint = 'Bottom border' + ImageIndex = 32 + end + object AcCellBorderBottomThick: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsMedium + Borders.South.Color = clBlack + Borders.South.Visible = True + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Bottom thick' + Hint = 'Thick bottom border' + ImageIndex = 33 + end + object AcCellBorderBottomDbl: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsDouble + Borders.South.Color = clBlack + Borders.South.Visible = True + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Bottom double' + Hint = 'Double bottom border' + ImageIndex = 34 + end + object AcCellBorderTopBottomThick: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = True + Borders.South.LineStyle = lsMedium + Borders.South.Color = clBlack + Borders.South.Visible = True + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Top & bottom thick' + Hint = 'Top and thick bottom borders' + ImageIndex = 36 + end + object AcCellBorderTopBottomDbl: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = True + Borders.South.LineStyle = lsDouble + Borders.South.Color = clBlack + Borders.South.Visible = True + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Top and double bottom' + Hint = 'Top and double bottom borders' + ImageIndex = 37 + end + object AcCellBorderAllHor: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = True + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = True + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = True + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'All horizontal' + Hint = 'All horizontal borders' + ImageIndex = 39 + end + object AcCellBorderLeft: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = False + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = True + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Left' + Hint = 'Left border' + ImageIndex = 40 + end + object AcCellBorderRight: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = True + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = False + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Right' + Hint = 'Right border' + ImageIndex = 41 + end + object AcCellBorderInnerVert: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = False + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = True + Caption = 'Inner vertical' + Hint = 'Inner vertical border' + ImageIndex = 42 + end + object AcCellBorderAllVert: TsCellBorderAction + Category = 'FPSpreadsheet' + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = True + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = False + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = True + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = True + Caption = 'All vertical' + Hint = 'All vertical borders' + ImageIndex = 43 + end + object AcCellBorderDiagUp: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = False + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = True + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Diagonal up' + Hint = 'Diagonal border, bottom-left to top-right' + ImageIndex = 63 + end + object AcCellBorderDiagDown: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = False + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = False + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = False + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = False + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = True + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'Diagonal down' + Hint = 'Diagonal border, top-left to bottom-right' + ImageIndex = 64 + end + object AcCellBorderAllOuter: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = True + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = True + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = True + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = True + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'All outer (thin)' + Hint = 'All outer borders (thin)' + ImageIndex = 28 + end + object AcCellBorderAllOuterThick: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsMedium + Borders.East.Color = clBlack + Borders.East.Visible = True + Borders.North.LineStyle = lsMedium + Borders.North.Color = clBlack + Borders.North.Visible = True + Borders.South.LineStyle = lsMedium + Borders.South.Color = clBlack + Borders.South.Visible = True + Borders.West.LineStyle = lsMedium + Borders.West.Color = clBlack + Borders.West.Visible = True + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = False + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = False + Caption = 'All outer (thick)' + Hint = 'All outer borders (thick)' + ImageIndex = 27 + end + object AcCellBorderAll: TsCellBorderAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Borders.East.LineStyle = lsThin + Borders.East.Color = clBlack + Borders.East.Visible = True + Borders.North.LineStyle = lsThin + Borders.North.Color = clBlack + Borders.North.Visible = True + Borders.South.LineStyle = lsThin + Borders.South.Color = clBlack + Borders.South.Visible = True + Borders.West.LineStyle = lsThin + Borders.West.Color = clBlack + Borders.West.Visible = True + Borders.DiagonalUp.LineStyle = lsThin + Borders.DiagonalUp.Color = clBlack + Borders.DiagonalUp.Visible = False + Borders.DiagonalDown.LineStyle = lsThin + Borders.DiagonalDown.Color = clBlack + Borders.DiagonalDown.Visible = False + Borders.InnerHor.LineStyle = lsThin + Borders.InnerHor.Color = clBlack + Borders.InnerHor.Visible = True + Borders.InnerVert.LineStyle = lsThin + Borders.InnerVert.Color = clBlack + Borders.InnerVert.Visible = True + Caption = 'All' + Hint = 'All borders (thin)' + ImageIndex = 29 + end + object AcMergeCells: TsMergeAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Merge' + Hint = 'Merge cells' + ImageIndex = 23 + end + object AcCopyFormat: TsCopyAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Copy format' + Hint = 'Copy format' + ImageIndex = 46 + end + object AcCopyToClipboard: TsCopyAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Copy' + CopyMode = cmCopy + ImageIndex = 51 + ShortCut = 16451 + end + object AcCutToClipboard: TsCopyAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Cut' + CopyMode = cmCut + ImageIndex = 52 + ShortCut = 16472 + end + object AcPasteAllFromClipboard: TsCopyAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Paste all' + CopyItem = ciAll + CopyMode = cmPaste + ImageIndex = 53 + ShortCut = 16470 + end + object AcPasteValueFromClipboard: TsCopyAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Paste value' + CopyItem = ciValue + CopyMode = cmPaste + end + object AcPasteFormatFromClipboard: TsCopyAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Paste format' + CopyMode = cmPaste + end + object AcPasteFormulaFromClipboard: TsCopyAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Paste formula' + CopyItem = ciFormula + CopyMode = cmPaste + end + object AcCommentNew: TsCellCommentAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Mode = ccmNew + Caption = 'New comment' + Hint = 'New comment' + ImageIndex = 54 + end + object AcCommentEdit: TsCellCommentAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Mode = ccmEdit + Caption = 'Edit comment...' + Hint = 'Edit comment' + ImageIndex = 56 + end + object AcCommentDelete: TsCellCommentAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Mode = ccmDelete + Caption = 'Delete comment' + Hint = 'Delete comment' + ImageIndex = 55 + end + object AcHyperlinkNew: TsCellHyperlinkAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Mode = chmNew + OnHyperlink = HyperlinkHandler + Caption = 'New hyperlink...' + Hint = 'Add hyperlink to active cell' + ImageIndex = 57 + end + object AcHyperlinkEdit: TsCellHyperlinkAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Mode = chmEdit + OnHyperlink = HyperlinkHandler + Caption = 'Edit hyperlink...' + Hint = 'Edit hyperlink of selected cell' + ImageIndex = 59 + end + object AcHyperlinkDelete: TsCellHyperlinkAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Mode = chmDelete + Caption = 'Delete hyperlink' + Hint = 'Delete hyperlink from selected cell' + ImageIndex = 58 + end + object AcZoom30: TsWorksheetZoomAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '30%' + Hint = 'Zoom factor 30%' + Zoom = 30 + end + object AcZoom50: TsWorksheetZoomAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '50%' + Hint = 'Zoom factor 50%' + Zoom = 50 + end + object AcZoom75: TsWorksheetZoomAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '75%' + Hint = 'Zoom factor 75%' + Zoom = 75 + end + object AcZoom90: TsWorksheetZoomAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '90%' + Hint = 'Zoom factor 90%' + Zoom = 90 + end + object AcZoom100: TsWorksheetZoomAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '100%' + Hint = 'Zoom factor 100%' + end + object AcZoom150: TsWorksheetZoomAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '150%' + Hint = 'Zoom factor 150%' + Zoom = 150 + end + object AcZoom200: TsWorksheetZoomAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '200%' + Hint = 'Zoom factor 200%' + Zoom = 200 + end + object AcZoom300: TsWorksheetZoomAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '300%' + Hint = 'Zoom factor 300%' + Zoom = 300 + end + object AcZoom500: TsWorksheetZoomAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = '500%' + Hint = 'Zoom factor 500%' + Zoom = 500 + end + object AcAutoRowHeights: TAction + Category = 'Edit' + Caption = 'Auto row heights' + Hint = 'Automatic row height adjustment' + OnExecute = AcAutoRowHeightsExecute + end + object AcFileNew: TAction + Category = 'File' + Caption = 'New...' + Hint = 'New spreadsheet' + ImageIndex = 71 + OnExecute = AcFileNewExecute + end + object AcFileOpen: TFileOpen + Category = 'File' + Caption = '&Open ...' + Dialog.Filter = 'All spreadsheet files|*.xls;*.xlsx;*.ods;*.csv|All Excel files (*.xls, *.xlsx)|*.xls;*.xlsx|Excel XML spreadsheets (*.xlsx)|*.xlsx|Excel XP/2003 XML spreadsheets (*.xml)|*.xml|Excel 97-2003 spreadsheets (*.xls)|*.xls|Excel 5 spreadsheets (*.xls)|*.xls|Excel 2.1 spreadsheets (*.xls)|*.xls|LibreOffice/OpenOffice spreadsheets (*.ods)|*.ods|HTML files (*.html; *.htm)|*.html;*.htm|Comma-separated text files (*.csv; *.txt)|*.csv;*.txt' + Dialog.Options = [ofExtensionDifferent, ofFileMustExist, ofEnableSizing, ofViewDetail] + Hint = 'Open spreadsheet file' + ImageIndex = 44 + ShortCut = 16463 + OnAccept = AcFileOpenAccept + end + object AcFileSaveAs: TFileSaveAs + Category = 'File' + Caption = 'Save &as ...' + Dialog.Title = 'AcSaveFileAs' + Dialog.Filter = 'Excel XML spreadsheet (*.xlsx)|*.xlsx|Excel XP/2003 XML spreadsheets (*.xml)|*.xml|Excel 97-2003 spreadsheets (*.xls)|*.xls|Excel 5 spreadsheet (*.xls)|*.xls|Excel 2.1 spreadsheets (*.xls)|*.xls|LibreOffice/OpenOffice spreadsheet (*.ods)|*.ods|Comma-delimited files (*.csv)|*.csv|HTML files (*.html; *.htm)|*.html;*.htm|WikiTable (WikiMedia-Format, *.wikitable_wikimedia)|*.wikitable_wikimedia' + Dialog.OnTypeChange = TSaveDialogTypeChange + Hint = 'Save spreadsheet' + ImageIndex = 45 + BeforeExecute = AcFileSaveAsBeforeExecute + OnAccept = AcFileSaveAsAccept + end + object AcFileExit: TFileExit + Category = 'File' + Caption = 'E&xit' + Hint = 'Exit' + ImageIndex = 0 + ShortCut = 32856 + end + object AcAbout: TAction + Category = 'Help' + Caption = 'About Spready...' + Hint = 'About this program' + ImageIndex = 72 + OnExecute = AcAboutExecute + end + object AcSort: TAction + Category = 'Edit' + Caption = 'Sort...' + Hint = 'Sort selected range' + OnExecute = AcSortExecute + end + object AcSortColAsc: TAction + Category = 'Edit' + Caption = 'Sort column only (ascending)' + Hint = 'Sort current column in ascending order' + OnExecute = AcSortColAscExecute + end + object AcRowHeight: TAction + Category = 'Edit' + Caption = 'Row height...' + Hint = 'Set height of current row' + OnExecute = AcRowHeightExecute + end + object AcColWidth: TAction + Category = 'Edit' + Caption = 'Column width...' + Hint = 'Set width of current column' + OnExecute = AcColWidthExecute + end + end + object ImageList: TImageList + left = 176 + top = 312 + Bitmap = { + 4C69490000001000000010000000003F9300003F9300003F9300003F9424003F + 948A003E93CC004095CC004095CC004095CC004095CC004095CC004095CC0040 + 95CC004095CC00409599003F9400003F9300003F9324003F938A0E4B9CD33F76 + C0EC5D90D4FF3365A9FFA0A0A0FFA9A9A9FFA9A9A9FFAAAAAAFFACACACFFAEAE + AEFFB0B0B0FF003E93CC003E9300003F938A0E4A9CD33E75BFEC5487CBFF3669 + ADFF23569AFF3363A6FFA9A9A9FFBCBCBCFFBDBDBDFFBFBFBFFFC1C1C1FFC4C4 + C4FFC7C7C7FF003C90CC003C9000003D91CC5D90D4FF3568ACFF285B9FFF1A4D + 91FF4477BBFF3361A4FFA9A9A9FFBDBDBDFFBFBFBFFFC1C1C1FFC4C4C4FFC7C7 + C7FFC9C9C9FF003A8DCC003A8D00003B8ECC588BCFFF1A4D91FF4376BAFF3265 + A9FF4376BAFF335FA1FFAAAAAAFFBFBFBFFFC1C1C1FFC4C4C4FFB1B1B1FFBBBB + BBFFCCCCCCFF003789CC0037890000398BCC5588CCFF275A9EFF4174B8FF3164 + A8FF4174B8FF335D9EFFACACACFFC1C1C1FFC4C4C4FFC7C7C7FFA8A8A8FFA8A8 + A8FFBEBEBEFF003485CC00348500003688CC5386CAFF295CA0FF3F72B6FF3063 + A7FF3F72B6FF335A9AFFAEAEAEFFACACACFFA5A5A5FFA5A5A5FFA5A5A5FFFDFD + FDFFA5A5A5FF122F609510295100003485CC5083C7FF1D5094FF3265A9FF2D60 + A4FF3D70B4FF335897FFB0B0B0FFA2A2A2FFF2F2F2FFF2F2F2FFF2F2F2FFF2F2 + F2FFF2F2F2FF1A1A1A661A1A1A1A003181CC4C7FC3FFBBBBBBFF22518CFF2C5F + A3FF3B6EB2FF335593FFB3B3B3FFAAAAAAFFA0A0A0FFA0A0A0FFA0A0A0FFE4E4 + E4FFA0A0A0FF051E4D950B204600002E7DCC497CC0FF09336FFF215090FF2B5E + A2FF396CB0FF335290FFB5B5B5FFCCCCCCFFD0D0D0FFD3D3D3FF9D9D9DFF9D9D + 9DFFBFBFBFFF002774CC00277400002B79CC477ABEFF2C5FA3FF376AAEFF2B5E + A2FF376AAEFF33508CFFB8B8B8FFD0D0D0FFD3D3D3FFD5D5D5FFAAAAAAFFBEBE + BEFFDCDCDCFF00246FCC00246F00002875CC4477BBFF2C5FA3FF3568ACFF2B5E + A2FF2E61A5FF334B87FFBBBBBBFFD3D3D3FFD5D5D5FFD8D8D8FFDBDBDBFFDCDC + DCFFDDDDDDFF001F68CC001F6800002571CC4174B8FF2C5FA3FF2D60A4FF2356 + 9AFF3D70B4FF334179FFBEBEBEFFD5D5D5FFD8D8D8FFDBDBDBFFDCDCDCFFDDDD + DDFFDDDDDDFF001258CC0012580000226DCC3F72B6FF225599FF3B6EB2FF2C51 + 96EC0A1C60D3000749A4000648CC000648CC000648CC000648CC000648CC0006 + 48CC000648CC00074A9900084B00001B64CC4174B8FF2A5094EC0A1A5ED30008 + 4A8A000648240006470000044500000445000004450000044500000445000004 + 4500000445000006480000084B0000105500000B4FCC0007498A000546240005 + 4700000648000006470000044500000445000004450000044500000445000004 + 4500000445000006480000084B007E7E7E007E7E7E007F7F7F00808080008080 + 800080808000808080008080800080808000129D000014A8000015A9009915A9 + 00CC15A9009914A80000129D00007E7E7E007E7E7E007F7F7F00808080008080 + 800080808000808080008080800080808000129D000013A1000014A400CC75EE + 64FF14A400CC13A10000129D00007E7E7E007E7E7E007F7F7F00808080008080 + 800080808000808080008080800080808000129C0099129D00CC129D00CC66EB + 55FF129D00CC129D00CC129C00997E7E7E007E7E7E007F7F7F227F7F7F597F7F + 7F667F7F7F667F7F7F667F7F7F667F7F7F661A930CE052E741FF52E741FF52E7 + 41FF52E741FF52E741FF109500CC7A7A7A007A7A7A007A7A7A5AE9E9E9D3FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6EBB66FF3EA333FF3EA333FF3DE2 + 2CFF178B0BDF0E8C00CC0E8D0099727272007272720072727268FCFCFCFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFF3C9B32FF2BDF + 1AFF16810BE10F8703000E8C00006A6A6A006A6A6A006A6A6A6AF8F8F8FFF6F6 + F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FF66A362FF3686 + 32FF266B22C43C6C39003B7A340058585800616161006161616BF4F4F4FFF0F0 + F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF4F4 + F4FF6161616B61616100585858004C4C4C00515151005656566CEFEFEFFFEAEA + EAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEFEF + EFFF5656566C515151004C4C4C004B4B4B534C4C4C6E4C4C4C6EEBEBEBFFE4E4 + E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFEBEB + EBFF4C4C4C6E4C4C4C6E4B4B4B533C3C3C70F0F0F0FFF0F0F0FFECECECFFE8E8 + E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFECEC + ECFFF0F0F0FFF0F0F0FF3C3C3C701B1B1B581717177517171775171717751717 + 1775171717751717177517171775171717751717177517171775171717751717 + 177517171775171717751B1B1B58FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF007E7E7E007E7E7E007F7F7F00808080008080 + 8000808080008080800080808000808080000000A6990000A7CC0000A7CC0000 + A7CC0000A7CC0000A7CC0000A6997E7E7E007E7E7E007F7F7F227F7F7F597F7F + 7F667F7F7F667F7F7F667F7F7F667F7F7F660C0C95E05E5EF7FF5E5EF7FF5E5E + F7FF5E5EF7FF5E5EF7FF000098CC7A7A7A007A7A7A007A7A7A5AE9E9E9D3FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6666B4FF333399FF333399FF2828 + 92F60B0B7FDF000080CC00008499727272007272720072727268FCFCFCFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFCFC + FCFF727272681C1C7600000080006A6A6A006A6A6A006A6A6A6AF8F8F8FFF6F6 + F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF6F6F6FFF8F8 + F8FF6A6A6A6A6A6A6A003434740058585800616161006161616BF4F4F4FFF0F0 + F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FFF4F4 + F4FF6161616B61616100585858004C4C4C00515151005656566CEFEFEFFFEAEA + EAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEAEAEAFFEFEF + EFFF5656566C515151004C4C4C004B4B4B534C4C4C6E4C4C4C6EEBEBEBFFE4E4 + E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFEBEB + EBFF4C4C4C6E4C4C4C6E4B4B4B533C3C3C70F0F0F0FFF0F0F0FFECECECFFE8E8 + E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFECEC + ECFFF0F0F0FFF0F0F0FF3C3C3C701B1B1B581717177517171775171717751717 + 1775171717751717177517171775171717751717177517171775171717751717 + 177517171775171717751B1B1B58FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF007E7E7E007E7E7E007F7F7F00808080008080 + 800080808000808080008080800080808000808080006E85890001A3BB005555 + 55002B2B9D390101DEAF0101C6407E7E7E007E7E7E007F7F7F00808080008080 + 800080808000808080008080800080808000808080006E85890001A3BB005454 + 542438386F7C8080FFFF0101B1C17E7E7E007E7E7E007F7F7F00808080008080 + 800080808000808080008080800080808000808080006E85890001A2BA3F4A4A + 4A6CF7F7F7FF1A1A468E00009F467E7E7E007E7E7E007F7F7F227F7F7F597F7F + 7F667F7F7F667F7F7F667F7F7F667F7F7F667F7F7F66538B948C1494A9D379E6 + F7FF2D2D2D8F1212122E00009C007A7A7A007A7A7A007A7A7A5AE9E9E9D3FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1E8EEFF4BB6C7FF79E6F7FF3496 + A8F44D6F7681444444003C3C8A00727272007272720072727268FCFCFCFFFBFB + FBFFFBFBFBFFFBFBFBFFFBFBFBFFBFE5EBFF4AB4C5FF79E6F7FF419EAFFFB9D8 + DEFF7272726872727200727272006A6A6A006A6A6A006A6A6A6AF8F8F8FFF6F6 + F6FFF6F6F6FFF6F6F6FFD2E4EAFF49B3C4FF79E6F7FF3F9DADFFB5D4DAFFF8F8 + F8FF6A6A6A6A6A6A6A006A6A6A0058585800616161006161616BF4F4F4FFF0F0 + F0FFF0F0F0FFF0F0F0FF79AFC1FFD9F4FFFF3E9BACFFB0CFD5FFF0F0F0FFF4F4 + F4FF6161616B61616100585858004C4C4C00515151005656566CEFEFEFFFEAEA + EAFFEAEAEAFFEAEAEAFF000000FF4F8393FFB2C6CCFFEAEAEAFFEAEAEAFFEFEF + EFFF5656566C515151004C4C4C004B4B4B534C4C4C6E4C4C4C6EEBEBEBFFE4E4 + E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFE4E4E4FFEBEB + EBFF4C4C4C6E4C4C4C6E4B4B4B533C3C3C70F0F0F0FFF0F0F0FFECECECFFE8E8 + E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFE8E8E8FFECEC + ECFFF0F0F0FFF0F0F0FF3C3C3C701B1B1B581717177517171775171717751717 + 1775171717751717177517171775171717751717177517171775171717751717 + 177517171775171717751B1B1B58FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00777777607777 + 77CF747474FF707070EF6B6B6B7F656565AF606060EF5959599F53535310FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007373 + 737F696969FF6A6A6ABFFFFFFF00FFFFFF005858589F545454FF4A4A4ACFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006D6D + 6D7F656565FF636363BFFFFFFF00FFFFFF004F4F4F7F4E4E4EFF414141FFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006767 + 677F5F5F5FFF5B5B5BBFFFFFFF004D4D4D10464646DF464646FF3838389FFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006060 + 607F595959FF535353DF4C4C4C7F454545CF444444FF363636BFFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF005858 + 587F535353FF4A4A4ABFFFFFFF00FFFFFF003434349F383838FF262626CF1F1F + 1F10FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004F4F + 4F7F4D4D4DFF414141BFFFFFFF00FFFFFF002B2B2B10262626FF2D2D2DFF1717 + 1770FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004646 + 467F464646FF383838BFFFFFFF00FFFFFF00FFFFFF001C1C1CFF292929FF1010 + 107FFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003D3D + 3D7F404040FF2F2F2FCFFFFFFF00FFFFFF001B1B1B70242424FF0F0F0FEF0A0A + 0A20FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003C3C3C603434 + 34AF2D2D2DBF262626BF1F1F1F8F1919198F131313BF0D0D0D8F09090920FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF006B6B6B80656565F0606060FF595959F0535353C0FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF005E5E5EE0595959FF51515160FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF005C5C5C30575757FF4F4F4FF0FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0054545490525252FF464646A0FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF004C4C4CE0494949FF3D3D3D50FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF004A4A4A30454545FF3C3C3CF0FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0041414190444444FF323232A0FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00383838E0383838FF2A2A2A50FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0036363640353535FF282828FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003434 + 34802D2D2DC0262626C01F1F1FC0191919B0FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00777777607777 + 77EF777777FF7575758FFFFFFF00FFFFFF00FFFFFF00616161AF5B5B5BFF5454 + 5470FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007777 + 77BF747474FFFFFFFF00FFFFFF00FFFFFF00FFFFFF0059595910535353CFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007373 + 73BF6E6E6EFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004A4A4ABFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006D6D + 6DBF686868FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00414141BFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006767 + 67BF616161FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00383838BFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006060 + 60BF595959FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF002F2F2FBFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF005858 + 58BF515151FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00262626BFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004F4F + 4F8F4B4B4BFF41414150FFFFFF00FFFFFF00FFFFFF00242424401E1E1E8FFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004646 + 46203F3F3FEF383838CF31313120FFFFFF00232323401C1C1CCF16161620FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00363636202F2F2F9F282828BF212121BF1B1B1B8F14141430FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF002B2B + 2BFF242424FF1E1E1EFF171717FF121212FF0C0C0CFF070707FF030303FFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0074747411707070996B6B6B666565657760606099595959BBFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF006E6E6EEE6A6A6A77FFFFFF00FFFFFF0058585877515151FFFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006D6D + 6D66666666FF63636388FFFFFF00FFFFFF00FFFFFF00484848BBFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006767 + 6744606060FF5B5B5BFF545454994D4D4D33FFFFFF003F3F3F44FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00595959BB555555FF515151FF484848FF3D3D3DCC36363644FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0077777775777777FF777777FF7777 + 77FF777777FF777777FF5F5F5FFF3C3C3CFF181818FF000000FF000000FF0000 + 00FF000000FF00000074FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004F4F + 4F11FFFFFF00FFFFFF00FFFFFF00323232662B2B2BDD323232FF1E1E1ECCFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004646 + 46663F3F3F77FFFFFF00FFFFFF00FFFFFF00FFFFFF001C1C1CFF161616DDFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003D3D + 3D66373737FF2F2F2F11FFFFFF00FFFFFF00FFFFFF00141414EE0F0F0F77FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003434 + 34662D2D2DEE262626CC1F1F1F7719191966131313770D0D0D88FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00767676FF747474FF7070 + 70FF6C6C6CFF686868FF636363FF5E5E5EFF595959FF535353FF4E4E4EFF4848 + 48FF424242FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006F6F6FFF6B6B6BFF6666 + 66FF616161FF5C5C5CFF575757FF515151FF4B4B4BFF454545FFFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00646464FF5F5F5FFF5A5A + 5AFF545454FF4F4F4FFF494949FF434343FF3D3D3DFF373737FF313131FF2B2B + 2BFF252525FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00585858FF525252FF4C4C + 4CFF464646FF404040FF3A3A3AFF343434FF2E2E2EFF282828FFFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004A4A4AFF444444FF3E3E + 3EFF383838FF323232FF2C2C2CFF262626FF202020FF1B1B1BFF161616FF1111 + 11FF0C0C0CFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003C3C3CFF353535FF2F2F + 2FFF292929FF242424FF1E1E1EFF191919FF141414FF0F0F0FFFFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00767676FF747474FF7070 + 70FF6C6C6CFF686868FF636363FF5E5E5EFF595959FF535353FF4E4E4EFF4848 + 48FF424242FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006B6B6B6B6666 + 66FF616161FF5C5C5CFF575757FF515151FF4B4B4BFF454545FF3F3F3FFF3939 + 396BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00646464FF5F5F5FFF5A5A + 5AFF545454FF4F4F4FFF494949FF434343FF3D3D3DFF373737FF313131FF2B2B + 2BFF252525FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF005252526B4C4C + 4CFF464646FF404040FF3A3A3AFF343434FF2E2E2EFF282828FF232323FF1D1D + 1D6BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004A4A4AFF444444FF3E3E + 3EFF383838FF323232FF2C2C2CFF262626FF202020FF1B1B1BFF161616FF1111 + 11FF0C0C0CFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003535356B2F2F + 2FFF292929FF242424FF1E1E1EFF191919FF141414FF0F0F0FFF0B0B0BFF0707 + 076BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00767676FF747474FF7070 + 70FF6C6C6CFF686868FF636363FF5E5E5EFF595959FF535353FF4E4E4EFF4848 + 48FF424242FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00616161FF5C5C5CFF575757FF515151FF4B4B4BFF454545FF3F3F3FFF3939 + 39FF333333FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00646464FF5F5F5FFF5A5A + 5AFF545454FF4F4F4FFF494949FF434343FF3D3D3DFF373737FF313131FF2B2B + 2BFF252525FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00464646FF404040FF3A3A3AFF343434FF2E2E2EFF282828FF232323FF1D1D + 1DFF181818FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004A4A4AFF444444FF3E3E + 3EFF383838FF323232FF2C2C2CFF262626FF202020FF1B1B1BFF161616FF1111 + 11FF0C0C0CFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00292929FF242424FF1E1E1EFF191919FF141414FF0F0F0FFF0B0B0BFF0707 + 07FF030303FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00757575FF737373FF6F6F + 6FFF6B6B6BFF676767FF626262FF5D5D5DFF585858FF525252FF4D4D4DFF4747 + 47FF414141FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006E6E6EFF6A6A6AFF6565 + 65FF606060FF5B5B5BFF565656FF505050FF4A4A4AFF444444FF3E3E3EFF3838 + 38FF323232FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00636363005E5E5E005959 + 5900535353004E4E4E0048484800424242003C3C3C0036363600303030002A2A + 2A0024242400FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0057575700515151004B4B + 4B00454545003F3F3F0039393900333333002D2D2D0027272700222222001C1C + 1C0017171700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0049494900434343003D3D + 3D0037373700313131002B2B2B00252525001F1F1F001A1A1A00151515001111 + 11000C0C0C00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003B3B3B00343434002E2E + 2E0028282800232323001D1D1D0018181800131313000F0F0F000B0B0B000707 + 070003030300FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0075757500737373006F6F + 6F006B6B6B0067676700626262005D5D5D0058585800525252004D4D4D004747 + 470041414100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006E6E6E006A6A6A006565 + 6500606060005B5B5B0056565600505050004A4A4A00444444003E3E3E003838 + 380032323200FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00636363FF5E5E5EFF5959 + 59FF535353FF4E4E4EFF484848FF424242FF3C3C3CFF363636FF303030FF2A2A + 2AFF242424FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00575757FF515151FF4B4B + 4BFF454545FF3F3F3FFF393939FF333333FF2D2D2DFF272727FF222222FF1C1C + 1CFF171717FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0049494900434343003D3D + 3D0037373700313131002B2B2B00252525001F1F1F001A1A1A00151515001111 + 11000C0C0C00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003B3B3B00343434002E2E + 2E0028282800232323001D1D1D0018181800131313000F0F0F000B0B0B000707 + 070003030300FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0075757500737373006F6F + 6F006B6B6B0067676700626262005D5D5D0058585800525252004D4D4D004747 + 470041414100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006E6E6E006A6A6A006565 + 6500606060005B5B5B0056565600505050004A4A4A00444444003E3E3E003838 + 380032323200FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00636363005E5E5E005959 + 5900535353004E4E4E0048484800424242003C3C3C0036363600303030002A2A + 2A0024242400FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0057575700515151004B4B + 4B00454545003F3F3F0039393900333333002D2D2D0027272700222222001C1C + 1C0017171700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00494949FF434343FF3D3D + 3DFF373737FF313131FF2B2B2BFF252525FF1F1F1FFF1A1A1AFF151515FF1111 + 11FF0C0C0CFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003B3B3BFF343434FF2E2E + 2EFF282828FF232323FF1D1D1DFF181818FF131313FF0F0F0FFF0B0B0BFF0707 + 07FF030303FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00D8874040D88B4385DA8E4994D989438FD8844090D884419AD373 + 3A8ACC62320DC95B2E01FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00D7833E53E2A76CDEE9BC91FFE7BA8FFFE7B78BFFE2A471FBD67E + 42B6CB5C2F0AFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00D67D3B1CDD9656BAE3A973F2E1A873F5E1A471F7D3773E98CB5F + 3008FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00D4793C77E2A670F7DA8847ADD67E43A0E4AE82FFCF6D3A99FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00D1713822DE9B63E2DC965EDFCF693554CF693580E2A97CFFD16C3AA5FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00D06A + 3503D78042AADF9F6AF7CD663466C95D2F0ACC613388E1A679FFD57A44D2C24A + 2706FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CF6A + 365CDF9D68F6DA8B52D1CB5F314EC7592E2ACD6737A0E1A67AFFD88653F2BF46 + 250DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CC633215DB93 + 5EEAE2A779FFD8834AD3CF6A3AB2CE6839B5D57A45D8E3A881FFD98656F9BE41 + 231BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CB5D3001D3743F9BE2A9 + 7CFFCC663799FFFFFF00FFFFFF00FFFFFF00CC6337B1DFA077FFDA895AFFBB3E + 2222FFFFFF00FFFFFF00FFFFFF00FFFFFF00CA5C2F0ACB5F3044E1A475FFDA8C + 58ECC6522C3DFFFFFF00FFFFFF00BF452413C348277FDC966BFFDB8F60FFBD3F + 2154B6381E02FFFFFF00FFFFFF00FFFFFF00CE6838AEDA8F5DFEDB9060FFD783 + 50EDC4502B8DBD422310BC3F222AC34D2BA2D07142EAD67E51FFD57C4DFFC655 + 31BDB6391D31FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101000101 + 0100010101000101012B010101AC0101012B010101000101012B010101AC0101 + 012BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101000101 + 01000101010001010160010101A6010101000101010001010160010101A60101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101000101 + 010001010100010101A9010101620101010001010100010101A9010101620101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000101012E0101 + 01B5010101B5010101B5010101B5010101B5010101B5010101B5010101B50101 + 01B5FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101000101 + 010001010166010101B1010101000101010001010166010101B1010101000101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101000101 + 0100010101B5010101690101010001010100010101B501010169010101000101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101C30101 + 01C3010101C3010101C3010101C3010101C3010101C3010101C3010101C30101 + 0131FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101000101 + 016F010101BE01010100010101000101016F010101BE01010100010101000101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101000101 + 01C7010101730101010001010100010101C70101017301010100010101000101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000003A0000 + 00E400000039000000000000003A000000E40000003900000000010101000101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101560101 + 01AC010101560101010001010100010101410101019601010100010101000101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000101012C010101AF0101 + 0100010101AF0101012C010101000101019A0101014201010100010101000101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000101012D010101B40101 + 0100010101B40101012D010101440101019D0101010001010100010101000101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101000101015D0101 + 01B90101015D01010100010101A2010101460101010001010100010101000101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 01000101010001010148010101A70101010001010160010101BF010101600101 + 0100FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 010001010100010101AD0101014A01010132010101C501010100010101C50101 + 0132FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 01000101014E010101B30101010001010133010101CC01010100010101CC0101 + 0133FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000 + 0000000000C600000054000000000000000000000070000000E1000000700000 + 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF001FD1F9241ECFF8E41ECEF7FC1CCCF6FF1CCAF5F81BC8F4CE1BC6F44FFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF001ECFF7F3A2E7FBFFD3F6FFFFC7F4FFFFBBF1FFFFA2E9FBFF1AC3F2DCFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF001CCCF6FFD6F7FFFFBCEFFFFFABEBFFFF9AE6FFFFA7EDFDFF18BFF0FFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF001CC9F4FFBAF0FDFFAAEAFEFFA2E9FEFF79DDFBFF7BDFFBFF17BBEDFFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF001BC6F3FF87E2FAFF40CBF5FF34C4F3FF25BAF1FF5CCDF6FF17B7EBFFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0019C3F1FFA2E9FCFF69D9FAFF51D2F9FF3EC9F7FF5ACCF5FF15B3E8FFFFFF + FF00FFFFFF00FFFFFF00FFFFFF001ECEF80E1DCCF7E41BCAF6FC1BC8F5FF1AC5 + F4F81AC2F2FF79DCF8FF3CC7F4FF30BFF3FF23B5F0FF6CD7F9FF14AFE5FFFFFF + FF00FFFFFF00FFFFFF00FFFFFF001CCBF68891E1FAFFDFF8FFFFD7F7FFFFCCF4 + FFFFA9E9FAFF2AC2F0FF64D6F9FF4CCFF8FF3BC6F6FF68D6F9FF14AAE2FFFFFF + FF00FFFFFF00FFFFFF00FFFFFF001BC8F4FFDAF7FEFFD1F4FFFFC3F1FFFFB7EE + FFFFBFF2FEFF17B7EBFF3AC4F3FF2DBBF2FF20B0EFFF51C7F4FF12A5DFFFFFFF + FF00FFFFFF00FFFFFF00FFFFFF001BC4F1FFCFF5FEFFC3F0FEFFBDEFFEFFA2E7 + FCFF99E8FCFF15B3E7FF5ED3F9FF48CCF8FF36C2F5FF61D3F8FF12A1DCFFFFFF + FF00FFFFFF00FFFFFF00FFFFFF0019C0EFFFAAEAFBFF78DAF8FF61D4F6FF44CD + F5FF66DBF8FF14ADE4FF36C1F2FF2BB7F1FF1AB1F2FF1BB7F4FF14B3F1FF13AF + F0FF13ACEDF811A8EACE11A5E84F18BBECFFBDEFFCFF99E3FBFF89DFFAFF74D9 + F9FF63DAF8FF13A8E0FF5BD2F9FF44C9F7FF16B5F1FFC2F0FDFFCEF4FFFFC6F4 + FFFFB8EFFEFF89E0F6FF109EE2DC16B7E9FFBFF1FDFF74D9F7FF5BD1F6FF44CB + F5FF8EE6FCFF12A2DCFF47C7F4FF2EB6F1FF13AFEEFFD6F7FFFFBDEFFFFFABEB + FFFF9FE7FFFFAEF0FEFF0F98DCFF16B2E6A98EDDF4FF9EE6FCFF85DEFAFF7BDD + FAFF6CD3F2FF24A9DFFF61D1F1FF72DEF9FF2CB6ECFF7EDAF5FFB5EEFEFFA7EB + FEFF8FE3FBFF58CFF1FF0E91D6A914ADE2705FCBEDFF8AE0F6FF88E3F9FF6FDA + F4FF47C1E6FF1099D5BC1097D4CC0F93D3F91099D9E24AC3ECFF72DAF5FF71DE + F7FF57D3F3FF39B8E5FF0D8AD17013A8DE0013A4DC8711A1DACC119ED7F9119A + D5CC1097D3871094D121FFFFFF00FFFFFF00109CDE210F98DA870E93D7CC0E8F + D4F90D8BD1CC0D89CE870D85CC21FFFFFF000101E4000101AC00000000370000 + 005F000000370101AC000101E5000101E5000101AC00000000370000005F0000 + 00370101AC000101E400FFFFFF00FFFFFF000101E4820101E4AC000095CCD6D6 + D6FF000095CC0101E4AC0101E4AC0101E4AC0101E4AC000095CCD6D6D6FF0000 + 95CC0101E4AC0101E482FFFFFF00FFFFFF000101DDB28383FFFF3D3DD5FFB1B1 + B1FF3D3DD5FF7E7EFFFF7E7EFFFF7E7EFFFF7E7EFFFF3D3DD5FFB1B1B1FF3D3D + D5FF8383FFFF0101DDB2FFFFFF00FFFFFF000101D5B97777FDFF2F2FC1FF1111 + 88FF2F2FC1FF6E6EFBFF6E6EFBFF6E6EFBFF6E6EFBFF2F2FC1FF111188FF2F2F + C1FF7777FDFF0101D5B9FFFFFF00FFFFFF000000CBC26D6DFBFFD7D7FBFFA1A1 + ECFFA8A8F1FFC4C4E8FF6464F5FF6464F5FF6464F5FF5C5CEFFF4E4EE4FF5C5C + EFFF6D6DFBFF0000CBC2FFFFFF00FFFFFF000000C3C96363F8FF4646DEFF5050 + E7FF5050E7FF4646DEFF5A5AF0FF5A5AF0FF5A5AF0FF5A5AF0FF5A5AF0FF5A5A + F0FF6363F8FF0000C3C9FFFFFF00FFFFFF0000002872FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF00002872FFFFFF00FFFFFF0000002775FEFEFDFFFDFDFBFFFDFD + FBFFFDFDFBFFFDFDFBFFFDFDFBFFFDFDFBFFFDFDFBFFFDFDFBFFFDFDFBFFFDFD + FBFFFEFEFDFF00002775FFFFFF00FFFFFF0000002678FDFDF9FFFAFAF7FFFAFA + F7FFFAFAF7FFFAFAF7FFFAFAF7FFFAFAF7FFFAFAF7FFFAFAF7FFFAFAF7FFFAFA + F7FFFDFDF9FF00002678FFFFFF00FFFFFF000000267BFBFBF5FFF7F7F1FFF7F7 + F1FFF7F7F1FFF7F7F1FFF7F7F1FFF7F7F1FFF7F7F1FFF7F7F1FFF7F7F1FFF7F7 + F1FFFBFBF5FF0000267BFFFFFF00FFFFFF000000257FFAFAF1FFF3F3EBFFF3F3 + EBFFF3F3EBFFF3F3EBFFF3F3EBFFF3F3EBFFF3F3EBFFF3F3EBFFF3F3EBFFF3F3 + EBFFFAFAF1FF0000257FFFFFFF00FFFFFF0000002482F8F8EDFFEFEFE6FFEFEF + E6FFEFEFE6FFEFEFE6FFEFEFE6FFEFEFE6FFEFEFE6FFEFEFE6FFEFEFE6FFEFEF + E6FFF8F8EDFF00002482FFFFFF00FFFFFF0000002386F6F6E9FFECECE0FFECEC + E0FFECECE0FFECECE0FFECECE0FFECECE0FFECECE0FFECECE0FFECECE0FFECEC + E0FFF6F6E9FF00002386FFFFFF00FFFFFF000101228DF5F5E6FFE9E9DAFFE9E9 + DAFFE9E9DAFFE9E9DAFFE9E9DAFFE9E9DAFFE9E9DAFFE9E9DAFFE9E9DAFFE9E9 + DAFFF5F5E6FF0101228DFFFFFF00FFFFFF0001011F9AF9F9E9FFF3F3E3FFF3F3 + E3FFF3F3E3FFF3F3E3FFF3F3E3FFF3F3E3FFF3F3E3FFF3F3E3FFF3F3E3FFF3F3 + E3FFF9F9E9FF01011F9AFFFFFF00FFFFFF0001011D7C01011DA501011DA50101 + 1DA501011DA501011DA501011DA501011DA501011DA501011DA501011DA50101 + 1DA501011DA501011D7CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF004E4E4E0050505000535353005454 + 540D5555553755555553555555625555556255555553555555375454540D5353 + 5300505050004E4E4E00FFFFFF00FFFFFF004E4E4E0050505000535353286262 + 60699F9F96AAD7D7CCDFECECE5F8ECECE5F8D7D7CCDF9F9F96AA626260695353 + 5328505050004E4E4E00FFFFFF00FFFFFF004E4E4E005050502868686578CECE + BFE3E7E7DBFFF1F1EBFFC1C1BEFFF1F1EBFFF1F1EBFFE7E7DBFFCECEBFE36969 + 6678505050284E4E4E00FFFFFF00FFFFFF004D4D4D0E5D5D5B6CCDCDBFE3E0E0 + D0FFF0F0E9FFF1F1EBFF8C8C8CFFF1F1EBFFF1F1EBFFF0F0E9FFE0E0D0FFCFCF + C2E35E5E5C6C4D4D4D0EFFFFFF00FFFFFF004A4A4A3A9A9A90ACDDDDCCFFE6E6 + DAFFF1F1EBFFF1F1EBFF848484FFF1F1EBFFF1F1EBFFF1F1EBFFE6E6DAFFDFDF + CEFF9D9D96AC4A4A4A3AFFFFFF00FFFFFF004646465ACBCBBDE1DDDDCCFFDDDD + CCFFDDDDCCFFDDDDCCFF5C5C5CFFDDDDCCFFDDDDCCFFDDDDCCFFDDDDCCFFDDDD + CCFFD2D2C7E14646465AFFFFFF00FFFFFF004242426BDBDBCCF8DDDDCCFFDDDD + CCFFF1F1EBFFF1F1EBFF4F4F4FFFF1F1EBFFF1F1EBFFF1F1EBFFEFEFE7FFDDDD + CCFFE2E2D6F84242426BFFFFFF00FFFFFF003E3E3E6DDDDDCEF8DDDDCCFFF1F1 + EBFFF1F1EBFF353535FF777777FF484848FF555555FF626262FF6E6E6EFFA9A9 + A0FFE5E5D9F83E3E3E6DFFFFFF00FFFFFF003A3A3A5ECECEC2E2DDDDCCFFF1F1 + EBFFF1F1EBFFDFDFDCFF383838FFDFDFDCFFDFDFDCFFDFDFDCFFDFDFDBFFD9D9 + CCFFD7D7CFE23A3A3A5EFFFFFF00FFFFFF003535353F94948EB3E0E0D0FFEFEF + E7FFF1F1EBFFF1F1EBFFDFDFDCFFF1F1EBFFF1F1EBFFF1F1EBFFEFEFE7FFE2E2 + D3FF9B9B99B33535353FFFFFFF00FFFFFF003232321044444377D4D4CAE6EDED + E4FFF1F1EBFFF1F1EBFFF1F1EBFFF1F1EBFFF1F1EBFFF1F1EBFFEDEDE5FFDADA + D5E64545457732323210FFFFFF00FFFFFF00303030002C2C2C2F4B4B4A89DADA + D5E6F3F3EEFFF1F1EBFFF1F1EBFFF1F1EBFFF1F1EBFFF3F3EEFFDEDEDBE64C4C + 4C892C2C2C2F30303000FFFFFF00FFFFFF00303030002A2A2A001C1C1C322F2F + 2F818D8D8CBBD9D9D7E6F3F3EFF9F3F3F0F9DADAD8E68E8E8EBB303030811C1C + 1C322A2A2A0030303000FFFFFF00FFFFFF00303030002A2A2A001A1A1A000F0F + 0F120C0C0C4A0C0C0C720C0C0C860C0C0C860C0C0C720C0C0C4A0F0F0F121A1A + 1A002A2A2A0030303000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 01000101013E010101AF010101B00101013E010101000101013F010101B40101 + 01B601010140FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 0112010101AF0101012C01010135010101B301010112010101B50101012E0101 + 0138010101B9FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 0112010101B10101010001010112010101B401010112010101B7010101000101 + 0113010101BBFFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 0112010101B20101010001010112010101B601010113010101B9010101000101 + 0113010101BEFFFFFF00FFFFFF00FFFFFF00FFFFFF00010101B1010101590101 + 0112010101B40101012E01010137010101B801010113010101BB0101012F0101 + 013A010101C0FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101B20101015A0101 + 010001010140010101B8010101B9010101410101010001010143010101BF0101 + 01C101010144FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101002C120A00AF45 + 230033150D000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F00B9543200AF45 + 2300D4573500A8462D0039181000010101000101010001010145010101C60101 + 01C801010147FFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F00BC573500AF45 + 23FFD4573540DF5D3B00702F1E000101010001010114010101C7010101320101 + 013D010101CDFFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815FFFBE5A38FFAF45 + 23E0D45735FFDF5D3B00391810000101010001010114010101CA010101000000 + 0015000000D5FFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F00BC573500AF45 + 23FFD457354039181000010101000101010001010115010101CC010101000000 + 0016000000DEFFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F00B9543200AF45 + 23009D40270001010100010101CA0101016600000015000000D5000000370000 + 0045000000E6FFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F00B9543200AF45 + 230033150D0001010100010101CC00000068000000000000004E000000E40000 + 00E900000053FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F00BE5A3800B34B + 2900D4573500DF5D3B00702F1E0001010100010101000101013F010101B40101 + 01B601010140FFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F40BE5A38FFB148 + 2600D4573500DF5D3B00702F1E000101010001010112010101B50101012E0101 + 0138010101B9FFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815FFFBE5A38E0AF45 + 23FFD45735FFDF5D3B00391810000101010001010112010101B7010101000101 + 0113010101BBFFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F40BE5A38FFB148 + 2600D457350039181000010101000101010001010113010101B9010101000101 + 0113010101BEFFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F00BE5A3800B34B + 29009D40270001010100010101B70101015C01010113010101BB0101012F0101 + 013A010101C0FFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F00BE5A3800873A + 21000101010001010100010101B90101015D0101010001010143010101BF0101 + 01C101010144FFFFFF00FFFFFF00FFFFFF00FFFFFF00E7815F00BE5A38002E15 + 0D00010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 010001010143010101BE010101C0010101440101010001010145010101C60101 + 01C801010147FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 0113010101BF010101300101013B010101C401010114010101C7010101320101 + 013D010101CDFFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 0113010101C10101010001010114010101C601010114010101CA010101000000 + 0015000000D5FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010100010101000101 + 0114010101C40101010001010114010101C901010115010101CC010101000000 + 0016000000DEFFFFFF00FFFFFF00FFFFFF00FFFFFF00010101C1010101610101 + 0114010101C6010101320101013D010101CB00000015000000D5000000370000 + 0045000000E6FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101C4010101630101 + 010001010146010101CB010101CC00000048000000000000004E000000E40000 + 00E900000053FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006B6FFEFF6B6FFEFF6B6F + FEFFFFFFFF0073AAFFFF73AAFFFF73AAFFFFFFFFFF0067D5F0FF67D5F0FF67D5 + F0FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006B6FFEFF6B6FFEFF6B6F + FEFFFFFFFF0073AAFFFF73AAFFFF73AAFFFFFFFFFF0067D5F0FF67D5F0FF67D5 + F0FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006B6FFEFF6B6FFEFF6B6F + FEFFFFFFFF0073AAFFFF73AAFFFF73AAFFFFFFFFFF0067D5F0FF67D5F0FF67D5 + F0FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B2EBD0FFB2EBD0FFB2EB + D0FFFFFFFF006DCC50FF6DCC50FF6DCC50FFFFFFFF00EBB060FFEBB060FFEBB0 + 60FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B2EBD0FFB2EBD0FFB2EB + D0FFFFFFFF006DCC50FF6DCC50FF6DCC50FFFFFFFF00EBB060FFEBB060FFEBB0 + 60FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B2EBD0FFB2EBD0FFB2EB + D0FFFFFFFF006DCC50FF6DCC50FF6DCC50FFFFFFFF00EBB060FFEBB060FFEBB0 + 60FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B07A58FFB07A58FFB07A + 58FFFFFFFF00DD9BD9FFDD9BD9FFDD9BD9FFFFFFFF00B177FFFFB177FFFFB177 + FFFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B07A58FFB07A58FFB07A + 58FFFFFFFF00DD9BD9FFDD9BD9FFDD9BD9FFFFFFFF00B177FFFFB177FFFFB177 + FFFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B07A58FFB07A58FFB07A + 58FFFFFFFF00DD9BD9FFDD9BD9FFDD9BD9FFFFFFFF00B177FFFFB177FFFFB177 + FFFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF007F7F554D7F7F55667F7F55667F7F55667F7F + 55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F55667F7F + 55667F7F55667F7F55667F7F554D7D7D5367FFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFF7D7D53677A7A5168FFFFFEFFFFCC44FFFECB43FFFDCA + 42FFFCC941FFFAC73FFFF8C53DFFF6C33CFFF5C23AFFF3C038FFF1BE36FFF0BD + 35FFEFBC34FFFFFFFEFF7A7A516877774E6AFEFEFCFFFFCC44FFFFEE88FFFDCA + 42FFFCEB85FFFBEA84FFF8C53DFFF6E57FFFF4E37DFFF3C038FFF1E07AFFEFDE + 78FFEFBC34FFFEFEFCFF77774E6A73734B6BFDFDF9FFFFCC44FFFECB43FFF5CE + 64FFEBD285FFE9D083FFE7CE81FFE5CC80FFE4CB7EFFE2C97CFFE0C77AFFDFC6 + 79FFDEC578FFFDFDF9FF73734B6B6F6F476DFCFCF7FFFFCC44FFFFEE88FFECD2 + 86FFFCFCFAFFFCFCFAFFD6D6C5FFFCFCFAFFFCFCFAFFD1D1C0FFFCFCFAFFFCFC + FAFFCDCDBCFFFCFCF7FF6F6F476D6B6B446EFBFBF4FFFFCC44FFFECB43FFECD2 + 86FFDADAC9FFD8D8C7FFE98361FFE98361FFE98361FFE98361FFE98361FFE983 + 61FFE98361FFFBFBF4FF6B6B446E67674070F9F9F1FFFFCC44FFFFEE88FFECD2 + 86FFF9F9F5FFF9F9F5FFC86442FFF9F9F5FFF9F9F5FFD1D1C0FFF9F9F5FFF9F9 + F5FFC86442FFF9F9F1FF6767407063633C72F8F8EEFFFFCC44FFFECB43FFECD2 + 86FFDADAC9FFD8D8C7FFAD4826FFD4D4C3FFD3D3C2FFD9D9CAFFCFCFBEFFCECE + BDFFAD4826FFF8F8EEFF63633C725E5E3873F7F7EBFFFFCC44FFFFEE88FFECD2 + 86FFF7F7F1FFF7F7F1FFB84927FFF7F7F1FFF7F7F1FFD1D1C0FFF7F7F1FFF7F7 + F1FFB84927FFF7F7EBFF5E5E38735A5A3475F6F6E9FFFFCC44FFFECB43FFECD2 + 86FFDADAC9FFD8D8C7FFDA5B39FFDA5B39FFDA5B39FFDA5B39FFDA5B39FFDA5B + 39FFDA5B39FFF6F6E9FF5A5A347555553077F5F5E6FFFFCC44FFFFEE88FFECD2 + 86FFF5F5EEFFF5F5EEFFD6D6C5FFF5F5EEFFF5F5EEFFD1D1C0FFF5F5EEFFF5F5 + EEFFCDCDBCFFF5F5E6FF555530774D4D297AF4F4E4FFFFCC44FFFECB43FFECD2 + 86FFDADAC9FFD8D8C7FFD6D6C5FFD4D4C3FFD3D3C2FFD1D1C0FFCFCFBEFFCECE + BDFFCDCDBCFFF4F4E4FF4D4D297A3A3A1881F9F9E9FFF3F3E2FFF3F3E2FFF3F3 + E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3E2FFF3F3 + E2FFF3F3E2FFF9F9E9FF3A3A18812D2D0D652B2B0B872B2B0B872B2B0B872B2B + 0B872B2B0B872B2B0B872B2B0B872B2B0B872B2B0B872B2B0B872B2B0B872B2B + 0B872B2B0B872B2B0B872D2D0D65FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00CC812900D58A3000DD923600E4993B00E99E + 3F48E99E3F99E89D3E00E89D3E00DB903500DB903500DB903500DB903500E297 + 3A00E79C3E00E99E3F99FFFFFF00CC812900D58A3000DD923600E3983B48E499 + 3BCCE4993BCCE4993B00DB903400DB903500DB903500DB903500DB903500DF94 + 3700E3983B7AE4993BCCFFFFFF00CC812900D58A3000DC913648DD9236CCFFE5 + 99FFDD9236CCD98E3300D78C3100DB903504DB903511DB903528DB903547DD92 + 368DE4A148CDDD9236B6FFFFFF00CC812900D4892F48D58A30CCFFE599FFFCD7 + 8BFFD58A30CCD58A30CCD58A30CCD68C32CDDA933BD1DF9E47D7E6AC57E0F3C2 + 73F1EDB968EBD58A308DFFFFFF00CB802848CC8129CCFFE397FFF4BE72FFF6C6 + 7AFFF8CE82FFF8CD81FFF8CC80FFF7CB7FFFF7C87CFFF6C478FFF5C074FFF3C1 + 74FCD48F3AD3CD822A35FFFFFF00C27722CCFDDF93FFEFB468FFEFB468FFEFB4 + 68FFEFB468FFEBB061FFE3A754FFDA9E49FFD59843FFD29541FFD69D4AFCCC8B + 38DDC2772279C67B2500FFFFFF00BA6F1C48B96E1BCCFAD68AFFEEB266FFF1B8 + 67FFF0B956FFECB240FFEBAF3BFFEAAD38FFE5A736F9D89833ECC17A23D3B96E + 1B79BD731E0ABF752000FFFFFF00B96E1B00B0651548AF6414CCFACC6CFFFCBD + 2CFFAF6414CCAF6414CCAF6414CCAF6414CBAF6414B6AF64148DB0651535B66B + 1900BD731E00BF752000FFFFFF00B96E1B00AF641400A75C0E48A65B0DCCFFC3 + 32FFA65B0DCCAB601100AD621200AD621200AD621200AD621200AF641400B66B + 1900BD731E00BF752000FFFFFF00B96E1B00AF641400A65B0D00A05509489F54 + 08CC9F5408CC9F540800A95E0F00AD621200AD621200AD621200AF641400B66B + 1900BD731E00BF752000FFFFFF00B96E1B00AF641400A65B0D009F5408009A4F + 04489A4F04999A4F04009A4F0400AD621200AD621200AD621200AF641400B66B + 1900BD731E00BF752000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0003030360030303BE03030360FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00030303C1030303C1030303C1FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0003030395030303C6030303C6FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF000303030002020266020202CCFFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0002020200020202B802020283FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0001010172010101E00101011CFFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670000000D000000670000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000D000000000000000000000000000000000000 + 00000000000DFFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 000000000000000000000000006B000000000000000000000000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000E000000000000000000000000000000000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 0000000000000000000000000071000000000000000000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000000000000000000000000000F000000000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 0000000000000000000000000010000000000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000000000000000 + 0000000000000000000000000080000000000000000000000000000000000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000010101000101 + 0100010101000000000000000011000000000101010001010100010101000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018901010100010101000101 + 0100010101000101010001010189010101000101010001010100010101000101 + 010001010189FFFFFF00FFFFFF00FFFFFF000101011401010100010101000101 + 0100010101000101010001010113010101000101010001010100010101000101 + 010001010113FFFFFF00FFFFFF00FFFFFF000101017B01010115010101A40101 + 0115010101A401010115010101A401010115010101A401010115010101A40101 + 01150101017BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF00010101AE010101AE010101AE0101 + 01AE010101AE010101AE010101AE010101AE010101AE010101AE010101AE0101 + 01AE010101AEFFFFFF00FFFFFF00FFFFFF00010101B0010101B0010101000101 + 010001010100010101000000006B010101000101010001010100010101000101 + 01B0010101B0FFFFFF00FFFFFF00FFFFFF00010101B3010101B3010101000101 + 010001010100010101000000000E000000000101010001010100010101000101 + 01B3010101B3FFFFFF00FFFFFF00FFFFFF00010101B6010101B6010101000101 + 0100000000000000000000000071000000000000000001010100010101000101 + 01B6010101B6FFFFFF00FFFFFF00FFFFFF00010101B9010101B9010101000000 + 000000000000000000000000000F000000000000000000000000010101000101 + 01B9010101B9FFFFFF00FFFFFF00FFFFFF00010101BC010101BC000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780101 + 01BC010101BCFFFFFF00FFFFFF00FFFFFF00010101C0010101C0010101000000 + 0000000000000000000000000010000000000000000000000000010101000101 + 01C0010101C0FFFFFF00FFFFFF00FFFFFF00010101C4010101C4010101000101 + 0100000000000000000000000080000000000000000001010100010101000101 + 01C4010101C4FFFFFF00FFFFFF00FFFFFF00010101C7010101C7010101000101 + 0100000000000000000000000011000000000000000001010100010101000101 + 01C7010101C7FFFFFF00FFFFFF00FFFFFF00010101CC010101CC010101000000 + 0000000000000000000001010189000000000000000000000000010101000101 + 01CC010101CCFFFFFF00FFFFFF00FFFFFF00000000D9000000D9000000D90000 + 00D9000000D9000000D9000000D9000000D9000000D9000000D9000000D90000 + 00D9000000D9FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF00010101AE01010100010101000101 + 010001010100010101000101010D010101000101010001010100010101000101 + 0100010101AEFFFFFF00FFFFFF00FFFFFF00010101B001010100010101000101 + 010001010100000000000000006B000000000101010001010100010101000101 + 0100010101B0FFFFFF00FFFFFF00FFFFFF00010101B301010100010101000101 + 010001010100000000000000000E000000000000000001010100010101000101 + 0100010101B3FFFFFF00FFFFFF00FFFFFF00010101B601010100010101000000 + 0000000000000000000000000071000000000000000000000000010101000101 + 0100010101B6FFFFFF00FFFFFF00FFFFFF00010101B901010100000000000000 + 000000000000000000000000000F000000000000000000000000000000000101 + 0100010101B9FFFFFF00FFFFFF00FFFFFF00010101BC0000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780101 + 010F010101BCFFFFFF00FFFFFF00FFFFFF00010101C001010100000000000000 + 0000000000000000000000000010000000000000000000000000000000000101 + 0100010101C0FFFFFF00FFFFFF00FFFFFF00010101C401010100010101000000 + 0000000000000000000000000080000000000000000000000000010101000101 + 0100010101C4FFFFFF00FFFFFF00FFFFFF00010101C701010100010101000101 + 0100000000000000000000000011000000000000000001010100010101000101 + 0100010101C7FFFFFF00FFFFFF00FFFFFF00010101CC01010100010101000000 + 0000000000000101010001010189010101000000000000000000010101000101 + 0100010101CCFFFFFF00FFFFFF00FFFFFF00000000D900000000000000000000 + 0000000000000000000001010113010101000000000000000000000000000000 + 0000000000D9FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF00010101AE01010100010101000101 + 01000101010001010100010101AE010101000101010001010100010101000101 + 0100010101AEFFFFFF00FFFFFF00FFFFFF00010101B001010100010101000101 + 01000101010001010100010101B0010101000101010001010100010101000101 + 0100010101B0FFFFFF00FFFFFF00FFFFFF00010101B301010100010101000101 + 01000101010001010100010101B3010101000101010001010100010101000101 + 0100010101B3FFFFFF00FFFFFF00FFFFFF00010101B601010100010101000101 + 01000101010001010100010101B6010101000101010001010100010101000101 + 0100010101B6FFFFFF00FFFFFF00FFFFFF00010101B901010100010101000101 + 01000101010001010100010101B9010101000101010001010100010101000101 + 0100010101B9FFFFFF00FFFFFF00FFFFFF00010101BC010101BC010101BC0101 + 01BC010101BC010101BC0101018E010101BC010101BC010101BC010101BC0101 + 01BC010101BCFFFFFF00FFFFFF00FFFFFF00010101C001010100010101000101 + 01000101010001010100010101C0010101000101010001010100010101000101 + 0100010101C0FFFFFF00FFFFFF00FFFFFF00010101C401010100010101000101 + 01000101010001010100010101C4010101000101010001010100010101000101 + 0100010101C4FFFFFF00FFFFFF00FFFFFF00010101C701010100010101000101 + 01000101010001010100010101C7010101000101010001010100010101000101 + 0100010101C7FFFFFF00FFFFFF00FFFFFF00010101CC01010100010101000000 + 00000101010001010100010101CC010101000101010000000000010101000101 + 0100010101CCFFFFFF00FFFFFF00FFFFFF00000000D900000000000000000000 + 00000000000000000000000000D9000000000000000000000000000000000000 + 0000000000D9FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670101010D010101AC0000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 00000000000001010100010101AE010101000000000000000000000000000000 + 00000000000DFFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 00000101010001010100010101B0010101000101010000000000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000010101000101 + 01000101010001010100010101B3010101000101010001010100010101000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000010101000101 + 01000101010001010100010101B6010101000101010001010100010101000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000101010F01010100010101000101 + 01000101010001010100010101B9010101000101010001010100010101000101 + 01000101010FFFFFFF00FFFFFF00FFFFFF00010101BC010101BC010101BC0101 + 01BC010101BC010101BC0101018E010101BC010101BC010101BC010101BC0101 + 01BC010101BCFFFFFF00FFFFFF00FFFFFF000101011001010100010101000101 + 01000101010001010100010101C0010101000101010001010100010101000101 + 010001010110FFFFFF00FFFFFF00FFFFFF000000008000000000010101000101 + 01000101010001010100010101C4010101000101010001010100010101000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000010101000101 + 01000101010001010100010101C7010101000101010001010100010101000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018901010100010101000101 + 01000101010001010100010101CC010101000101010001010100010101000101 + 010001010189FFFFFF00FFFFFF00FFFFFF000101011401010100010101000101 + 01000101010001010100000000D9010101000101010001010100010101000101 + 010001010113FFFFFF00FFFFFF00FFFFFF000101017B01010115010101A40101 + 0115010101A401010115000000E601010115010101A401010115010101A40101 + 01150101017BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF000101010E01010100010101000101 + 010001010100010101000101010D010101000101010001010100010101000101 + 01000101010DFFFFFF00FFFFFF00FFFFFF000000006B00000000010101000101 + 010001010100000000000000006B000000000101010001010100010101000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000010101000101 + 010001010100000000000000000E000000000000000001010100010101000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 0000000000000000000000000071000000000000000000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000000000000000000000000000F000000000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 0000000000000000000000000010000000000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000000000000000 + 0000000000000000000000000080000000000000000000000000000000000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000010101000101 + 0100010101000000000000000011000000000101010001010100010101000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018901010100010101000101 + 0100010101000101010001010189010101000101010001010100010101000101 + 010001010189FFFFFF00FFFFFF00FFFFFF000101011401010100010101000101 + 0100010101000101010001010113010101000101010001010100010101000101 + 010001010113FFFFFF00FFFFFF00FFFFFF000101017B01010115010101A40101 + 0115010101A401010115010101A401010115010101A401010115010101A40101 + 01150101017BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670000000D000000670000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000D000000000000000000000000000000000000 + 00000000000DFFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 000000000000000000000000006B000000000000000000000000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000E000000000000000000000000000000000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 0000000000000000000000000071000000000000000000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000000000000000000000000000F000000000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 0000000000000000000000000010000000000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000000000000000 + 0000000000000000000000000080000000000000000000000000000000000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000000000000000 + 0000000000000000000000000011000000000000000000000000000000000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018901010100000000000000 + 0000000000000101010001010189010101000000000000000000000000000101 + 010001010189FFFFFF00FFFFFF00FFFFFF000101011400000000000000000000 + 0000000000000000000001010113010101000000000000000000000000000000 + 000001010113FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670000000D000000670000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000D000000000000000000000000000000000000 + 00000000000DFFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 000000000000000000000000006B000000000000000000000000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000E000000000000000000000000000000000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 0000000000000000000000000071000000000000000000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000000000000000000000000000F000000000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 0000000000000000000000000010000000000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000000000000000 + 0000000000000000000000000080000000000000000000000000000000000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000000000000000 + 0000000000000000000000000011000000000000000000000000000000000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018900000000000000000000 + 0000000000000000000001010189000000000000000000000000000000000000 + 000001010189FFFFFF00FFFFFF00FFFFFF00000000D9000000D9000000D90000 + 00D9000000D9000000D9000000D9000000D9000000D9000000D9000000D90000 + 00D9000000D9FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670000000D000000670000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000D000000000000000000000000000000000000 + 00000000000DFFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 000000000000000000000000006B000000000000000000000000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000E000000000000000000000000000000000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 0000000000000000000000000071000000000000000000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000000000000000000000000000F000000000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 0000000000000000000000000010000000000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000010101000101 + 0100010101000000000000000080000000000101010001010100010101000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000101011101010100010101000101 + 0100010101000101010001010111010101000101010001010100010101000101 + 010001010111FFFFFF00FFFFFF00FFFFFF00010101CC010101CC010101CC0101 + 01CC010101CC010101CC010101CC010101CC010101CC010101CC010101CC0101 + 01CC010101CCFFFFFF00FFFFFF00FFFFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF000101010E01010100010101000101 + 010001010100010101000101010D010101000101010001010100010101000101 + 01000101010DFFFFFF00FFFFFF00FFFFFF000000006B00000000010101000101 + 010001010100000000000000006B000000000101010001010100010101000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000010101000101 + 010001010100000000000000000E000000000000000001010100010101000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 0000000000000000000000000071000000000000000000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000000000000000000000000000F000000000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 0000000000000000000000000010000000000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000000000000000 + 0000000000000000000000000080000000000000000000000000000000000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000000000000000 + 0000000000000000000000000011000000000000000000000000000000000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018901010100000000000000 + 0000000000000101010001010189010101000000000000000000000000000101 + 010001010189FFFFFF00FFFFFF00FFFFFF000101011400000000000000000000 + 0000000000000000000001010113010101000000000000000000000000000000 + 000001010113FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF000101010E01010100010101000101 + 010001010100010101000101010D010101000101010001010100010101000101 + 01000101010DFFFFFF00FFFFFF00FFFFFF000000006B00000000010101000101 + 010001010100000000000000006B000000000101010001010100010101000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000010101000101 + 010001010100000000000000000E000000000000000001010100010101000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 0000000000000000000000000071000000000000000000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000000000000000000000000000F000000000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 0000000000000000000000000010000000000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000000000000000 + 0000000000000000000000000080000000000000000000000000000000000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000000000000000 + 0000000000000000000000000011000000000000000000000000000000000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018900000000000000000000 + 0000000000000000000001010189000000000000000000000000000000000000 + 000001010189FFFFFF00FFFFFF00FFFFFF00000000D9000000D9000000D90000 + 00D9000000D9000000D9000000D9000000D9000000D9000000D9000000D90000 + 00D9000000D9FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF000101010E01010100010101000101 + 010001010100010101000101010D010101000101010001010100010101000101 + 01000101010DFFFFFF00FFFFFF00FFFFFF000000006B00000000010101000101 + 010001010100000000000000006B000000000101010001010100010101000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000010101000101 + 010001010100000000000000000E000000000000000001010100010101000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 0000000000000000000000000071000000000000000000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000000000000000000000000000F000000000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 0000000000000000000000000010000000000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000010101000101 + 0100010101000000000000000080000000000101010001010100010101000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000101011101010100010101000101 + 0100010101000101010001010111010101000101010001010100010101000101 + 010001010111FFFFFF00FFFFFF00FFFFFF00010101CC010101CC010101CC0101 + 01CC010101CC010101CC010101CC010101CC010101CC010101CC010101CC0101 + 01CC010101CCFFFFFF00FFFFFF00FFFFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670000000D000000670000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000D000000000000000000000000000000000000 + 00000000000DFFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 000000000000000000000000006B000000000000000000000000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000010101000101 + 010001010100000000000000000E000000000101010001010100010101000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000010101000101 + 0100010101000000000000000071000000000101010001010100010101000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000101010F01010100010101000101 + 010001010100010101000101010F010101000101010001010100010101000101 + 01000101010FFFFFFF00FFFFFF00FFFFFF00010101BC010101BC010101BC0101 + 01BC010101BC010101BC010101BC010101BC010101BC010101BC010101BC0101 + 01BC010101BCFFFFFF00FFFFFF00FFFFFF000101011001010100010101000101 + 0100010101000101010001010110010101000101010001010100010101000101 + 010001010110FFFFFF00FFFFFF00FFFFFF000000008000000000010101000101 + 0100010101000000000000000080000000000101010001010100010101000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000010101000101 + 0100010101000000000000000011000000000101010001010100010101000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018901010100010101000101 + 0100010101000101010001010189010101000101010001010100010101000101 + 010001010189FFFFFF00FFFFFF00FFFFFF000101011401010100010101000101 + 0100010101000101010001010113010101000101010001010100010101000101 + 010001010113FFFFFF00FFFFFF00FFFFFF000101017B01010115010101A40101 + 0115010101A401010115010101A401010115010101A401010115010101A40101 + 01150101017BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF000101010E01010100010101000101 + 010001010100010101000101010D010101000101010001010100010101000101 + 01000101010DFFFFFF00FFFFFF00FFFFFF000000006B00000000010101000101 + 010001010100000000000000006B000000000101010001010100010101000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000010101000101 + 010001010100000000000000000E000000000101010001010100010101000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000010101000101 + 0100010101000000000000000071000000000101010001010100010101000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000101010F01010100010101000101 + 010001010100010101000101010F010101000101010001010100010101000101 + 01000101010FFFFFFF00FFFFFF00FFFFFF00010101BC010101BC010101BC0101 + 01BC010101BC010101BC010101BC010101BC010101BC010101BC010101BC0101 + 01BC010101BCFFFFFF00FFFFFF00FFFFFF000101011001010100010101000101 + 0100010101000101010001010110010101000101010001010100010101000101 + 010001010110FFFFFF00FFFFFF00FFFFFF000000008000000000010101000101 + 0100010101000000000000000080000000000101010001010100010101000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000010101000101 + 0100010101000000000000000011000000000000000001010100010101000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018901010100000000000000 + 0000000000000101010001010189010101000000000000000000000000000101 + 010001010189FFFFFF00FFFFFF00FFFFFF000101011400000000000000000000 + 0000000000000000000001010113010101000000000000000000000000000000 + 000001010113FFFFFF00FFFFFF00FFFFFF00000000AC000000E6000000E60000 + 00E6000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101810000000D000000670000 + 000D000000670000000D000000670000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF00010101AE01010100000000000000 + 000000000000000000000000000D000000000000000000000000000000000000 + 00000000000DFFFFFF00FFFFFF00FFFFFF00010101B001010100010101000000 + 000000000000000000000000006B000000000000000000000000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF00010101B301010100010101000101 + 010000000000000000000000000E000000000000000000000000000000000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF00010101B601010100010101000000 + 0000000000000000000000000071000000000000000000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF00010101B901010100000000000000 + 000000000000000000000000000F000000000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00010101BC0000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF00010101C001010100000000000000 + 0000000000000000000000000010000000000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF00010101C401010100010101000000 + 0000000000000000000000000080000000000000000000000000000000000000 + 000000000080FFFFFF00FFFFFF00FFFFFF00010101C701010100010101000101 + 0100010101000000000000000011000000000101010001010100010101000000 + 000000000011FFFFFF00FFFFFF00FFFFFF00010101CC01010100010101000101 + 0100010101000101010001010189010101000101010001010100010101000101 + 010001010189FFFFFF00FFFFFF00FFFFFF00000000D901010100010101000101 + 0100010101000101010001010113010101000101010001010100010101000101 + 010001010113FFFFFF00FFFFFF00FFFFFF00000000AC01010115010101A40101 + 0115010101A401010115010101A401010115010101A401010115010101A40101 + 01150101017BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670000000D000000670000000D000000670000000D000000670101 + 010D01010181FFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000D000000000000000000000000000000000101 + 0100010101AEFFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 000000000000000000000000006B000000000000000000000000010101000101 + 0100010101B0FFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000E000000000000000001010100010101000101 + 0100010101B3FFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 0000000000000000000000000071000000000000000000000000010101000101 + 0100010101B6FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000000000000000000000000000F000000000000000000000000000000000101 + 0100010101B9FFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780000000F000000780000000F000000780000000F000000780101 + 010F010101BCFFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 0000000000000000000000000010000000000000000000000000000000000101 + 0100010101C0FFFFFF00FFFFFF00FFFFFF000000008000000000000000000000 + 0000000000000000000000000080000000000000000000000000010101000101 + 0100010101C4FFFFFF00FFFFFF00FFFFFF000000001100000000010101000101 + 0100010101000000000000000011000000000101010001010100010101000101 + 0100010101C7FFFFFF00FFFFFF00FFFFFF000101018901010100010101000101 + 0100010101000101010001010189010101000101010001010100010101000101 + 0100010101CCFFFFFF00FFFFFF00FFFFFF000101011401010100010101000101 + 0100010101000101010001010113010101000101010001010100010101000101 + 0100000000D9FFFFFF00FFFFFF00FFFFFF000101017B01010115010101A40101 + 0115010101A401010115010101A401010115010101A401010115010101A40101 + 0115000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670101010D010101AC0000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 00000000000001010100010101AE010101000000000000000000000000000000 + 00000000000DFFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 00000101010001010100010101B0010101000101010000000000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000101 + 01000101010001010100010101B3010101000101010001010100000000000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 00000101010001010100010101B6010101000101010000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 00000000000001010100010101B9010101000000000000000000000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780000 + 000F000000780101010F010101BC0000000F000000780000000F000000780000 + 000F00000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000000 + 00000000000001010100010101C0010101000000000000000000000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000000000000000 + 00000101010001010100010101C4010101000101010000000000000000000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000010101000101 + 01000101010001010100010101C7010101000101010001010100010101000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018901010100010101000101 + 01000101010001010100010101CC010101000101010001010100010101000101 + 010001010189FFFFFF00FFFFFF00FFFFFF000101011401010100010101000101 + 01000101010001010100000000D9010101000101010001010100010101000101 + 010001010113FFFFFF00FFFFFF00FFFFFF000101017B01010115010101A40101 + 0115010101A401010115000000E601010115010101A401010115010101A40101 + 01150101017BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101810000000D000000670000 + 000D000000670101010D010101AC0000000D000000670000000D000000670101 + 010D01010181FFFFFF00FFFFFF00FFFFFF00010101AE01010100000000000000 + 00000000000001010100010101AE010101000000000000000000000000000101 + 0100010101AEFFFFFF00FFFFFF00FFFFFF00010101B001010100010101000000 + 00000101010001010100010101B0010101000101010000000000010101000101 + 0100010101B0FFFFFF00FFFFFF00FFFFFF00010101B301010100010101000101 + 01000101010001010100010101B3010101000101010001010100010101000101 + 0100010101B3FFFFFF00FFFFFF00FFFFFF00010101B601010100010101000000 + 00000101010001010100010101B6010101000101010000000000010101000101 + 0100010101B6FFFFFF00FFFFFF00FFFFFF00010101B901010100000000000000 + 00000000000001010100010101B9010101000000000000000000000000000101 + 0100010101B9FFFFFF00FFFFFF00FFFFFF00010101BC0000000F000000780000 + 000F000000780101010F010101BC0000000F000000780000000F000000780101 + 010F010101BCFFFFFF00FFFFFF00FFFFFF00010101C001010100000000000000 + 00000000000001010100010101C0010101000000000000000000000000000101 + 0100010101C0FFFFFF00FFFFFF00FFFFFF00010101C401010100010101000000 + 00000101010001010100010101C4010101000101010000000000010101000101 + 0100010101C4FFFFFF00FFFFFF00FFFFFF00010101C701010100010101000101 + 01000101010001010100010101C7010101000101010001010100010101000101 + 0100010101C7FFFFFF00FFFFFF00FFFFFF00010101CC01010100010101000101 + 01000101010001010100010101CC010101000101010001010100010101000101 + 0100010101CCFFFFFF00FFFFFF00FFFFFF00000000D901010100010101000101 + 01000101010001010100000000D9010101000101010001010100010101000101 + 0100000000D9FFFFFF00FFFFFF00FFFFFF00000000AC01010115010101A40101 + 0115010101A401010115000000E601010115010101A401010115010101A40101 + 0115000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000088CC610088CC810088 + 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 + 8900005D8C0000669900FFFFFF00BC6B3671BC6B3690BC6B36CCBC6B36EEBC6B + 36FABB6B36FEBB6B36FFBB6A36FFBB6A36FFBC6C39FFBD6E3BFFBB6D3AFFBB6B + 38EFBB703ECBB6693554FFFFFF00BC6B369BF6E0D1FFF7E0D1FFFEFBF8FFFEFB + F7FFFDF9F6FFFCF5F0FFFAF0EAFFFBF2EDFFFDF9F6FFFDFAF7FFFBF1EBFFF8E9 + DFFEECD0BDFBC9895EECB5693563BC6B36D8F6DFD1FFE9AA80FFFEFAF6FFFDFA + F6FFC88C64FFFBF3EEFFFBF1EAFFFCF6F2FFFEFBF8FFFCF6F1FFF9ECE2FFF8E7 + DBFFEED0BAFFECD0BDFFBB703EF8BC6B36F0F6DFD0FFE8A87EFFFCF6F1FFFCF6 + F1FFC88C64FFFAF1E9FFFBF4EEFFFDFAF7FFFDF9F6FFFAF0E8FFF8E8DDFFF7E6 + DBFFE1A37AFFEFD5C3FFB76935FEBC6B36FAF5DDCCFFE7A87EFFFAF0E8FFFAF0 + E8FFC98D66FFFAF0E9FFFDF8F3FFFEFAF8FFFCF4EFFFF9E9DFFFF7E7DBFFF7E5 + D9FFE0A278FFE7C2A9FFB66835FFBB6B36FEF4DCC9FFE7A77DFFF9ECE1FFF9EC + E1FFF9EDE3FFFCF4EEFFFDFAF7FFFDF7F3FFFAEDE5FFF7E7DBFFF7E5D9FFF6E5 + D8FFDEA077FFE4BEA4FFB46734FFBB6B36FFF4D9C7FFE6A67DFFC88C64FFC98D + 65FFC98E67FFCB926CFFCB926DFFCA9069FFC88C65FFC88C64FFC88C64FFC88C + 64FFDA9C74FFE1BA9FFFB36634FFBB6A36FFF2D8C5FFE3A47BFFE3A37AFFE3A4 + 7AFFE2A47BFFE2A37BFFE1A37BFFE1A279FFDFA077FFDE9F76FFDD9E74FFDB9C + 72FFDC9D74FFDDB59AFFB16534FFBB6A36FFF2D5C2FFE3A37AFFE3A37AFFE2A3 + 7BFFE2A37BFFE2A47BFFE1A279FFE0A178FFDEA077FFDE9E75FFDC9D74FFDA9B + 73FFD99B73FFDAB095FFAF6433FFBB6A36FFF0D2BEFFE2A37AFFE2A37AFFE1A3 + 7AFFE2A37BFFE1A37BFFE0A178FFDE9F77FFDD9F76FFDC9D74FFD99B72FFD899 + 71FFD69970FFD5AB8EFFAD6333FFBA6A36FFEFD0BBFFE2A27AFFFEFBF8FFFEFB + F8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFB + F8FFD3966DFFD2A78AFFAB6232FFBB6B38FFEFCEB8FFE1A279FFFEFAF7FF62C0 + 88FF62C088FF62C088FF62C088FF62C088FF62C088FF62C088FF62C088FFFDF9 + F6FFCF936AFFCEA384FFAA6132FFBB6C38FFEECCB6FFE1A27AFFFEFAF7FFBFDC + C2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFFDF9 + F6FFCD9068FFCC9E81FFA86132FFBA6B37FEEDCAB3FFE0A27AFFFEFAF7FF62C0 + 88FF62C088FF62C088FF62C088FF62C088FF62C088FF62C088FF62C088FFFDF9 + F6FFCA8D65FFC99B7CFFA76031FEBA6A35DEEBC6ADFFEAC5ADFFFEFBF8FFFEFB + F8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFB + F8FFC89A7CFFC79879FFA76031EDBA6A3600B96935B5B86935EEB76835FFB568 + 35FFB46734FFB26634FFB06533FFAE6433FFAC6332FFAA6232FFA96132FFA860 + 31FFA76031FEA66031F1A86131C4FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00016395000163940001629300016192000162 + 930001629300016394000000000001334C00016597000164960001639400003A + 8C00003E9248003C8FCC00378A48016395000163940001629300016192000162 + 930001629300016394000000000001334C390165969C0164959C0163943E0039 + 8B48003688CC5285C9FF002E7ECC016395000163940001629300016192000162 + 93000162930001639400000000240000006788CCDDFF87CBDDFF016091AF0030 + 80CC3F72B6FF002774CC00247048016395000163940001629300016192000162 + 9300016293100162936D00000069DDDCDCFF949494FF70B4D6FF80C4DBFF015C + 8DB2001A63CC0013584800226E00016395050163941401629328016192410161 + 9277106C9AAB4B9BBADB79B9D5FC919191FFD9D4D4FF8D8D8DFF68ACCEFF74B8 + D4FF015887B4015686400155840001629383126D9BB82078A2C33385ABD058A2 + C0E774B9D1FB6EACCCFF669DC8FF83C7DAFF888888FFD3CACAFF838383FF60A4 + C6FF63A7C9FF015382A5015281000160913E015E8FB16AAEC9FF66A8C5FF5692 + B8FF4B80AFFF5D97BFFF77B9D2FF669DC8FF7BBAD5FF7E7E7EFFCEC0C0FF7979 + 79FF5588BBFF014F7EA6014E7D00015F9000002B5548002B55CC336898FF508C + B3FF69ABC8FF67A7C6FF4D80B3FF71B1CEFF6EA9CDFF6CA3CEFF6D6D6DFFAA99 + 99FF010101A5014C7A42014B7A00015F9000002B55000157873F015585B65FA1 + C0FF3F79A3FF4278A7FF66A6C5FF619DC2FF5E95C1FF74B4D1FF6598CBFF0101 + 01AB0101013C014B7900014B7A00015F9000002B550001568600002B5548002B + 55CC4F8DB3FF68ACC8FF4880ACFF5087B3FF6AAAC8FF5588BBFF00416EC1003E + 6A4401010100014B7900014B7A00015F9000002B550001568600002B5500014D + 7C41014B79BB3A719FFF386F9DFF5F9FC0FF4578ABFF003763C600356046003C + 680001010100014B7900014B7A00015F9000002B550001568600002B5500014C + 7B00002B5548002B55CC5494B7FF34679AFF00305ACA002D584800335E00003C + 680001010100014B7900014B7A00015F9000002B550001568600002B5500014C + 7B00002B550000315C47002D57CC002C56CC002B5548002C570000335E00003C + 680001010100014B7900014B7A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A2AE8EFF5F9771FF4F8E + 66FF49895FFFA2AE8EFFFFFFFF00FFFFFF00EFC2A37EEFC1A2E3EDC09FFFEBBE + 9DFFEBBC9AFFE9BA96FFE7B793FFE6B590FF9DAF91FF61AB81FF95D4B4FFBAE6 + D0FF6ABB8FFF2D8F57FF196B378CFFFFFF00EEC1A1EBFBF7F4FFFBF7F4FFFBF7 + F4FFFBF7F4FFFBF7F4FFFBF7F4FFFBF7F4FF498960FF90D3B1FF92D6B1FFFFFF + FFFF65BC8CFF67BC8FFF196B37F7FFFFFF00ECBF9EFFFBF7F4FF9CD5A5FF98D3 + A1FF94D09DFF90CE98FF8BCB93FF87C98EFF317B4CFF9CD4B6FFFFFFFFFFFFFF + FFFFFFFFFFFF95D2B2FF196B37FFFFFFFF00EBBD9BFFFBF7F4FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22703EFF62BA8BFF60BA87FFFFFF + FFFF60B987FF67BC8FFF196B37F7FFFFFF00E9BA98FFFBF7F4FF4FA358FF4FA3 + 58FF59B163FFE9C3A6FFE9C3A6FFE9C3A6FFA2AE8EFF288C53FF64BA8DFF95D2 + B2FF64BA8DFF288C53FF196B378CFFFFFF00E7B794FFFBF7F4FF489B51FFB9DF + BDFF54AB5EFFFFFFFFFFFFFFFFFFFFFFFFFFE8C7ACFF84B094FF257341FF196B + 37FF247240FF6C7C4AFFFFFFFF00FFFFFF00E5B48FFFFAF6F2FF42924AFFB6DD + BAFF4FA358FFE9C7ADFFE9C9AEFFE9C9B0FFE8C7ACFFE9C9B0FFE8C8B0FFE8CC + B5FFF2E7DEFFC88A59FFFFFFFF00FFFFFF00E3B18CFFFAF6F1FF3B8842FFACD8 + B0FF489B51FFFFFFFFFFFFFFFFFFFFFFFFFFE8C7ACFFFFFFFFFFFFFFFFFFFFFF + FFFFF1E5DBFFC68655FFFFFFFF00FFFFFF00E1AE87FFFAF4F0FF347E3AFFA0D3 + A4FF42924AFFEACCB3FFEACCB3FFEACEB7FFE8C7ACFFE8C7ACFFE8C8B0FFE8C8 + AEFFF0E2D8FFC48654FFFFFFFF00FFFFFF00DFAA82FFF9F3EFFF2E7533FF92CC + 97FF3B8842FFFFFFFFFFFFFFFFFFFFFFFFFFEACFBAFFFBF6F2FFFFFFFFFFFFFF + FFFFF0E2D8FFC88D5FFFFFFFFF00FFFFFF00DDA87EFFF9F3EFFF276D2CFF84C6 + 8AFF347E3AFFEBD0BBFFEBD0BBFFEBD1BDFFEACDB5FFEACDB5FFEACDB5FFEACD + B5FFF0E2D8FFC68A5CFFFFFFFF00FFFFFF00D9A47AFFF9F3EEFF1D5F21FF2265 + 26FF276D2CFFFFFFFFFFFFFFFFFFFFFFFFFFEAC7ADFFFFFFFFFFFFFFFFFFFFFF + FFFFF0E2D8FFC68C5FFFFFFFFF00FFFFFF00D7A175FFF8F2EDFFF7F0EAFFF6ED + E6FFF4EAE2FFF3E7DEFFF1E4DBFFF0E2D8FFF0E2D8FFF0E2D8FFF0E2D8FFF0E2 + D8FFF0E2D8FFC58A5DFDFFFFFF00FFFFFF00D69E72C4D3996EF4D19668FFCE92 + 63FFCB8E5EFFC98A5BFFC78756FFC38452FFC38452FFC38452FFC38452FFC384 + 52FFC38452FFBB7742B0FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A2AE8EFF5F9771FF4F8E + 66FF49895FFFA2AE8EFFFFFFFF00FFFFFF00EFC2A37EEFC1A2E3EDC09FFFEBBE + 9DFFEBBC9AFFE9BA96FFE7B793FFE6B590FF9DAF91FF61AB81FF95D4B4FFBAE6 + D0FF6ABB8FFF2D8F57FF196B378CFFFFFF00EEC1A1EBFBF7F4FFFBF7F4FFFBF7 + F4FFFBF7F4FFFBF7F4FFFBF7F4FFFBF7F4FF498960FF90D3B1FF92D6B1FFFFFF + FFFF65BC8CFF67BC8FFF196B37F7FFFFFF00ECBF9EFFFBF7F4FF9CD5A5FF98D3 + A1FF94D09DFF90CE98FF8BCB93FF87C98EFF317B4CFF9CD4B6FFFFFFFFFFFFFF + FFFFFFFFFFFF95D2B2FF196B37FFFFFFFF00EBBD9BFFFBF7F4FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22703EFF62BA8BFF60BA87FFFFFF + FFFF60B987FF67BC8FFF196B37F7FFFFFF00E9BA98FFFBF7F4FFE9C3A6FFE9C3 + A6FFE9C3A6FFE9C3A6FFE9C3A6FFE9C3A6FFA2AE8EFF288C53FF64BA8DFF95D2 + B2FF64BA8DFF288C53FF196B378CFFFFFF00E7B794FFFBF7F4FFE9C3A6FFFFFF + FFFFE8C4A9FFFFFFFFFFFFFFFFFFFFFFFFFFE8C7ACFF84B094FF257341FF196B + 37FF247240FF6C7C4AFFFFFFFF00FFFFFF00E5B48FFFFAF6F2FFE9C6AAFFE9C6 + ACFFEAC7ACFFE9C7ADFFE9C9AEFFE9C9B0FFE8C7ACFFE9C9B0FFE8C8B0FFE8CC + B5FFF2E7DEFFC88A59FFFFFFFF00FFFFFF00E3B18CFFFAF6F1FFEAC9AEFFFFFF + FFFFEAC9B0FFFFFFFFFFFFFFFFFFFFFFFFFFE8C7ACFFFFFFFFFFFFFFFFFFFFFF + FFFFF1E5DBFFC68655FFFFFFFF00FFFFFF00E1AE87FFFAF4F0FF59B163FF54AB + 5EFF4FA358FF4FA358FF489B51FF42924AFF3B8842FF347E3AFF2E7533FF276D + 2CFFF0E2D8FFC48654FFFFFFFF00FFFFFF00DFAA82FFF9F3EFFF58B162FFB9DF + BDFFB6DDBAFFB6DDBAFFACD8B0FFA0D3A4FF92CC97FF84C68AFF79C17EFF2265 + 26FFF0E2D8FFC88D5FFFFFFFFF00FFFFFF00DDA87EFFF9F3EFFF4FA358FF489B + 51FF42924AFF42924AFF3B8842FF347E3AFF2E7533FF276D2CFF226526FF1D5F + 21FFF0E2D8FFC68A5CFFFFFFFF00FFFFFF00D9A47AFFF9F3EEFFEBD2BEFFFFFF + FFFFEBD3BFFFFFFFFFFFFFFFFFFFFFFFFFFFEAC7ADFFFFFFFFFFFFFFFFFFFFFF + FFFFF0E2D8FFC68C5FFFFFFFFF00FFFFFF00D7A175FFF8F2EDFFF7F0EAFFF6ED + E6FFF4EAE2FFF3E7DEFFF1E4DBFFF0E2D8FFF0E2D8FFF0E2D8FFF0E2D8FFF0E2 + D8FFF0E2D8FFC58A5DFDFFFFFF00FFFFFF00D69E72C4D3996EF4D19668FFCE92 + 63FFCB8E5EFFC98A5BFFC78756FFC38452FFC38452FFC38452FFC38452FFC384 + 52FFC38452FFBB7742B0FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007591C3FF235BC0FF0543 + BCFF1D58BFFF7591C2FFFFFFFF00FFFFFF00EFC2A37EEFC1A2E3EDC09FFFEBBE + 9DFFEBBC9AFFE9BA96FFE7B793FFE6B590FF96B1E3FF3D76D2FF8DB5F7FFB8D6 + FEFF72A8F5FF2E6BCAFF0443BA6DFFFFFF00EEC1A1EBFBF7F4FFFBF7F4FFFBF7 + F4FFFBF7F4FFFBF7F4FFFBF7F4FFFBF7F4FF255DC2FF8DB5F6FF4D92FFFF1177 + FFFF2186FFFF408AEBFF0344B9DEFFFFFF00ECBF9EFFFBF7F4FF9CD5A5FF98D3 + A1FF94D09DFF90CE98FF8BCB93FF87C98EFF0543BCFFAECDFEFFFFFFFFFFFFFF + FFFFFFFFFFFF187FEFFF0442BCFEFFFFFF00EBBD9BFFFBF7F4FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF164BAEFF639DF4FF187FFFFF0076 + F8FF0076EEFF0368E1FF0345B9E4FFFFFF00E9BA98FFFBF7F4FF6D6FFCFF7478 + FEFF7478FEFFE9C3A6FFE9C3A6FFE9C3A6FF818DB5FF2865C8FF2177E6FF0579 + EAFF0164DDFF064EBCFF0345B87AFFFFFF00E7B794FFFBF7F4FF6263FAFFC4CE + FDFF7478FEFFFFFFFFFFFFFFFFFFFFFFFFFFE8C7ACFF95B0E3FF235CC2FF0543 + BCFF1E58BEFF6B6C8AFFFFFFFF00FFFFFF00E5B48FFFFAF6F2FF5654F7FFC1CB + FCFF6D6FFCFFE9C7ADFFE9C9AEFFE9C9B0FFE8C7ACFFE9C9B0FFE8C8B0FFE8CC + B5FFF2E7DEFFC88A59FFFFFFFF00FFFFFF00E3B18CFFFAF6F1FF3A35F1FFB1B9 + FBFF5654F7FFFFFFFFFFFFFFFFFFFFFFFFFFE8C7ACFFFFFFFFFFFFFFFFFFFFFF + FFFFF1E5DBFFC68655FFFFFFFF00FFFFFF00E1AE87FFFAF4F0FF2E26EEFFA6AD + FBFF4845F4FFEACCB3FFEACCB3FFEACEB7FFE8C7ACFFE8C7ACFFE8C8B0FFE8C8 + AEFFF0E2D8FFC48654FFFFFFFF00FFFFFF00DFAA82FFF9F3EFFF231AECFF9CA2 + FAFF3A35F1FFFFFFFFFFFFFFFFFFFFFFFFFFEACFBAFFFBF6F2FFFFFFFFFFFFFF + FFFFF0E2D8FFC88D5FFFFFFFFF00FFFFFF00DDA87EFFF9F3EFFF1C11EAFF9399 + F9FF2E26EEFFEBD0BBFFEBD0BBFFEBD1BDFFEACDB5FFEACDB5FFEACDB5FFEACD + B5FFF0E2D8FFC68A5CFFFFFFFF00FFFFFF00D9A47AFFF9F3EEFF1C11EAFF1C11 + EAFF231AECFFFFFFFFFFFFFFFFFFFFFFFFFFEAC7ADFFFFFFFFFFFFFFFFFFFFFF + FFFFF0E2D8FFC68C5FFFFFFFFF00FFFFFF00D7A175FFF8F2EDFFF7F0EAFFF6ED + E6FFF4EAE2FFF3E7DEFFF1E4DBFFF0E2D8FFF0E2D8FFF0E2D8FFF0E2D8FFF0E2 + D8FFF0E2D8FFC58A5DFDFFFFFF00FFFFFF00D69E72C4D3996EF4D19668FFCE92 + 63FFCB8E5EFFC98A5BFFC78756FFC38452FFC38452FFC38452FFC38452FFC384 + 52FFC38452FFBB7742B0FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007590C3FF2359BFFF0541 + BBFF1D55BFFF758FC1FFFFFFFF00FFFFFF00EFC1A37EEFC0A1E3EDBF9FFFEBBD + 9DFFEBBB99FFE9B995FFE7B693FFE6B390FF95B0E3FF3D73D1FF8DB3F7FFB8D5 + FEFF71A5F5FF2E69CAFF0440BA6DFFFFFF00EEBFA0EBFBF6F3FFFBF6F3FFFBF6 + F3FFFBF6F3FFFBF6F3FFFBF6F3FFFBF6F3FF255BC1FF8CB2F6FF4D91FFFF1174 + FFFF2184FFFF3F86EBFF0342B9DEFFFFFF00ECBE9EFFFBF6F3FF9BD5A3FF97D3 + A0FF94D09DFF90CE97FF8BCB92FF87C98DFF0541BBFFAECCFEFFFFFFFFFFFFFF + FFFFFFFFFFFF187BEEFF0441BCFEFFFFFF00EBBC9BFFFBF6F3FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1648AEFF629CF4FF177BFFFF0073 + F8FF0073EEFF0366E1FF0342B9E4FFFFFF00E9B997FFFBF6F3FFE9C1A5FFE9C1 + A5FFE9C1A5FFE9C1A5FFE9C1A5FFE9C1A5FF818CB5FF2862C8FF2075E6FF0577 + E9FF0164DDFF064BBCFF0342B77AFFFFFF00E7B693FFFBF6F3FFE9C1A5FFFFFF + FFFFE8C2A8FFFFFFFFFFFFFFFFFFFFFFFFFFE8C7ACFF95AFE3FF235AC1FF0541 + BBFF1E56BEFF6B6B89FFFFFFFF00FFFFFF00E5B28FFFFAF6F2FFE9C4A9FFE9C4 + ABFFEAC6ACFFE9C7ADFFE9C8ADFFE9C8AFFFE8C7ACFFE9C8AFFFE8C7B0FFE8CB + B4FFF2E7DEFFC88858FFFFFFFF00FFFFFF00E3AF8BFFFAF5F0FFEAC9AEFFFFFF + FFFFEAC8B0FFFFFFFFFFFFFFFFFFFFFFFFFFE8C7ACFFFFFFFFFFFFFFFFFFFFFF + FFFFF1E4DBFFC58555FFFFFFFF00FFFFFF00E1AE87FFFAF4F0FF7476FEFF7476 + FEFF7476FEFF6C6CFCFF6262FAFF5353F7FF4644F4FF3835F1FF2C26EEFF211A + ECFFF0E2D8FFC48454FFFFFFFF00FFFFFF00DFA881FFF9F3EFFF7476FEFFC3CC + FDFFC3CCFDFFC0CAFCFFBAC2FCFFB1B8FBFFA5AAFBFF9CA0FAFF9398F9FF1B11 + E9FFF0E2D8FFC88B5EFFFFFFFF00FFFFFF00DDA67DFFF9F3EFFF6C6CFCFF6262 + FAFF6262FAFF5353F7FF4644F4FF3835F1FF2C26EEFF211AECFF1B11E9FF1B11 + E9FFF0E2D8FFC6895CFFFFFFFF00FFFFFF00D9A279FFF9F2EDFFEBD0BDFFFFFF + FFFFEBD2BFFFFFFFFFFFFFFFFFFFFFFFFFFFEAC5ACFFFFFFFFFFFFFFFFFFFFFF + FFFFF0E2D8FFC68B5EFFFFFFFF00FFFFFF00D79F75FFF8F1ECFFF7EFE9FFF6EC + E6FFF4E9E2FFF3E6DDFFF1E3DBFFF0E2D8FFF0E2D8FFF0E2D8FFF0E2D8FFF0E2 + D8FFF0E2D8FFC5885DFDFFFFFF00FFFFFF00D69D72C4D3976DF4D09568FFCE90 + 62FFCB8C5DFFC9885BFFC78655FFC28252FFC28252FFC28252FFC28252FFC282 + 52FFC28252FFBA7642B0FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00C77947AACC8655CECC8857DECB8856DBCC88 + 56DBCB8757DBCA8350D0C479426EB2673C08FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00CA8554D0FFFFFFDBFDF3E9DEFDF3EADEFCF2 + E8DEFAEFE3DEFAF2E7DEEABB88DECF85559CB4693D0AFFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00CB8656DAFEF5EDDEFCDEC5DEFBE0C7DEF9DC + C2DEF5D3B4DEFEF9F3DEFAE2C4DEECC193DEC37D4880FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00CB8655DBFEF6F0DEFCE2CDDEFCE3CDDEFADF + C8DEF7D9BCDEF5E9DDDEFAF3EBDEFBF8F3DECD9565DCFFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00CB8655DBFEF7F1DEFCE5D2DEFCE4D1DEFBE2 + CCDEF9DDC4DEEAC39DFFE6BF96FFE4BB92FFE4BB92FFD1A06CF5D09E6DF6CC96 + 5FDAC479427EB2673C09FFFFFF00CB8654DBFFF7F2DEFEE7D5DEFEE7D5DEFDE5 + D1DEFAE0CADEE5BE96FFFFFFFEFFFDF3E9FFFDF3EAFFFCF2E8FFFAEFE3FFFAF2 + E7FFEABB88FFCF8555B3B4693D0CCB8553DBFFF7F0DEFFE7D5DEFDE7D6DEFDE6 + D4DEFCE4D0DEE4BB93FFFEF5EDFFFCDEC5FFFBE0C7FFF9DCC2FFF5D3B4FFFEF9 + F3FFFAE2C4FFECC193FFC37D4893CA8452DBFFF7F1DEFFE9D9DEFFEADBDEFFE9 + D9DEFFE7D7DEE4BB92FFFEF6F0FFFCE2CDFFFCE3CDFFFADFC8FFF7D9BCFFF5E9 + DDFFFAF3EBFFFBF8F3FFCA8353FECC8352DBFBF5EEDEFFE9D9DEFFEADBDEFFE9 + D9DEFFE7D7DEE4BB92FFFEF7F1FFFCE5D2FFFCE4D1FFFBE2CCFFF9DDC4FFF6D7 + BBFFF3D1AFFFFAEFE4FFCC8758FECF8253DEEFF1E7DEFFE9D9DEFFEADBDEFFE9 + D9DEFFE7D7DEE4BB91FFFFF7F2FFFEE7D5FFFEE7D5FFFDE5D1FFFAE0CAFFF9DE + C4FFF7D9BCFFFDF2E7FFCC8757FEC87C4ED3FCF3ECDEFAF1E8DEFAF0E7DEFBF1 + E9DEFBF2EADEE4BA91FFFFF7F0FFFFE7D5FFFDE7D6FFFDE6D4FFFCE4D0FFFBE3 + CBFFFADCC2FFFEF3E8FFCC8656FEC7794AB9C8794BCEC87545DDC77545D4C875 + 45D4C77545D4CA8452FFFFF7F1FFFFE9D9FFFFEADBFFFFE9D9FFFFE7D7FFFFE5 + D2FFFFE2CBFFFFF7F1FFCB8555FEFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00CC8352FBFBF5EEFFFFE9D9FFFFEADBFFFFE9D9FFFFE7D7FFFFE5 + D2FFFFE2CBFFFBF6EFFFCC8355FEFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00CF8253FFEFF1E7FFFFE9D9FFFFEADBFFFFE9D9FFFFE7D7FFFFE5 + D2FFFFE2CBFFEFF2E8FFCE8156FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00C77949EDFCF3ECFFFAF1E8FFFAF0E7FFFBF1E9FFFBF2EAFFFBF2 + EAFFFBF2EBFFFDF4EEFFCA8054F9FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00C57342C1C67545E6C87545FEC77545F3C87545F3C77545F3C775 + 45F3C87546F4C57444E8CA7F53F1FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00996A252AA77B3E9E92611905FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00A67B3E69CBAE87E4905D1409FFFFFF00FFFFFF00FFFF + FF0092601702FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00A97E436ED5BC9DF89261190FFFFFFF00FFFFFF009867 + 222DAE854CB5FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00AB814774DEC8AEFF95641D1EFFFFFF0093601827D1B6 + 93E4BB9767B6FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00AD844C7BE6D4C0FF96651E248F5C121DD3B999DCD3B8 + 97E1915E1518FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00AF875084EDDECEFF97662063CEB38FCBE7D6C3FC9666 + 203BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00B28A5489F1E2D3FFCFB38EF6F5E9DCFFA276376CFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF005E3D0D02FFFFFF00B68F598BF5E9DDFFE2CDB4FFB99461A0FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006644121A9D69 + 32ABB17E42D29E682CA4BC9767CDF0E0D0FFB6915FC581531104FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0066431218B17E42DBDCAA + 60FFD09E54F3EAB365FFD8BA99FFF8EBE1FFAE8957BC57390D41FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF009C6A32ACD6A55EFD704D + 1A3E6E4B184FE4AD60FFDCBD9BFFEFCDA5FFEFB767FFD8A65DFF66491D64FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00BE8A4AF2A87E41B6FFFF + FF00966E3297E7B066FFCAA274FEE5B167FF945E2DC1B88D4DD3AF703BF44930 + 0B08FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B58244E7D6A45AE8AE82 + 41C5ECB666FFA76E36D8AC6C37EBC49551F3FFFFFF0076562776B77840FF5238 + 121BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0077531E56C79751ECD8A6 + 5AFEA66C36CB51350A18A86835E1D1A057FA412A091E8E6A369CB4753FFC4D33 + 0D10FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00674514186A48 + 1620FFFFFF00FFFFFF009F5E2FC6E7B263FFBF924FE5DDAB62FFA26232D8FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF004A310C07A06131D7B6763FF7A46534E04B320C14FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF002063982A206398FF2063 + 98FF206398FF206398FF206398FF206398F0FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0020639832206398B2206398FF3775A4FFB6EF + FEFF80DBF3FF80DBF3FFB6EFFEFF2E6EA1FF206398FF206398A520639853FFFF + FF00FFFFFF00FFFFFF00FFFFFF00206398E094C9E0FDAEE2F2FF4E9DDFFFB5EE + FDFF75D4F0FF75D4F0FFB5EEFDFF4B9BDEFF8ECBE9FF8DCAE8F2206398F3FFFF + FF00FFFFFF00FFFFFF00FFFFFF00206398FFB0E1F2FF79BDE2FF4498DDFF4497 + DCFF4396DCFF4296DCFF4295DCFF4195DBFF539ED4FF89C6E6FF206398FFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00206398FFAADDF1FF74B9E0FF70B6DFFF6CB3 + DDFF6BB2DCFFD9AF84FFD7AE81FFD7AC7FFFD7AC7FFFCCA070FFCD9F71FFB38F + 67FFCB8856D6B2673C09FFFFFF00206398FFA5DAEFFF6FB5DEFF68B0DCFF60A9 + D9FF5FA9D9FFD7AD81FFFFFFFEFFFDF3E9FFFDF3EAFFFCF2E8FFFAEFE3FFFAF2 + E7FFEABB88FFCE8959E7B4693D0C206398FF9ED6EDFF6BB2DCFF66AFDCFF60AA + DAFF5FA9D9FFD9AF84FFFEF5EDFFFCDEC5FFFBE0C7FFF9DCC2FFF5D3B4FFFEF9 + F3FFFAE2C4FFECC193FFCB8857DC206398FF98D2EBFF65AEDAFF60AAD9FF5DA6 + D8FF5CA5D7FFD9AF84FFFEF6F0FFFCE2CDFFFCE3CDFFFADFC8FFF7D9BCFFF5E9 + DDFFFAF3EBFFFBF8F3FFCA8353FE206398FF91CDE9FF5FA9D9FF5DA5D8FF5AA0 + D6FF599FD6FFD8AD81FFFEF7F1FFFCE5D2FFFCE4D1FFFBE2CCFFF9DDC4FFF6D7 + BBFFF3D1AFFFFAEFE4FFCC8758FE206398FF8BC9E7FF5CA5D7FF59A0D5FF579C + D3FF569AD3FFD7AC7FFFFFF7F2FFFEE7D5FFFEE7D5FFFDE5D1FFFAE0CAFFF9DE + C4FFF7D9BCFFFDF2E7FFCC8757FE206398FF88C4E6FF599FD6FF569BD3FF5397 + D1FF5395D1FFD7AC7FFFFFF7F0FFFFE7D5FFFDE7D6FFFDE6D4FFFCE4D0FFFBE3 + CBFFFADCC2FFFEF3E8FFCC8656FE206398FF84BFE2FF569AD3FF5397D1FF5092 + CFFF5091CFFFD6A97DFFFFF7F1FFFFE9D9FFFFEADBFFFFE9D9FFFFE7D7FFFFE5 + D2FFFFE2CBFFFFF7F1FFCB8555FE206398FF80B9E1FF5395D1FF5092D0FF4E8E + CEFF4D8CCDFFD6A97DFFFBF5EEFFFFE9D9FFFFEADBFFFFE9D9FFFFE7D7FFFFE5 + D2FFFFE2CBFFFBF6EFFFCC8355FE206398C274ADD8FF7BB2DDFF78AEDCFF75AA + DAFF74A9DAFFDAA97DFFEFF1E7FFFFE9D9FFFFEADBFFFFE9D9FFFFE7D7FFFFE5 + D2FFFFE2CBFFEFF2E8FFCE8156FF2063984A206398CF206398FF206398FF2063 + 98FF206398FFC98F67FFFCF3ECFFFAF1E8FFFAF0E7FFFBF1E9FFFBF2EAFFFBF2 + EAFFFBF2EBFFFDF4EEFFCA8054F9FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00C57342C1C67545E6C87545FEC77545F3C87545F3C77545F3C775 + 45F3C87546F4C57444E8CA7F53F1000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000026EB628026EB669026EB679026E + B679026EB679026EB679026EB679026EB679026EB679026EB679026EB679026E + B679026EB669026EB6280000000000000000026DB46BC1E3F1D9E6FBFFFFE5FA + FFFFE5FAFFFFE5FAFFFFE5FAFFFFE5FAFFFFE5FAFFFFE4FAFFFFE4FAFFFFE5FA + FFFFBDE2F1D9026DB46B0000000000000000026BB17EE5FAFFFFD9F4FFFFD9F4 + FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4 + FFFFE0F8FFFF026BB17E0000000000000000026AAE81E0F9FFFFD4F2FFFFD4F2 + FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2 + FFFFD9F5FFFF026AAE8100000000000000000268AB84DCF7FFFFCFF0FFFFCFF0 + FFFFCFF0FFFFC2EDFCFFA8E8F4FF91E3EDFF84E0E9FF7CDEE7FF7CDEE7FF84E0 + E9FF9CE6EFFF0268AB8400000000000000000266A788D8F4FFFFCCEEFFFFC2EC + FCFF9DE5F1FF85E0EAFF82E0E9FF82E0E9FF82E0E9FF82E0E9FF82E0E9FF82E0 + E9FF8AE2EBFF0266A78800000000000000000264A48CD6F3FFFFB6EBF9FF94E4 + F0FF8FE3EEFF8FE3EEFF8FE3EEFF8FE3EEFF8FE3EEFF45C05FFF2DB42FFF45C0 + 5FFF91E4EFFF0264A48C00000000000000000261A090C1EFFBFF9EE7F4FF9DE6 + F4FF9DE6F4FF9DE6F4FF9DE6F4FF9DE6F4FF9DE6F4FF2FB130FF75EE64FF2FB1 + 30FF9DE6F4FF0261A0900000000000000000025F9C8191D0E6E1B0ECF9FFAEEB + F9FFADEBF9FFACEBF9FFABEAF9FF4EBB63FF30AC31FF30AC31FF66EB55FF30AC + 31FF26A529F90D8C27CD0000000000000000025C9832025C9785025C9799025C + 9799B7EDFDFF025C9799025C97990E8D13EB52E741FF52E741FF52E741FF52E7 + 41FF52E741FF0F9207D600000000000000000000000000000000000000000355 + 8BA603558BA603568D39035993020E8D00990E8C00CC0E8C00CC3DE22CFF0E8C + 00CC0E8C00CC0E8D00990000000000000000000000000000000000000000034D + 7DB5034E7F3D000000000000000000000000000000000C8300CC2BDF1AFF0C83 + 00CC000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000066D0099056900CC066D + 0099000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000026EB628026EB669026EB679026E + B679026EB679026EB679026EB679026EB679026EB679026EB679026EB679026E + B679026EB669026EB6280000000000000000026DB46BC1E3F1D9E6FBFFFFE5FA + FFFFE5FAFFFFE5FAFFFFE5FAFFFFE5FAFFFFE5FAFFFFE4FAFFFFE4FAFFFFE5FA + FFFFBDE2F1D9026DB46B0000000000000000026BB17EE5FAFFFFD9F4FFFFD9F4 + FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4 + FFFFE0F8FFFF026BB17E0000000000000000026AAE81E0F9FFFFD4F2FFFFD4F2 + FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2 + FFFFD9F5FFFF026AAE8100000000000000000268AB84DCF7FFFFCFF0FFFFCFF0 + FFFFCFF0FFFFC2EDFCFFA8E8F4FF91E3EDFF84E0E9FF7CDEE7FF7CDEE7FF84E0 + E9FF9CE6EFFF0268AB8400000000000000000266A788D8F4FFFFCCEEFFFFC2EC + FCFF9DE5F1FF85E0EAFF82E0E9FF82E0E9FF82E0E9FF82E0E9FF82E0E9FF82E0 + E9FF8AE2EBFF0266A78800000000000000000264A48CD6F3FFFFB6EBF9FF94E4 + F0FF8FE3EEFF8FE3EEFF8FE3EEFF8FE3EEFF8FE3EEFF8FE3EEFF8FE3EEFF8FE3 + EEFF91E4EFFF0264A48C00000000000000000261A090C1EFFBFF9EE7F4FF9DE6 + F4FF9DE6F4FF9DE6F4FF9DE6F4FF9DE6F4FF9DE6F4FF9DE6F4FF9DE6F4FF9DE6 + F4FF9DE6F4FF0261A0900000000000000000025F9C8191D0E6E1B0ECF9FFAEEB + F9FFADEBF9FFACEBF9FFABEAF9FF445DC7FF222EB7FF222EB7FF222EB7FF222E + B7FF1824B2F90018A3CD0000000000000000025C9832025C9785025C9799025C + 9799B7EDFDFF025C9799025C9799000C97EB5E5EF7FF5E5EF7FF5E5EF7FF5E5E + F7FF5E5EF7FF000498D600000000000000000000000000000000000000000355 + 8BA603558BA603568D390359930200008499000080CC000080CC000080CC0000 + 80CC000080CC000084990000000000000000000000000000000000000000034D + 7DB5034E7F3D0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000026EB628026EB669026EB679026E + B679026EB679026EB679026EB679026EB679026EB679026EB679026EB679026E + B679026EB669026EB6280000000000000000026DB46BC1E3F1D9E6FBFFFFE5FA + FFFFE5FAFFFFE5FAFFFFE5FAFFFFE5FAFFFFE5FAFFFFE4FAFFFFE4FAFFFFE5FA + FFFFBDE2F1D9026DB46B0000000000000000026BB17EE5FAFFFFD9F4FFFFD9F4 + FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4FFFFD9F4 + FFFFE0F8FFFF026BB17E0000000000000000026AAE81E0F9FFFFD4F2FFFFD4F2 + FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2FFFFD4F2 + FFFFD9F5FFFF026AAE8100000000000000000268AB84DCF7FFFFCFF0FFFFCFF0 + FFFFCFF0FFFFC2EDFCFFA8E8F4FF91E3EDFF84E0E9FF7CDEE7FF7CDEE7FF70B7 + D8FF3148E3FF013FB5A300000000000000000266A788D8F4FFFFCCEEFFFFC2EC + FCFF9DE5F1FF85E0EAFF82E0E9FF82E0E9FF82E0E9FF82E0E9FF7BCCD3FF5E8E + ADFF8080FFFF010FAFE200000000000000000264A48CD6F3FFFFB6EBF9FF94E4 + F0FF8FE3EEFF8FE3EEFF8FE3EEFF8FE3EEFF8FE3EEFF6BD2E1FF71A2A8FFF7F7 + F7FF4E7390FF013BA1AC00000000000000000261A090C1EFFBFF9EE7F4FF9DE6 + F4FF9DE6F4FF9DE6F4FF9DE6F4FF9DE6F4FF76D5E5FF2EADC3FF79E6F7FF6085 + 8DFF83BFCBFF0261A0900000000000000000025F9C8191D0E6E1B0ECF9FFAEEB + F9FFADEBF9FFACEBF9FFABEAF9FF80D8E9FF32AFC5FF79E6F7FF2C99AEFF80BF + CDFF86CCE5E1025F9C810000000000000000025C9832025C9785025C9799025C + 9799B7EDFDFF025C97990174A3B2018BABE179E6F7FF017895E5016491B4025C + 9799025C9785025C983200000000000000000000000000000000000000000355 + 8BA603558BA6016798570196AFB679E6F7FF017E95BE00728944000000000000 + 000000000000000000000000000000000000000000000000000000000000034D + 7DB5034E7F3D016D917FD9F4FFFF017E95BE0072894400000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000FF014F68AB015F773D0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000C7740200CB770200DB830300E1870308E58A + 0344E68B038AE68B03ACE68B03BBE68B03ACE68B038AE58A0344E1870308DB83 + 0300CB770200C7740200C7740200C7740200CB770200D9820320DB830399E29C + 37CFECC487EBF2D5A6F8F2D9B2FEFCF1CDF8F6DCA5EBE6A645CFDB830399D982 + 0320CB770200C7740200C7740200C7740200C9760220CF7F0FB0E2B36FE6EFD7 + ABFFFCF2CCFFF1D5A5FFEFCE9BFFF8EAC6FFFFFAD7FFFFF9D7FFEDCB8EE6CF7F + 0FB0C9760220C7740200C7740200B5670209BA6A029EDDB06FE7E7C389FFF8E7 + BAFFFEF2CCFFEFD4A5FFF2D9ADFFF8E9C3FFFCF0CAFFFFF5CAFFFFF4C6FFE6C3 + 86E7BA6A029EB5670209B5670200A65C0147B87A2AD5DAA95FFFDFB268FFF4D9 + A1FFE4BE82FFE4BD7DFFF3D8A7FFFFEDBFFFDCB57EFFF4D9A3FFFFE8AEFFFBE3 + ACFFB67525D5A65C0147A35A010097510192CE9D5EEFD79E48FFD8A045FFD8A3 + 4FFFDCAA57FFDEAD5DFFDFB069FFD2A05CFFC9934EFFFAD18FFFEDBF7AFFE0AD + 62FFCE9D5AEF9751019297510100894700B8E8B571FAD49541FFCD8F2FFFD498 + 38FFD49B3BFFD59C3EFFCF953CFFE6AD5EFFFDC577FFF5BB6CFFCE8F3EFFCB8B + 30FFCE984AFA894700B889470000814100C9BC7F38FEE59E43FFC98525FFCD8C + 28FFCE8C29FFCE8D2AFFCB8A29FFCE8A32FFD7903EFFF5AD54FFB9741DFFD48D + 32FFC88C3EFE814100C981410000804000B9CB8A3BFAC88221FFCC8724FFCE8A + 25FFCE8A27FFCE8A27FFCE8A28FFC88425FFDC9036FFF5A546FFB96F1EFFFFAD + 4BFFE9A351FA804000B98040000085430094B8772BF0D28926FFD38B28FFD48E + 2CFFD48F30FFD59132FFD59132FFD18D30FFDC9137FFD1842FFF619B13FF44AA + 0EFF609E19F885430094854300008D480049A35D12DADC9133FFDC9132FFDE95 + 3AFFDF9942FFDF9C47FFE09D48FFDF9B46FFDC9741FFCF8635FF43A812FF75EE + 64FF309A06F86E5E00494F720000964E0009995000A4CA7E28EBE79942FFE9A0 + 4EFFEAA659FFEBAA60FFEBAB63FFEBAA60FF68A023FF3A9B0FFF41A617FF66EB + 55FF259300ED139D00CE129C0099A2570000A4580022AA5D04BAD48732EBF0A8 + 5EFFF2B06BFFF3B473FFF3B576FFF3B473FF3D9B16FF52E741FF52E741FF52E7 + 41FF52E741FF52E741FF109500CCA2570000A5590000B0600022B16100A4C576 + 1CD9E59B4FF0F1AD6AFAF6B475FEF1AD6AFA61901CF72E8805F8258600ED3DE2 + 2CFF0E8C00CC0E8C00CC0E8D0099A2570000A5590000B1610000B6640009B967 + 0049BA670094BA6700B9BA6700C9BA6700B9BA670094B96700490D8300CE2BDF + 1AFF0C8300CC0D8800000E8C0000A2570000A5590000B1610000B6640000BA67 + 0000BC680000BC680000BC680000BC680000BC680000626D0000066D00990569 + 00CC066D0099077100000E8C0000C7740200CB770200DB830300E1870308E58A + 0344E68B038AE68B03ACE68B03BBE68B03ACE68B038AE58A0344E1870308DB83 + 0300CB770200C7740200647F5100C7740200CB770200D9820320DB830399E29C + 37CFECC487EBF2D5A6F8F2D9B2FEFCF1CDF8F6DCA5EBE6A645CFDB830399D982 + 0320CB770200C7740200C7740200C7740200C9760220CF7F0FB0E2B36FE6EFD7 + ABFFFCF2CCFFF1D5A5FFEFCE9BFFF8EAC6FFFFFAD7FFFFF9D7FFEDCB8EE6CF7F + 0FB0C9760220C7740200C7740200B5670209BA6A029EDDB06FE7E7C389FFF8E7 + BAFFFEF2CCFFEFD4A5FFF2D9ADFFF8E9C3FFFCF0CAFFFFF5CAFFFFF4C6FFE6C3 + 86E7BA6A029EB5670209B5670200A65C0147B87A2AD5DAA95FFFDFB268FFF4D9 + A1FFE4BE82FFE4BD7DFFF3D8A7FFFFEDBFFFDCB57EFFF4D9A3FFFFE8AEFFFBE3 + ACFFB67525D5A65C0147A35A010097510192CE9D5EEFD79E48FFD8A045FFD8A3 + 4FFFDCAA57FFDEAD5DFFDFB069FFD2A05CFFC9934EFFFAD18FFFEDBF7AFFE0AD + 62FFCE9D5AEF9751019297510100894700B8E8B571FAD49541FFCD8F2FFFD498 + 38FFD49B3BFFD59C3EFFCF953CFFE6AD5EFFFDC577FFF5BB6CFFCE8F3EFFCB8B + 30FFCE984AFA894700B889470000814100C9BC7F38FEE59E43FFC98525FFCD8C + 28FFCE8C29FFCE8D2AFFCB8A29FFCE8A32FFD7903EFFF5AD54FFB9741DFFD48D + 32FFC88C3EFE814100C981410000804000B9CB8A3BFAC88221FFCC8724FFCE8A + 25FFCE8A27FFCE8A27FFCE8A28FFC88425FFDC9036FFF5A546FFB96F1EFFFFAD + 4BFFE9A351FA804000B98040000085430094B8772BF0D28926FFD38B28FFD48E + 2CFFD48F30FFD59132FFD59132FFD18D30FFDC9137FFD1842FFFE8993BFFFFAC + 47FFDD9543F085430094854300008D480049A35D12DADC9133FFDC9132FFDE95 + 3AFFDF9942FFDF9C47FFE09D48FFDF9B46FFDC9741FFCF8635FFFFB656FFFFB6 + 56FFAE691CDA6A362B4946245400964E0009995000A4CA7E28EBE79942FFE9A0 + 4EFFEAA659FFEBAA60FFEBAB63FFEBAA60FF5D4287FF2C1E95FF33289CFF291E + 95FB150B90ED0201A6CE0000A699A2570000A4580022AA5D04BAD48732EBF0A8 + 5EFFF2B06BFFF3B473FFF3B576FFF3B473FF31248FFF5E5EF7FF5E5EF7FF5E5E + F7FF5E5EF7FF5E5EF7FF000098CCA2570000A5590000B0600022B16100A4C576 + 1CD9E59B4FF0F1AD6AFAF6B475FEF1AD6AFA583B6BF723156EF8190E6EED0503 + 7CD3000080CC000080CC00008499A2570000A5590000B1610000B6640009B967 + 0049BA670094BA6700B9BA6700C9BA6700B9BA670094B9670049633737090000 + 7700000077000000770000008000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00C7740200CB770200DB830300E1870308E58A + 0344E68B038AE68B03ACE68B03BBE68B03ACE68B038AE58A0344E18703089A6D + 2C002B2B9D390101DEAF0101C640C7740200CB770200D9820320DB830399E29C + 37CFECC487EBF2D5A6F8F2D9B2FEFCF1CDF8F6DCA5EBE6A645CFDB830399956A + 2D4038386F7C8080FFFF0101B1C1C7740200C9760220CF7F0FB0E2B36FE6EFD7 + ABFFFCF2CCFFF1D5A5FFEFCE9BFFF8EAC6FFFFFAD7FFFFF9D7FFB1BF97EB8A64 + 2FD2F7F7F7FF1A1A468E00009F46B5670209BA6A029EDDB06FE7E7C389FFF8E7 + BAFFFEF2CCFFEFD4A5FFF2D9ADFFF8E9C3FFFCF0CAFFC2E1C6FF4CB3B6FF79E6 + F7FF5C3E16CE281D103600009C00A65C0147B87A2AD5DAA95FFFDFB268FFF4D9 + A1FFE4BE82FFE4BD7DFFF3D8A7FFFFEDBFFFA9B391FF48ABACFF79E6F7FF4198 + 9BFF846F39DEA65C0147A35A010097510192CE9D5EEFD79E48FFD8A045FFD8A3 + 4FFFDCAA57FFDEAD5DFFDFB069FFA2A377FF3C9693FF79E6F7FF3D8F8EFFA29A + 67FFCE9D5AEF9751019297510100894700B8E8B571FAD49541FFCD8F2FFFD498 + 38FFD49B3BFFD59C3EFFB2924CFF449D98FF79E6F7FF3F8E8AFF95854EFFCB8B + 30FFCE984AFA894700B889470000814100C9BC7F38FEE59E43FFC98525FFCD8C + 28FFCE8C29FFCE8D2AFF667B5DFFD9F4FFFF37837FFFB39C60FFB9741DFFD48D + 32FFC88C3EFE814100C981410000804000B9CB8A3BFAC88221FFCC8724FFCE8A + 25FFCE8A27FFCE8A27FF000000FF446052FFAE8747FFF5A546FFB96F1EFFFFAD + 4BFFE9A351FA804000B98040000085430094B8772BF0D28926FFD38B28FFD48E + 2CFFD48F30FFD59132FFD59132FFD18D30FFDC9137FFD1842FFFE8993BFFFFAC + 47FFDD9543F085430094854300008D480049A35D12DADC9133FFDC9132FFDE95 + 3AFFDF9942FFDF9C47FFE09D48FFDF9B46FFDC9741FFCF8635FFFFB656FFFFB6 + 56FFAE691CDA8D4800498B470000964E0009995000A4CA7E28EBE79942FFE9A0 + 4EFFEAA659FFEBAA60FFEBAB63FFEBAA60FFEAA659FFDA9148FFFFC66EFFDA9A + 44EB995000A4964E0009964E0000A2570000A4580022AA5D04BAD48732EBF0A8 + 5EFFF2B06BFFF3B473FFF3B576FFF3B473FFF2B06BFFE49C59FFDEA754EBAB60 + 07BAA4580022A2570000A2570000A2570000A5590000B0600022B16100A4C576 + 1CD9E59B4FF0F1AD6AFAF6B475FEF1AD6AFAE59B4FF0C3731BD9B16100A4B060 + 0022A5590000A2570000A2570000A2570000A5590000B1610000B6640009B967 + 0049BA670094BA6700B9BA6700C9BA6700B9BA670094B9670049B6640009B161 + 0000A5590000A2570000A2570000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003B7F320015A9000015A9000015A9 + 000015A9000015AA009915AA00CC15AA00CC15AA009915A9000015A9000015A9 + 000015A90000119A0000FFFFFF00FFFFFF00119A0000129F000014A8000014A8 + 000014A8000014A800CC72E961FF71E860FF14A800CC14A8000014A8000014A8 + 0000129F0000119A0000FFFFFF00FFFFFF00119A0000119B0000129E000014A5 + 000014A5000014A500CC69E058FF69E058FF14A500CC14A5000014A50000129E + 0000119B0000119A0000FFFFFF00FFFFFF00119A0000119B0000119B0000129D + 000013A2000013A200CC62D951FF61D850FF13A200CC13A20000129D0000119B + 0000119B0000119A0000FFFFFF00FFFFFF00119A0000119B0000119B0000119B + 0000129C0000129E00CC5AD149FF59D048FF129E00CC129C0000119B0000119B + 0000119B0000119A0000FFFFFF00FFFFFF00119A0099119A00CC119A00CC119A + 00CC119A00CC119A00CC54CB43FF52C941FF119A00CC119A00CC119A00CC119A + 00CC119A00CC119A0099FFFFFF00FFFFFF00109600CC5ED54DFF55CC44FF54CB + 43FF53CA42FF52C941FF4BC23AFF4AC139FF4FC63EFF4EC53DFF4DC43CFF4CC3 + 3BFF4EC53DFF109600CCFFFFFF00FFFFFF000F9200CC59D048FF50C73FFF50C7 + 3FFF4FC63EFF4AC139FF3BB32AFF31A920FF31A920FF2CA51BFF2BA31AFF2DA5 + 1CFF33AB22FF0F9200CCFFFFFF00FFFFFF000E8E00990E8D00CC0E8D00CC0E8D + 00CC0E8D00CC0E8D00CC2DAE1CFF2BAC1AFF0E8D00CC0E8D00CC0E8D00CC0E8D + 00CC0E8D00CC0E8E0099FFFFFF00FFFFFF000E8D00000E8C00000E8C00000E8C + 00000E8B00000D8900CC29B618FF27B416FF0D8900CC0E8B00000E8C00000E8C + 00000E8C00000E8D0000FFFFFF00FFFFFF000E8D00000E8C00000E8C00000E8A + 00000C8400000C8400CC25C014FF24C013FF0C8400CC0C8400000E8A00000E8C + 00000E8C00000E8D0000FFFFFF00FFFFFF000E8D00000E8C00000D8800000A7D + 00000A7D00000A7D00CC23CD12FF22CC11FF0A7D00CC0A7D00000A7D00000D88 + 00000E8C00000E8D0000FFFFFF00FFFFFF000E8D00000C830000066D0000066D + 0000066D0000066D00CC22D811FF22D811FF066D00CC066D0000066D0000066D + 00000C8300000E8D0000FFFFFF00FFFFFF000E8D000003600000036000000360 + 000003600000035F0099025D00CC025D00CC035F009903600000036000000360 + 0000036000000E8D0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A7990000A8CC0000A8CC0000 + A8CC0000A8CC0000A8CC0000A8CC0000A8CC0000A8CC0000A8CC0000A8CC0000 + A8CC0000A8CC0000A799FFFFFF00FFFFFF0000009ECC6666EEFF5B5BE3FF5555 + DDFF4F4FD7FF4A4AD2FF4545CDFF4343CBFF4141C9FF4040C8FF3F3FC7FF3E3E + C6FF4040C8FF00009ECCFFFFFF00FFFFFF0000008FCC5F5FE7FF5252DAFF4C4C + D4FF4646CEFF4141C9FF3E3EC6FF3D3DC5FF3C3CC4FF3B3BC3FF3A3AC2FF3939 + C1FF3A3AC2FF00008FCCFFFFFF00FFFFFF0000007E99000078CC000078CC0000 + 78CC000078CC000078CC000078CC000078CC000078CC000078CC000078CC0000 + 78CC000078CC00007E99FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF000101010001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF000101010001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF00010101B501010109010101B50101 + 0109010101B501010109010101B501010109010101B501010109010101B50101 + 0109010101B5FFFFFF00FFFFFF00FFFFFF000101010001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF000101010001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF00010101C3010101C3010101C30101 + 019301010100010101C3010101C3010101C30101010001010193010101C30101 + 01C3010101C3FFFFFF00FFFFFF00FFFFFF000101010001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000FFFFFF00FFFFFF00FFFFFF00000000AA0000000C000000E40000 + 00E4000000E40000000C000000E40000000C000000E4000000E4000000E40000 + 000C000000AAFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670000000D000000670000000D000000670000000D000000330101 + 012B01010181FFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 00000000000000000000000000000000000000000000010101000101012C0101 + 01AE0101012CFFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 000000000000000000000000000001010100010101000101012C010101B00101 + 012C00000036FFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 0000000000000101010001010100010101000101012D010101B30101012D0101 + 01000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 00000101010001010100010101000101012E010101B60101012E010101000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000101 + 010001010100010101000101012F010101B90101012E01010100010101000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF000000007800000000000000000101 + 01000101010001010130010101BC0101012F0101010001010100000000000000 + 000000000078FFFFFF00FFFFFF00FFFFFF000000001000000000010101000101 + 010001010131010101C001010130010101000101010001010100000000000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000010101000101 + 0132010101C40101013101010100010101000101010000000000000000000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000010101320101 + 01C7010101320101010001010100010101000101010001010100010101000000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101014500000034010101CC0101 + 0133010101000101010001010100010101000101010001010100010101000101 + 010001010189FFFFFF00FFFFFF00FFFFFF0001010138000000D9010101360101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010113FFFFFF00FFFFFF00FFFFFF00000000AC01010139010101540101 + 0115010101A401010115010101A401010115010101A401010115010101A40101 + 01150101017BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00010101810101012B000000330000 + 000D000000670000000D000000670000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF000101012C010101AE0101012C0101 + 0100000000000000000000000000000000000000000000000000000000000000 + 00000000000DFFFFFF00FFFFFF00FFFFFF00000000360101012C010101B00101 + 012C010101000101010000000000000000000000000000000000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E010101000101012D0101 + 01B30101012D0101010001010100010101000000000000000000000000000000 + 00000000000EFFFFFF00FFFFFF00FFFFFF000000007100000000010101000101 + 012E010101B60101012E01010100010101000101010000000000000000000000 + 000000000071FFFFFF00FFFFFF00FFFFFF000000000F00000000010101000101 + 01000101012E010101B90101012F010101000101010001010100000000000000 + 00000000000FFFFFFF00FFFFFF00FFFFFF000000007800000000000000000101 + 0100010101000101012F010101BC010101300101010001010100000000000000 + 000000000078FFFFFF00FFFFFF00FFFFFF000000001000000000000000000101 + 0100010101000101010001010130010101C00101013101010100010101000000 + 000000000010FFFFFF00FFFFFF00FFFFFF000000008000000000000000000000 + 000001010100010101000101010001010131010101C401010132010101000000 + 000000000080FFFFFF00FFFFFF00FFFFFF000000001100000000010101000101 + 01000101010001010100010101000101010001010132010101C7010101320000 + 000000000011FFFFFF00FFFFFF00FFFFFF000101018901010100010101000101 + 0100010101000101010001010100010101000101010001010133010101CC0000 + 003401010145FFFFFF00FFFFFF00FFFFFF000101011401010100010101000101 + 0100010101000101010001010100010101000101010001010100010101360000 + 00D901010138FFFFFF00FFFFFF00FFFFFF000101017B01010115010101A40101 + 0115010101A401010115010101A401010115010101A401010115010101540101 + 0139000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0001010181010101AC010101AC0101 + 01AC010101AC010101AC010101AC010101AC010101AC010101AC010101AC0101 + 01AC01010181FFFFFF00FFFFFF00FFFFFF000101010001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF000101010001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF00010101B5010101B5010101B50101 + 01B5010101B5010101B5010101B5010101B5010101B5010101B5010101B50101 + 01B5010101B5FFFFFF00FFFFFF00FFFFFF00010101BA010101BA010101BA0101 + 01BA010101BA010101BA010101BA010101BA010101BA010101BA010101BA0101 + 01BA010101BAFFFFFF00FFFFFF00FFFFFF000101010001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF000101010001010100010101000101 + 0100010101000101010001010100010101000101010001010100010101000101 + 010001010100FFFFFF00FFFFFF00FFFFFF00010101C8010101C8010101C80101 + 01C8010101C8010101C8010101C8010101C8010101C8010101C8010101C80101 + 01C8010101C8FFFFFF00FFFFFF00FFFFFF00010101D1010101D1010101D10101 + 01D1010101D1010101D1010101D1010101D1010101D1010101D1010101D10101 + 01D1010101D1FFFFFF00FFFFFF00FFFFFF00000000AA000000E4000000E40000 + 00E4000000E4000000E4000000E4000000E4000000E4000000E4000000E40000 + 00E4000000AAFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 + 000001535F0001A6BE0001A6BE0051515100515151000101E5000101E5160101 + D1000000B3000000B3000000B300000000000000000000000000003E530001A6 + BE0001A6BE0001A6BE0001A6BE0051515100515151000101E53C0101E1AE0101 + CF870000B3000000B3000000B300003E5300003E5300007CA500007CA50001A6 + BE0001A6BE0001A6BE0001A6BE0051515100505050264141416F7575FEFF4747 + E2E90000AE440000AE000000AE00007CA500007CA500007CA500007CA50001A6 + BE0001A6BE0001A6BE0001A6BE00505050264141416FFDFDFDFFACACACD50000 + AAC40000A5000000A5000000A500007CA500007CA500007CA500007CA50001A6 + BE0001A6BE0001A6BE0001A5BD3F019AB2B452C6D7FF33AABCF0090909880101 + 7C000000A0000000A0000000A000007CA500007CA500007CA500007CA50001A6 + BE0001A6BE0001A5BD3F019AB2B47BE8F9FF50C1D4EA006F86C3041E24000202 + 52000000A0000000A0000000A000007CA500007CA500007CA500007CA50001A6 + BE0001A5BD3F019AB2B47BE8F9FF50C1D4EA006F86C3006A8000023641000202 + 52000000A0000000500000000000007CA500007CA500007CA500007CA50001A5 + BD3F019AB2B47BE8F9FF50C1D4EA006F86C3006A800000687E00023641000101 + 290000000000000000000000000000749A0000749A0000759C000078A01E0D7A + 9D7D66DDEEFF34A2B6E8006F86C3006A800000687E0000343F00000000000000 + 0000000000000000000000000000006C8F00006C8F00006E9201016C8F82CCEE + FFFF015672A00150697A01647B0000343F000000000000000000000000000000 + 000000000000000000000000000001688900016889000165868CA6D5E6FF0152 + 6CA7013B4E490127340000000000000000000000000000000000000000000000 + 00000000000000000000000000004D33800000000000000000FF014F68AA013B + 4E2B00000077000000EA000000D9000000C3000000AA0000008D0000006F0000 + 0052000000370000001E0000000C9966FF009865FF004B3280004B58B300925F + FF00482F8000472D8000452C8000442B80004329800041288000402780003F26 + 80003E2580003D2480003C2380009966FF009865FFFF9663FFFF9461FFFF925F + FFFF905DFFFF8D5AFFFF8A57FFFF8855FFFF8552FFFF824FFFFF804DFFFF7E4B + FFFF7C49FFFF7A47FFFF7845FFC09966FFFF9865FFFF9663FFFF9461FFFF925F + FFFF905DFFFF8D5AFFFF8A57FFFF8855FFFF8552FFFF824FFFFF804DFFFF7E4B + FFFF7C49FFFF7A47FFFF7845FFFF9966FF009865FFFF9663FFFF9461FFFF925F + FFFF905DFFFF8D5AFFFF8A57FFFF8855FFFF8552FFFF824FFFFF804DFFFF7E4B + FFFF7C49FFFF7A47FFFF7845FFC0FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000004D0000000D000000670000 + 000D000000670000000D000000670000000D000000670000000D000000670000 + 000D0000004DFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000000000000000000000000000D000000000000000000000000000000000000 + 000000000013FFFFFF00FFFFFF00FFFFFF000000006B00000000000000000000 + 000000000000000000000000006B000000000101650001013000000000000000 + 00000000006BFFFFFF00FFFFFF00FFFFFF000000000E00000000000000000000 + 000001525E002B2B2B0016164F0E0101A9000101C9000101BD00000000000000 + 000000000024FFFFFF00FFFFFF00FFFFFF000000007100000000000000000000 + 000001A3BB00555555002B2B9D390101DEAF0101C6400101BD00010101000000 + 000000000073FFFFFF00FFFFFF00FFFFFF000000000F00000000000000000000 + 000001A3BB005454542438386F7C8080FFFF0101B1C101015600010101000101 + 01000101013CFFFFFF00FFFFFF00FFFFFF00000000780000000F000000780129 + 2F0F01A2BA3F4A4A4A6CF7F7F7FF1A1A468E00009F460101012E0101015A0101 + 015901010183FFFFFF00FFFFFF00FFFFFF000000001001292F0001525E0001A2 + BA3F0197B0B579E6F7FF2222227D1212122E00009C0001010100010101000101 + 01000101015EFFFFFF00FFFFFF00FFFFFF000000008001525E0001A2BA3F0197 + B0B579E6F7FF017E95BE053E49410808080001014F0001010100010101000101 + 01000101019BFFFFFF00FFFFFF00FFFFFF0000202B1101A2BA3F0197B0B579E6 + F7FF017E95BE0072894401010151010101000101010001010100010101000101 + 010001010189FFFFFF00FFFFFF00FFFFFF00007EA7260197B0B579E6F7FF017E + 95BE0072894401394400010101B5010101000101010000000000010101000101 + 0100010101B9FFFFFF00FFFFFF00FFFFFF00016D917FD9F4FFFF017E95BE0056 + 6744001C220000000000000000D0000000000000000000000000000000000000 + 0000000000C2FFFFFF00FFFFFF00FFFFFF00000000FF014F68AB015F773D0000 + 0074000000E6000000E6000000E6000000E6000000E6000000E6000000E60000 + 00E6000000ACFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF008AA8 + BF427EABC6BD78B3CDED7BB8D0FA7AB4CDFA71A9C4E8719DB9B07A99B039FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0086AAC29678BA + D2F9C8D9E3FFDDE7EAFFEEF1F1FFECF0F0FFD2E0E4FFA8C4D2FF679CB8F46C8F + A97DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0085A8C09197CCDCFFE1EB + EEFFEEE1D9FFDFBEACFFD5AD96FFD4AA92FFDCB7A3FFE8DACEFFC6D9DFFF689B + B6FF64859F75FFFFFF00FFFFFF00FFFFFF0088A3B93C74B3CCFADFE9ECFFE6CF + C2FFDFBFAEFFF1E3DCFFF3F1ECFFF4F1EBFFF1E2D9FFDCBAA3FFDEC1AFFFB7CF + D8FF5883A4F56A869B31FFFFFF00FFFFFF0077A1BCB6B7CFDBFFEDE0D7FFDEBD + AAFFFFFFFFFFF0F0EEFFE7E5DAFFFFFFF7FFFFFFF7FFFFFEF3FFDCB498FFE1D1 + C4FF73A4BBFF597C98A3FFFFFF00FFFFFF006DA2BEE7D3E1E6FFDBB9A4FFF1E3 + D6FFFEFBF5FFF5F5F3FF9F9E95FFF0F0E9FFF8F8F2FFBEB9ADFFF0DAC2FFD1A7 + 8BFFA9CAD3FF537B9BDFFFFFFF00FFFFFF006CA1BDF7E4ECEEFFD1A58AFFFAF6 + E9FFFDF8EEFFFFFFF9FF818079FFB1AEA4FF817F77FFC9C6BAFFFAF0D3FFC995 + 72FFC9DFE2FF547B9EF6FFFFFF00FFFFFF00679AB8F7DDEAECFFCF9F81FFFAF3 + E2FFFDF6E9FFF2F0E3FF8D8C84FF817F77FFD2CFC2FFFFFBEBFFFAECCCFFC790 + 6DFFC1DDE1FF53799DF6FFFFFF00FFFFFF005E8EADDEB7D3DDFFD1AA90FFF0DB + C1FFFFF7E6FFFAF2E3FFC5C0B6FFF1EDDEFFFFFCE8FFFFF5DFFFEFD4AFFFC99B + 7BFF92C2D0FF507595E2FFFFFF00FFFFFF005E85A09F78A9C0FFDAD1C6FFD9AA + 88FFFFFEEBFFFFFAEEFFFFFDF2FFFFFEF2FFFFFCEFFFFFFDEBFFD9A37AFFCBC6 + B9FF5894B1FF547490AAFFFFFF00FFFFFF006B879D305782A2F6A2CCD8FFCDB7 + A5FFD8AA89FFEFDFCFFFFAF6F3FFFAF5F3FFEFDFD1FFD7A785FFC3AC98FF82BD + CEFF4D7194F7627B9135FFFFFF00FFFFFF00FFFFFF0061819A785588A6FF96C8 + D6FFCCCABFFFC89F86FFC59276FFC49073FFC49A80FFC3C4B9FF7DBDCDFF4777 + 98FF5A778F80FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF005D7C957D5078 + 9AF35A97B1FF85BDCEFFA4D6DEFFA0D5DEFF7BB9CBFF4F8CABFF4D7294F45976 + 8F82FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00617D + 9536537591A74E7293E14D7497F64D7497F64E7293E1527490A95E7A9137FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0086C38BF582C0870EFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0084C28AF596CD9BFF80BE85FF79B97E0EFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0083C188F594CD9AFFB3E2B7FF93CB98FF77B77CFF70B2 + 740EFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0082C087F594CC99FFB2E2B7FFA3DCAAFFB0E0B6FF8CC692FF6EB1 + 73FF66AB6B0EFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF0081BF86F593CC98FFB1E1B7FFA3DBA9FF9BD8A2FF73B477FFAFDFB4FF87C3 + 8CFF65AA69FF5DA4610EFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007FBE + 85F592CB97FFB1E1B6FF85C38AFF80C185FF99D7A0FF98D79FFF9FD9A5FFACDF + B2FF7DBB81FF58A05CF6FFFFFF00FFFFFF00FFFFFF00FFFFFF007EBD83F691CA + 96FFB1E0B6FFD9F3DDFFF7FCF8FFA4D0A7FF7EC084FF9FD9A5FFACDEB2FF7BBB + 80FF569F5AFBFFFFFF00FFFFFF00FFFFFF008EC993257DBC82FA90C995FFB0E0 + B6FF85C28AFFF7FCF8FF95C297FFDDEEDFFF82C287FFABDEB1FF7BBA7FFF58A0 + 5CFF59A15DFF539C5704FFFFFF008DC9937D7DBB82FF8FC894FFB0E0B6FFA2DA + A8FF7FC185FFA4D0A7FFDDEEDFFF80B883FFABDEB1FF7AB97FFF569F5AFFC4E7 + C8FF78B87CFF4E995284FFFFFF007BBB80FF8EC893FFAFDFB5FFA1DAA7FF98D7 + 9FFF97D69EFF7EC083FF82C187FFABDDB0FF79B97DFF63AE67FFC4E7C8FFC1E4 + C4FFB9E0BEFF4F9A53FF459249117FBD84A07FBD84FF97CE9CFFADDFB3FF6FB3 + 74FF96D59DFF9DD8A3FFAADDB0FF78B87CFF72BA76FFC3E7C8FFB2DAB5FF69B8 + 6EF8569E59FF45914873418F44327FBE84197BBB80FF77B77CFF91CB97FFABDE + B1FF9CD7A2FFAADDB0FF77B77CFF60AC65FFAED8B2FF8BC491FF4C9750B94894 + 4C9144914822FFFFFF00FFFFFF00FFFFFF0075B67A9B9CCDA0FF6FB273FF8DC7 + 92FFAADCAFFF76B67BFF519B55FF77B77BFF509A53DD4B964F4247934B29FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006FB274277CBB81FCB7DEBBFF67AC + 6CFF75B67AFF4E9851FE539C57B84F99537AFFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006AAE6E0565AA69AF60A665FD6BAE + 6FFF4C9750FB529C56344E995222FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0060A664315BA25FCC569F + 5A4BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FCDEC102FADCBF97F9D9 + BBE3F6D6B8FDF4D3B4FDF1CFAFE3EECBAB97EBC6A602FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FCDEC002FADBBEC0F9E2CDFFFAEC + DEFFF9EEE2FFF9EDE2FFF8E9DAFFF0D5BDFFE7C09FC0E3BC9A02FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FADBBD97F8E2CCFFFAEEE3FFF7E7 + D6FFF6E2CEFFF6E1CBFFF6E3D0FFF9EADDFFECCFB5FFDFB69397FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F7D7B9E3F9EBDEFFF7E7D6FFF6E1 + CCFFF5E0CAFFF5DEC8FFF5DDC5FFF6E1CBFFF5E2D0FFDBB08CE3FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F4D3B4FDF9EDE1FFF6E1CCFFF5DF + C9FFF5DEC7FFF4DCC4FFF4DBC2FFF4DAC0FFF8E7D6FFD7AA86FDFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F0CEAEFDF9ECDFFFF5DFC8FFF5DD + C6FFF4DCC3FFF4DAC1FFF3D9BEFFF3D7BDFFF8E6D3FFD3A57FFDFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00ECC8A8E3F7E7D7FFF6E1CCFFF4DB + C2FFF4DAC0FFF3D8BDFFF3D7BBFFF4DBC2FFF3DEC9FFCD9F7BE7FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E8C3A297EDD0B7FFF8E8D9FFF5DE + C8FFF3D8BDFFF3D6BBFFF4DBC2FFF7E4D2FFDFBB9DFF9D9492F74B84BC27FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E4BD9B02E1B896C0E8C9AEFFF5E1 + CDFFF7E5D3FFF7E5D1FFF3DDC8FFDFBA9CFFC7A891FF86AED5FF417DB5EB3977 + AF27FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00DDB28F02D9AE8A97D6A9 + 85E3D3A57FFDD0A07BFDCD9C76E4A2938ADE75A2CCFFABCBE8FF76A4CEFF3070 + A8EB286BA327FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00447FB7063C79B1AD6497C5FF9DC1E4FF6699 + C7FF1F659DEBFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003272AA062B6DA5AD558DBCFF89B5 + DDFF185F97FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0022669E061B629AAD2267 + 9DFF115B9387FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00145D9503105A + 921AFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000001C00000033000000360000 + 0036000000360000003600000036000000360000003600000036000000200000 + 0002FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000033F8F8F8F0FBFBFBFDFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFF8F8F8FF949494910000 + 002000000002FFFFFF00FFFFFF00FFFFFF0000000036FBFBFBFDF4F4F4FFF5F5 + F5FFF5F5F5FFF5F5F5FFF1F1F1FFEFEFEFFFE9E9E9FFFCFCFCFFE7E7E7FF9595 + 95910000002000000002FFFFFF000000000100000036FCFCFCFFF7F7F7FFF9F9 + F9FFF7F7F7FFF7F7F7FFF3F3F3FFF0F0F0FFEAEAEAFFFCFCFCFFF6F6F6FFF4F4 + F4FF9999999100000020FFFFFF000000000100000036FCFCFCFFF9F9F9FFF9F9 + F9FFF9F9F9FFF7F7F7FFF6F6F6FFF2F2F2FFEBEBEBFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFF00000036000000010000000100000036FCFCFCFFFBFBFBFFFCFC + FCFFFCFCFCFFFBFBFBFFF8F8F8FFF5F5F5FFF1F1F1FFECECECFFEAEAEAFFE6E6 + E6FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFBFBFBFFF8F8F8FFF5F5F5FFF2F2F2FFEFEFEFFFEDED + EDFFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFBFBFBFFF8F8F8FFF6F6F6FFF3F3F3FFF2F2 + F2FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFAFAFAFFF9F9F9FFF6F6F6FFF6F6 + F6FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFBFBFBFFF9F9F9FFF9F9F9FFF8F8 + F8FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFBFBFBFFFBFBFBFFFBFBFBFFFAFAFAFFFAFAFAFFF8F8F8FFF8F8 + F8FFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFBFBFBFFFBFBFBFFFAFAFAFFFAFAFAFFFAFAFAFFFAFAFAFFFAFA + FAFFFCFCFCFF00000036000000010000000100000036FCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFBFBFFFBFB + FBFFFCFCFCFF00000036000000010000000100000036FCFCFCFEFCFCFCFFFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFFFCFCFCFD00000036FFFFFF00FFFFFF0000000034F9F9F9F5FCFCFCFDFCFC + FCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFC + FCFDF9F9F9F300000033FFFFFF00FFFFFF000000001D00000034000000360000 + 0036000000360000003600000036000000360000003600000036000000360000 + 0036000000330000001DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B32C0300B52D0300B82F0300B92F + 0318BA300364BA30039ABA3003B6BA3003B6BA30039ABA300364B92F0318B82F + 0300B52D0300B32C0300FFFFFF00FFFFFF00B32C0300B52D0300B82F0348BD38 + 0DB3D96841DAED8B67F1F49673FCF49572FCED8966F1D8663FDABD380DB3B82F + 0348B52D0300B32C0300FFFFFF00FFFFFF00B32C0300B52D0348C03E15C2ED8A + 67F3EB8765FFD87250FFD87250FFD87250FFD87250FFEA8765FFEA8662F3BF3D + 14C2B52D0348B32C0300FFFFFF00FFFFFF00B22C0319B8350DB4E98664F3E07B + 59FFD26C4AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA8E74FFE07B59FFE37E + 5AF3B7340CB4B22C0319FFFFFF00FFFFFF00AF2A0365D1613CDBDC7856FFD670 + 4EFFD16B49FFD5A291FFD5A291FFE6C2B6FFFFFFFFFFE0AD9CFFD6704EFFDA75 + 53FFC95732DBAF2A0365FFFFFF00FFFFFF00AB27029DDD7956F2CF6947FFCF69 + 47FFCF6947FFCA6442FFC05937FFC28875FFCCCCCCFFBC8977FFAD4624FFB04A + 27FFC15936F2AB27029DFFFFFF00FFFFFF00A72502B9DD7B59FCCC6644FFC962 + 40FFBD5431FFB54B27FFBD735AFFD1CFCFFFC7AEA5FFB24926FFB44A26FFB44A + 26FFBD5431FCA72502B9FFFFFF00FFFFFF00A32302BAD97755FDC85F3BFFC052 + 2CFFBE502AFFB94E28FFDBDBDBFFDBDBDBFFBA4E29FFBE502AFFBE502AFFBE50 + 2AFFC2552FFDA32302BAFFFFFF00FFFFFF009F20029ED06542F3CB5930FFCB58 + 2FFFCB582FFFCB582FFFBC4F29FFBC4F29FFCB582FFFCB582FFFCB582FFFCB58 + 2FFFC5502AF39F20029EFFFFFF00FFFFFF009B1E0268BD4725DDD96338FFD860 + 35FFD86035FFCD5930FFEEEEEEFFEEEEEEFFCD5930FFD86035FFD86035FFD860 + 35FFB83D1ADE9B1E0268FFFFFF00FFFFFF00971B02199C2108B8DA6138F4E668 + 3AFFE5673AFFD75F34FFEEEEEEFFEEEEEEFFD75F34FFE5673AFFE5673AFFD85B + 31F49C2006B8971B0219FFFFFF00FFFFFF00951A02009218024A9D240BC7E162 + 36F4F16F3FFFF16F3EFFCF5A31FFCF5A31FFF16F3EFFF16F3EFFE06034F49D23 + 0AC79218024A951A0200FFFFFF00FFFFFF00951A020090170200820F014B8915 + 06BCB83D20E1E36136F4F57040FDF57040FDE36136F4B83D20E1891506BC820F + 014B90170200951A0200FFFFFF00FFFFFF00951A020090170200800E01007506 + 001A7205006B720500A5720500C3720500C3720500A57205006B7506001A800E + 010090170200951A0200FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00 + } + end + object MainMenu: TMainMenu + Images = ImageList + left = 176 + top = 376 + object MnuFile: TMenuItem + Caption = 'File' + object MnuFileNew: TMenuItem + Action = AcFileNew + end + object MnuFileOpen: TMenuItem + Action = AcFileOpen + end + object MnuFileReopen: TMenuItem + Caption = 'Recently opened files' + end + object MenuItem50: TMenuItem + Caption = '-' + end + object MnuFileSaveAs: TMenuItem + Action = AcFileSaveAs + end + object MenuItem49: TMenuItem + Caption = '-' + end + object MnuFileExit: TMenuItem + Action = AcFileExit + end + end + object MnuEdit: TMenuItem + Caption = 'Edit' + object MenuItem101: TMenuItem + Action = AcCopyToClipboard + end + object MenuItem100: TMenuItem + Action = AcCutToClipboard + end + object MenuItem2: TMenuItem + Action = AcPasteAllFromClipboard + end + object MenuItem4: TMenuItem + Action = AcPasteValueFromClipboard + end + object MenuItem3: TMenuItem + Action = AcPasteFormulaFromClipboard + end + object MenuItem90: TMenuItem + Action = AcPasteFormatFromClipboard + end + object MenuItem98: TMenuItem + Caption = '-' + end + object MenuItem132: TMenuItem + Action = AcSearch + end + object MenuItem92: TMenuItem + Caption = '-' + end + object MenuItem91: TMenuItem + Action = AcSort + end + object MenuItem93: TMenuItem + Action = AcSortColAsc + end + end + object MenuItem51: TMenuItem + Caption = 'Worksheet' + object MenuItem161: TMenuItem + Action = AcAddWorksheet + end + object MenuItem162: TMenuItem + Action = AcDeleteWorksheet + end + object MenuItem163: TMenuItem + Caption = '-' + end + object MenuItem160: TMenuItem + Action = acRenameWorksheet + end + object MenuItem165: TMenuItem + Caption = '-' + end + object MenuItem164: TMenuItem + Action = AcWorksheetRTL + AutoCheck = True + end + end + object MenuItem166: TMenuItem + Caption = 'Row' + object MenuItem167: TMenuItem + Action = AcRowAdd + end + object MenuItem168: TMenuItem + Action = AcRowDelete + end + object MenuItem174: TMenuItem + Caption = '-' + end + object MenuItem175: TMenuItem + Action = AcFrozenRows + AutoCheck = True + end + object MenuItem177: TMenuItem + Caption = '-' + end + object MenuItem99: TMenuItem + Action = AcRowHeight + end + object MenuItem176: TMenuItem + Action = AcAutoRowHeights + end + end + object MenuItem169: TMenuItem + Caption = 'Column' + object MenuItem170: TMenuItem + Action = AcColAdd + end + object MenuItem171: TMenuItem + Action = AcColDelete + end + object MenuItem173: TMenuItem + Caption = '-' + end + object MenuItem172: TMenuItem + Action = AcFrozenCols + AutoCheck = True + end + object MenuItem103: TMenuItem + Caption = '-' + end + object MenuItem102: TMenuItem + Action = AcColWidth + end + end + object MnuFormat: TMenuItem + Caption = 'Cell' + object MenuItem89: TMenuItem + Action = AcBackgroundColorDialog + end + object MenuItem68: TMenuItem + Caption = 'Font' + object MenuItem69: TMenuItem + Action = AcCellFontDialog + end + object MenuItem70: TMenuItem + Caption = '-' + end + object MenuItem71: TMenuItem + Action = AcFontBold + AutoCheck = True + end + object MenuItem72: TMenuItem + Action = AcFontItalic + AutoCheck = True + end + object MenuItem73: TMenuItem + Action = AcFontUnderline + AutoCheck = True + end + object MenuItem74: TMenuItem + Action = AcFontStrikeout + AutoCheck = True + end + end + object MenuItem76: TMenuItem + Caption = 'Text rotation' + object MenuItem77: TMenuItem + Action = AcTextRotHor + AutoCheck = True + end + object MenuItem78: TMenuItem + Caption = '-' + end + object MenuItem79: TMenuItem + Action = AcTextRot90CW + AutoCheck = True + end + object MenuItem80: TMenuItem + Action = AcTextRot90CCW + AutoCheck = True + end + object MenuItem81: TMenuItem + Action = AcTextRotStacked + AutoCheck = True + end + end + object MenuItem75: TMenuItem + Caption = 'Horizontal text alignment' + object MenuItem82: TMenuItem + Action = AcHorAlignLeft + AutoCheck = True + end + object MenuItem83: TMenuItem + Action = AcHorAlignCenter + AutoCheck = True + end + object MenuItem84: TMenuItem + Action = AcHorAlignRight + AutoCheck = True + end + end + object MenuItem85: TMenuItem + Caption = 'Vertical text alignment' + object MenuItem86: TMenuItem + Action = AcVertAlignTop + AutoCheck = True + end + object MenuItem87: TMenuItem + Action = AcVertAlignCenter + AutoCheck = True + end + object MenuItem88: TMenuItem + Action = AcVertAlignBottom + AutoCheck = True + end + end + object MenuItem10: TMenuItem + Caption = 'Number format' + object MenuItem122: TMenuItem + Action = AcNumFormatCustom + AutoCheck = True + end + object MenuItem121: TMenuItem + Caption = '-' + end + object MenuItem55: TMenuItem + Action = AcNumFormatGeneral + AutoCheck = True + end + object MenuItem54: TMenuItem + Caption = '-' + end + object MenuItem12: TMenuItem + Action = AcNumFormatFixed + AutoCheck = True + end + object MenuItem11: TMenuItem + Action = AcNumFormatFixedTh + AutoCheck = True + end + object MenuItem13: TMenuItem + Caption = '-' + end + object MenuItem117: TMenuItem + Action = AcNumFormatFraction1 + AutoCheck = True + end + object MenuItem116: TMenuItem + Action = AcNumFormatFraction2 + AutoCheck = True + end + object MenuItem115: TMenuItem + Action = AcNumFormatFraction3 + AutoCheck = True + end + object MenuItem114: TMenuItem + Caption = '-' + end + object MenuItem53: TMenuItem + Action = AcNumFormatExp + AutoCheck = True + end + object MenuItem14: TMenuItem + Action = AcNumFormatPercentage + AutoCheck = True + end + object MenuItem15: TMenuItem + Caption = '-' + end + object MenuItem17: TMenuItem + Action = AcNumFormatCurrency + AutoCheck = True + end + object MenuItem16: TMenuItem + Action = AcNumFormatCurrencyRed + AutoCheck = True + end + object MenuItem56: TMenuItem + Caption = '-' + end + object MenuItem57: TMenuItem + Action = AcNumFormatDateTime + AutoCheck = True + end + object MenuItem58: TMenuItem + Caption = '-' + end + object MenuItem59: TMenuItem + Action = AcNumFormatLongDate + AutoCheck = True + end + object MenuItem60: TMenuItem + Action = AcNumFormatShortDate + AutoCheck = True + end + object MenuItem61: TMenuItem + Caption = '-' + end + object MenuItem62: TMenuItem + Action = AcNumFormatLongTime + AutoCheck = True + end + object MenuItem63: TMenuItem + Action = AcNumFormatShortTime + AutoCheck = True + end + object MenuItem64: TMenuItem + Action = AcNumFormatLongTimeAM + AutoCheck = True + end + object MenuItem65: TMenuItem + Action = AcNumFormatShortTimeAM + AutoCheck = True + end + object MenuItem66: TMenuItem + Caption = '-' + end + object MenuItem67: TMenuItem + Action = AcNumFormatTimeInterval + AutoCheck = True + end + object MenuItem144: TMenuItem + Caption = '-' + end + object MenuItem145: TMenuItem + Action = AcNumFormatText + AutoCheck = True + end + end + end + object MnuView: TMenuItem + Caption = 'View' + object MenuItem134: TMenuItem + Action = AcShowGridLines + AutoCheck = True + end + object MenuItem135: TMenuItem + Action = AcShowHeaders + AutoCheck = True + end + object MenuItem133: TMenuItem + Caption = '-' + end + object MnuZoom: TMenuItem + Caption = 'Zoom' + object MenuItem148: TMenuItem + Action = AcZoom30 + end + object MenuItem149: TMenuItem + Action = AcZoom50 + end + object MenuItem150: TMenuItem + Action = AcZoom75 + end + object MenuItem146: TMenuItem + Action = AcZoom90 + end + object MenuItem153: TMenuItem + Caption = '-' + end + object MenuItem151: TMenuItem + Action = AcZoom100 + end + object MenuItem154: TMenuItem + Caption = '-' + end + object MenuItem152: TMenuItem + Action = AcZoom150 + end + object MenuItem155: TMenuItem + Action = AcZoom200 + end + object MenuItem156: TMenuItem + Action = AcZoom300 + end + object MenuItem157: TMenuItem + Action = AcZoom500 + end + end + object MenuItem147: TMenuItem + Caption = '-' + end + object MenuItem52: TMenuItem + Action = AcViewInspector + AutoCheck = True + end + end + object MnuSettings: TMenuItem + Caption = 'Settings' + object MenuItem109: TMenuItem + Action = AcSettingsFormatSettings + end + object MenuItem107: TMenuItem + Action = AcSettingsCSVParams + end + object MenuItem108: TMenuItem + Action = AcSettingsCurrency + end + end + object MnuHelp: TMenuItem + Caption = 'Help' + object MenuItem1: TMenuItem + Action = AcAbout + end + end + end + object PuNumFormat: TPopupMenu + left = 504 + top = 216 + object MenuItem19: TMenuItem + Action = AcNumFormatGeneral + AutoCheck = True + end + object MenuItem18: TMenuItem + Caption = '-' + end + object MenuItem6: TMenuItem + Action = AcNumFormatFixed + AutoCheck = True + end + object MenuItem5: TMenuItem + Action = AcNumFormatFixedTh + AutoCheck = True + end + object MenuItem20: TMenuItem + Caption = '-' + end + object MenuItem112: TMenuItem + Action = AcNumFormatFraction1 + AutoCheck = True + end + object MenuItem110: TMenuItem + Action = AcNumFormatFraction2 + AutoCheck = True + end + object MenuItem113: TMenuItem + Action = AcNumFormatFraction3 + AutoCheck = True + end + object MenuItem111: TMenuItem + Caption = '-' + end + object MenuItem21: TMenuItem + Action = AcNumFormatExp + AutoCheck = True + end + object MenuItem123: TMenuItem + Caption = '-' + end + object MenuItem124: TMenuItem + Action = AcNumFormatCustom + AutoCheck = True + end + end + object PuCurrencyFormat: TPopupMenu + left = 504 + top = 280 + object MenuItem7: TMenuItem + Action = AcNumFormatCurrency + AutoCheck = True + end + object MenuItem8: TMenuItem + Action = AcNumFormatCurrencyRed + AutoCheck = True + end + object MenuItem125: TMenuItem + Caption = '-' + end + object MenuItem126: TMenuItem + Action = AcNumFormatCustom + AutoCheck = True + end + end + object PuDateFormat: TPopupMenu + left = 504 + top = 344 + object MenuItem22: TMenuItem + Action = AcNumFormatDateTime + AutoCheck = True + end + object MenuItem23: TMenuItem + Caption = '-' + end + object MenuItem24: TMenuItem + Action = AcNumFormatLongDate + AutoCheck = True + end + object MenuItem25: TMenuItem + Action = AcNumFormatShortDate + AutoCheck = True + end + object MenuItem118: TMenuItem + Caption = '-' + end + object MenuItem119: TMenuItem + Action = AcNumFormatDayMonth + AutoCheck = True + end + object MenuItem120: TMenuItem + Action = AcNumFormatMonthYear + AutoCheck = True + end + object MenuItem127: TMenuItem + Caption = '-' + end + object MenuItem128: TMenuItem + Action = AcNumFormatCustom + AutoCheck = True + end + end + object PuTimeFormat: TPopupMenu + left = 504 + top = 408 + object MenuItem26: TMenuItem + Action = AcNumFormatLongTime + AutoCheck = True + end + object MenuItem27: TMenuItem + Action = AcNumFormatShortTime + AutoCheck = True + end + object MenuItem28: TMenuItem + Caption = '-' + end + object MenuItem29: TMenuItem + Action = AcNumFormatLongTimeAM + AutoCheck = True + end + object MenuItem30: TMenuItem + Action = AcNumFormatShortTimeAM + AutoCheck = True + end + object MenuItem129: TMenuItem + Caption = '-' + end + object MenuItem130: TMenuItem + Action = AcNumFormatCustom + AutoCheck = True + end + end + object PuBorders: TPopupMenu + Images = ImageList + left = 504 + top = 160 + object MenuItem41: TMenuItem + Action = AcCellBorderNone + end + object MenuItem40: TMenuItem + Caption = '-' + end + object MenuItem31: TMenuItem + Action = AcCellBorderTop + end + object MenuItem32: TMenuItem + Action = AcCellBorderInnerHor + end + object MenuItem33: TMenuItem + Action = AcCellBorderBottom + end + object MenuItem43: TMenuItem + Action = AcCellBorderBottomThick + end + object MenuItem44: TMenuItem + Action = AcCellBorderBottomDbl + end + object MenuItem48: TMenuItem + Action = AcCellBorderAllHor + end + object MenuItem36: TMenuItem + Caption = '-' + end + object MenuItem34: TMenuItem + Action = AcCellBorderLeft + end + object MenuItem37: TMenuItem + Action = AcCellBorderInnerVert + end + object MenuItem35: TMenuItem + Action = AcCellBorderRight + end + object MenuItem47: TMenuItem + Action = AcCellBorderAllVert + end + object MenuItem38: TMenuItem + Caption = '-' + end + object MenuItem142: TMenuItem + Action = AcCellBorderDiagUp + end + object MenuItem141: TMenuItem + Action = AcCellBorderDiagDown + end + object MenuItem143: TMenuItem + Caption = '-' + end + object MenuItem39: TMenuItem + Action = AcCellBorderAllOuter + end + object MenuItem42: TMenuItem + Action = AcCellBorderAllOuterThick + end + object MenuItem45: TMenuItem + Caption = '-' + end + object MenuItem46: TMenuItem + Action = AcCellBorderAll + end + end + object PuPaste: TPopupMenu + left = 504 + top = 471 + object MenuItem9: TMenuItem + Action = AcPasteAllFromClipboard + end + object MenuItem94: TMenuItem + Caption = '-' + end + object MenuItem95: TMenuItem + Action = AcPasteValueFromClipboard + end + object MenuItem96: TMenuItem + Action = AcPasteFormatFromClipboard + end + object MenuItem97: TMenuItem + Action = AcPasteFormulaFromClipboard + end + end + object PuRecentFiles: TPopupMenu + left = 504 + top = 536 + end +end diff --git a/applications/spready/smain.pas b/applications/spready/smain.pas new file mode 100644 index 000000000..c0a2d5803 --- /dev/null +++ b/applications/spready/smain.pas @@ -0,0 +1,1198 @@ +unit smain; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, mrumanager, Forms, Controls, Graphics, Dialogs, + ExtCtrls, ComCtrls, ActnList, Menus, StdActns, Buttons, fpstypes, + fpspreadsheet, fpspreadsheetctrls, fpspreadsheetgrid, fpsActions, + fpsRegFileFormats, fpsSYLK, xlsxml, Grids, Types; + +type + + { TMainForm } + + TMainForm = class(TForm) + AcRowDelete: TAction; + AcColDelete: TAction; + AcRowAdd: TAction; + AcColAdd: TAction; + AcSettingsCSVParams: TAction; + AcSettingsCurrency: TAction; + AcSettingsFormatSettings: TAction; + AcSearch: TAction; + AcShowGridLines: TAction; + AcShowHeaders: TAction; + AcFrozenRows: TAction; + AcFrozenCols: TAction; + AcAutoRowHeights: TAction; + AcFileNew: TAction; + AcAbout: TAction; + AcSort: TAction; + AcSortColAsc: TAction; + AcRowHeight: TAction; + AcColWidth: TAction; + AcWorksheetRTL: TAction; + AcViewInspector: TAction; + ActionList: TActionList; + AcFileExit: TFileExit; + AcFileOpen: TFileOpen; + AcFileSaveAs: TFileSaveAs; + ImageList: TImageList; + MainMenu: TMainMenu; + MenuItem1: TMenuItem; + MenuItem102: TMenuItem; + MenuItem103: TMenuItem; + MenuItem160: TMenuItem; + MenuItem161: TMenuItem; + MenuItem162: TMenuItem; + MenuItem163: TMenuItem; + MenuItem164: TMenuItem; + MenuItem165: TMenuItem; + MenuItem166: TMenuItem; + MenuItem167: TMenuItem; + MenuItem168: TMenuItem; + MenuItem169: TMenuItem; + MenuItem170: TMenuItem; + MenuItem171: TMenuItem; + MenuItem172: TMenuItem; + MenuItem173: TMenuItem; + MenuItem174: TMenuItem; + MenuItem175: TMenuItem; + MenuItem176: TMenuItem; + MenuItem177: TMenuItem; + MenuItem2: TMenuItem; + MenuItem3: TMenuItem; + MenuItem4: TMenuItem; + MenuItem51: TMenuItem; + MenuItem90: TMenuItem; + MenuItem91: TMenuItem; + MenuItem92: TMenuItem; + MenuItem93: TMenuItem; + MenuItem99: TMenuItem; + MnuHelp: TMenuItem; + MnuFileNew: TMenuItem; + MnuFileExit: TMenuItem; + MenuItem10: TMenuItem; + MenuItem100: TMenuItem; + MenuItem101: TMenuItem; + MenuItem107: TMenuItem; + MenuItem108: TMenuItem; + MenuItem109: TMenuItem; + MenuItem110: TMenuItem; + MenuItem111: TMenuItem; + MenuItem112: TMenuItem; + MenuItem113: TMenuItem; + MenuItem114: TMenuItem; + MenuItem115: TMenuItem; + MenuItem116: TMenuItem; + MenuItem117: TMenuItem; + MenuItem118: TMenuItem; + MenuItem119: TMenuItem; + MenuItem120: TMenuItem; + MenuItem121: TMenuItem; + MenuItem122: TMenuItem; + MenuItem123: TMenuItem; + MenuItem124: TMenuItem; + MenuItem125: TMenuItem; + MenuItem126: TMenuItem; + MenuItem127: TMenuItem; + MenuItem128: TMenuItem; + MenuItem129: TMenuItem; + MenuItem130: TMenuItem; + MenuItem132: TMenuItem; + MenuItem133: TMenuItem; + MenuItem134: TMenuItem; + MenuItem135: TMenuItem; + MenuItem141: TMenuItem; + MenuItem142: TMenuItem; + MenuItem143: TMenuItem; + MenuItem144: TMenuItem; + MenuItem145: TMenuItem; + MenuItem146: TMenuItem; + MenuItem148: TMenuItem; + MenuItem149: TMenuItem; + MenuItem150: TMenuItem; + MenuItem151: TMenuItem; + MenuItem152: TMenuItem; + MenuItem153: TMenuItem; + MenuItem154: TMenuItem; + MenuItem155: TMenuItem; + MenuItem156: TMenuItem; + MenuItem157: TMenuItem; + MenuItem50: TMenuItem; + MnuFileReopen: TMenuItem; + MnuZoom: TMenuItem; + MenuItem147: TMenuItem; + MnuSettings: TMenuItem; + MenuItem11: TMenuItem; + MenuItem12: TMenuItem; + MenuItem13: TMenuItem; + MenuItem14: TMenuItem; + MenuItem15: TMenuItem; + MenuItem16: TMenuItem; + MenuItem17: TMenuItem; + MenuItem18: TMenuItem; + MenuItem19: TMenuItem; + MenuItem20: TMenuItem; + MenuItem21: TMenuItem; + MenuItem22: TMenuItem; + MenuItem23: TMenuItem; + MenuItem24: TMenuItem; + MenuItem25: TMenuItem; + MenuItem26: TMenuItem; + MenuItem27: TMenuItem; + MenuItem28: TMenuItem; + MenuItem29: TMenuItem; + MenuItem30: TMenuItem; + MenuItem31: TMenuItem; + MenuItem32: TMenuItem; + MenuItem33: TMenuItem; + MenuItem34: TMenuItem; + MenuItem35: TMenuItem; + MenuItem36: TMenuItem; + MenuItem37: TMenuItem; + MenuItem38: TMenuItem; + MenuItem39: TMenuItem; + MenuItem40: TMenuItem; + MenuItem41: TMenuItem; + MenuItem42: TMenuItem; + MenuItem43: TMenuItem; + MenuItem44: TMenuItem; + MenuItem45: TMenuItem; + MenuItem46: TMenuItem; + MenuItem47: TMenuItem; + MenuItem48: TMenuItem; + MenuItem49: TMenuItem; + MenuItem5: TMenuItem; + MnuFileOpen: TMenuItem; + MnuFileSaveAs: TMenuItem; + MenuItem52: TMenuItem; + MenuItem53: TMenuItem; + MenuItem54: TMenuItem; + MenuItem55: TMenuItem; + MenuItem56: TMenuItem; + MenuItem57: TMenuItem; + MenuItem58: TMenuItem; + MenuItem59: TMenuItem; + MenuItem60: TMenuItem; + MenuItem61: TMenuItem; + MenuItem62: TMenuItem; + MenuItem63: TMenuItem; + MenuItem64: TMenuItem; + MenuItem65: TMenuItem; + MenuItem66: TMenuItem; + MenuItem67: TMenuItem; + MenuItem68: TMenuItem; + MenuItem69: TMenuItem; + MenuItem70: TMenuItem; + MenuItem71: TMenuItem; + MenuItem72: TMenuItem; + MenuItem73: TMenuItem; + MenuItem74: TMenuItem; + MenuItem75: TMenuItem; + MenuItem76: TMenuItem; + MenuItem77: TMenuItem; + MenuItem78: TMenuItem; + MenuItem79: TMenuItem; + MenuItem80: TMenuItem; + MenuItem81: TMenuItem; + MenuItem82: TMenuItem; + MenuItem83: TMenuItem; + MenuItem84: TMenuItem; + MenuItem85: TMenuItem; + MenuItem86: TMenuItem; + MenuItem87: TMenuItem; + MenuItem88: TMenuItem; + MenuItem89: TMenuItem; + MenuItem9: TMenuItem; + MenuItem95: TMenuItem; + MenuItem96: TMenuItem; + MenuItem97: TMenuItem; + MenuItem98: TMenuItem; + MenuItem94: TMenuItem; + MnuAddWorksheet: TMenuItem; + MnuView: TMenuItem; + MenuItem6: TMenuItem; + MenuItem7: TMenuItem; + MenuItem8: TMenuItem; + MnuFormat: TMenuItem; + MnuFile: TMenuItem; + MnuEdit: TMenuItem; + OpenDialog: TOpenDialog; + OpenDialog1: TOpenDialog; + CellEdit: TsCellEdit; + CellIndicator: TsCellIndicator; + AcFontBold: TsFontStyleAction; + AcFontItalic: TsFontStyleAction; + AcVertAlignTop: TsVertAlignmentAction; + AcVertAlignCenter: TsVertAlignmentAction; + AcVertAlignBottom: TsVertAlignmentAction; + AcHorAlignLeft: TsHorAlignmentAction; + AcHorAlignCenter: TsHorAlignmentAction; + AcHorAlignRight: TsHorAlignmentAction; + AcTextRotHor: TsTextRotationAction; + AcTextRot90CW: TsTextRotationAction; + AcTextRot90CCW: TsTextRotationAction; + AcTextRotStacked: TsTextRotationAction; + AcWordWrap: TsWordwrapAction; + AcNumFormatFixed: TsNumberFormatAction; + AcNumFormatFixedTh: TsNumberFormatAction; + AcNumFormatPercentage: TsNumberFormatAction; + AcNumFormatCurrency: TsNumberFormatAction; + AcNumFormatCurrencyRed: TsNumberFormatAction; + Panel2: TPanel; + PuRecentFiles: TPopupMenu; + PuPaste: TPopupMenu; + PuBorders: TPopupMenu; + PuTimeFormat: TPopupMenu; + PuDateFormat: TPopupMenu; + PuCurrencyFormat: TPopupMenu; + PuNumFormat: TPopupMenu; + AcNumFormatGeneral: TsNumberFormatAction; + AcNumFormatExp: TsNumberFormatAction; + AcNumFormatDateTime: TsNumberFormatAction; + AcNumFormatLongDate: TsNumberFormatAction; + AcNumFormatShortDate: TsNumberFormatAction; + AcNumFormatLongTime: TsNumberFormatAction; + AcNumFormatShortTime: TsNumberFormatAction; + AcNumFormatLongTimeAM: TsNumberFormatAction; + AcNumFormatShortTimeAM: TsNumberFormatAction; + AcNumFormatTimeInterval: TsNumberFormatAction; + AcIncDecimals: TsDecimalsAction; + AcDecDecimals: TsDecimalsAction; + AcCellFontDialog: TsFontDialogAction; + AcBackgroundColorDialog: TsBackgroundColorDialogAction; + AcCellBorderTop: TsCellBorderAction; + AcCellBorderBottom: TsCellBorderAction; + AcCellBorderLeft: TsCellBorderAction; + AcCellBorderRight: TsCellBorderAction; + AcCellBorderInnerHor: TsCellBorderAction; + AcCellBorderInnerVert: TsCellBorderAction; + AcCellBorderAllHor: TsCellBorderAction; + AcCellBorderBottomThick: TsCellBorderAction; + AcCellBorderBottomDbl: TsCellBorderAction; + AcCellBorderAllOuter: TsCellBorderAction; + AcCellBorderNone: TsNoCellBordersAction; + AcCellBorderAllOuterThick: TsCellBorderAction; + AcCellBorderTopBottomThick: TsCellBorderAction; + AcCellBorderTopBottomDbl: TsCellBorderAction; + AcCellBorderAll: TsCellBorderAction; + AcCellBorderAllVert: TsCellBorderAction; + AcCopyFormat: TsCopyAction; + FontColorCombobox: TsCellCombobox; + BackgroundColorCombobox: TsCellCombobox; + FontnameCombo: TsCellCombobox; + FontsizeCombo: TsCellCombobox; + AcMergeCells: TsMergeAction; + AcCopyToClipboard: TsCopyAction; + AcCutToClipboard: TsCopyAction; + AcPasteAllFromClipboard: TsCopyAction; + AcPasteValueFromClipboard: TsCopyAction; + AcPasteFormatFromClipboard: TsCopyAction; + AcPasteFormulaFromClipboard: TsCopyAction; + AcCommentNew: TsCellCommentAction; + AcCommentEdit: TsCellCommentAction; + AcCommentDelete: TsCellCommentAction; + AcHyperlinkNew: TsCellHyperlinkAction; + AcHyperlinkEdit: TsCellHyperlinkAction; + AcHyperlinkDelete: TsCellHyperlinkAction; + AcNumFormatFraction2: TsNumberFormatAction; + AcNumFormatFraction1: TsNumberFormatAction; + AcNumFormatFraction3: TsNumberFormatAction; + AcNumFormatDayMonth: TsNumberFormatAction; + AcNumFormatMonthYear: TsNumberFormatAction; + AcNumFormatCustom: TsNumberFormatAction; + AcCellBorderDiagUp: TsCellBorderAction; + AcCellBorderDiagDown: TsCellBorderAction; + AcNumFormatText: TsNumberFormatAction; + Splitter2: TSplitter; + Splitter3: TSplitter; + AcZoom100: TsWorksheetZoomAction; + AcZoom90: TsWorksheetZoomAction; + AcZoom30: TsWorksheetZoomAction; + AcZoom50: TsWorksheetZoomAction; + AcZoom75: TsWorksheetZoomAction; + AcZoom150: TsWorksheetZoomAction; + AcZoom200: TsWorksheetZoomAction; + AcZoom300: TsWorksheetZoomAction; + AcZoom500: TsWorksheetZoomAction; + ToolBar2: TToolBar; + ToolBar3: TToolBar; + ToolButton1: TToolButton; + ToolButton11: TToolButton; + ToolButton12: TToolButton; + ToolButton13: TToolButton; + ToolButton14: TToolButton; + ToolButton15: TToolButton; + ToolButton16: TToolButton; + ToolButton17: TToolButton; + ToolButton18: TToolButton; + ToolButton19: TToolButton; + AcFontUnderline: TsFontStyleAction; + AcFontStrikeout: TsFontStyleAction; + InspectorSplitter: TSplitter; + Inspector: TsSpreadsheetInspector; + InspectorTabControl: TTabControl; + AcAddWorksheet: TsWorksheetAddAction; + AcDeleteWorksheet: TsWorksheetDeleteAction; + acRenameWorksheet: TsWorksheetRenameAction; + ToolBar1: TToolBar; + ToolButton10: TToolButton; + ToolButton2: TToolButton; + ToolButton20: TToolButton; + ToolButton21: TToolButton; + ToolButton22: TToolButton; + ToolButton23: TToolButton; + ToolButton24: TToolButton; + ToolButton25: TToolButton; + ToolButton26: TToolButton; + ToolButton27: TToolButton; + ToolButton28: TToolButton; + ToolButton29: TToolButton; + ToolButton3: TToolButton; + ToolButton30: TToolButton; + ToolButton31: TToolButton; + TbBorders: TToolButton; + ToolButton32: TToolButton; + ToolButton33: TToolButton; + ToolButton34: TToolButton; + ToolButton35: TToolButton; + ToolButton36: TToolButton; + ToolButton37: TToolButton; + ToolButton38: TToolButton; + ToolButton39: TToolButton; + TbCommentAdd: TToolButton; + ToolButton4: TToolButton; + ToolButton40: TToolButton; + ToolButton41: TToolButton; + ToolButton42: TToolButton; + ToolButton43: TToolButton; + ToolButton44: TToolButton; + ToolButton45: TToolButton; + ToolButton46: TToolButton; + ToolButton47: TToolButton; + ToolButton48: TToolButton; + ToolButton49: TToolButton; + ToolButton5: TToolButton; + TbCommentDelete: TToolButton; + TbCommentEdit: TToolButton; + ToolButton50: TToolButton; + ToolButton51: TToolButton; + ToolButton52: TToolButton; + ToolButton53: TToolButton; + ToolButton54: TToolButton; + ToolButton55: TToolButton; + ToolButton6: TToolButton; + ToolButton7: TToolButton; + ToolButton8: TToolButton; + tbFileOpen: TToolButton; + ToolButton9: TToolButton; + WorkbookSource: TsWorkbookSource; + WorkbookTabControl: TsWorkbookTabControl; + WorksheetGrid: TsWorksheetGrid; + procedure AcAboutExecute(Sender: TObject); + procedure AcAutoRowHeightsExecute(Sender: TObject); + procedure AcColAddExecute(Sender: TObject); + procedure AcColDeleteExecute(Sender: TObject); + procedure AcColWidthExecute(Sender: TObject); + procedure AcFileNewExecute(Sender: TObject); + procedure AcFileOpenAccept(Sender: TObject); + procedure AcFileSaveAsAccept(Sender: TObject); + procedure AcFileSaveAsBeforeExecute(Sender: TObject); + procedure AcFrozenColsExecute(Sender: TObject); + procedure AcFrozenColsUpdate(Sender: TObject); + procedure AcFrozenRowsExecute(Sender: TObject); + procedure AcFrozenRowsUpdate(Sender: TObject); + procedure AcNumFormatCustomGetNumberFormatString(Sender: TObject; + AWorkbook: TsWorkbook; var ANumFormatStr: String); + procedure AcRowAddExecute(Sender: TObject); + procedure AcRowDeleteExecute(Sender: TObject); + procedure AcRowHeightExecute(Sender: TObject); + procedure AcSortColAscExecute(Sender: TObject); + procedure AcSortExecute(Sender: TObject); + procedure ActionListUpdate(AAction: TBasicAction; var Handled: Boolean); + procedure AcWorksheetRTLExecute(Sender: TObject); + procedure AcWorksheetRTLUpdate(Sender: TObject); + procedure AcSearchExecute(Sender: TObject); + procedure AcSettingsCSVParamsExecute(Sender: TObject); + procedure AcSettingsCurrencyExecute(Sender: TObject); + procedure AcSettingsFormatSettingsExecute(Sender: TObject); + procedure AcShowGridLinesExecute(Sender: TObject); + procedure AcShowGridLinesUpdate(Sender: TObject); + procedure AcShowHeadersExecute(Sender: TObject); + procedure AcShowHeadersUpdate(Sender: TObject); + procedure AcViewInspectorExecute(Sender: TObject); + procedure EditCut1Execute(Sender: TObject); + procedure ColorComboboxAddColors(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure HyperlinkHandler(Sender: TObject; ACaption: String; + var AHyperlink: TsHyperlink); + procedure InspectorEnter(Sender: TObject); + procedure InspectorExit(Sender: TObject); + procedure InspectorTabControlChange(Sender: TObject); + procedure TSaveDialogTypeChange(Sender: TObject); + procedure WorksheetGridClickHyperlink(Sender: TObject; + const AHyperlink: TsHyperlink); + procedure WorksheetGridMouseWheel(Sender: TObject; Shift: TShiftState; + WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); + private + { private declarations } + FOpenFormats: TsSpreadFormatIDArray; + FSaveFormats: TsSpreadFormatIDArray; + FMRUMenuManager: TMRUMenuManager; + procedure LoadFile(const AFileName: String); + procedure MRUMenuManagerRecentFile(Sender: TObject; const AFileName: string); + procedure SearchClose(Sender: TObject; var CloseAction: TCloseAction); + procedure SearchFound(Sender: TObject; AFound: Boolean; + AWorksheet: TsWorksheet; ARow, ACol: Cardinal); + procedure UpdateCaption; + procedure UpdateInspectorColumns; + protected + procedure ReadFromIni; + procedure WriteToIni; + public + { public declarations } + procedure BeforeRun; + end; + +var + MainForm: TMainForm; + + +implementation + +{$R *.lfm} + +uses + LCLIntf, inifiles, uriparser, ValEdit, + fpsUtils, fpsCSV, + sCSVParamsForm, sCurrencyForm, sFormatSettingsForm, sSortParamsForm, + sHyperlinkForm, sNumFormatForm, sSearchForm, sColWidthForm, sRowHeightForm, + sAbout; + +var + SEARCH_DLG_POS: TPoint = (X: -1; Y: -1); + +function CreateIni: TCustomIniFile; +begin + Result := TMemIniFile.Create(GetAppConfigFile(false)); +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.AcAutoRowHeightsExecute(Sender: TObject); +begin + Screen.Cursor := crHourglass; + try + WorksheetGrid.UpdateRowHeights(0, true); + finally + Screen.Cursor := crDefault; + end; +end; + +{ Adds a column before the active cell } +procedure TMainForm.AcColAddExecute(Sender: TObject); +begin + WorksheetGrid.InsertCol(WorksheetGrid.Col); + WorksheetGrid.Col := WorksheetGrid.Col + 1; +end; + +{ Deletes the column with the active cell } +procedure TMainForm.AcColDeleteExecute(Sender: TObject); +var + c: Integer; +begin + c := WorksheetGrid.Col; + WorksheetGrid.DeleteCol(c); + WorksheetGrid.Col := c; +end; + +procedure TMainForm.AcColWidthExecute(Sender: TObject); +var + F: TColWidthForm; + sc: Cardinal; + book: TsWorkbook; + sheet: TsWorksheet; +begin + book := WorkbookSource.Workbook; + sheet := WorkbookSource.Worksheet; + sc := WorksheetGrid.GetWorksheetCol(WorksheetGrid.Col); + F := TColWidthForm.Create(nil); + try + F.Caption := 'Width of column ' + GetColString(sc); + F.SetData(book, sheet.GetColWidth(sc, book.Units), sheet.GetColWidthType(sc)); + if F.ShowModal = mrOK then begin + sheet.WriteColWidth(sc, F.ColWidth, F.Units, F.ColWidthType); + WorksheetGrid.UpdateColWidth(WorksheetGrid.Col); + end; + finally + F.Free; + end; +end; + +procedure TMainForm.AcFileNewExecute(Sender: TObject); +begin + WorkbookSource.CreateNewWorkbook; + + //WorksheetGrid.NewWorkbook(26, 100); + + WorksheetGrid.BeginUpdate; + try + WorksheetGrid.Col := WorksheetGrid.FixedCols; + WorksheetGrid.Row := WorksheetGrid.FixedRows; + UpdateCaption; + //SetupBackgroundColorBox; + //WorksheetGridSelection(nil, WorksheetGrid.Col, WorksheetGrid.Row); + finally + WorksheetGrid.EndUpdate; + end; +end; + +{ Loads the spreadsheet file selected by the AcFileOpen action } +procedure TMainForm.AcFileOpenAccept(Sender: TObject); +begin + WorkbookSource.AutodetectFormat := false; + case AcFileOpen.Dialog.FilterIndex of + 1: WorkbookSource.AutoDetectFormat := true; // All spreadsheet files + 2: WorkbookSource.AutoDetectFormat := true; // All Excel files + else WorkbookSource.FileFormatID := FOpenFormats[AcFileOpen.Dialog.FilterIndex - 3]; + // -3 because FilterIndex is 1-based and there are 2 add'l items at the top. + end; + LoadFile(AcFileOpen.Dialog.FileName); +end; + +{ Saves the spreadsheet to the file selected by the AcFileSaveAs action } +procedure TMainForm.AcFileSaveAsAccept(Sender: TObject); +var + fmt: TsSpreadFormatID; + fmts: TsSpreadFormatIDArray; + ext: String; +begin + Screen.Cursor := crHourglass; + try + fmt := FSaveFormats[AcFileSaveAs.Dialog.FilterIndex - 1]; + ext := ExtractFileExt(ACFileSaveAs.Dialog.Filename); + WorkbookSource.SaveToSpreadsheetFile(UTF8ToAnsi(AcFileSaveAs.Dialog.FileName), fmt); + UpdateCaption; + finally + Screen.Cursor := crDefault; + end; +end; + +procedure TMainForm.AcFileSaveAsBeforeExecute(Sender: TObject); +var + i: Integer; +begin + if WorkbookSource.FileName = '' then + exit; + + AcFileSaveAs.Dialog.InitialDir := ExtractFileDir(WorkbookSource.FileName); + AcFileSaveAs.Dialog.FileName := ExtractFileName(WorkbookSource.FileName); + + // Pre-select the file format according to the input file + if WorkbookSource.Workbook.FileFormatID = sfidUnknown then + exit; + for i:=0 to High(FSaveformats) do + if FSaveFormats[i] = WorkbookSource.Workbook.FileFormatID then begin + AcFileSaveAs.Dialog.FilterIndex := i + 1; + break; + end; +end; + +procedure TMainForm.AcFrozenColsExecute(Sender: TObject); +begin + if AcFrozenCols.Checked then + WorksheetGrid.FrozenCols := WorksheetGrid.GetWorksheetCol(WorksheetGrid.Col) + else + WorksheetGrid.FrozenCols := 0; +end; + +procedure TMainForm.AcFrozenColsUpdate(Sender: TObject); +begin + AcFrozenCols.Checked := WorksheetGrid.FrozenCols > 0; +end; + +procedure TMainForm.AcFrozenRowsExecute(Sender: TObject); +begin + if AcFrozenRows.Checked then + WorksheetGrid.FrozenRows := WorksheetGrid.GetWorksheetRow(WorksheetGrid.Row) + else + WorksheetGrid.FrozenRows := 0; +end; + +procedure TMainForm.AcFrozenRowsUpdate(Sender: TObject); +begin + AcFrozenRows.Checked := WorksheetGrid.FrozenRows > 0; +end; + +procedure TMainForm.AcNumFormatCustomGetNumberFormatString(Sender: TObject; + AWorkbook: TsWorkbook; var ANumFormatStr: String); +var + F: TNumFormatForm; + sample: Double; +begin + Unused(AWorkbook); + F := TNumFormatForm.Create(nil); + try + F.Position := poMainFormCenter; + with WorkbookSource.Worksheet do + sample := ReadAsNumber(ActiveCellRow, ActiveCellCol); + F.SetData(ANumFormatStr, WorkbookSource.Workbook, sample); + if F.ShowModal = mrOK then + ANumFormatStr := F.NumFormatStr; + finally + F.Free; + end; +end; + +{ Adds a row before the active cell } +procedure TMainForm.AcRowAddExecute(Sender: TObject); +begin + WorksheetGrid.InsertRow(WorksheetGrid.Row); + WorksheetGrid.Row := WorksheetGrid.Row + 1; +end; + +{ Deletes the row with the active cell } +procedure TMainForm.AcRowDeleteExecute(Sender: TObject); +var + r: Integer; +begin + r := WorksheetGrid.Row; + WorksheetGrid.DeleteRow(r); + WorksheetGrid.Row := r; +end; + +procedure TMainForm.AcRowHeightExecute(Sender: TObject); +var + F: TRowHeightForm; + sr: Cardinal; + book: TsWorkbook; + sheet: TsWorksheet; +begin + book := WorkbookSource.Workbook; + sheet := WorkbookSource.Worksheet; + sr := WorksheetGrid.GetWorksheetRow(WorksheetGrid.Row); + F := TRowHeightForm.Create(nil); + try + F.Caption := Format('Height of row %d', [WorksheetGrid.Row]); + F.SetData(book, sheet.GetRowHeight(sr, book.Units), sheet.GetRowHeightType(sr)); + if F.ShowModal = mrOK then begin + sheet.WriteRowHeight(sr, F.RowHeight, F.Units, F.RowHeightType); + WorksheetGrid.UpdateRowHeight(WorksheetGrid.Row, F.RowHeightType = rhtAuto); + end; + finally + F.Free; + end; +end; + +procedure TMainForm.AcWorksheetRTLExecute(Sender: TObject); +begin + if AcWorksheetRTL.Checked then + begin + if WorksheetGrid.IsRightToLeft then + WorksheetGrid.Worksheet.BiDiMode := bdLTR else + WorksheetGrid.Worksheet.BiDiMode := bdRTL; + end else + WorksheetGrid.Worksheet.BiDiMode := bdDefault; +end; + +procedure TMainForm.AcWorksheetRTLUpdate(Sender: TObject); +begin + AcWorksheetRTL.Checked := WorksheetGrid.Worksheet.BiDiMode <> bdDefault; +end; + +procedure TMainForm.AcSearchExecute(Sender: TObject); +begin + if SearchForm = nil then + SearchForm := TSearchForm.Create(self) + else + if not SearchForm.Showing then + begin + SearchForm.Position := poDesigned; + SearchForm.Left := SEARCH_DLG_POS.X; + SearchForm.Top := SEARCH_DLG_POS.Y; + end else + SearchForm.BringToFront; + SearchForm.OnFound := @SearchFound; + SearchForm.OnClose := @SearchClose; + SearchForm.SearchParams := DefaultSearchParams; + SearchForm.ReplaceParams := DefaultReplaceParams; + SearchForm.Execute(WorkbookSource.Workbook); +end; + +procedure TMainForm.AcSettingsCSVParamsExecute(Sender: TObject); +var + F: TCSVParamsForm; +begin + F := TCSVParamsForm.Create(nil); + try + F.SetParams(fpscsv.CSVParams); + if F.ShowModal = mrOK then + F.GetParams(fpscsv.CSVParams); + finally + F.Free; + end; +end; + +procedure TMainForm.AcSettingsCurrencyExecute(Sender: TObject); +var + F: TCurrencyForm; +begin + F := TCurrencyForm.Create(nil); + try + F.ShowModal; + finally + F.Free; + end; +end; + +procedure TMainForm.AcSettingsFormatSettingsExecute(Sender: TObject); +var + F: TFormatSettingsForm; +begin + if WorksheetGrid.Workbook = nil then + exit; + + F := TFormatSettingsForm.Create(nil); + try + F.FormatSettings := WorksheetGrid.Workbook.FormatSettings; + if F.ShowModal = mrOK then + begin + WorksheetGrid.Workbook.FormatSettings := F.FormatSettings; + WorksheetGrid.Invalidate; + end; + finally + F.Free; + end; +end; + +procedure TMainForm.AcShowGridLinesExecute(Sender: TObject); +begin + WorksheetGrid.ShowGridLines := AcShowGridLines.Checked; +end; + +procedure TMainForm.AcShowGridLinesUpdate(Sender: TObject); +begin + AcShowGridLines.Checked := WorksheetGrid.ShowGridLines; +end; + +procedure TMainForm.AcShowHeadersExecute(Sender: TObject); +begin + WorksheetGrid.ShowHeaders := AcShowHeaders.Checked; +end; + +procedure TMainForm.AcShowHeadersUpdate(Sender: TObject); +begin + AcShowHeaders.Checked := WorksheetGrid.ShowHeaders; +end; + +procedure TMainForm.AcSortColAscExecute(Sender: TObject); +var + c: Cardinal; + sortParams: TsSortParams; +begin + c := WorksheetGrid.GetWorksheetCol(WorksheetGrid.Col); + sortParams := InitSortParams; + WorksheetGrid.BeginUpdate; + try + with WorkbookSource.Worksheet do + Sort(sortParams, 0, c, GetLastOccupiedRowIndex, c); + finally + WorksheetGrid.EndUpdate; + end; +end; + +procedure TMainForm.AcSortExecute(Sender: TObject); +var + F: TSortParamsForm; + r1,c1,r2,c2: Cardinal; +begin + F := TSortParamsForm.Create(nil); + try + F.WorksheetGrid := WorksheetGrid; + if F.ShowModal = mrOK then + begin + // Limits of the range to be sorted + with WorksheetGrid do begin + r1 := GetWorksheetRow(Selection.Top); + c1 := GetWorksheetCol(Selection.Left); + r2 := GetWorksheetRow(Selection.Bottom); + c2 := GetWorksheetCol(Selection.Right); + end; + // Execute sorting. Use Begin/EndUpdate to avoid unnecessary redraws. + WorksheetGrid.BeginUpdate; + try + WorksheetGrid.Worksheet.Sort(F.SortParams, r1, c1, r2, c2) + finally + WorksheetGrid.EndUpdate; + end; + end; + finally + F.Free; + end; +end; + +procedure TMainForm.ActionListUpdate(AAction: TBasicAction; var Handled: Boolean + ); +begin + if AAction = AcAutoRowHeights then + AcAutoRowHeights.Enabled := WorkbookSource.Worksheet <> nil; +end; + +{ Toggles the spreadsheet inspector on and off } +procedure TMainForm.AcViewInspectorExecute(Sender: TObject); +begin + InspectorTabControl.Visible := AcViewInspector.Checked; + InspectorSplitter.Visible := AcViewInspector.Checked; + InspectorSplitter.Left := 0; + // Make sure that the splitter is always at the left of the inspector tabcontrol + UpdateInspectorColumns; +end; + +procedure TMainForm.BeforeRun; +begin + ReadFromIni; +end; + +procedure TMainForm.ColorComboboxAddColors(Sender: TObject); +begin + with TsCellCombobox(Sender) do begin + // These are the Excel-8 palette colors, a bit rearranged and without the + // duplicates. + AddColor($000000, 'black'); + AddColor($333333, 'gray 80%'); + AddColor($808080, 'gray 50%'); + AddColor($969696, 'gray 40%'); + AddColor($C0C0C0, 'silver'); + AddColor($FFFFFF, 'white'); + AddColor($FF0000, 'red'); + AddColor($00FF00, 'green'); + AddColor($0000FF, 'blue'); + AddColor($FFFF00, 'yellow'); + AddColor($FF00FF, 'magenta'); + AddColor($00FFFF, 'cyan'); + + AddColor($800000, 'dark red'); + AddColor($008000, 'dark green'); + AddColor($000080, 'dark blue'); + AddColor($808000, 'olive'); + AddColor($800080, 'purple'); + AddColor($008080, 'teal'); + AddColor($9999FF, 'periwinkle'); + AddColor($993366, 'plum'); + AddColor($FFFFCC, 'ivory'); + AddColor($CCFFFF, 'light turquoise'); + AddColor($660066, 'dark purple'); + AddColor($FF8080, 'coral'); + AddColor($0066CC, 'ocean blue'); + AddColor($CCCCFF, 'ice blue'); + + AddColor($00CCFF, 'sky blue'); + AddColor($CCFFCC, 'light green'); + AddColor($FFFF99, 'light yellow'); + AddColor($99CCFF, 'pale blue'); + AddColor($FF99CC, 'rose'); + AddColor($CC99FF, 'lavander'); + AddColor($FFCC99, 'tan'); + + AddColor($3366FF, 'light blue'); + AddColor($33CCCC, 'aqua'); + AddColor($99CC00, 'lime'); + AddColor($FFCC00, 'gold'); + AddColor($FF9900, 'light orange'); + AddColor($FF6600, 'orange'); + AddColor($666699, 'blue gray'); + AddColor($003366, 'dark teal'); + AddColor($339966, 'sea green'); + AddColor($003300, 'very dark green'); + AddColor($333300, 'olive green'); + AddColor($993300, 'brown'); + AddColor($333399, 'indigo'); + end; +end; + +procedure TMainForm.EditCut1Execute(Sender: TObject); +begin + // +end; + +procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: boolean); +begin + if CanClose then + try + WriteToIni; + except + end; +end; + +procedure TMainForm.FormCreate(Sender: TObject); +var + priorityFormats: Array[0..8] of TsSpreadFormatID; +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 := PuRecentFiles; + OnRecentFile := @MRUMenuManagerRecentFile; + end; + + priorityFormats[0] := ord(sfOOXML); + priorityFormats[1] := ord(sfExcel8); + priorityFormats[2] := ord(sfExcel5); + priorityFormats[3] := ord(sfExcel2); + priorityFormats[4] := ord(sfExcelXML); + priorityFormats[5] := ord(sfOpenDocument); + priorityFormats[6] := ord(sfCSV); + priorityFormats[7] := sfidSYLK; + priorityFormats[8] := ord(sfHTML); + + AcFileOpen.Dialog.Filter := GetFileFormatFilter('|', ';', faRead, priorityFormats, true, true); + FOpenFormats := GetSpreadFormats(faRead, priorityFormats); + + AcFileSaveAs.Dialog.Filter := GetFileFormatFilter('|', ';', faWrite, priorityFormats); + FSaveFormats := GetSpreadFormats(faWrite, priorityFormats); + + {$IFDEF WINDOWS} + if Win32MajorVersion >= 10 then begin + // avoid the ugly themed grid of Win10... + WorksheetGrid.TitleStyle := tsLazarus; + Inspector.TitleStyle := tsLazarus; + end; + {$ENDIF} +end; + +procedure TMainForm.FormShow(Sender: TObject); +begin + UpdateInspectorColumns; +end; + +{ Event handler for hyperlinks: it only has to provide the hyperlink data + which are applied to the active cell by the TsCellHyperlinkAction. + Is called by the "new hyperlink" and "edit hyperlink" actions. + Here we open the HyperlinkForm which is similar to the one used by + Open/LibreOffice. + + Caption .... Caption of the form in which the hyperlink can be specified + Hyperlink .. Data record (target, tooltip) for/from the the hyperlink form. } +procedure TMainForm.HyperlinkHandler(Sender: TObject; ACaption: String; + var AHyperlink: TsHyperlink); +begin + if HyperlinkForm = nil then + HyperlinkForm := THyperlinkForm.Create(self); + HyperlinkForm.Caption := ACaption; + HyperlinkForm.SetHyperlink(WorkbookSource.Worksheet, AHyperlink); + if HyperlinkForm.ShowModal = mrOK then + HyperlinkForm.GetHyperlink(AHyperlink); +end; + +procedure TMainForm.InspectorEnter(Sender: TObject); +begin + Inspector.Options := Inspector.Options + [goDrawFocusSelected]; +end; + +procedure TMainForm.InspectorExit(Sender: TObject); +begin + Inspector.Options := Inspector.Options - [goDrawFocusSelected]; +end; + +{ Event handler to synchronize the mode of the spreadsheet inspector with the + selected tab of the TabControl } +procedure TMainForm.InspectorTabControlChange(Sender: TObject); +begin + Inspector.Mode := TsInspectorMode(InspectorTabControl.TabIndex); + UpdateInspectorColumns; +end; + +procedure TMainForm.LoadFile(const AFileName: String); +var + crs: TCursor; +begin + crs := Screen.Cursor; + Screen.Cursor := crHourglass; + try + WorkbookSource.FileName := UTF8ToAnsi(AFileName); // this loads the file + FMRUMenuManager.AddToRecent(AFileName); + UpdateCaption; + finally + Screen.Cursor := crs; + end; +end; + +procedure TMainForm.MRUMenuManagerRecentFile(Sender: TObject; + const AFileName: string); +begin + WorkbookSource.AutoDetectFormat := true; + LoadFile(AFileName); +end; + +procedure TMainForm.ReadFromIni; +var + ini: TCustomIniFile; + s: String; + b: Boolean; + L,T,W,H: Integer; + Rect: TRect; +begin + ini := CreateIni; + try + L := ini.ReadInteger('MainForm', 'Left', Left); + T := ini.ReadInteger('MainForm', 'Top', Top); + W := ini.ReadInteger('MainForm', 'Width', Width); + H := ini.ReadInteger('MainForm', 'Height', Height); + Rect := Screen.DesktopRect; + if W > Rect.Right - Rect.Left then W := Rect.Right - Rect.Left; + if H > Rect.Bottom - Rect.Top then H := Rect.Bottom - Rect.Top; + if L + W > Rect.Right then L := Rect.Right - W; + if L < Rect.Left then L := Rect.Left; + if T + H > Rect.Bottom then T := Rect.Bottom - H; + if T < Rect.Top then T := Rect.Top; + SetBounds(L, T, W, H); + if ini.ReadBool('MainForm', 'Maximized', WindowState = wsMaximized) then + WindowState := wsMaximized else + WindowState := wsNormal; + + InspectortabControl.Width := ini.ReadInteger('Inspector', + 'Width', InspectorTabControl.Width); + s := ini.ReadString('Inspector', 'Page', ''); + if s <> '' then + InspectorTabControl.PageIndex := InspectorTabControl.Pages.IndexOf(s);; + b := ini.ReadBool('Inspector', 'Visible', false); + AcViewInspector.Checked := b; + AcviewInspectorExecute(nil); + finally + ini.Free; + end; +end; + +procedure TMainForm.SearchClose(Sender: TObject; var CloseAction: TCloseAction); +begin + Unused(CloseAction); + DefaultSearchParams := TSearchForm(Sender).SearchParams; + DefaultReplaceParams := TSearchForm(Sender).ReplaceParams; + SEARCH_DLG_POS.X := SearchForm.Left; + SEARCH_DLG_POS.Y := SearchForm.Top; +end; + +procedure TMainForm.SearchFound(Sender: TObject; AFound: Boolean; + AWorksheet: TsWorksheet; ARow, ACol: Cardinal); +begin + Unused(AWorksheet, ARow, ACol); + + if AFound then + begin + // + end + else + begin + DefaultSearchParams := TSearchForm(Sender).SearchParams; + MessageDlg( + Format('The search text "%s" could not be found.', [DefaultSearchParams.SearchText]), + mtInformation, + [mbOK], 0 + ); + end; +end; + +procedure TMainForm.TSaveDialogTypeChange(Sender: TObject); +var + ext: String; +begin + ext := GetSpreadFormatExt(FSaveFormats[AcFileSaveAs.Dialog.FilterIndex - 1]); + AcFileSaveAs.Dialog.FileName := ChangeFileExt(AcFileSaveAs.Dialog.FileName, ext); +end; + +procedure TMainForm.UpdateCaption; +begin + if (WorkbookSource = nil) or (WorkbookSource.FileName = '') then + Caption := 'spready' + else + Caption := Format('spready - "%s" [%s]', [ + AnsiToUTF8(WorkbookSource.Filename), + GetSpreadTechnicalName(WorkbookSource.Workbook.FileFormatID) + ]); +end; + +procedure TMainForm.UpdateInspectorColumns; +begin + Inspector.DisplayOptions := Inspector.DisplayOptions + [doAutoColResize]; + Inspector.DisplayOptions := Inspector.DisplayOptions - [doAutoColResize]; +end; + +procedure TMainForm.WriteToIni; +var + ini: TCustomIniFile; +begin + ini := CreateIni; + try + ini.WriteBool('MainForm', 'Maximized', WindowState = wsMaximized); + if WindowState = wsNormal then begin + ini.WriteInteger('MainForm', 'Left', Left); + ini.WriteInteger('MainForm', 'Top', Top); + ini.WriteInteger('MainForm', 'Width', Width); + ini.WriteInteger('MainForm', 'Height', Height); + end; + + ini.WriteInteger('Inspector', 'Width', InspectorTabControl.Width); + ini.WriteString('Inspector', 'Page', InspectorTabControl.Tabs[InspectorTabControl.TabIndex]); + ini.WriteBool('Inspector', 'Visible', InspectorTabControl.Visible); + finally + ini.Free; + end; +end; + +{ Event handler if an external hyperlink in a cell is activated. Usually the + linked documents/web sites etc. are opened. } +procedure TMainForm.WorksheetGridClickHyperlink(Sender: TObject; + const AHyperlink: TsHyperlink); +var + u: TUri; +begin + u := ParseURI(AHyperlink.Target); + case Lowercase(u.Protocol) of + 'http', 'https', 'ftp', 'mailto', 'file': + OpenUrl(AHyperlink.Target); + else + ShowMessage('Hyperlink ' + AHyperlink.Target + ' clicked'); + end; +end; + +procedure TMainForm.WorksheetGridMouseWheel(Sender: TObject; + Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; + var Handled: Boolean); +const + GROWTH_FACTOR = 1.05; +begin + if ([ssCtrl, ssShift] * Shift = [ssCtrl, ssShift]) then begin + if WheelDelta > 0 then + WorksheetGrid.ZoomFactor := GROWTH_FACTOR* WorksheetGrid.ZoomFactor + else + WorksheetGrid.ZoomFactor := WorksheetGrid.ZoomFactor / GROWTH_FACTOR; + Handled := true; + end; +end; + +end. + diff --git a/applications/spready/snumformatform.lfm b/applications/spready/snumformatform.lfm new file mode 100644 index 000000000..f9fad4d69 --- /dev/null +++ b/applications/spready/snumformatform.lfm @@ -0,0 +1,387 @@ +object NumFormatForm: TNumFormatForm + Left = 336 + Height = 394 + Top = 173 + Width = 559 + BorderStyle = bsDialog + Caption = 'Number format' + ClientHeight = 394 + ClientWidth = 559 + ShowHint = True + LCLVersion = '1.7' + object ButtonPanel1: TButtonPanel + Left = 6 + Height = 34 + Top = 354 + Width = 547 + OKButton.Name = 'OKButton' + OKButton.Hint = 'Accept changes and close' + OKButton.DefaultCaption = True + HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True + CloseButton.Name = 'CloseButton' + CloseButton.DefaultCaption = True + CancelButton.Name = 'CancelButton' + CancelButton.Hint = 'Discard changes and close' + CancelButton.DefaultCaption = True + TabOrder = 2 + ShowButtons = [pbOK, pbCancel] + end + object Panel1: TPanel + Left = 0 + Height = 297 + Top = 0 + Width = 122 + Align = alLeft + BevelOuter = bvNone + ClientHeight = 297 + ClientWidth = 122 + TabOrder = 0 + object Label1: TLabel + Left = 6 + Height = 15 + Top = 6 + Width = 112 + Align = alTop + BorderSpacing.Left = 2 + BorderSpacing.Top = 2 + BorderSpacing.Bottom = 2 + BorderSpacing.Around = 4 + Caption = 'Category' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + end + object LbCategory: TListBox + Left = 6 + Height = 270 + Top = 27 + Width = 116 + Align = alClient + BorderSpacing.Left = 6 + Items.Strings = ( + 'Number' + 'Percent' + 'Scientific' + 'Fraction' + 'Currency' + 'Date' + 'Time' + 'Text' + ) + ItemHeight = 15 + OnClick = LbCategoryClick + TabOrder = 0 + end + end + object Panel2: TPanel + Left = 122 + Height = 297 + Top = 0 + Width = 230 + Align = alLeft + BevelOuter = bvNone + ClientHeight = 297 + ClientWidth = 230 + TabOrder = 1 + object Label2: TLabel + Left = 6 + Height = 15 + Top = 6 + Width = 220 + Align = alTop + BorderSpacing.Left = 2 + BorderSpacing.Top = 2 + BorderSpacing.Bottom = 2 + BorderSpacing.Around = 4 + Caption = 'Format' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + end + object LbFormat: TListBox + Left = 6 + Height = 225 + Top = 27 + Width = 224 + Align = alClient + BorderSpacing.Left = 6 + ItemHeight = 0 + OnClick = LbFormatClick + OnDrawItem = LbFormatDrawItem + Style = lbOwnerDrawFixed + TabOrder = 0 + end + object CurrSymbolPanel: TPanel + Left = 6 + Height = 41 + Top = 256 + Width = 224 + Align = alBottom + BorderSpacing.Left = 6 + BorderSpacing.Top = 4 + BevelOuter = bvNone + ClientHeight = 41 + ClientWidth = 224 + TabOrder = 1 + Visible = False + object Label5: TLabel + Left = 0 + Height = 15 + Top = 0 + Width = 224 + Align = alTop + BorderSpacing.Bottom = 2 + Caption = 'Currency string' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + end + object CbCurrSymbol: TComboBox + Left = 0 + Height = 23 + Hint = 'List of registered currency symbols' + Top = 16 + Width = 200 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + OnSelect = CbCurrSymbolSelect + Style = csDropDownList + TabOrder = 0 + end + object BtnAddCurrSymbol: TSpeedButton + Left = 201 + Height = 23 + Hint = 'Add new currency symbol' + Top = 16 + Width = 23 + Anchors = [akTop, akRight] + Caption = '...' + OnClick = BtnAddCurrSymbolClick + end + end + end + object DetailsPanel: TPanel + Left = 352 + Height = 297 + Top = 0 + Width = 207 + Align = alClient + BevelOuter = bvNone + ClientHeight = 297 + ClientWidth = 207 + TabOrder = 3 + object GbOptions: TGroupBox + Left = 8 + Height = 121 + Top = 7 + Width = 187 + Anchors = [akTop, akLeft, akRight] + Caption = 'Options' + ClientHeight = 101 + ClientWidth = 183 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 0 + object Label3: TLabel + Left = 15 + Height = 15 + Top = 11 + Width = 79 + Caption = 'Decimal places' + ParentColor = False + ParentFont = False + end + object EdDecimals: TSpinEdit + Left = 121 + Height = 23 + Top = 7 + Width = 50 + Anchors = [akTop, akRight] + MaxValue = 16 + OnChange = EdDecimalsChange + ParentFont = False + TabOrder = 0 + end + object CbThousandSep: TCheckBox + Left = 15 + Height = 19 + Top = 40 + Width = 125 + Caption = 'Thousand separator' + OnClick = CbThousandSepClick + ParentFont = False + TabOrder = 1 + end + object CbNegRed: TCheckBox + Left = 15 + Height = 19 + Top = 67 + Width = 100 + Caption = 'Negative in red' + OnClick = CbNegRedClick + ParentFont = False + TabOrder = 2 + end + end + object GroupBox3: TGroupBox + Left = 8 + Height = 62 + Top = 136 + Width = 187 + Anchors = [akTop, akLeft, akRight] + Caption = 'Sample' + ClientHeight = 42 + ClientWidth = 183 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 1 + object Shape1: TShape + Left = 8 + Height = 34 + Top = 0 + Width = 167 + Align = alClient + BorderSpacing.Left = 8 + BorderSpacing.Right = 8 + BorderSpacing.Bottom = 8 + end + object Sample: TLabel + Left = 9 + Height = 32 + Top = 1 + Width = 165 + Align = alClient + Alignment = taCenter + AutoSize = False + BorderSpacing.Left = 8 + BorderSpacing.Right = 8 + BorderSpacing.Bottom = 8 + BorderSpacing.Around = 1 + Caption = 'Sample' + Color = clWhite + Layout = tlCenter + ParentColor = False + ParentFont = False + Transparent = False + end + end + end + object GbFormatString: TGroupBox + Left = 6 + Height = 47 + Top = 301 + Width = 547 + Align = alBottom + BorderSpacing.Left = 6 + BorderSpacing.Top = 4 + BorderSpacing.Right = 6 + Caption = 'Format string' + ClientHeight = 27 + ClientWidth = 543 + Font.Style = [fsBold] + ParentFont = False + TabOrder = 4 + object EdNumFormatStr: TEdit + Left = 8 + Height = 23 + Hint = 'Number format string' + Top = 0 + Width = 483 + Anchors = [akTop, akLeft, akRight] + OnChange = EdNumFormatStrChange + ParentFont = False + TabOrder = 0 + end + object BtnAddFormat: TSpeedButton + Left = 493 + Height = 23 + Hint = 'Add this format string to list' + Top = 0 + Width = 23 + Anchors = [akTop, akRight] + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0041924E233D8F497D3A8C44DB368940F332873CF32F84 + 37DB2C81337D287F3023FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0049995853459653E6419950FF7DC28FFF96D0A6FF96CFA6FF78BE + 89FF368D42FF2C8134E6297F3053FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00519F61534D9C5DF464B478FFA8DBB5FF87CC98FF66BC7DFF64BA7CFF86CB + 98FFA5D9B4FF58AA6BFF2C8134F4297F3053FFFFFF00FFFFFF00FFFFFF0059A6 + 6B2256A366E56AB97DFFA8DBB2FF60BC77FF5CBA73FF59B870FF59B56FFF58B5 + 6FFF5BB774FFA5D9B3FF5AAA6CFF2C8234E5297F3022FFFFFF00FFFFFF005DA9 + 707E53AB68FFAADDB4FF64C179FF5FBE71FF60BC77FFFFFFFFFFFFFFFFFF59B8 + 70FF58B56EFF5CB774FFA6DAB4FF388F43FF2C82347EFFFFFF00FFFFFF0061AC + 75DB8ACC98FF89D396FF6BC67AFF63C170FF55AB65FFFFFFFFFFFFFFFFFF59B8 + 70FF59B870FF5BB972FF85CC97FF7BBE8DFF308539DBFFFFFF00FFFFFF0065AF + 7AF6A9DDB3FF7DCF8AFF75CC81FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF59B870FF67BE7DFF9CD4ABFF34883DF6FFFFFF00FFFFFF0069B2 + 7EF6B6E2BEFF8BD597FF7AC986FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF59B870FF69C17EFF9DD4AAFF388B42F6FFFFFF00FFFFFF006DB5 + 83DBACDDB6FFA6DFAFFF81CB8CFF7CC986FF6EBD79FFFFFFFFFFFFFFFFFF5BAC + 6AFF60BC77FF5CBA73FF8BD199FF80C592FF3C8E47DBFFFFFF00FFFFFF0070B8 + 877E85C797FFD2EED7FF95D9A0FF8AD394FF7FC889FFFFFFFFFFFFFFFFFF79CD + 85FF6BC37CFF6FC77EFFACDFB5FF459E57FF40914C7EFFFFFF00FFFFFF0073BA + 8A2270B887E5AADAB7FFD8F1DCFF92D89DFF88CD93FF84CC8EFF8BD496FF8AD4 + 95FF83D28EFFAFE0B7FF6BB97DFF489856E544945122FFFFFF00FFFFFF00FFFF + FF0073BB8B5370B887F4AFDCBBFFDCF2E0FFB6E4BDFF9BDBA5FF96D9A0FFA5DF + AFFFC0E8C5FF79C28AFF509E5FF44C9B5B53FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0073BB8B5371B887E694CEA4FFC3E6CBFFCFEBD4FFC9E9CEFFAFDD + B8FF6DB97FFF58A569E654A16553FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0074BB8B2371B9887D6EB684DB6AB380F367B17CF363AE + 77DB60AB737D5CA86E23FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = BtnAddFormatClick + end + object BtnDeleteFormat: TSpeedButton + Left = 516 + Height = 23 + Hint = 'Remove this format string from list' + Top = 0 + Width = 23 + Anchors = [akTop, akRight] + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF003F54C3233A50C27D3853BEDB3551BDF3304BBCF32E4E + B8DB2B4CB77D2748B523FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF004658C8534255C6E63C52CCFF757AE8FF8F92EEFF8F92EEFF7178 + E4FF334DC1FF2B4AB7E6294BB553FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF004D5ACD534959CBF45C65E0FFA1A6F5FF7E86EFFF5B63E9FF595DE7FF7D84 + EEFF9EA0F4FF515DD7FF2B4AB7F4294BB553FFFFFF00FFFFFF00FFFFFF00545F + D2225361CFE5616BE3FFA1ACF5FF545FECFF505CEAFF4D59E9FF4E59E6FF4C56 + E6FF5056E6FF9EA2F4FF5460D6FF2A4AB8E5294BB522FFFFFF00FFFFFF005860 + D47E4B56DBFFA2ABF6FF5664F0FF5266EEFF4D59E9FF4D59E9FF4D59E9FF4D59 + E9FF4C58E6FF525AE6FF9FA3F5FF3450C4FF2A4AB87EFFFFFF00FFFFFF005C62 + D7DB818CEEFF7E91F7FF5D73F3FF4D59E9FF4D59E9FF4D59E9FF4D59E9FF4D59 + E9FF4D59E9FF4F5BE9FF7B83F0FF757BE2FF2E4BBADBFFFFFF00FFFFFF005F63 + DAF6A1ABF7FF7086F8FF6882F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF4D59E9FF5C66EAFF969CF1FF3250BCF6FFFFFF00FFFFFF006469 + DBF6AFB9F9FF7F93FAFF7085F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF4D59E9FF5E6AEEFF969DF1FF364FBEF6FFFFFF00FFFFFF00676A + DEDBA5AFF5FF9DABFAFF778CF0FF545FECFF545FECFF545FECFF545FECFF545F + ECFF545FECFF6377F2FF818EF4FF787FE9FF3A53C0DBFFFFFF00FFFFFF006A69 + E07E7D83EAFFCDD4FCFF8B9DFAFF7E93F7FF758AEEFF6C84F6FF6C84F6FF6C84 + F6FF6C84F6FF6379F3FFA4AFF8FF3E4FD0FF3E54C27EFFFFFF00FFFFFF006C6C + E1226A69E0E5A3A7F3FFD4DBFDFF879AFAFF7F91F0FF7A8EF1FF7F94F8FF7E92 + F9FF768CF8FFA8B6F8FF636EE3FF4557C7E54156C522FFFFFF00FFFFFF00FFFF + FF006D6CE3536A69E0F4AAADF2FFD8DCFDFFAEBAFAFF91A3FAFF8B9DFAFF9CA9 + FBFFBAC7FCFF707BE9FF4C5BCCF44858CA53FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF006D6CE3536A6ADFE68E93EDFFBEC3F8FFCCD3F9FFC4CBF9FFAAB4 + F4FF6670E2FF535ED1E6505DCE53FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF006D6DE2236B6AE17D686ADDDB6364DCF36164DAF35D63 + D9DB5B63D67D5862D423FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = BtnDeleteFormatClick + end + end +end diff --git a/applications/spready/snumformatform.pas b/applications/spready/snumformatform.pas new file mode 100644 index 000000000..4652c0389 --- /dev/null +++ b/applications/spready/snumformatform.pas @@ -0,0 +1,829 @@ +unit sNumFormatForm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ButtonPanel, + ExtCtrls, StdCtrls, Spin, Buttons, types, inifiles, + fpsTypes, fpsNumFormat, fpSpreadsheet; + +type + TsNumFormatCategory = (nfcNumber, nfcPercent, nfcScientific, nfcFraction, + nfcCurrency, nfcDate, nfcTime, nfcText); + + { TNumFormatForm } + + TNumFormatForm = class(TForm) + ButtonPanel1: TButtonPanel; + CbThousandSep: TCheckBox; + CbNegRed: TCheckBox; + CbCurrSymbol: TComboBox; + EdNumFormatStr: TEdit; + GbOptions: TGroupBox; + GbFormatString: TGroupBox; + GroupBox3: TGroupBox; + Label1: TLabel; + Label2: TLabel; + Label3: TLabel; + DetailsPanel: TPanel; + Sample: TLabel; + Label5: TLabel; + LbCategory: TListBox; + LbFormat: TListBox; + Panel1: TPanel; + Panel2: TPanel; + EdDecimals: TSpinEdit; + CurrSymbolPanel: TPanel; + BtnAddCurrSymbol: TSpeedButton; + Shape1: TShape; + BtnAddFormat: TSpeedButton; + BtnDeleteFormat: TSpeedButton; + procedure BtnAddCurrSymbolClick(Sender: TObject); + procedure BtnAddFormatClick(Sender: TObject); + procedure BtnDeleteFormatClick(Sender: TObject); + procedure CbCurrSymbolSelect(Sender: TObject); + procedure CbNegRedClick(Sender: TObject); + procedure CbThousandSepClick(Sender: TObject); + procedure EdDecimalsChange(Sender: TObject); + procedure EdNumFormatStrChange(Sender: TObject); + procedure LbCategoryClick(Sender: TObject); + procedure LbFormatClick(Sender: TObject); + procedure LbFormatDrawItem(Control: TWinControl; Index: Integer; + ARect: TRect; State: TOwnerDrawState); + private + { private declarations } + FWorkbook: TsWorkbook; + FSampleValue: Double; + FSampleText: String; + FGenerator: array[TsNumFormatCategory] of Double; + FNumFormatStrOfList: String; + FLockCount: Integer; + function GetNumFormatStr: String; + procedure SetNumFormatStr(const AValue: String); + protected + function FindNumFormat(ACategory: TsNumFormatCategory; + ANumFormatStr: String): Integer; + function FormatStrOfListIndex(AIndex: Integer): String; + procedure ReplaceCurrSymbol; + procedure ReplaceDecs; + procedure SelectCategory(ACategory: TsNumFormatCategory); + procedure SelectFormat(AIndex: Integer); + procedure UpdateControls(ANumFormatParams: TsNumFormatParams); + procedure UpdateSample(ANumFormatParams: TsNumFormatParams); + public + { public declarations } + constructor Create(AOwner: TComponent); override; + procedure SetData(ANumFormatStr: String; AWorkbook: TsWorkbook; + ASample: variant); + property NumFormatStr: String read GetNumFormatStr; + end; + +var + NumFormatForm: TNumFormatForm; + +procedure ReadNumFormatsFromIni(const AIniFile: TCustomIniFile); +procedure WriteNumFormatsToIni(const AIniFile: TCustomIniFile); + +implementation + +{$R *.lfm} + +uses + LCLType, Math, DateUtils, TypInfo, variants, + fpsUtils, fpsNumFormatParser, fpsCurrency, + sCurrencyForm; + +const + BUILTIN_OFFSET = 1; + USER_OFFSET = 1000; + +var + NumFormats: TStringList = nil; + +procedure AddToList(ACategory: TsNumFormatCategory; AFormatStr: String; + AOffset: Integer = BUILTIN_OFFSET); +begin + if NumFormats.IndexOf(AFormatStr) = -1 then + NumFormats.AddObject(AFormatStr, TObject(PtrInt(AOffset + ord(ACategory)))); +end; + +procedure InitNumFormats(AFormatSettings: TFormatSettings); +var + copiedFormats: TStringList; + nfs: String; + data: PtrInt; + i: Integer; + fs: TFormatSettings absolute AFormatSettings; +begin + copiedFormats := nil; + + // Store user-defined formats already added to NumFormats list + if NumFormats <> nil then + begin + copiedFormats := TStringList.Create; + for i:=0 to NumFormats.Count-1 do + begin + nfs := NumFormats.Strings[i]; + data := PtrInt(NumFormats.Objects[i]); + if data >= USER_OFFSET then + copiedFormats.AddObject(nfs, TObject(data)); + end; + NumFormats.Free; + end; + + NumFormats := TStringList.Create; + + // Add built-in formats + AddToList(nfcNumber, 'General'); + AddToList(nfcNumber, '0'); + AddToList(nfcNumber, '0.0'); + AddToList(nfcNumber, '0.00'); + AddToList(nfcNumber, '0.000'); + AddToList(nfcNumber, '#,##0'); + AddToList(nfcNumber, '#,##0.0'); + AddToList(nfcNumber, '#,##0.00'); + AddToList(nfcNumber, '#,##0.000'); + + AddToList(nfcPercent, '0%'); + AddToList(nfcPercent, '0.0%'); + AddToList(nfcPercent, '0.00%'); + AddToList(nfcPercent, '0.000%'); + + AddToList(nfcScientific, '0E+0'); + AddToList(nfcScientific, '0E+00'); + AddToList(nfcScientific, '0E+000'); + AddToList(nfcScientific, '0.0E+0'); + AddToList(nfcScientific, '0.0E+00'); + AddToList(nfcScientific, '0.0E+000'); + AddToList(nfcScientific, '0.00E+0'); + AddToList(nfcScientific, '0.00E+00'); + AddToList(nfcScientific, '0.00E+000'); + AddToList(nfcScientific, '0.000E+0'); + AddToList(nfcScientific, '0.000E+00'); + AddToList(nfcScientific, '0.000E+000'); + AddToList(nfcScientific, '0E-0'); + AddToList(nfcScientific, '0E-00'); + AddToList(nfcScientific, '0E-000'); + AddToList(nfcScientific, '0.0E-0'); + AddToList(nfcScientific, '0.0E-00'); + AddToList(nfcScientific, '0.0E-000'); + AddToList(nfcScientific, '0.00E-0'); + AddToList(nfcScientific, '0.00E-00'); + AddToList(nfcScientific, '0.00E-000'); + AddToList(nfcScientific, '0.000E-0'); + AddToList(nfcScientific, '0.000E-00'); + AddToList(nfcScientific, '0.000E-000'); + + AddToList(nfcFraction, '# ?/?'); + AddToList(nfcFraction, '# ??/??'); + AddToList(nfcFraction, '# ???/???'); + AddToList(nfcFraction, '# ?/2'); + AddToList(nfcFraction, '# ?/4'); + AddToList(nfcFraction, '# ?/8'); + AddToList(nfcFraction, '# ?/16'); + AddToList(nfcFraction, '# ?/32'); + AddToList(nfcFraction, '?/?'); + AddToList(nfcFraction, '?/??'); + AddToList(nfcFraction, '?/???'); + AddToList(nfcFraction, '?/2'); + AddToList(nfcFraction, '?/4'); + AddToList(nfcFraction, '?/8'); + AddToList(nfcFraction, '?/16'); + AddToList(nfcFraction, '?/32'); + + AddToList(nfcCurrency, '#,##0 [$$];-#,##0 [$$]'); + AddToList(nfcCurrency, '#,##0.00 [$$];-#,##0.00 [$$]'); + AddToList(nfcCurrency, '#,##0 [$$];(#,##0) [$$]'); + AddToList(nfcCurrency, '#,##0.00 [$$];(#,##0.00) [$$]'); + AddToList(nfcCurrency, '#,##0 [$$];[red]-#,##0 [$$]'); + AddToList(nfcCurrency, '#,##0.00 [$$];[red]-#,##0.00 [$$]'); + AddToList(nfcCurrency, '#,##0 [$$];[red](#,##0) [$$]'); + AddToList(nfcCurrency, '#,##0.00 [$$];[red]-#,##0.00 [$$]'); + AddToList(nfcCurrency, '[$$] #,##0;[$$] -#,##0'); + AddToList(nfcCurrency, '[$$] #,##0.00;[$$] -#,##0.00'); + AddToList(nfcCurrency, '[$$] #,##0;[$$] (#,##0)'); + AddToList(nfcCurrency, '[$$] #,##0.00;[$$] (#,##0.00)'); + AddToList(nfcCurrency, '[$$] #,##0;[red][$$] -#,##0'); + AddToList(nfcCurrency, '[$$] #,##0.00;[red][$$] -#,##0.00'); + AddToList(nfcCurrency, '[$$] #,##0;[red][$$] (#,##0)'); + AddToList(nfcCurrency, '[$$] #,##0.00;[red][$$] -#,##0.00'); + + AddToList(nfcDate, 'dddd, '+fs.LongDateFormat + ' ' + fs.ShortTimeFormat); + AddToList(nfcDate, 'dddd, '+fs.ShortDateFormat + ' ' + fs.ShortTimeFormat); + AddToList(nfcDate, 'dddd, '+fs.LongDateFormat); + AddToList(nfcDate, 'dddd, '+fs.ShortDateFormat); + AddToList(nfcDate, 'ddd., '+fs.LongDateFormat + ' ' + fs.ShortTimeFormat); + AddToList(nfcDate, 'ddd., '+fs.ShortDateFormat + ' ' + fs.ShortTimeFormat); + AddToList(nfcDate, 'ddd., '+fs.LongDateFormat); + AddToList(nfcDate, 'ddd., '+fs.ShortDateFormat); + AddToList(nfcDate, fs.LongDateFormat + ' ' + fs.ShortTimeFormat); + AddToList(nfcDate, fs.ShortDateFormat + ' ' + fs.ShortTimeFormat); + AddToList(nfcDate, fs.LongDateFormat); + AddToList(nfcDate, fs.ShortDateFormat); + AddToList(nfcDate, 'dd. mmmm'); + AddToList(nfcDate, 'dd. mmm.'); + AddToList(nfcDate, 'd. mmmm'); + AddToList(nfcDate, 'd. mmm.'); + AddToList(nfcDate, 'mmmm dd'); + AddToList(nfcDate, 'mmmm d'); + AddToList(nfcDate, 'mmm. dd'); + AddToList(nfcDate, 'mmm. d'); + AddToList(nfcDate, 'mmmm yyyy'); + AddToList(nfcDate, 'mmm. yy'); + AddToList(nfcDate, 'yyyy-mmm'); + AddToList(nfcDate, 'yy-mmm'); + + AddToList(nfcTime, fs.LongTimeFormat); + AddToList(nfcTime, fs.ShortTimeFormat); + AddToList(nfcTime, AddAMPM(fs.LongTimeFormat, fs)); + AddToList(nfcTime, AddAMPM(fs.ShortTimeFormat, fs)); + AddToList(nfcTime, 'nn:ss'); + AddToList(nfcTime, 'nn:ss.0'); + AddToList(nfcTime, 'nn:ss.00'); + AddToList(nfcTime, 'nn:ss.000'); + AddToList(nfcTime, '[h]:nn'); + AddToList(nfcTime, '[h]:nn:ss'); + + AddToList(nfcText, '@'); + + // Add user-defined formats + if copiedFormats <> nil then + begin + for i:=0 to copiedFormats.Count-1 do begin + nfs := copiedFormats.Strings[i]; + data := PtrInt(copiedFormats.Objects[i]); + NumFormats.AddObject(nfs, TObject(PtrInt(data))); + end; + copiedFormats.Free; + end; +end; + +procedure DestroyNumFormats; +begin + NumFormats.Free; +end; + +{ Reads the user-defined number format strings from an ini file. } +procedure ReadNumFormatsFromIni(const AIniFile: TCustomIniFile); +var + section: String; + list: TStringList; + cat: TsNumFormatCategory; + i: Integer; + nfs: String; + scat: String; +begin + if NumFormats = nil + then NumFormats := TStringList.Create + else NumFormats.Clear; + + list := TStringList.Create; + try + section := 'Built-in number formats'; + AIniFile.ReadSection(section, list); + for i:=0 to list.Count-1 do begin + scat := list.Names[i]; + nfs := list.Values[scat]; + cat := TsNumFormatCategory(GetEnumValue(TypeInfo(TsNumFormatCategory), scat)); + AddToList(cat, nfs, BUILTIN_OFFSET); + end; + + list.Clear; + section := 'User-defined number formats'; + AIniFile.ReadSection(section, list); + for i:=0 to list.Count-1 do begin + scat := list.Names[i]; + nfs := list.Values[scat]; + cat := TsNumFormatCategory(GetEnumValue(TypeInfo(TsNumFormatCategory), scat)); + AddToList(cat, nfs, USER_OFFSET); + end; + + finally + list.Free; + end; +end; + +procedure WriteNumFormatsToIni(const AIniFile: TCustomIniFile); +var + data: PtrInt; + section: String; + i: Integer; + cat: TsNumFormatCategory; + scat: String; + nfs: String; +begin + section := 'Built-in number formats'; + for i:=0 to NumFormats.Count-1 do + begin + data := PtrInt(NumFormats.Objects[i]); + if data < USER_OFFSET then + begin + cat := TsNumFormatCategory(data - BUILTIN_OFFSET); + scat := Copy(GetEnumName(TypeInfo(TsNumFormatCategory), ord(cat)), 3, MaxInt); + nfs := NumFormats.Strings[i]; + AIniFile.WriteString(section, scat, nfs); + end; + end; + + section := 'User-defined number formats'; + for i:=0 to NumFormats.Count-1 do + begin + data := PtrInt(NumFormats.Objects[i]); + if data >= USER_OFFSET then + begin + cat := TsNumFormatCategory(data - USER_OFFSET); + scat := Copy(GetEnumName(TypeInfo(TsNumFormatCategory), ord(cat)), 3, MaxInt); + nfs := NumFormats.Strings[i]; + AIniFile.WriteString(section, scat, nfs); + end; + end; +end; + + + +{ TNumFormatForm } + +constructor TNumFormatForm.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FGenerator[nfcNumber] := -1234.123456; + FGenerator[nfcPercent] := -0.123456789; + FGenerator[nfcScientific] := -1234.5678; + FGenerator[nfcFraction] := -1234; //-1.23456; + FGenerator[nfcCurrency] := -1234.56789; + FGenerator[nfcDate] := EncodeDate(YearOf(date), 1, 1); + FGenerator[nfcTime] := EncodeTime(9, 0, 2, 235); + FGenerator[nfcText] := NaN; + GetRegisteredCurrencies(CbCurrSymbol.Items); +end; + +procedure TNumFormatForm.BtnAddCurrSymbolClick(Sender: TObject); +var + F: TCurrencyForm; +begin + F := TCurrencyForm.Create(nil); + try + if F.ShowModal = mrOK then + begin + GetRegisteredCurrencies(CbCurrSymbol.Items); + CbCurrSymbol.ItemIndex := CbCurrSymbol.Items.IndexOf(F.CurrencySymbol); + ReplaceCurrSymbol; + end; + finally + F.Free; + end; +end; + +procedure TNumFormatForm.BtnAddFormatClick(Sender: TObject); +var + cat: TsNumFormatCategory; + idx: Integer; + nfs: String; +begin + if LbCategory.ItemIndex > -1 then begin + cat := TsNumFormatCategory(LbCategory.ItemIndex); + nfs := EdNumFormatStr.Text; + if nfs = '' then nfs := 'General'; + if NumFormats.IndexOf(nfs) = -1 then + begin + AddToList(cat, nfs, USER_OFFSET); + SelectCategory(cat); // Rebuilds the "Format" listbox + idx := FindNumFormat(cat, nfs); + SelectFormat(idx); + end; + end; +end; + +procedure TNumFormatForm.BtnDeleteFormatClick(Sender: TObject); +var + cat: TsNumFormatCategory; + idx: Integer; + nfs: String; + n, i: Integer; +begin + if LbCategory.ItemIndex > -1 then begin + // Find in internal template list + idx := NumFormats.IndexOf(EdNumFormatStr.Text); + if idx > -1 then begin + nfs := NumFormats.Strings[idx]; + n := PtrInt(NumFormats.Objects[idx]); + if n >= USER_OFFSET + then cat := TsNumFormatCategory(n - USER_OFFSET) + else cat := TsNumFormatCategory(n - BUILTIN_OFFSET); + i := FindNumFormat(cat, nfs); // Index in format listbox + // Delete from internal template list + NumFormats.Delete(idx); + + // Rebuild format listbox (without the deleted item) + SelectCategory(cat); + if i >= LbFormat.Items.Count + then SelectFormat(LbFormat.Items.Count-1) + else SelectFormat(i); + end; + end; +end; + +procedure TNumFormatForm.CbCurrSymbolSelect(Sender: TObject); +begin + ReplaceCurrSymbol; +end; + +procedure TNumFormatForm.CbNegRedClick(Sender: TObject); +var + nfs: String; + nfp: TsNumFormatParams; +begin + if FLockCount > 0 then + exit; + + if EdNumFormatStr.Text = '' then nfs := 'General' else nfs := EdNumFormatStr.Text; + nfp := CreateNumFormatParams(nfs, FWorkbook.FormatSettings); + if nfp <> nil then + try + nfp.SetNegativeRed(CbNegRed.Checked); + EdNumFormatStr.Text := nfp.NumFormatStr; + SelectCategory(TsNumFormatCategory(LbCategory.ItemIndex)); // to rebuild the format listbox + UpdateSample(nfp); + finally + nfp.Free; + end; +end; + +procedure TNumFormatForm.CbThousandSepClick(Sender: TObject); +var + nfs: String; + nfp: TsNumFormatParams; +begin + if FLockCount > 0 then + exit; + + if EdNumFormatStr.Text = '' then nfs := 'General' else nfs := EdNumFormatStr.Text; + nfp := CreateNumFormatParams(nfs, FWorkbook.FormatSettings); + if nfp <> nil then + try + nfp.SetThousandSep(CbThousandSep.Checked); + EdNumFormatStr.Text := nfp.NumFormatStr; + SelectCategory(TsNumFormatCategory(LbCategory.ItemIndex)); // to rebuild the format listbox + UpdateSample(nfp); + finally + nfp.Free; + end; +end; + +procedure TNumFormatForm.EdDecimalsChange(Sender: TObject); +begin + if FLockCount > 0 then + exit; + ReplaceDecs; +end; + +procedure TNumFormatForm.EdNumFormatStrChange(Sender: TObject); +var + nfp: TsNumFormatParams; +begin + nfp := CreateNumFormatParams(EdNumFormatStr.Text, FWorkbook.FormatSettings); + try + UpdateControls(nfp); + finally + nfp.Free; + end; +end; + +{ Returns the index of a specific number format string in the format listbox + shown for a particular category } +function TNumFormatForm.FindNumFormat(ACategory: TsNumFormatCategory; + ANumFormatStr: String): Integer; +var + i: Integer; + data: PtrInt; + cat: TsNumFormatCategory; + nfs: String; +begin + Result := -1; + if ANumFormatStr = '' then ANumFormatStr := 'General'; + for i := 0 to NumFormats.Count-1 do begin + nfs := NumFormats.Strings[i]; + data := PtrInt(NumFormats.Objects[i]); + if data >= USER_OFFSET then + cat := TsNumFormatCategory(data - USER_OFFSET) + else + cat := TsNumFormatCategory(data - BUILTIN_OFFSET); + if (cat = ACategory) then + inc(Result); + if SameText(nfs, ANumFormatStr) then + exit; + end; +end; + +function TNumFormatForm.FormatStrOfListIndex(AIndex: Integer): String; +var + idx: PtrInt; +begin + if (AIndex >= 0) and (AIndex < LbFormat.Count) then + begin + idx := PtrInt(LbFormat.Items.Objects[AIndex]); + Result := NumFormats.Strings[idx]; + end else + Result := ''; +end; + +function TNumFormatForm.GetNumFormatStr: String; +begin + Result := EdNumFormatStr.Text; +end; + +procedure TNumFormatForm.LbCategoryClick(Sender: TObject); +begin + SelectCategory(TsNumFormatCategory(LbCategory.ItemIndex)); +end; + +procedure TNumFormatForm.LbFormatClick(Sender: TObject); +begin + SelectFormat(LbFormat.ItemIndex); +end; + +procedure TNumFormatForm.LbFormatDrawItem(Control: TWinControl; Index: Integer; + ARect: TRect; State: TOwnerDrawState); +var + s: String; + nfs: String; + nfp: TsNumFormatParams; + idx: PtrInt; +begin + Unused(Control); + LbFormat.Canvas.Brush.Color := clWindow; + LbFormat.Canvas.Font.Assign(LbFormat.Font); + if State * [odSelected, odFocused] <> [] then + begin + LbFormat.Canvas.Font.Color := clHighlightText; + LbFormat.Canvas.Brush.Color := clHighlight; + end; + if (Index > -1) and (Index < LbFormat.Items.Count) then + begin + s := LbFormat.Items[Index]; + idx := PtrInt(LbFormat.Items.Objects[Index]); + nfs := NumFormats.Strings[idx]; + nfp := CreateNumFormatParams(nfs, FWorkbook.FormatSettings); + try + if (nfp <> nil) and (Length(nfp.Sections) > 1) and (nfp.Sections[1].Color = scRed) then + LbFormat.Canvas.Font.Color := clRed; + finally + nfp.Free; + end; + end else + s := ''; + LbFormat.Canvas.FillRect(ARect); + LbFormat.Canvas.TextRect(ARect, ARect.Left+1, ARect.Top+1, s); +end; + +procedure TNumFormatForm.ReplaceCurrSymbol; +var + cs: String; + i: Integer; + nfp: TsNumFormatParams; + data: PtrInt; + cat: TsNumFormatCategory; +begin + cs := CbCurrSymbol.Items[CbCurrSymbol.ItemIndex]; + for i:=0 to NumFormats.Count-1 do + begin + data := PtrInt(NumFormats.Objects[i]); + if (data >= USER_OFFSET) then + cat := TsNumFormatCategory(data - USER_OFFSET) + else + cat := TsNumFormatCategory(data - BUILTIN_OFFSET); + if cat = nfcCurrency then + begin + nfp := CreateNumFormatParams(NumFormats.Strings[i], FWorkbook.FormatSettings); + if (nfp <> nil) then + try + nfp.SetCurrSymbol(cs); + finally + nfp.Free; + end; + end; + end; + SelectCategory(TsNumFormatCategory(LbCategory.ItemIndex)); // to rebuild the format listbox +end; + +procedure TNumFormatForm.ReplaceDecs; +var + nfp: TsNumFormatParams; +begin + if EdDecimals.Text = '' then + exit; + + nfp := CreateNumFormatParams(EdNumFormatStr.Text, FWorkbook.FormatSettings); + try + nfp.SetDecimals(EdDecimals.Value); + EdNumFormatStr.Text := nfp.NumFormatStr; + UpdateSample(nfp); + finally + nfp.Free; + end; +end; + +procedure TNumFormatForm.SelectCategory(ACategory: TsNumFormatCategory); +var + nfp: TsNumFormatParams; + i, digits, numdigits: Integer; + data: PtrInt; + s: String; + genvalue: Double; + cat: TsNumFormatCategory; +begin + LbCategory.ItemIndex := ord(ACategory); + with LbFormat.Items do + begin + Clear; + for i:=0 to NumFormats.Count-1 do + begin + data := PtrInt(NumFormats.Objects[i]); + if data >= USER_OFFSET then + cat := TsNumFormatCategory(data - USER_OFFSET) + else + cat := TsNumFormatCategory(data - BUILTIN_OFFSET); + if cat = ACategory then + begin + nfp := CreateNumFormatParams(NumFormats.Strings[i], FWorkbook.FormatSettings); + try + if IsTextFormat(nfp) then + s := 'abc' + else + begin + genValue := FGenerator[ACategory]; + if nfkTimeInterval in nfp.Sections[0].Kind then + genvalue := genValue + 1.0; + if ACategory = nfcFraction then + begin + digits := nfp.Sections[0].FracInt; + numdigits := nfp.Sections[0].FracDenominator; + genvalue := 1.0 / (IntPower(10, numdigits) - 3); + if digits <> 0 then genvalue := -(1234 + genValue); + end; + s := ConvertFloatToStr(genValue, nfp, FWorkbook.FormatSettings); + if s = '' then s := 'General'; + end; + LbFormat.Items.AddObject(s, TObject(PtrInt(i))); + finally + nfp.Free; + end; + end; + end; + end; + CurrSymbolPanel.Visible := (ACategory = nfcCurrency); + GbOptions.Visible := not (ACategory in [nfcDate, nfcTime]); +end; + +procedure TNumFormatForm.SelectFormat(AIndex: Integer); +var + nfp: TsNumFormatParams; +begin + if LbCategory.ItemIndex = -1 then + exit; + + LbFormat.ItemIndex := AIndex; + if AIndex >= 0 then begin + FNumFormatStrOfList := NumFormats.Strings[PtrInt(LbFormat.Items.Objects[AIndex])]; + nfp := CreateNumFormatParams(FNumFormatStrOfList, FWorkbook.FormatSettings); + try + UpdateControls(nfp); + finally + nfp.Free; + end; + end; +end; + +procedure TNumFormatForm.SetData(ANumFormatStr: String; AWorkbook: TsWorkbook; + ASample: variant); +var + cs: String; +begin + FWorkbook := AWorkbook; + cs := FWorkbook.FormatSettings.CurrencyString; + if (cs = '?') or (cs = '') then + cs := DefaultFormatSettings.CurrencyString; + CbCurrSymbol.ItemIndex := CbCurrSymbol.Items.IndexOf(cs); + + if varIsStr(ASample) then + FSampleText := VarToStr(ASample) + else + FSampleValue := ASample; + InitNumFormats(FWorkbook.FormatSettings); + SetNumFormatStr(ANumFormatStr); +end; + +procedure TNumFormatForm.SetNumFormatStr(const AValue: String); +var + nfs: String; + nfp: TsNumFormatParams; + cat: TsNumFormatCategory; + i: Integer; +begin + if AValue = '' then + i := NumFormats.IndexOf('General') + else + i := NumFormats.IndexOf(AValue); + if i = -1 then + exit; + + nfs := NumFormats.Strings[i]; + nfp := CreateNumFormatParams(nfs, FWorkbook.FormatSettings); + try + if nfkPercent in nfp.Sections[0].Kind then + cat := nfcPercent + else + if nfkExp in nfp.Sections[0].Kind then + cat := nfcScientific + else + if nfkCurrency in nfp.Sections[0].Kind then + cat := nfcCurrency + else + if nfkFraction in nfp.Sections[0].Kind then + cat := nfcFraction + else + if nfkDate in nfp.Sections[0].Kind then + cat := nfcDate + else + if (nfp.Sections[0].Kind * [nfkDate, nfkTime] = [nfkTime]) then + cat := nfcTime + else + cat := nfcNumber; + SelectCategory(cat); + SelectFormat(FindNumFormat(cat, AValue)); + UpdateControls(nfp); + ReplaceCurrSymbol; + finally + nfp.Free; + end; +end; + +procedure TNumFormatForm.UpdateControls(ANumFormatParams: TsNumFormatParams); +var + cs: String; + i: Integer; +begin + if ANumFormatParams = nil then + begin + EdNumFormatStr.Text := 'General'; + GbOptions.Hide; + end else + begin + EdNumFormatStr.Text := ANumFormatParams.NumFormatStr; + if (ANumFormatParams.Sections[0].Kind * [nfkDate, nfkTime] <> []) then + GbOptions.Hide + else begin + GbOptions.Show; + inc(FLockCount); + EdDecimals.Value := ANumFormatParams.Sections[0].Decimals; + CbNegRed.Checked := (Length(ANumFormatParams.Sections) > 1) and + (ANumFormatParams.Sections[1].Color = scRed); + CbThousandSep.Checked := nfkHasThSep in ANumFormatParams.Sections[0].Kind; + dec(FLockCount); + end; + if (nfkCurrency in ANumFormatParams.Sections[0].Kind) then + begin + cs := ANumFormatParams.Sections[0].CurrencySymbol; + if cs <> '' then + begin + i := CbCurrSymbol.Items.IndexOf(cs); + if i = -1 then begin + RegisterCurrency(cs); + i := CbCurrSymbol.Items.Add(cs); + end; + CbCurrSymbol.ItemIndex := i; + end; + end; + end; + UpdateSample(ANumFormatParams); +end; + +procedure TNumFormatForm.UpdateSample(ANumFormatParams: TsNumFormatParams); +begin + if (FSampleValue < 0) and + (Length(ANumFormatParams.Sections) > 1) and + (ANumFormatParams.Sections[1].Color = scRed) + then + Sample.Font.Color := clRed + else + Sample.Font.Color := clWindowText; + + if IsTextFormat(ANumFormatParams) then + Sample.Caption := ApplyTextFormat(FSampleText, ANumFormatParams) + else + Sample.Caption := ConvertFloatToStr(FSampleValue, ANumFormatParams, + FWorkbook.FormatSettings); + + BtnAddFormat.Enabled := (EdNumFormatStr.Text <> FNumFormatStrOfList); +end; + + +initialization + +finalization + DestroyNumFormats; + +end. + diff --git a/applications/spready/spready.ico b/applications/spready/spready.ico new file mode 100644 index 000000000..af0851c77 Binary files /dev/null and b/applications/spready/spready.ico differ diff --git a/applications/spready/spready.lpi b/applications/spready/spready.lpi new file mode 100644 index 000000000..4f0c99328 --- /dev/null +++ b/applications/spready/spready.lpi @@ -0,0 +1,191 @@ + + + + + + + + + + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <Icon Value="0"/> + </General> + <i18n> + <EnableI18N LFM="False"/> + </i18n> + <VersionInfo> + <UseVersionInfo Value="True"/> + <AutoIncrementBuild Value="True"/> + <MajorVersionNr Value="1"/> + <MinorVersionNr Value="7"/> + <BuildNr Value="2"/> + <StringTable InternalName="Spready" ProductName="Spready" ProductVersion="0.0.0.0"/> + </VersionInfo> + <BuildModes Count="2"> + <Item1 Name="Debug" Default="True"/> + <Item2 Name="Release"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + </Item2> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + </local> + </RunParams> + <RequiredPackages Count="4"> + <Item1> + <PackageName Value="TurboPowerIPro"/> + </Item1> + <Item2> + <PackageName Value="lazmrumenu"/> + </Item2> + <Item3> + <PackageName Value="laz_fpspreadsheet_visual"/> + </Item3> + <Item4> + <PackageName Value="LCL"/> + </Item4> + </RequiredPackages> + <Units Count="14"> + <Unit0> + <Filename Value="spready.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + <Unit1> + <Filename Value="smain.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="MainForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit1> + <Unit2> + <Filename Value="scsvparamsform.pas"/> + <IsPartOfProject Value="True"/> + <HasResources Value="True"/> + </Unit2> + <Unit3> + <Filename Value="sctrls.pas"/> + <IsPartOfProject Value="True"/> + </Unit3> + <Unit4> + <Filename Value="scurrencyform.pas"/> + <IsPartOfProject Value="True"/> + <HasResources Value="True"/> + </Unit4> + <Unit5> + <Filename Value="sformatsettingsform.pas"/> + <IsPartOfProject Value="True"/> + <HasResources Value="True"/> + </Unit5> + <Unit6> + <Filename Value="shyperlinkform.pas"/> + <IsPartOfProject Value="True"/> + <HasResources Value="True"/> + </Unit6> + <Unit7> + <Filename Value="snumformatform.pas"/> + <IsPartOfProject Value="True"/> + <HasResources Value="True"/> + </Unit7> + <Unit8> + <Filename Value="ssearchform.pas"/> + <IsPartOfProject Value="True"/> + <HasResources Value="True"/> + </Unit8> + <Unit9> + <Filename Value="ssortparamsform.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="SortParamsForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="sSortParamsForm"/> + </Unit9> + <Unit10> + <Filename Value="sutils.pas"/> + <IsPartOfProject Value="True"/> + </Unit10> + <Unit11> + <Filename Value="sabout.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="AboutForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="sAbout"/> + </Unit11> + <Unit12> + <Filename Value="scolwidthform.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="ColWidthForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="sColWidthForm"/> + </Unit12> + <Unit13> + <Filename Value="srowheightform.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="RowHeightForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="sRowHeightForm"/> + </Unit13> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="bin\$(TargetCPU)-$(TargetOS)\spready"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + </CodeGeneration> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/applications/spready/spready.lpr b/applications/spready/spready.lpr new file mode 100644 index 000000000..5770ecb98 --- /dev/null +++ b/applications/spready/spready.lpr @@ -0,0 +1,21 @@ +program spready; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX}{$IFDEF UseCThreads} + cthreads, + {$ENDIF}{$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, smain, sColWidthForm; + +{$R *.res} + +begin + RequireDerivedFormResource := True; + Application.Initialize; + Application.CreateForm(TMainForm, MainForm); + MainForm.BeforeRun; + Application.Run; +end. + diff --git a/applications/spready/spready.res b/applications/spready/spready.res new file mode 100644 index 000000000..0a79a679e Binary files /dev/null and b/applications/spready/spready.res differ diff --git a/applications/spready/srowheightform.lfm b/applications/spready/srowheightform.lfm new file mode 100644 index 000000000..2ef11c39a --- /dev/null +++ b/applications/spready/srowheightform.lfm @@ -0,0 +1,123 @@ +object RowHeightForm: TRowHeightForm + Left = 479 + Height = 203 + Top = 289 + Width = 325 + HorzScrollBar.Page = 304 + HorzScrollBar.Range = 304 + VertScrollBar.Page = 168 + VertScrollBar.Range = 168 + BorderStyle = bsDialog + Caption = 'RowHeightForm' + ClientHeight = 203 + ClientWidth = 325 + OnCreate = FormCreate + Position = poMainFormCenter + LCLVersion = '1.7' + object ButtonPanel1: TButtonPanel + Left = 6 + Height = 34 + Top = 163 + Width = 313 + OKButton.Name = 'OKButton' + OKButton.DefaultCaption = True + HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True + CloseButton.Name = 'CloseButton' + CloseButton.Caption = 'Close' + CloseButton.DefaultCaption = False + CancelButton.Name = 'CancelButton' + CancelButton.DefaultCaption = True + TabOrder = 0 + ShowButtons = [pbOK, pbCancel] + end + object EdRowHeight: TFloatSpinEdit + AnchorSideLeft.Control = LblRowHeight + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = RbCustom + AnchorSideTop.Side = asrBottom + Left = 108 + Height = 23 + Top = 121 + Width = 74 + Alignment = taRightJustify + BorderSpacing.Left = 24 + BorderSpacing.Top = 24 + BorderSpacing.Bottom = 24 + Increment = 1 + MaxValue = 100 + MinValue = 0 + TabOrder = 1 + Value = 15 + end + object LblRowHeight: TLabel + AnchorSideTop.Control = EdRowHeight + AnchorSideTop.Side = asrCenter + Left = 24 + Height = 15 + Top = 125 + Width = 60 + BorderSpacing.Left = 24 + BorderSpacing.Bottom = 24 + Caption = 'Row height' + ParentColor = False + end + object CbUnits: TComboBox + AnchorSideLeft.Control = EdRowHeight + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = EdRowHeight + AnchorSideTop.Side = asrCenter + Left = 190 + Height = 23 + Top = 121 + Width = 114 + BorderSpacing.Left = 8 + ItemHeight = 15 + OnChange = CbUnitsChange + Style = csDropDownList + TabOrder = 2 + end + object RbDefault: TRadioButton + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = Owner + Left = 24 + Height = 19 + Top = 24 + Width = 102 + BorderSpacing.Left = 24 + BorderSpacing.Top = 24 + Caption = 'Reset to default' + OnChange = RowHeightTypeChanged + TabOrder = 3 + end + object RbAuto: TRadioButton + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = RbDefault + AnchorSideTop.Side = asrBottom + Left = 24 + Height = 19 + Top = 51 + Width = 76 + BorderSpacing.Left = 24 + BorderSpacing.Top = 8 + Caption = 'Automatic' + OnChange = RowHeightTypeChanged + TabOrder = 4 + end + object RbCustom: TRadioButton + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = RbAuto + AnchorSideTop.Side = asrBottom + Left = 24 + Height = 19 + Top = 78 + Width = 62 + BorderSpacing.Left = 24 + BorderSpacing.Top = 8 + Caption = 'Custom' + Checked = True + OnChange = RowHeightTypeChanged + TabOrder = 5 + TabStop = True + end +end diff --git a/applications/spready/srowheightform.pas b/applications/spready/srowheightform.pas new file mode 100644 index 000000000..b4eb56dea --- /dev/null +++ b/applications/spready/srowheightform.pas @@ -0,0 +1,143 @@ +unit sRowHeightForm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ButtonPanel, + StdCtrls, Spin, ExtCtrls, fpsTypes, fpspreadsheet; + +type + + { TRowHeightForm } + + TRowHeightForm = class(TForm) + ButtonPanel1: TButtonPanel; + CbUnits: TComboBox; + EdRowHeight: TFloatSpinEdit; + LblRowHeight: TLabel; + RbDefault: TRadioButton; + RbAuto: TRadioButton; + RbCustom: TRadioButton; + procedure CbUnitsChange(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure RowHeightTypeChanged(Sender: TObject); + private + FWorkbook: TsWorkbook; + FOldUnits: TsSizeUnits; + function GetRowHeight: Single; + function GetRowHeightType: TsRowHeightType; + function GetUnits: TsSizeUnits; + procedure SetRowHeight(AValue: Single); + procedure SetRowHeightType(AValue: TsRowHeightType); + procedure SetUnits(AValue: TsSizeUnits); + procedure SetWorkbook(AValue: TsWorkbook); + protected + + public + procedure SetData(AWorkbook: TsWorkbook; ARowHeight: single; + ARowHeightType: TsRowHeightType); + property RowHeight: Single read GetRowHeight; + property RowHeightType: TsRowHeightType read GetRowHeightType; + property Units: TsSizeUnits read GetUnits; + end; + +var + RowHeightForm: TRowHeightForm; + +implementation + +{$R *.lfm} + +{ TRowHeightForm } + +procedure TRowHeightForm.CbUnitsChange(Sender: TObject); +begin + if FWorkbook <> nil then + EdRowHeight.Value := FWorkbook.ConvertUnits(EdRowHeight.Value, FOldUnits, GetUnits); + FOldUnits := GetUnits; +end; + +procedure TRowHeightForm.FormCreate(Sender: TObject); +begin + CbUnits.Items.Clear; + CbUnits.Items.AddObject('Lines', TObject(PtrInt(ord(suLines)))); + CbUnits.Items.AddObject('mm', TObject(PtrInt(ord(suMillimeters)))); + CbUnits.Items.AddObject('cm', TObject(PtrInt(ord(suCentimeters)))); + CbUnits.Items.AddObject('Points', TObject(PtrInt(ord(suPoints)))); + CbUnits.Items.AddObject('Inches', TObject(PtrInt(ord(suInches)))); +end; + +function TRowHeightForm.GetRowHeight: Single; +begin + Result := EdRowHeight.Value; +end; + +function TRowHeightForm.GetRowHeightType: TsRowHeightType; +begin + if RbDefault.Checked then + Result := rhtDefault + else if RbAuto.Checked then + Result := rhtAuto + else + Result := rhtCustom; +end; + +function TRowHeightForm.GetUnits: TsSizeUnits; +begin + if CbUnits.ItemIndex = -1 then + Result := FWorkbook.Units else + Result := TsSizeUnits(IntPtr(CbUnits.Items.Objects[CbUnits.ItemIndex])); +end; + +procedure TRowHeightForm.RowHeightTypeChanged(Sender: TObject); +begin + LblRowHeight.Enabled := RbCustom.Checked; + EdRowHeight.Enabled := RbCustom.Checked; + CbUnits.Enabled := RbCustom.Checked; +end; + +procedure TRowHeightForm.SetData(AWorkbook: TsWorkbook; ARowHeight: Single; + ARowHeightType: TsRowHeightType); +begin + SetWorkbook(AWorkbook); + SetRowHeight(ARowHeight); + SetUnits(AWorkbook.Units); + SetRowHeightType(ARowHeightType); +end; + +procedure TRowHeightForm.SetRowHeight(AValue: Single); +begin + EdRowHeight.Value := AValue; +end; + +procedure TRowHeightForm.SetRowHeightType(AValue: TsRowHeightType); +begin + RbDefault.Checked := AValue = rhtDefault; + RbAuto.Checked := AValue= rhtAuto; + RbCustom.Checked := AValue = rhtCustom; + RowHeightTypeChanged(nil); +end; + +procedure TRowHeightForm.SetUnits(AValue: TsSizeUnits); +var + i: Integer; +begin + FOldUnits := GetUnits; + for i:=0 to CbUnits.Items.Count-1 do + if TsSizeUnits(IntPtr(CbUnits.Items.Objects[i])) = AValue then + begin + CbUnits.ItemIndex := i; + exit; + end; +end; + +procedure TRowHeightForm.SetWorkbook(AValue: TsWorkbook); +begin + FWorkbook := AValue; + FOldUnits := FWorkbook.Units; +end; + +end. + diff --git a/applications/spready/ssearchform.lfm b/applications/spready/ssearchform.lfm new file mode 100644 index 000000000..63bc78d82 --- /dev/null +++ b/applications/spready/ssearchform.lfm @@ -0,0 +1,309 @@ +object SearchForm: TSearchForm + Left = 238 + Height = 341 + Top = 157 + Width = 487 + BorderStyle = bsDialog + Caption = 'Search' + ClientHeight = 341 + ClientWidth = 487 + FormStyle = fsStayOnTop + OnClose = FormClose + OnCreate = FormCreate + OnShow = FormShow + LCLVersion = '1.5' + object ButtonPanel: TPanel + Left = 0 + Height = 38 + Top = 303 + Width = 487 + Align = alBottom + BevelOuter = bvNone + ClientHeight = 38 + ClientWidth = 487 + TabOrder = 0 + object Bevel1: TBevel + Left = 6 + Height = 3 + Top = 0 + Width = 475 + Align = alTop + BorderSpacing.Left = 6 + BorderSpacing.Right = 6 + Shape = bsTopLine + end + object BtnSearchBack: TBitBtn + Left = 244 + Height = 25 + Top = 7 + Width = 75 + Anchors = [akTop, akRight] + Caption = 'Previous' + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000000000000000 + 000000000000000000000000000000000000994E035C994E0399000000000000 + 0000000000000000000000000000000000000000000000000000000000002E2E + 2E2A141414840505055C000000009E53075C9D5206CC9D5206CC000000000000 + 0000000000000000000000000000000000000000000000000000000000003737 + 3774EADADAFF433F3F9E713E0987A3580BCCFFBA16FFA3580BCC000000000000 + 0000000000000000000000000000000000000000000000000000000000003E3E + 3E4B64606090CAA88BFF9A5813EAF7BA30FFF6B11DFFAA5F10CC000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000915B2180A6631CE7ECB952FFE09E29FFE5A83AFFB16616CC000000000000 + 000000000000000000000000000000000000000000000000000000000000BA6F + 1D5CB96E1CCCE9BD6EFFCF9240FFCF9240FFD9A352FFB26A1BD4040404560404 + 047904040487040404790404045604040416000000000000000000000000C277 + 22CCFAD589FFE9AD61FFDFA357FFD5994DFFDCA95DFFB06D22E79D9791A5EEE8 + E3C4F9F3EDD6EFEAE5C5A3A09EA92928287D1111112A0000000000000000C97E + 275CCA7F28CCFBD88CFFEEB266FFEEB266FFF4C276FFCD8B40F2F3E6D9CBF6ED + E4CEF6EDE4CEF6EDE4CEF7EFE6D1DFD9D3B83D3C3B7426262614000000000000 + 0000D1862D5CD2872ECCFDDD91FFF2B96DFFF7CA7EFFD59345F3F5E9DFCBF6ED + E4CEF6EDE4CEF6EDE4CEF6EDE4CEF6ECE2CEADA69E9D31313149000000000000 + 000000000000D88D335CD98E33CCFEE195FFFBD488FFDB9848F2F6EDE4CEF6ED + E4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEE7D8CAB838383865000000000000 + 00000000000000000000DF94385CD08C38E2FFE498FFE19E4CF2E8D2BBC0F6ED + E4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEEDDBC8C53E3E3E6F000000000000 + 0000000000000000000000000000A4773E99E4A14DEEE5A24FF2E8D2BBC0E8D2 + BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E4D3C1B243434360000000000000 + 000000000000000000000000000049494943CB9E68B7E8AF69E6F1E3D5C8F6ED + E4CEF6EDE4CEF6EDE4CEF6EDE4CEF2E4D6C8B0A4979149494943000000000000 + 00000000000000000000000000004D4D4D115F5D5A64D5C1AEA1EBD8C4C2F6EC + E2CDF6EDE4CEF6EDE4CEF6ECE2CDD9C8B8A4605D5B644D4D4D11000000000000 + 0000000000000000000000000000000000005151512163605E62B1A3948BE6D5 + C5AFF4EADFC7EDE3D9B5B6ACA28E63605E625151512100000000000000000000 + 0000000000000000000000000000000000000000000054545411555555405555 + 555A555555655555555A55555540545454110000000000000000 + } + OnClick = ExecuteClick + TabOrder = 0 + Visible = False + end + object BtnClose: TBitBtn + Left = 404 + Height = 25 + Top = 7 + Width = 75 + Anchors = [akTop, akRight] + Cancel = True + DefaultCaption = True + Kind = bkClose + ModalResult = 11 + TabOrder = 1 + end + object BtnSearch: TBitBtn + Left = 324 + Height = 25 + Top = 7 + Width = 75 + Anchors = [akTop, akRight] + Caption = 'Search' + Default = True + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000994E0399994E + 035C000000000000000000000000000000000000000000000000000000002E2E + 2E2A141414840505055C000000000000000000000000000000009D5206CC9D52 + 06CC9E53075C0000000000000000000000000000000000000000000000003737 + 3774EADADAFF433F3F9E05050544000000000000000000000000A3580BCCFFBF + 25FFA3580BCCA4590C5C00000000000000000000000000000000000000003E3E + 3E4B64606090DDD1D1FF302E2E96040404330000000000000000AA5F10CCFBB8 + 21FFFBBF34FFAA5F10CCAB60115C000000000000000000000000000000000000 + 00003D3D3D3853515186CCC4C4FF2221218C0404042500000000B16616CCEFB3 + 39FFEAA41DFFF2BD4AFFB16616CCB267175C0000000000000000000000000000 + 0000000000003C3C3C2A4746467CBCB8B8FF161515830404042AAB651ADDE4AE + 50FFD99934FFD99934FFEABB60FFB56B1BD0BA6F1D5C00000000000000000000 + 000000000000000000003B3B3B1F3C3C3C73AFADADFF2B292887BC7B31EDE5B4 + 66FFCE9244FFCD9143FFCD9143FFE7BC6FFFBB7321D400000000000000000000 + 0000000000000000000000000000373737244746447BDED1C4BED09045F5F5C6 + 7AFFE9AD61FFDFA357FFF1CC80FFCD8C42F18A602FA626262614000000000000 + 000000000000000000000000000031313149A89D9397EAD5BFC3D7974BF5F7CB + 7FFFF1B66AFFFDDC90FFD8984CF5E6C297E0ADA69E9D31313149000000000000 + 000000000000000000000000000038383865E1CFBCB1E8D2BBC0DD9D50F5FBD4 + 88FFFFE397FFDD9D50F5E9C59BE0F6EDE4CEE7D8CAB838383865000000000000 + 00000000000000000000000000003E3E3E6FE9D4BEBEE8D2BBC0E19E4CF2FFE5 + 99FFE3A354F5ECC89DE0F6EDE4CEF6EDE4CEEDDBC8C53E3E3E6F000000000000 + 000000000000000000000000000043434360E0CBB6ACE8D2BBC0E5A24FF2E5A2 + 4FF2E6BA84D7E8D2BBC0E8D2BBC0E8D2BBC0E4D3C1B243434360000000000000 + 000000000000000000000000000049494943AD9F918EE8D2BBC0EBB573E9F0CC + A0E0F6EDE4CEF6EDE4CEF6EDE4CEF2E4D6C8B0A4979149494943000000000000 + 00000000000000000000000000004D4D4D115F5D5A64D5C1AEA1EBD8C4C2F6EC + E2CDF6EDE4CEF6EDE4CEF6ECE2CDD9C8B8A4605D5B644D4D4D11000000000000 + 0000000000000000000000000000000000005151512163605E62B1A3948BE6D5 + C5AFF4EADFC7EDE3D9B5B6ACA28E63605E625151512100000000000000000000 + 0000000000000000000000000000000000000000000054545411555555405555 + 555A555555655555555A55555540545454110000000000000000 + } + OnClick = ExecuteClick + TabOrder = 2 + end + end + object TabControl: TTabControl + Left = 8 + Height = 287 + Top = 8 + Width = 471 + OnChange = TabControlChange + OnChanging = TabControlChanging + TabIndex = 0 + Tabs.Strings = ( + 'Search' + 'Replace' + ) + Align = alClient + BorderSpacing.Around = 8 + TabOrder = 1 + object SearchTextPanel: TPanel + Left = 2 + Height = 33 + Top = 23 + Width = 467 + Align = alTop + BevelOuter = bvNone + ClientHeight = 33 + ClientWidth = 467 + ParentColor = False + TabOrder = 1 + object LblSearchText: TLabel + Left = 14 + Height = 15 + Top = 12 + Width = 53 + Caption = 'Search for' + ParentColor = False + end + object CbSearchText: TComboBox + Left = 104 + Height = 23 + Top = 8 + Width = 351 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + TabOrder = 0 + end + end + object ReplaceTextPanel: TPanel + Left = 2 + Height = 33 + Top = 56 + Width = 467 + Align = alTop + BevelOuter = bvNone + ClientHeight = 33 + ClientWidth = 467 + ParentColor = False + TabOrder = 2 + Visible = False + object LblSearchText1: TLabel + Left = 14 + Height = 15 + Top = 12 + Width = 67 + Caption = 'Replace with' + ParentColor = False + end + object CbReplaceText: TComboBox + Left = 104 + Height = 23 + Top = 8 + Width = 351 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 15 + TabOrder = 0 + end + end + object SearchParamsPanel: TPanel + Left = 2 + Height = 196 + Top = 89 + Width = 467 + Align = alClient + BevelOuter = bvNone + ClientHeight = 196 + ClientWidth = 467 + ParentColor = False + TabOrder = 3 + object CgOptions: TCheckGroup + Left = 16 + Height = 163 + Top = 16 + Width = 192 + AutoFill = True + Caption = 'Options' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.TopBottomSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 1 + ClientHeight = 143 + ClientWidth = 188 + Items.Strings = ( + 'Compare entire cell ' + 'Match case' + 'Regular expression' + 'Search along rows' + 'Continue at start/end' + ) + TabOrder = 0 + Data = { + 050000000202020202 + } + end + object RgSearchWithin: TRadioGroup + Left = 232 + Height = 67 + Top = 16 + Width = 223 + AutoFill = True + Caption = 'Search within' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclTopToBottomThenLeftToRight + ChildSizing.ControlsPerLine = 2 + ClientHeight = 47 + ClientWidth = 219 + ColumnLayout = clVerticalThenHorizontal + Columns = 2 + ItemIndex = 0 + Items.Strings = ( + 'workbook' + 'worksheet' + 'column' + 'row' + ) + TabOrder = 1 + end + object RgSearchStart: TRadioGroup + Left = 232 + Height = 56 + Top = 123 + Width = 223 + AutoFill = True + Caption = 'Start search at' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 2 + ClientHeight = 36 + ClientWidth = 219 + Columns = 2 + ItemIndex = 0 + Items.Strings = ( + 'active cell' + 'beginning/end' + ) + TabOrder = 2 + end + end + end +end diff --git a/applications/spready/ssearchform.pas b/applications/spready/ssearchform.pas new file mode 100644 index 000000000..11aa2cdad --- /dev/null +++ b/applications/spready/ssearchform.pas @@ -0,0 +1,372 @@ +unit sSearchForm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, + StdCtrls, ExtCtrls, Buttons, ComCtrls, fpsTypes, fpspreadsheet, fpsSearch; + +type + TsSearchEvent = procedure (Sender: TObject; AFound: Boolean; + AWorksheet: TsWorksheet; ARow, ACol: Cardinal) of object; + + { TSearchForm } + + TSearchForm = class(TForm) + Bevel1: TBevel; + BtnSearchBack: TBitBtn; + BtnClose: TBitBtn; + BtnSearch: TBitBtn; + CbSearchText: TComboBox; + CbReplaceText: TComboBox; + CgOptions: TCheckGroup; + LblSearchText: TLabel; + ButtonPanel: TPanel; + LblSearchText1: TLabel; + SearchParamsPanel: TPanel; + SearchTextPanel: TPanel; + RgSearchStart: TRadioGroup; + RgSearchWithin: TRadioGroup; + ReplaceTextPanel: TPanel; + TabControl: TTabControl; + procedure ExecuteClick(Sender: TObject); + procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure TabControlChange(Sender: TObject); + procedure TabControlChanging(Sender: TObject; var AllowChange: Boolean); + private + { private declarations } + FSearchEngine: TsSearchEngine; + FWorkbook: TsWorkbook; + FFoundWorksheet: TsWorksheet; + FFoundRow, FFoundCol: Cardinal; + FSearchParams: TsSearchParams; + FReplaceParams: TsReplaceParams; + FOnFound: TsSearchEvent; + function GetReplaceParams: TsReplaceParams; + function GetSearchParams: TsSearchParams; + procedure SetReplaceParams(const AValue: TsReplaceParams); + procedure SetSearchParams(const AValue: TsSearchParams); + protected + procedure ConfirmReplacementHandler(Sender: TObject; AWorksheet: TsWorksheet; + ARow, ACol: Cardinal; const ASearchText, AReplaceText: String; + var AConfirmReplacement: TsConfirmReplacementResult); + procedure PopulateOptions; + public + { public declarations } + procedure Execute(AWorkbook: TsWorkbook); + property Workbook: TsWorkbook read FWorkbook; + property SearchParams: TsSearchParams read GetSearchParams write SetSearchParams; + property ReplaceParams: TsReplaceParams read GetReplaceParams write SetReplaceParams; + property OnFound: TsSearchEvent read FOnFound write FOnFound; + end; + +var + SearchForm: TSearchForm; + + DefaultSearchParams: TsSearchParams = ( + SearchText: ''; + Options: []; + Within: swWorksheet + ); + DefaultReplaceParams: TsReplaceParams = ( + ReplaceText: ''; + Options: [roConfirm] + ); + + +implementation + +{$R *.lfm} + +uses + fpsUtils; + +const + MAX_SEARCH_ITEMS = 10; + + // Search & replace + COMPARE_ENTIRE_CELL = 0; + MATCH_CASE = 1; + REGULAR_EXPRESSION = 2; + SEARCH_ALONG_ROWS = 3; + CONTINUE_AT_START_END = 4; + // Replace only + REPLACE_ENTIRE_CELL = 5; + REPLACE_ALL = 6; + CONFIRM_REPLACEMENT = 7; + + BASE_HEIGHT = 340; // Design height of SearchForm + + SEARCH_TAB = 0; + REPLACE_TAB = 1; + +var + CONFIRM_REPLACEMENT_DLG_X: Integer = -1; + CONFIRM_REPLACEMENT_DLG_Y: Integer = -1; + +{ TSearchForms } + +procedure TSearchForm.ConfirmReplacementHandler(Sender: TObject; + AWorksheet: TsWorksheet; ARow, ACol: Cardinal; const ASearchText, AReplaceText: String; + var AConfirmReplacement: TsConfirmReplacementResult); +var + F: TForm; +begin + Unused(AWorksheet, ARow, ACol); + Unused(ASearchText, AReplaceText); + F := CreateMessageDialog('Replace?', mtConfirmation, [mbYes, mbNo, mbCancel]); + try + if (CONFIRM_REPLACEMENT_DLG_X = -1) then + F.Position := poMainformCenter + else begin + F.Position := poDesigned; + F.Left := CONFIRM_REPLACEMENT_DLG_X; + F.Top := CONFIRM_REPLACEMENT_DLG_Y; + end; + case F.ShowModal of + mrYes: AConfirmReplacement := crReplace; + mrNo : AConfirmReplacement := crIgnore; + mrCancel: AConfirmReplacement := crAbort; + end; + CONFIRM_REPLACEMENT_DLG_X := F.Left; + CONFIRM_REPLACEMENT_DLG_Y := F.Top; + finally + F.Free; + end; + { + case MessageDlg('Replace?', mtConfirmation, [mbYes, mbNo, mbCancel], 0) of + mrYes: AConfirmReplacement := crReplace; + mrNo : AConfirmReplacement := crIgnore; + mrCancel: AConfirmReplacement := crAbort; + end; + } +end; + +procedure TSearchForm.Execute(AWorkbook: TsWorkbook); +begin + FWorkbook := AWorkbook; + Show; +end; + +procedure TSearchForm.ExecuteClick(Sender: TObject); +var + sp: TsSearchParams; + rp: TsReplaceParams; + found: Boolean; + crs: TCursor; +begin + sp := GetSearchParams; + if sp.SearchText = '' then + exit; + + if TabControl.TabIndex = REPLACE_TAB then + rp := GetReplaceParams; + + if CbSearchText.Items.IndexOf(sp.SearchText) = -1 then + begin + CbSearchText.Items.Insert(0, sp.SearchText); + while CbSearchText.Items.Count > MAX_SEARCH_ITEMS do + CbSearchText.Items.Delete(CbSearchText.Items.Count-1); + end; + + if (TabControl.TabIndex = REPLACE_TAB) and + (CbReplaceText.Items.IndexOf(rp.ReplaceText) = -1) then + begin + CbReplaceText.items.Insert(0, rp.ReplaceText); + while CbReplaceText.Items.Count > MAX_SEARCH_ITEMS do + CbReplaceText.Items.Delete(CbReplaceText.Items.Count-1); + end; + + crs := Screen.Cursor; + try + Screen.Cursor := crHourglass; + if FSearchEngine = nil then + begin + FSearchEngine := TsSearchEngine.Create(FWorkbook); + FSearchEngine.OnConfirmReplacement := @ConfirmReplacementHandler; + if (soBackward in sp.Options) then + Include(sp.Options, soBackward) else + Exclude(sp.Options, soBackward); + case Tabcontrol.TabIndex of + 0: found := FSearchEngine.FindFirst(sp, FFoundWorksheet, FFoundRow, FFoundCol); + 1: found := FSearchEngine.ReplaceFirst(sp, rp, FFoundWorksheet, FFoundRow, FFoundCol); + end; + end else + begin + // Adjust "backward" option according to the button clicked + if (Sender = BtnSearchBack) then + Include(sp.Options, soBackward) else + Exclude(sp.Options, soBackward); + // Begin searching at current position + Exclude(sp.Options, soEntireDocument); + // User may select a different worksheet/different cell to continue search! + FFoundWorksheet := FWorkbook.ActiveWorksheet; + FFoundRow := FFoundWorksheet.ActiveCellRow; + FFoundCol := FFoundWorksheet.ActiveCellCol; + case TabControl.TabIndex of + 0: found := FSearchEngine.FindFirst(sp, FFoundWorksheet, FFoundRow, FFoundCol); + 1: found := FSearchEngine.ReplaceFirst(sp, rp, FFoundWorksheet, FFoundRow, FFoundCol); + end; + end; + + finally + Screen.Cursor := crs; + end; + + if Assigned(FOnFound) then + FOnFound(self, found, FFoundWorksheet, FFoundRow, FFoundCol); + + BtnSearchBack.Visible := true; + BtnSearch.Caption := 'Next'; +end; + +procedure TSearchForm.FormClose(Sender: TObject; var CloseAction: TCloseAction); +var + P: TPoint; +begin + Unused(CloseAction); + FreeAndNil(FSearchEngine); + P.X := Left; + P.Y := Top; + Position := poDesigned; + Left := P.X; + Top := P.Y; +end; + +procedure TSearchForm.FormCreate(Sender: TObject); +begin + {$IFDEF MSWINDOWS} + SearchTextPanel.Color := clNone; + ReplaceTextPanel.Color := clNone; + SearchParamsPanel.Color := clNone; + {$ENDIF} + Position := poMainFormCenter; + PopulateOptions; +end; + +procedure TSearchForm.FormShow(Sender: TObject); +begin + BtnSearch.Caption := 'Search'; + BtnSearchBack.Visible := false; + + FFoundCol := UNASSIGNED_ROW_COL_INDEX; + FFoundRow := UNASSIGNED_ROW_COL_INDEX; + FFoundWorksheet := nil; +end; + +function TSearchForm.GetReplaceParams: TsReplaceParams; +begin + if TabControl.TabIndex = 0 then + Result := FReplaceParams + else + begin + Result.ReplaceText := CbReplaceText.Text; + Result.Options := []; + if CgOptions.Checked[REPLACE_ENTIRE_CELL] then + Include(Result.Options, roReplaceEntireCell); + if CgOptions.Checked[REPLACE_ALL] then + Include(Result.Options, roReplaceAll); + if CgOptions.Checked[CONFIRM_REPLACEMENT] then + Include(Result.Options, roConfirm); + FReplaceParams := Result; + end; +end; + +function TSearchForm.GetSearchParams: TsSearchParams; +begin + Result.SearchText := CbSearchText.Text; + Result.Options := []; + if CgOptions.Checked[COMPARE_ENTIRE_CELL] then + Include(Result.Options, soCompareEntireCell); + if CgOptions.Checked[MATCH_CASE] then + Include(Result.Options, soMatchCase); + if CgOptions.Checked[REGULAR_EXPRESSION] then + Include(Result.Options, soRegularExpr); + if CgOptions.Checked[SEARCH_ALONG_ROWS] then + Include(Result.Options, soAlongRows); + if CgOptions.Checked[CONTINUE_AT_START_END] then + Include(Result.Options, soWrapDocument); + if RgSearchStart.ItemIndex = 1 then + Include(Result.Options, soEntireDocument); + Result.Within := TsSearchWithin(RgSearchWithin.ItemIndex); +end; + +procedure TSearchForm.PopulateOptions; +begin + with CgOptions.Items do + begin + Clear; + Add('Compare entire cell'); + Add('Match case'); + Add('Regular expression'); + Add('Search along rows'); + Add('Continue at start/end'); + if TabControl.TabIndex = REPLACE_TAB then + begin + Add('Replace entire cell'); + Add('Replace all'); + Add('Confirm replacement'); + end; + end; +end; + +procedure TSearchForm.SetSearchParams(const AValue: TsSearchParams); +begin + CbSearchText.Text := Avalue.SearchText; + CgOptions.Checked[COMPARE_ENTIRE_CELL] := (soCompareEntireCell in AValue.Options); + CgOptions.Checked[MATCH_CASE] := (soMatchCase in AValue.Options); + CgOptions.Checked[REGULAR_EXPRESSION] := (soRegularExpr in Avalue.Options); + CgOptions.Checked[SEARCH_ALONG_ROWS] := (soAlongRows in AValue.Options); + CgOptions.Checked[CONTINUE_AT_START_END] := (soWrapDocument in Avalue.Options); + RgSearchWithin.ItemIndex := ord(AValue.Within); + RgSearchStart.ItemIndex := ord(soEntireDocument in AValue.Options); +end; + +procedure TSearchForm.SetReplaceParams(const AValue: TsReplaceParams); +begin + FReplaceParams := AValue; + if TabControl.TabIndex = REPLACE_TAB then + begin + CbReplaceText.Text := AValue.ReplaceText; + CgOptions.Checked[REPLACE_ENTIRE_CELL] := (roReplaceEntireCell in AValue.Options); + CgOptions.Checked[REPLACE_ALL] := (roReplaceAll in AValue.Options); + CgOptions.Checked[CONFIRM_REPLACEMENT] := (roConfirm in AValue.Options); + end; +end; + +procedure TSearchForm.TabControlChange(Sender: TObject); +var + h, d: Integer; +begin + ReplaceTextPanel.Visible := (TabControl.TabIndex = REPLACE_TAB); + PopulateOptions; + SetSearchParams(FSearchParams); + SetReplaceParams(FReplaceParams); + h := RgSearchStart.Top + RgSearchStart.Height - CgOptions.Top; + if TabControl.TabIndex = 0 then + begin + CgOptions.Height := h; + Height := BASE_HEIGHT - ReplaceTextPanel.Height; + end else + begin + d := 3 * 16; + CgOptions.Height := h + d; + Height := BASE_HEIGHT + d; + end; +end; + +procedure TSearchForm.TabControlChanging(Sender: TObject; + var AllowChange: Boolean); +begin + AllowChange := true; + FSearchParams := GetSearchParams; + FReplaceParams := GetReplaceParams; +end; + + +end. + diff --git a/applications/spready/ssortparamsform.lfm b/applications/spready/ssortparamsform.lfm new file mode 100644 index 000000000..04de28be6 --- /dev/null +++ b/applications/spready/ssortparamsform.lfm @@ -0,0 +1,218 @@ +object SortParamsForm: TSortParamsForm + Left = 434 + Height = 314 + Top = 274 + Width = 496 + Caption = 'Sorting criteria' + ClientHeight = 314 + ClientWidth = 496 + OnCreate = FormCreate + LCLVersion = '1.7' + object ButtonPanel: TButtonPanel + Left = 6 + Height = 34 + Top = 274 + Width = 484 + OKButton.Name = 'OKButton' + OKButton.DefaultCaption = True + OKButton.OnClick = OKButtonClick + HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True + CloseButton.Name = 'CloseButton' + CloseButton.DefaultCaption = True + CancelButton.Name = 'CancelButton' + CancelButton.DefaultCaption = True + TabOrder = 0 + ShowButtons = [pbOK, pbCancel] + end + object Grid: TStringGrid + Left = 0 + Height = 226 + Top = 42 + Width = 496 + Align = alClient + ColCount = 4 + Columns = < + item + ButtonStyle = cbsPickList + Title.Caption = 'Column' + Width = 120 + end + item + ButtonStyle = cbsCheckboxColumn + PickList.Strings = ( + 'ascending' + 'descending' + ) + Title.Alignment = taCenter + Title.Caption = 'Descending' + Width = 120 + end + item + ButtonStyle = cbsCheckboxColumn + Title.Alignment = taCenter + Title.Caption = 'Ignore case' + Width = 120 + end> + DefaultColWidth = 120 + Options = [goFixedVertLine, goFixedHorzLine, goHorzLine, goRangeSelect, goEditing, goAlwaysShowEditor, goSmoothScroll] + RowCount = 2 + TabOrder = 1 + TitleStyle = tsNative + OnSelectEditor = GridSelectEditor + Cells = ( + 1 + 0 + 1 + 'Sort by' + ) + end + object TopPanel: TPanel + Left = 0 + Height = 42 + Top = 0 + Width = 496 + Align = alTop + BevelOuter = bvNone + ClientHeight = 42 + ClientWidth = 496 + TabOrder = 2 + object BtnAdd: TBitBtn + AnchorSideTop.Control = TopPanel + AnchorSideTop.Side = asrCenter + Left = 7 + Height = 30 + Top = 6 + Width = 83 + Caption = 'Add' + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0041924E233D8F497D3A8C44DB368940F332873CF32F84 + 37DB2C81337D287F3023FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0049995853459653E6419950FF7DC28FFF96D0A6FF96CFA6FF78BE + 89FF368D42FF2C8134E6297F3053FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00519F61534D9C5DF464B478FFA8DBB5FF87CC98FF66BC7DFF64BA7CFF86CB + 98FFA5D9B4FF58AA6BFF2C8134F4297F3053FFFFFF00FFFFFF00FFFFFF0059A6 + 6B2256A366E56AB97DFFA8DBB2FF60BC77FF5CBA73FF59B870FF59B56FFF58B5 + 6FFF5BB774FFA5D9B3FF5AAA6CFF2C8234E5297F3022FFFFFF00FFFFFF005DA9 + 707E53AB68FFAADDB4FF64C179FF5FBE71FF60BC77FFFFFFFFFFFFFFFFFF59B8 + 70FF58B56EFF5CB774FFA6DAB4FF388F43FF2C82347EFFFFFF00FFFFFF0061AC + 75DB8ACC98FF89D396FF6BC67AFF63C170FF55AB65FFFFFFFFFFFFFFFFFF59B8 + 70FF59B870FF5BB972FF85CC97FF7BBE8DFF308539DBFFFFFF00FFFFFF0065AF + 7AF6A9DDB3FF7DCF8AFF75CC81FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF59B870FF67BE7DFF9CD4ABFF34883DF6FFFFFF00FFFFFF0069B2 + 7EF6B6E2BEFF8BD597FF7AC986FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF59B870FF69C17EFF9DD4AAFF388B42F6FFFFFF00FFFFFF006DB5 + 83DBACDDB6FFA6DFAFFF81CB8CFF7CC986FF6EBD79FFFFFFFFFFFFFFFFFF5BAC + 6AFF60BC77FF5CBA73FF8BD199FF80C592FF3C8E47DBFFFFFF00FFFFFF0070B8 + 877E85C797FFD2EED7FF95D9A0FF8AD394FF7FC889FFFFFFFFFFFFFFFFFF79CD + 85FF6BC37CFF6FC77EFFACDFB5FF459E57FF40914C7EFFFFFF00FFFFFF0073BA + 8A2270B887E5AADAB7FFD8F1DCFF92D89DFF88CD93FF84CC8EFF8BD496FF8AD4 + 95FF83D28EFFAFE0B7FF6BB97DFF489856E544945122FFFFFF00FFFFFF00FFFF + FF0073BB8B5370B887F4AFDCBBFFDCF2E0FFB6E4BDFF9BDBA5FF96D9A0FFA5DF + AFFFC0E8C5FF79C28AFF509E5FF44C9B5B53FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF0073BB8B5371B887E694CEA4FFC3E6CBFFCFEBD4FFC9E9CEFFAFDD + B8FF6DB97FFF58A569E654A16553FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0074BB8B2371B9887D6EB684DB6AB380F367B17CF363AE + 77DB60AB737D5CA86E23FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = BtnAddClick + TabOrder = 0 + end + object BtnDelete: TBitBtn + AnchorSideLeft.Control = BtnAdd + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = BtnAdd + Left = 96 + Height = 30 + Top = 6 + Width = 83 + BorderSpacing.Left = 6 + Caption = 'Delete' + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF003F54C3233A50C27D3853BEDB3551BDF3304BBCF32E4E + B8DB2B4CB77D2748B523FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF004658C8534255C6E63C52CCFF757AE8FF8F92EEFF8F92EEFF7178 + E4FF334DC1FF2B4AB7E6294BB553FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF004D5ACD534959CBF45C65E0FFA1A6F5FF7E86EFFF5B63E9FF595DE7FF7D84 + EEFF9EA0F4FF515DD7FF2B4AB7F4294BB553FFFFFF00FFFFFF00FFFFFF00545F + D2225361CFE5616BE3FFA1ACF5FF545FECFF505CEAFF4D59E9FF4E59E6FF4C56 + E6FF5056E6FF9EA2F4FF5460D6FF2A4AB8E5294BB522FFFFFF00FFFFFF005860 + D47E4B56DBFFA2ABF6FF5664F0FF5266EEFF4D59E9FF4D59E9FF4D59E9FF4D59 + E9FF4C58E6FF525AE6FF9FA3F5FF3450C4FF2A4AB87EFFFFFF00FFFFFF005C62 + D7DB818CEEFF7E91F7FF5D73F3FF4D59E9FF4D59E9FF4D59E9FF4D59E9FF4D59 + E9FF4D59E9FF4F5BE9FF7B83F0FF757BE2FF2E4BBADBFFFFFF00FFFFFF005F63 + DAF6A1ABF7FF7086F8FF6882F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF4D59E9FF5C66EAFF969CF1FF3250BCF6FFFFFF00FFFFFF006469 + DBF6AFB9F9FF7F93FAFF7085F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF4D59E9FF5E6AEEFF969DF1FF364FBEF6FFFFFF00FFFFFF00676A + DEDBA5AFF5FF9DABFAFF778CF0FF545FECFF545FECFF545FECFF545FECFF545F + ECFF545FECFF6377F2FF818EF4FF787FE9FF3A53C0DBFFFFFF00FFFFFF006A69 + E07E7D83EAFFCDD4FCFF8B9DFAFF7E93F7FF758AEEFF6C84F6FF6C84F6FF6C84 + F6FF6C84F6FF6379F3FFA4AFF8FF3E4FD0FF3E54C27EFFFFFF00FFFFFF006C6C + E1226A69E0E5A3A7F3FFD4DBFDFF879AFAFF7F91F0FF7A8EF1FF7F94F8FF7E92 + F9FF768CF8FFA8B6F8FF636EE3FF4557C7E54156C522FFFFFF00FFFFFF00FFFF + FF006D6CE3536A69E0F4AAADF2FFD8DCFDFFAEBAFAFF91A3FAFF8B9DFAFF9CA9 + FBFFBAC7FCFF707BE9FF4C5BCCF44858CA53FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF006D6CE3536A6ADFE68E93EDFFBEC3F8FFCCD3F9FFC4CBF9FFAAB4 + F4FF6670E2FF535ED1E6505DCE53FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF006D6DE2236B6AE17D686ADDDB6364DCF36164DAF35D63 + D9DB5B63D67D5862D423FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = BtnDeleteClick + TabOrder = 1 + end + object CbSortColsRows: TComboBox + AnchorSideLeft.Control = BtnDelete + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = BtnAdd + AnchorSideTop.Side = asrCenter + Left = 187 + Height = 23 + Top = 10 + Width = 160 + BorderSpacing.Left = 8 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'Sort top to bottom' + 'Sort left to right' + ) + OnChange = CbSortColsRowsChange + Style = csDropDownList + TabOrder = 2 + Text = 'Sort top to bottom' + end + object CbPriority: TComboBox + AnchorSideLeft.Control = CbSortColsRows + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = BtnAdd + AnchorSideTop.Side = asrCenter + Left = 355 + Height = 23 + Top = 10 + Width = 120 + BorderSpacing.Left = 8 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'Numbers first' + 'Text first' + ) + Style = csDropDownList + TabOrder = 3 + Text = 'Numbers first' + end + end +end diff --git a/applications/spready/ssortparamsform.pas b/applications/spready/ssortparamsform.pas new file mode 100644 index 000000000..0a252eea3 --- /dev/null +++ b/applications/spready/ssortparamsform.pas @@ -0,0 +1,268 @@ +unit sSortParamsForm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, + ButtonPanel, Grids, ExtCtrls, Buttons, StdCtrls, + fpstypes, fpspreadsheetgrid; + +type + + { TSortParamsForm } + + TSortParamsForm = class(TForm) + BtnAdd: TBitBtn; + BtnDelete: TBitBtn; + ButtonPanel: TButtonPanel; + CbSortColsRows: TComboBox; + CbPriority: TComboBox; + TopPanel: TPanel; + Grid: TStringGrid; + procedure BtnAddClick(Sender: TObject); + procedure BtnDeleteClick(Sender: TObject); + procedure CbSortColsRowsChange(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure GridSelectEditor(Sender: TObject; aCol, aRow: Integer; + var Editor: TWinControl); + procedure OKButtonClick(Sender: TObject); + private + { private declarations } + FWorksheetGrid: TsWorksheetGrid; + function GetSortParams: TsSortParams; + procedure SetWorksheetGrid(AValue: TsWorksheetGrid); + procedure UpdateColRowList; + procedure UpdateCmds; + function ValidParams(out AMsg: String): Boolean; + public + { public declarations } + property SortParams: TsSortParams read GetSortParams; + property WorksheetGrid: TsWorksheetGrid read FWorksheetGrid write SetWorksheetGrid; + end; + +var + SortParamsForm: TSortParamsForm; + +implementation + +{$R *.lfm} + +uses + fpsutils; + +procedure TSortParamsForm.CbSortColsRowsChange(Sender: TObject); +begin + UpdateColRowList; + UpdateCmds; +end; + +procedure TSortParamsForm.FormCreate(Sender: TObject); +begin + {$IFDEF WINDOWS} + if Win32MajorVersion >= 10 then begin + // avoid the ugly themed grid of Win10... + Grid.TitleStyle := tsLazarus; + end; + {$ENDIF} +end; + +procedure TSortParamsForm.GridSelectEditor(Sender: TObject; + aCol, aRow: Integer; var Editor: TWinControl); +begin + Unused(aCol, aRow); + if (Editor is TCustomComboBox) then + (Editor as TCustomComboBox).Style := csDropDownList; +end; + +procedure TSortParamsForm.OKButtonClick(Sender: TObject); +var + msg: String; +begin + if not ValidParams(msg) then begin + MessageDlg(msg, mtError, [mbOK], 0); + ModalResult := mrNone; + end; +end; + +procedure TSortParamsForm.BtnAddClick(Sender: TObject); +var + numConditions: Integer; +begin + case CbSortColsRows.ItemIndex of + 0: numConditions := FWorksheetGrid.Selection.Right - FWorksheetGrid.Selection.Left + 1; + 1: numConditions := FWorksheetGrid.Selection.Bottom - FWorksheetGrid.Selection.Top + 1; + end; + if Grid.RowCount - Grid.FixedRows >= numConditions then + exit; // there can't be more conditions than defined by the worksheetgrid selection + Grid.RowCount := Grid.RowCount + 1; + Grid.Cells[0, Grid.RowCount-1] := 'Then by'; + Grid.Cells[1, Grid.RowCount-1] := ''; + Grid.Cells[2, Grid.RowCount-1] := '0'; + Grid.Cells[3, Grid.RowCount-1] := '0'; + UpdateCmds; +end; + +procedure TSortParamsForm.BtnDeleteClick(Sender: TObject); +begin + if Grid.RowCount = Grid.FixedRows + 1 then + exit; // 1 condition must remain + Grid.DeleteRow(Grid.Row); + Grid.Cells[0, 1] := 'Sort by'; + UpdateCmds; +end; + +function TSortParamsForm.GetSortParams: TsSortParams; +var + i, p: Integer; + n: Cardinal; + sortOptions: TsSortOptions; + s: String; +begin + // Sort by column or rows? + Result := InitSortParams(CbSortColsRows.ItemIndex = 0, 0); + + // Number before Text, or reversed? + Result.Priority := TsSortPriority(CbPriority.ItemIndex); + + for i:=Grid.FixedRows to Grid.RowCount-1 do + begin + sortOptions := []; + + // Sort index column + s := Grid.Cells[1, i]; // the cell text is "Column A" or "Row A" + if s = '' then + raise Exception.Create('[TSortParamsForm.GetSortParams] No sort index selected.'); + // This case should have been detected already by the ValidParams method. + + p := pos(' ', s); // we look for the space and extract column/row index + if p = 0 then + raise Exception.Create('[TSortParamsForm.GetSortParams] Unexpected string in grid.'); + s := copy(s, p+1, Length(s)); + case CbSortColsRows.ItemIndex of + 0: if not ParseCellColString(s, n) then + raise Exception.CreateFmt('[TSortParamsForm.GetSortParams] '+ + 'Unexpected column identifier in row %d', [i]); + 1: if TryStrToInt(s, LongInt(n)) then + dec(n) + else + raise Exception.CreateFmt('[TSortParamsForm.GetSortParams] ' + + 'Unexpected row identifier in row %s', [i]); + end; + + // Sort order column + s := Grid.Cells[2, i]; + if s = '' then + raise Exception.Create('[TSortParamsForm.GetSortParams] No sort direction selected.'); + if s = '1' then + Include(sortOptions, ssoDescending); + + // Case sensitivity column + s := Grid.Cells[3, i]; + if s = '1' then + Include(sortOptions, ssoCaseInsensitive); + + SetLength(Result.Keys, Length(Result.Keys) + 1); + with Result.Keys[Length(Result.Keys)-1] do + begin + Options := sortOptions; + ColRowIndex := n; + end; + end; // for +end; + +procedure TSortParamsForm.SetWorksheetGrid(AValue: TsWorksheetGrid); +begin + FWorksheetGrid := AValue; + UpdateColRowList; + UpdateCmds; + Grid.Cells[1, 1] := Grid.Columns[0].PickList[0]; // Sorting index + Grid.Cells[2, 1] := '0'; // Ascending sort order Grid.Columns[1].CheckedPickList[0]; + Grid.Cells[3, 1] := '0'; // case-sensitive comparisons +end; + +procedure TSortParamsForm.UpdateColRowList; +var + L: TStrings; + r,c: LongInt; + r1,c1, r2,c2: Cardinal; +begin + with FWorksheetGrid do begin + r1 := GetWorksheetRow(Selection.Top); + c1 := GetWorksheetCol(Selection.Left); + r2 := GetWorksheetRow(Selection.Bottom); + c2 := GetWorksheetCol(Selection.Right); + end; + L := TStringList.Create; + try + case CbSortColsRows.ItemIndex of + 0: begin + Grid.RowCount := Grid.FixedRows + 1; + Grid.Columns[0].Title.Caption := 'Columns'; + for c := c1 to c2 do + L.Add('Column ' + GetColString(c)); + end; + 1: begin + Grid.RowCount := Grid.FixedRows + 1; + Grid.Columns[0].Title.Caption := 'Rows'; + for r := r1 to r2 do + L.Add('Row ' + IntToStr(r+1)); + end; + end; + Grid.Columns[0].PickList.Assign(L); + for r := Grid.FixedRows to Grid.RowCount-1 do + begin + Grid.Cells[1, r] := ''; + Grid.Cells[2, r] := '' + end; + finally + L.Free; + end; +end; + +procedure TSortParamsForm.UpdateCmds; +var + r1,c1,r2,c2: Cardinal; + numConditions: Integer; +begin + with FWorksheetGrid do begin + r1 := GetWorksheetRow(Selection.Top); + c1 := GetWorksheetCol(Selection.Left); + r2 := GetWorksheetRow(Selection.Bottom); + c2 := GetWorksheetCol(Selection.Right); + end; + numConditions := Grid.RowCount - Grid.FixedRows; + case CbSortColsRows.ItemIndex of + 0: BtnAdd.Enabled := numConditions < c2-c1+1; + 1: BtnAdd.Enabled := numConditions < r2-r1+1; + end; + BtnDelete.Enabled := numConditions > 1; +end; + +function TSortParamsForm.ValidParams(out AMsg: String): Boolean; +var + i: Integer; +begin + Result := false; + for i:=Grid.FixedRows to Grid.RowCount-1 do + begin + if Grid.Cells[1, i] = '' then + begin + AMsg := Format('No sorting criteria selected in row %d.', [i]); + Grid.SetFocus; + exit; + end; + if Grid.Cells[2, i] = '' then + begin + AMsg := Format('No sort order specified in row %d.', [i]); + Grid.SetFocus; + exit; + end; + end; + Result := true; +end; + + +end. + diff --git a/applications/spready/sutils.pas b/applications/spready/sutils.pas new file mode 100644 index 000000000..628dc27fa --- /dev/null +++ b/applications/spready/sutils.pas @@ -0,0 +1,166 @@ +unit sutils; + +{$mode objfpc}{$H+} + +interface + +uses + fpstypes, fpspreadsheet; + +function GetCellFormatAsString(AWorkbook: TsWorkbook; AIndex: Integer): String; +function GetColorName(AColor: TsColor): String; +function GetFontAsString(AFont: TsFont): String; + + +implementation + +{@@ ---------------------------------------------------------------------------- + Determines the name of a color from its rgb value +-------------------------------------------------------------------------------} +function GetColorName(AColor: TsColor): string; +var + rgba: TRGBA absolute AColor; +begin + case AColor of + scAqua : Result := rsAqua; + scBeige : Result := rsBeige; + scBlack : Result := rsBlack; + scBlue : Result := rsBlue; + scBlueGray : Result := rsBlueGray; + scBrown : Result := rsBrown; + scCoral : Result := rsCoral; + scCyan : Result := rsCyan; + scDarkBlue : Result := rsDarkBlue; + scDarkGreen : Result := rsDarkGreen; + scDarkPurple : Result := rsDarkPurple; + scDarkRed : Result := rsDarkRed; + scDarkTeal : Result := rsDarkTeal; + scGold : Result := rsGold; + scGray : Result := rsGray; + scGray10pct : Result := rsGray10pct; + scGray20pct : Result := rsGray20pct; + scGray40pct : Result := rsGray40pct; + scGray80pct : Result := rsGray80pct; + scGreen : Result := rsGreen; + scIceBlue : Result := rsIceBlue; + scIndigo : Result := rsIndigo; + scIvory : Result := rsIvory; + scLavander : Result := rsLavander; + scLightBlue : Result := rsLightBlue; + scLightGreen : Result := rsLightGreen; + scLightOrange: Result := rsLightOrange; + scLightTurquoise: Result := rsLightTurquoise; + scLightYellow: Result := rsLightYellow; + scLime : Result := rsLime; + scMagenta : Result := rsMagenta; + scNavy : Result := rsNavy; + scOceanBlue : Result := rsOceanBlue; + scOlive : Result := rsOlive; + scOliveGreen : Result := rsOliveGreen; + scOrange : Result := rsOrange; + scPaleBlue : Result := rsPaleBlue; + scPeriwinkle : Result := rsPeriwinkle; + scPink : Result := rsPink; + scPlum : Result := rsPlum; + scPurple : Result := rsPurple; + scRed : Result := rsRed; + scRose : Result := rsRose; + scSeaGreen : Result := rsSeaGreen; + scSilver : Result := rsSilver; + scSkyBlue : Result := rsSkyBlue; + scTan : Result := rsTan; + scTeal : Result := rsTeal; + scVeryDarkGreen: Result := rsVeryDarkGreen; +// scViolet : Result := rsViolet; + scWheat : Result := rsWheat; + scWhite : Result := rsWhite; + scYellow : Result := rsYellow; + scTransparent: Result := rsTransparent; + scNotDefined : Result := rsNotDefined; + else + case rgba.a of + $00: + Result := Format('R%d G%d B%d', [rgba.r, rgba.g, rgba.b]); + scPaletteIndexMask shr 24: + Result := Format(rsPaletteIndex, [AColor and $00FFFFFF]); + else + Result := ''; + end; + end; +end; + +{@@ ---------------------------------------------------------------------------- + Returns a string describing the cell format with the specified index. +-------------------------------------------------------------------------------} +function GetCellFormatAsString(AWorkbook: TsWorkbook; AIndex: Integer): String; +var + fmt: PsCellFormat; + cb: TsCellBorder; + s: String; + numFmt: TsNumFormatParams; +begin + Result := ''; + fmt := GetPointerToCellFormat(AIndex); + if fmt = nil then + exit; + + if (uffFont in fmt^.UsedFormattingFields) then + Result := Format('%s; Font%d', [Result, fmt^.FontIndex]); + if (uffBackground in fmt^.UsedFormattingFields) then begin + Result := Format('%s; Bg %s', [Result, GetColorName(fmt^.Background.BgColor)]); + Result := Format('%s; Fg %s', [Result, GetColorName(fmt^.Background.FgColor)]); + Result := Format('%s; Pattern %s', [Result, GetEnumName(TypeInfo(TsFillStyle), ord(fmt^.Background.Style))]); + end; + if (uffHorAlign in fmt^.UsedFormattingfields) then + Result := Format('%s; %s', [Result, GetEnumName(TypeInfo(TsHorAlignment), ord(fmt^.HorAlignment))]); + if (uffVertAlign in fmt^.UsedFormattingFields) then + Result := Format('%s; %s', [Result, GetEnumName(TypeInfo(TsVertAlignment), ord(fmt^.VertAlignment))]); + if (uffWordwrap in fmt^.UsedFormattingFields) then + Result := Format('%s; Word-wrap', [Result]); + if (uffNumberFormat in fmt^.UsedFormattingFields) then + begin + numFmt := GetNumberFormat(fmt^.NumberFormatIndex); + if numFmt <> nil then + Result := Format('%s; %s (%s)', [Result, + GetEnumName(TypeInfo(TsNumberFormat), ord(numFmt.NumFormat)), + numFmt.NumFormatStr + ]) + else + Result := Format('%s; %s', [Result, 'nfGeneral']); + end else + Result := Format('%s; %s', [Result, 'nfGeneral']); + if (uffBorder in fmt^.UsedFormattingFields) then + begin + s := ''; + for cb in fmt^.Border do + if s = '' then s := GetEnumName(TypeInfo(TsCellBorder), ord(cb)) + else s := s + '+' + GetEnumName(TypeInfo(TsCellBorder), ord(cb)); + Result := Format('%s; %s', [Result, s]); + end; + if (uffBiDi in fmt^.UsedFormattingFields) then + Result := Format('%s; %s', [Result, GetEnumName(TypeInfo(TsBiDiMode), ord(fmt^.BiDiMode))]); + if Result <> '' then Delete(Result, 1, 2); +end; + +{@@ ---------------------------------------------------------------------------- + Returns a string which identifies the font. + + @param AIndex Index of the font + @return String with font name, font size etc. +-------------------------------------------------------------------------------} +function GetFontAsString(AFont: TsFont): String; +begin + if AFont <> nil then begin + Result := Format('%s; size %.1g; %s', [ + AFont.FontName, AFont.Size, GetColorName(AFont.Color)]); + if (fssBold in AFont.Style) then Result := Result + '; bold'; + if (fssItalic in AFont.Style) then Result := Result + '; italic'; + if (fssUnderline in AFont.Style) then Result := Result + '; underline'; + if (fssStrikeout in AFont.Style) then result := Result + '; strikeout'; + if AFont.Position = fpSubscript then Result := Result + '; subscript'; + if AFont.Position = fpSuperscript then Result := Result + '; superscript'; + end else + Result := ''; +end; + +end.