Ver Fonte

UPD: Update DSXLocate plugin after changes to DSX interface.

cobines há 15 anos atrás
pai
commit
c3d8ccb490

+ 7 - 77
plugins/dsx/DSXLocate/src/DSXLocate.lpi

@@ -3,15 +3,15 @@
   <ProjectOptions>
     <Version Value="7"/>
     <General>
+      <SessionStorage Value="InProjectDir"/>
       <MainUnit Value="0"/>
       <TargetFileExt Value=""/>
       <Title Value="DSXLocate"/>
-      <ActiveEditorIndexAtStart Value="0"/>
     </General>
     <VersionInfo>
-      <ProjectVersion Value=""/>
-      <Language Value=""/>
-      <CharSet Value=""/>
+      <Language Value="041C"/>
+      <CharSet Value="0000"/>
+      <StringTable Comments="" CompanyName="" FileDescription="" FileVersion="0.0.0.0" InternalName="" LegalCopyright="" LegalTrademarks="" OriginalFilename="" ProductName="" ProductVersion=""/>
     </VersionInfo>
     <PublishOptions>
       <Version Value="2"/>
@@ -25,88 +25,18 @@
         <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
       </local>
     </RunParams>
-    <Units Count="3">
+    <Units Count="2">
       <Unit0>
         <Filename Value="DSXLocate.lpr"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="DSXLocate"/>
-        <CursorPos X="25" Y="69"/>
-        <TopLine Value="64"/>
-        <EditorIndex Value="0"/>
-        <UsageCount Value="25"/>
-        <Loaded Value="True"/>
       </Unit0>
       <Unit1>
-        <Filename Value="udsxplugin.pas"/>
-        <UnitName Value="udsxplugin"/>
-        <CursorPos X="1" Y="37"/>
-        <TopLine Value="8"/>
-        <UsageCount Value="13"/>
-      </Unit1>
-      <Unit2>
         <Filename Value="un_process.pas"/>
+        <IsPartOfProject Value="True"/>
         <UnitName Value="un_process"/>
-        <CursorPos X="14" Y="27"/>
-        <TopLine Value="13"/>
-        <EditorIndex Value="1"/>
-        <UsageCount Value="13"/>
-        <Loaded Value="True"/>
-      </Unit2>
+      </Unit1>
     </Units>
-    <JumpHistory Count="13" HistoryIndex="12">
-      <Position1>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="48" Column="5" TopLine="19"/>
-      </Position1>
-      <Position2>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="54" Column="7" TopLine="27"/>
-      </Position2>
-      <Position3>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="64" Column="11" TopLine="36"/>
-      </Position3>
-      <Position4>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="32" Column="19" TopLine="16"/>
-      </Position4>
-      <Position5>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="38" Column="22" TopLine="23"/>
-      </Position5>
-      <Position6>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="119" Column="14" TopLine="94"/>
-      </Position6>
-      <Position7>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="38" Column="22" TopLine="23"/>
-      </Position7>
-      <Position8>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="119" Column="14" TopLine="94"/>
-      </Position8>
-      <Position9>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="126" Column="8" TopLine="98"/>
-      </Position9>
-      <Position10>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="64" Column="5" TopLine="35"/>
-      </Position10>
-      <Position11>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="52" Column="42" TopLine="45"/>
-      </Position11>
-      <Position12>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="40" Column="15" TopLine="13"/>
-      </Position12>
-      <Position13>
-        <Filename Value="DSXLocate.lpr"/>
-        <Caret Line="77" Column="3" TopLine="62"/>
-      </Position13>
-    </JumpHistory>
   </ProjectOptions>
   <CompilerOptions>
     <Version Value="8"/>

+ 119 - 81
plugins/dsx/DSXLocate/src/DSXLocate.lpr

@@ -30,141 +30,179 @@ library DSXLocate;
 uses
   Classes, SysUtils, DsxPlugin, un_process;
 
-var List:TStringList;
-    LocatePath:String;
+var
+  List: TStringList;
+  LocatePath: String;
 
 type
 
-       { TPlugInfo }
-
-       TPlugInfo = class
-         private
-          FProcess:TExProcess;
-          FAddProc:TSAddFileProc;
-          FUpdateProc:TSUpdateStatusProc;
-          FSearchAttr:TSearchAttrRecord;
-          FStartPath:String;
-          FilesScaned:integer;
-         public
-          PluginNr:integer;
-         //---------------------
-         constructor Create(Nr:integer);
-         procedure SetProcs(AddProc:TSAddFileProc; UpdateProc:TSUpdateStatusProc);
-         procedure SetDefs(SearchAttr:TSearchAttrRecord; StartPath:String);
-         destructor Destroy; override;
-         //---------------------
-         procedure Start;
-         procedure Stop;
-         procedure OnReadLn(str: string);
-       end;
-
-constructor TPlugInfo.Create(Nr:integer);
+  { TPlugInfo }
+
+  TPlugInfo = class
+  private
+    FProcess: TExProcess;
+    FAddProc: TSAddFileProc;
+    FUpdateProc: TSUpdateStatusProc;
+    FSearchRec: TDsxSearchRecord;
+    FilesScanned: Integer;
+  public
+    PluginNr: Integer;
+    //---------------------
+    constructor Create(Nr: Integer);
+    procedure SetProcs(AddProc: TSAddFileProc; UpdateProc: TSUpdateStatusProc);
+    procedure SetDefs(pSearchRec: PDsxSearchRecord);
+    destructor Destroy; override;
+    //---------------------
+    procedure Start;
+    procedure Stop;
+    procedure OnReadLn(str: String);
+  end;
+
+constructor TPlugInfo.Create(Nr: Integer);
 begin
-  PluginNr:=Nr;
+  PluginNr := Nr;
+  FProcess := nil;
 end;
 
 procedure TPlugInfo.SetProcs(AddProc: TSAddFileProc; UpdateProc: TSUpdateStatusProc);
 begin
-FAddProc:=AddProc;
-FUpdateProc:=UpdateProc;
+  FAddProc    := AddProc;
+  FUpdateProc := UpdateProc;
 end;
 
-procedure TPlugInfo.SetDefs(SearchAttr: TSearchAttrRecord; StartPath: String);
+procedure TPlugInfo.SetDefs(pSearchRec: PDsxSearchRecord);
 begin
-FSearchAttr:=SearchAttr;
-FStartPath:=StartPath;
+  FSearchRec := pSearchRec^;
 end;
 
-
 destructor TPlugInfo.Destroy;
 begin
-if Assigned(FProcess) then FreeAndNil(FProcess);
+  if Assigned(FProcess) then
+    FreeAndNil(FProcess);
   inherited Destroy;
 end;
 
 procedure TPlugInfo.Start;
+var
+  sSearch: String;
 begin
-  FilesScaned:=0;
-  FProcess:=TExProcess.Create();
-  FProcess.OnReadLn:=@OnReadLn;
-  FProcess.SetCmdLine(LocatePath+' '+string(FSearchAttr.rFileMask));
+  FilesScanned := 0;
+  if Assigned(FProcess) then
+    FreeAndNil(FProcess);
+  FProcess := TExProcess.Create;
+  FProcess.OnReadLn := @OnReadLn;
+
+  with FSearchRec do
+  begin
+    // TProcess doesn't support passing parameters other than quoted in "".
+    // Adapt this code when this changes.
+    sSearch := String(StartPath);
+    if sSearch <> '' then
+    begin
+      // Search in given start path and in subdirectories.
+      sSearch := '"' + IncludeTrailingPathDelimiter(sSearch) + String(FileMask) + '" ' +
+                 '"' + IncludeTrailingPathDelimiter(sSearch) + '*' + PathDelim + String(FileMask) + '"';
+    end
+    else
+      sSearch := '"' + String(FileMask) + '"';
+  end;
+
+  if LocatePath <> '' then
+    FProcess.SetCmdLine(LocatePath + ' ' + sSearch);
   FProcess.Execute;
 end;
 
 procedure TPlugInfo.Stop;
 begin
-  FProcess.Stop;
-  FreeAndNil(FProcess);
+  if Assigned(FProcess) then
+  begin
+    FProcess.Stop;
+    FreeAndNil(FProcess);
+  end;
 end;
 
-procedure TPlugInfo.OnReadLn(str: string);
+procedure TPlugInfo.OnReadLn(str: String);
 begin
-  FilesScaned:=FilesScaned+1;
-  FAddProc(PluginNr,PChar(str));
-  FUpdateProc(PluginNr,PChar(str),FilesScaned);
+  if str <> '' then
+    Inc(FilesScanned);
+  FAddProc(PluginNr, PChar(str));
+  FUpdateProc(PluginNr, PChar(str), FilesScanned);
 end;
 
 
 {Main --------------------------------------------------------------------------------}
 
-function Init(dps:pDSXDefaultParamStruct; pAddFileProc:TSAddFileProc; pUpdateStatus:TSUpdateStatusProc):integer; stdcall;
-var i:integer;
+function Init(dps: PDsxDefaultParamStruct; pAddFileProc: TSAddFileProc;
+  pUpdateStatus: TSUpdateStatusProc): Integer; stdcall;
+var
+  i: Integer;
 begin
-  if not assigned(List) then List:=TStringList.Create;
-  I:=List.Count;
-  List.AddObject(IntToStr(I),TPlugInfo.Create(I));
-  TPlugInfo(List.Objects[I]).SetProcs(pAddFileProc,pUpdateStatus);
+  if not assigned(List) then
+    List := TStringList.Create;
+  I := List.Count;
+  List.AddObject(IntToStr(I), TPlugInfo.Create(I));
+  TPlugInfo(List.Objects[I]).SetProcs(pAddFileProc, pUpdateStatus);
+  Result := I;
 end;
 
-procedure StartSearch(FPluginNr:integer; StartPath:pchar; SearchAttrRec:TSearchAttrRecord); stdcall;
+procedure StartSearch(FPluginNr: Integer; pSearchRecRec: PDsxSearchRecord); stdcall;
 begin
-  TPlugInfo(List.Objects[FPluginNr]).SetDefs(SearchAttrRec,string(StartPath));
+  TPlugInfo(List.Objects[FPluginNr]).SetDefs(pSearchRecRec);
   TPlugInfo(List.Objects[FPluginNr]).Start;
 end;
 
-procedure StopSearch(FPluginNr:integer); stdcall;
+procedure StopSearch(FPluginNr: Integer); stdcall;
 begin
-TPlugInfo(List.Objects[FPluginNr]).Stop;
+  TPlugInfo(List.Objects[FPluginNr]).Stop;
 end;
 
-procedure Finalize(FPluginNr:integer); stdcall;
+procedure Finalize(FPluginNr: Integer); stdcall;
 begin
-if not Assigned(List) then exit;
-if (FPluginNr>List.Count) or (FPluginNr<0) or (List.Count=0) then exit;
+  if not Assigned(List) then
+    exit;
+  if (FPluginNr > List.Count) or (FPluginNr < 0) or (List.Count = 0) then
+    exit;
 
-//Destroy PlugInfo Item №
+  //Destroy PlugInfo Item №
   TPlugInfo(List.Objects[FPluginNr]).Free;
   List.Delete(FPluginNr);
-  if List.Count=0 then
+  if List.Count = 0 then
     FreeAndNil(List);
 end;
 
-
 exports
-       Init,
-       StartSearch,
-       StopSearch,
-       Finalize;
-       
-type Tx=class
-        procedure OnReadLnWhich(str: string);
-       end;
-
-procedure Tx.OnReadLnWhich(str: string);
+  Init,
+  StartSearch,
+  StopSearch,
+  Finalize;
+
+type
+  Tx = class
+    procedure OnReadLnWhich(str: String);
+  end;
+
+procedure Tx.OnReadLnWhich(str: String);
 begin
-  if str<>'' then
-   begin
-     LocatePath:=str;
-     //WriteLn('PLUGIN: locate found in '+str);
-   end;
+  if str <> '' then
+  begin
+    LocatePath := str;
+    //WriteLn('PLUGIN: locate found in '+str);
+  end;
 end;
 
-var Pr:TExProcess; x:TX;
+var
+  Pr: TExProcess;
+  x:  TX;
 begin
-pr:=TExProcess.Create('which locate');
-x:=Tx.Create;
-pr.OnReadLn:=@(x.OnReadLnWhich);
-pr.Execute;
-x.free;
+  pr := TExProcess.Create('which locate');
+  x  := Tx.Create;
+  pr.OnReadLn := @x.OnReadLnWhich;
+  pr.Execute;
+  pr.Free;
+  x.Free;
+  {$IFDEF UNIX}
+  if LocatePath = '' then
+    Writeln('DSXLocate: Locate utility not found.');
+  {$ENDIF}
 end.
 

+ 58 - 42
plugins/dsx/DSXLocate/src/un_process.pas

@@ -1,102 +1,118 @@
 {$mode delphi}
 {$longstrings on}
+
 unit un_process;
 
 interface
- uses process, math,sysutils;
- 
+
+uses
+  process, Math, SysUtils;
+
 type
 
-  TOnReadLn=procedure (str: string) of object;
-  
+  TOnReadLn = procedure(str: String) of object;
+
   { TExProcess }
 
   TExProcess = class
   protected
     p: TProcess;
-    s: string;
-    FStop:boolean;
-    function _GetExitStatus(): integer;
+    s: String;
+    FStop: Boolean;
+    function _GetExitStatus(): Integer;
   public
-    OnReadLn:TOnReadLn;
-    constructor Create(commandline: string='');
+    OnReadLn: TOnReadLn;
+    constructor Create(commandline: String = '');
     procedure Execute;
     procedure Stop;
-    procedure SetCmdLine(commandline:string);
-    destructor Destroy;
- 
-    property ExitStatus: integer read _GetExitStatus;
+    procedure SetCmdLine(commandline: String);
+    destructor Destroy; override;
+
+    property ExitStatus: Integer read _GetExitStatus;
   end;
 
 implementation
 
-const buf_len = 3000;
+const
+  buf_len = 3000;
 
 
 { TExProcess }
 
-function TExProcess._GetExitStatus(): integer;
+function TExProcess._GetExitStatus(): Integer;
 begin
-  Result:=p.ExitStatus;
+  Result := p.ExitStatus;
 end;
 
-constructor TExProcess.Create(commandline: string='');
+constructor TExProcess.Create(commandline: String = '');
 begin
-  s:='';
-  p:=TProcess.Create(nil);
-  p.CommandLine:=commandline;
-   p.Options:=[poUsePipes,poNoConsole];
-
+  s := '';
+  p := TProcess.Create(nil);
+  p.CommandLine := commandline;
+  p.Options := [poUsePipes, poNoConsole, poWaitOnExit];
 end;
 
 procedure TExProcess.Execute;
 var
-  buf: string;
-  i, j, c, n: integer;
+  buf: String;
+  i, j: Integer;
 begin
   try
     p.Execute;
     repeat
-      if FStop then exit;
+      if FStop then
+        exit;
       SetLength(buf, buf_len);
       SetLength(buf, p.output.Read(buf[1], length(buf))); //waits for the process output
       // cut the incoming stream to lines:
-      s:=s + buf; //add to the accumulator
+      s := s + buf; //add to the accumulator
 
       repeat //detect the line breaks and cut.
-        i:=Pos(#13, s);
-        j:=Pos(#10, s);
-        if i=0 then i:=j;
-        if j=0 then j:=i;
-        if j = 0 then Break; //there are no complete lines yet.
+        i := Pos(#13, s);
+        j := Pos(#10, s);
+        if i = 0 then
+          i := j;
+        if j = 0 then
+          j := i;
+        if j = 0 then
+          Break; //there are no complete lines yet.
         if Assigned(OnReadLn) then
-        OnReadLn(Copy(s, 1, min(i, j) - 1)); //return the line without the CR/LF characters
-        s:=Copy(s, max(i, j) + 1, length(s) - max(i, j)); //remove the line from accumulator
-      until false;
+          OnReadLn(Copy(s, 1, min(i, j) - 1));
+        //return the line without the CR/LF characters
+        s := Copy(s, max(i, j) + 1, length(s) - max(i, j));
+        //remove the line from accumulator
+      until False;
     until buf = '';
     if s <> '' then
       if Assigned(OnReadLn) then
-       OnReadLn(s);
-    buf:='';
-    if Assigned(OnReadLn) then
-      OnReadLn(buf); //Empty line to notify DC about search process finish
-  finally
+        OnReadLn(s);
+    buf := '';
+  except
+    {$IFDEF UNIX}
+    on e: Exception do
+      Writeln('DSXLocate error: ', e.Message);
+    {$ENDIF}
   end;
+
+  if Assigned(OnReadLn) then
+    OnReadLn(buf); //Empty line to notify DC about search process finish
 end;
 
 procedure TExProcess.Stop;
 begin
-  FStop:=true;
+  FStop := True;
 end;
 
-procedure TExProcess.SetCmdLine(commandline:string);
+procedure TExProcess.SetCmdLine(commandline: String);
 begin
-  p.CommandLine:=commandline;
+  p.CommandLine := commandline;
 end;
 
 destructor TExProcess.Destroy;
 begin
   FreeAndNil(p);
+  inherited Destroy;
 end;
 
 end.
+

+ 14 - 13
sdk/dsxplugin.pas

@@ -7,10 +7,12 @@ uses
 
 type
 
+  PDsxSearchRecord = ^TDsxSearchRecord;
   TDsxSearchRecord = record
+    StartPath: array[0..1024] of AnsiChar;
     FileMask: array[0..1024] of AnsiChar;
     Attributes: Cardinal;
-    AttribStr: array[0..32] of AnsiChar;
+    AttribStr: array[0..128] of AnsiChar;
     CaseSensitive: Boolean;
     { Date/time search }
     IsDateFrom,
@@ -33,29 +35,28 @@ type
   end;
 
 
-  tDSXDefaultParamStruct = record
-    size,
+  TDsxDefaultParamStruct = record
+    Size,
     PluginInterfaceVersionLow,
     PluginInterfaceVersionHi: Longint;
     DefaultIniName: array[0..MAX_PATH - 1] of Char;
   end;
-  pDSXDefaultParamStruct = ^tDSXDefaultParamStruct;
+  PDsxDefaultParamStruct = ^TDsxDefaultParamStruct;
 
   {Prototypes}
   {Callbacks procs}
-  TSAddFileProc = procedure(PlugNr: Integer; FoundFile: PChar); Stdcall;
+  TSAddFileProc = procedure(PluginNr: Integer; FoundFile: PChar); stdcall;
   //if FoundFile='' then searching is finished
 
-  TSUpdateStatusProc = procedure(PlugNr: Integer; CurrentFile: PChar;
-    FilesScaned: Integer); Stdcall;
+  TSUpdateStatusProc = procedure(PluginNr: Integer; CurrentFile: PChar;
+    FilesScaned: Integer); stdcall;
 
   {Mandatory (must be implemented)}
-  {
-  function Init(dps:pDSXDefaultParamStruct; pAddFileProc:TSAddFileProc; pUpdateStatus:TSUpdateStatusProc):integer; stdcall;
-  procedure StartSearch(FPluginNr:integer; StartPath:pchar; SearchAttrRec:TSearchAttrRecord); stdcall;
-  procedure StopSearch(FPluginNr:integer); stdcall;
-  procedure Finalize(FPluginNr:integer); stdcall;
-  }
+  TSInit = function(dps: PDsxDefaultParamStruct; pAddFileProc: TSAddFileProc;
+    pUpdateStatus: TSUpdateStatusProc): Integer; stdcall;
+  TSStartSearch = procedure(PluginNr: Integer; pSearchRec: PDsxSearchRecord); stdcall;
+  TSStopSearch = procedure(PluginNr: Integer); stdcall;
+  TSFinalize = procedure(PluginNr: Integer); stdcall;
 
 implementation
 

+ 2 - 1
src/fFindDlg.pas

@@ -501,6 +501,7 @@ begin
   begin
     FillByte(SRec, SizeOf(TDsxSearchRecord), 0);
 
+    SRec.StartPath:= Copy(StartPath, 1, SizeOf(SRec.StartPath));
     SRec.FileMask:= Copy(FilesMasks, 1, SizeOf(SRec.FileMask));
     SRec.Attributes:= faAnyFile;  // AttrStrToFileAttr?
     SRec.AttribStr:= Copy(AttributesPattern, 1, SizeOf(SRec.AttribStr));
@@ -607,7 +608,7 @@ begin
           FindOptionsToDSXSearchRec(FindOptions, sr);
           FSearchingActive := True;
           DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallInit(@SAddFileProc,@SUpdateStatusProc);
-          DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallStartSearch(PChar(edtFindPathStart.Text),sr);
+          DSXPlugins.GetDSXModule(cmbPlugin.ItemIndex).CallStartSearch(sr);
         end
         else
           StopSearch;

+ 11 - 25
src/udsxmodule.pas

@@ -34,16 +34,6 @@ uses
 
 type
 
-  {Prototypes}
-  {Mandatory (must be implemented)}
-  TSInit = function(dps: pDSXDefaultParamStruct; pAddFileProc: TSAddFileProc;
-    pUpdateStatus: TSUpdateStatusProc): integer; stdcall;
-  TSStartSearch = procedure(PluginNr: integer; StartPath: PChar;
-    SearchRec: TDsxSearchRecord); stdcall;
-  TSStopSearch = procedure(PluginNr: integer); stdcall;
-  TSFinalize = procedure(PluginNr: integer); stdcall;
-
-
   { TDsxModule }
 
   TDsxModule = class
@@ -70,7 +60,7 @@ type
     procedure UnloadModule;
     //---------------------
     function CallInit(pAddFileProc: TSAddFileProc; pUpdateStatus: TSUpdateStatusProc): integer;
-    procedure CallStartSearch(StartPath: PChar; SearchRec: TDsxSearchRecord);
+    procedure CallStartSearch(SearchRec: TDsxSearchRecord);
     procedure CallStopSearch;
     procedure CallFinalize;
     //---------------------
@@ -172,27 +162,23 @@ end;
 
 function TDsxModule.CallInit(pAddFileProc: TSAddFileProc; pUpdateStatus: TSUpdateStatusProc): integer;
 var
-  dps: pDSXDefaultParamStruct;
+  dps: TDsxDefaultParamStruct;
 begin
   if Assigned(SInit) then
   begin
-    GetMem(dps, SizeOf(tDSXDefaultParamStruct));
-    dps^.DefaultIniName := gpCfgDir + DsxIniFileName;
-    dps^.PluginInterfaceVersionHi := 0;
-    dps^.PluginInterfaceVersionLow := 10;
-    dps^.size := SizeOf(tDSXDefaultParamStruct);
-    FPluginNr := Sinit(dps, pAddFileProc, pUpdateStatus);
-    Result := FPluginNr;
-    FreeMem(dps, SizeOf(tDSXDefaultParamStruct));
+    dps.DefaultIniName := gpCfgDir + DsxIniFileName;
+    dps.PluginInterfaceVersionHi := 0;
+    dps.PluginInterfaceVersionLow := 10;
+    dps.size  := SizeOf(TDsxDefaultParamStruct);
+    FPluginNr := Sinit(@dps, pAddFileProc, pUpdateStatus);
+    Result    := FPluginNr;
   end;
 end;
 
-procedure TDsxModule.CallStartSearch(StartPath: PChar; SearchRec: TDsxSearchRecord);
+procedure TDsxModule.CallStartSearch(SearchRec: TDsxSearchRecord);
 begin
   if Assigned(SStartSearch) then
-  begin
-    SStartSearch(FPluginNr, StartPath, SearchRec);
-  end;
+    SStartSearch(FPluginNr, @SearchRec);
 end;
 
 procedure TDsxModule.CallStopSearch;
@@ -424,4 +410,4 @@ begin
 end;
 
 end.
-
+