{**********************************************************************
Copyright (C) 2009 by Salvatore Licciardi

Web http://www.webalice.it/turylicciardi    eMail turylicciardi@tiscali.it

 This program is free software: you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
 Foundation, version 3 of the License.
 This program is distributed in the hope  that it will be useful , but WITHOUT
 ANY WARRANTY without even the implied warranty  of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.
 See the GNU General Public License for more details. You should have received
 a copy of the GNU General Public License along with this program. If not, see
 http://www.gnu.org/licenses/

 **********************************************************************}

{$MODE ObjFpc}
unit Altro32D;  { per DOS/Windows/OS2/Linux 32 bit }

interface
{$H+}  // longstring

{$ifdef Win64}
 {$define Win32}
{$endif}
{$ifdef Go32v2}
 {$define TxtCrt}
{$endif}
{$ifdef Win32}
 {$define TxtVideo}
{$endif}
{$ifdef OS2}
 {$define TxtVideo}
{$endif}
{$ifdef Linux}
 {$define TxtCrt}
{$endif}


uses Crt,Dos,SysUtils,Math,Video,Keyboard,
     {$ifdef Go32v2}
      MsMouse,
      {$else}
      Mouse,
     {$endif}
     {$ifdef TxtVideo}
      TxtVideo,
     {$endif}
     MClick22, Altro32;


function  SfogliaFile(XX,YY:byte; all,ordina,topo,mancino:boolean; testo,percorso_:string; var ifiles:string; CD,num_righe:longint;
                      nome,lista,elementi,data,ora,attributi,Ricerca_files:string; nome_char,lista_char:char):string;
function  ReadString(stringa:string; Xstart,Xtot,status:byte; topo,avanzate,mancino:boolean;
                     var ins:boolean;  var lastD,lastU,posto:byte):string;
function  ReadString2(stringa:string; Xstart,Xtot,status:byte; topo,avanzate,mancino,asterischi:boolean;
                     var ins:boolean; var lastD,lastU,cursore_,x_:byte):string;
function  SfogliaDirectory(XX,YY:byte; all,ordina,topo,mancino:boolean; testo,percorso_:string; CD,num_righe:longint;
                      nome,lista,elementi,data,ora,attributi,Ricerca_files:string; nome_char,lista_char:char):string;


implementation

const maxx=2000;
type  {$ifdef Go32v2}
       tipo1=string[13];
      {$else}
       tipo1=string;
      {$endif}

      AA=array[1..maxx] of tipo1;

var  A:AA;          {per il QSort}
     q:word;

var   percorso,nomefile:string;
      count,iesimo,app:word;
      selezionato,X,Y:byte;
      righe:longint;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

function Partition(var A:AA; p,r:word):word;
var i,j:word;
    x,xx: tipo1;
begin
x:=A[p];
i:=p-1;
j:=r+1;
while true do
      begin
      repeat
       dec(j);
      until A[j]<=x;
      repeat
       inc(i);
      until A[i]>=x;
      if i<j then
             begin
             xx:=A[i];
             A[i]:=A[j];
             A[j]:=xx;
             end
            else
             begin
             Partition:=j;
             Break;
             end;
      end;
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

procedure QuickSort(var A:AA; p,r:word);
begin
if p<r then
       begin
       q:=Partition(A,p,r);
       QuickSort(A,p,q);
       QuickSort(A,q+1,r);
       end;
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

procedure FindFiles2(path:string; const all:boolean);
var F: TSearchRec;
    nome:shortstring;
    i:longint;
begin
showmouse;
if FindFirst(Path,  Anyfile - VolumeId - Directory, F)=0 then
 repeat
  if (not all) and ((f.attr and hidden)<>0)or((f.attr and sysfile)<>0) then Continue;
  if (f.attr and directory) =0  then
                                begin
                                Inc(Count);
                                nome:=pathof(path)+f.name;
                                GetshortName(nome);
                                A[count]:='f'+NameOf(nome);
                                for i:=1 to count-1 do
                                    if A[count]=A[i] then
                                       begin
                                       dec(count);
                                       break;
                                       end;
                                end;
 until (FindNext(F)<>0) or (Count >= Maxx);
FindClose(F)
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

function CercaFile(nome:tipo1):word;
var i:word;
begin
nome:=upCase(nome);
for i:=1 to count do if UpCase(Copy_end(A[i],2))=nome then Exit(i);
Exit(0);
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

function CercaFile2(nome:tipo1):word;
var i:word;
begin
nome:=upCase(nome);
for i:=1 to count do if UpCase(Copy(A[i],2,length(nome)))=nome then Exit(i);
Exit(0);
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

procedure FindAllFiles(cartella:boolean; percorso:string; var ifiles:string; all:boolean);
var testa,coda:string;   {casi speciali in cui ifiles= '' *. .* . }
    F: TSearchRec;
    nome_corto:shortstring;

begin
if copy(ifiles,length(ifiles),1)=';' then ifiles:=copy(ifiles,1,length(ifiles)-1);
if (ifiles='') or cartella then ifiles:={$ifdef Linux}'*'{$else}'*.*'{$endif}; // se del tipo *.exe;*.com... far diventare *.* quando Š SfogliaCartella
if not cartella then
   begin
   testa:=ifiles;
   while (testa<>'') do
          begin
          Testa_Coda(testa,';',testa,coda);
          if testa[1]=';' then delete(testa,1,1);
          if (testa=';')or(testa='') then testa:={$ifdef Linux}'*'{$else}'*.*'{$endif};
          if copy(testa,1,1)='.' then testa:='*'+testa;
          if copy(testa,posRL('.',testa,255)+1,1)='' then testa:=testa+'*';
          FindFiles2(percorso+testa,all);
          testa:=coda;
          end;
   end;
if FindFirst(percorso+{$ifdef Linux}'*'{$else}'*.*'{$endif}, directory, F)=0 then
 repeat
  if f.name[1]='.' then continue;
  if (not all) and ((f.attr and hidden)<>0)or((f.attr and sysfile)<>0) then Continue;
  if (f.attr and directory) <>0  then
                                 begin
                                 Inc(Count);
                                 f.name:=percorso+f.name;
                                 nome_corto:=f.name;
                                 GetshortName(nome_corto);
                                 A[count]:='D'+nameof(nome_corto);
                                 end;
 until (FindNext(F)<>0) or (Count >= Maxx);
FindClose(F);
if count<maxx then
              begin
              inc(count);
              A[count]:='D.';
              end
             else A[1]:='D.';
if not ( (length(percorso)=3)and(percorso[3]='\')and(percorso[2]=':')and(UpCase(percorso[1]) in ['A'..'Z']) ) then
   if count<maxx then
                 begin
                 if (copy(percorso,1,2)='\\') then
                    if conta('\',copy_end(percorso,3),1,true)<=2 then Exit;
                 inc(count);
                 A[count]:='D..';
                 end
                else A[2]:='D..';
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

procedure YellowZona;
var str:string[14];
begin
str:=copy(copy_end(A[iesimo],2),1,12);
if A[iesimo][1]='D' then str:=str+pathdelim;
while length(str)<13 do str:=str+' ';
{$ifdef TxtCrt}
textbackground(3);
textcolor(yellow);
gotoxy(X+4,Y+5+selezionato);
write(str);
{$endif}
{$ifdef TxtVideo}
outtextxy(x+3,y+4+selezionato,str,255,3,yellow);
{$endif}
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

procedure NonTrovato;
begin
textcolor(white);
textbackground(3);
gotoxy(x+20,y+17);
case DosError of    // *** i messaggi non saranno visibili
     3:    write('Percorso non trovato.');
     2,18: write('File non trovato.');
     end;
{$ifdef TxtCrt}
sound(300);
delay2(0);
nosound;
{$endif}
Tast_Vuota;
end;


{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

procedure BarraV(const topo:boolean; var pos_barraV:byte);
var i:word;
    old_pos_barraV:byte;
begin
if topo then HideMouse;
i:=count div (righe-2);
if i<>0 then i:=iesimo div i;
i:=i+2;
if i>righe then i:=byte(righe);
if iesimo=1 then i:=2;
old_pos_barraV:=pos_barraV;
if Y+5+i<>old_pos_barraV then
        begin
        pos_barrav:=Y+5+i;
        {$ifdef TxtCrt}
        gotoxy(X+18,Y+7);
        for i:=2 to righe do
            begin
            write(c_B);  // '±'
            gotoxy(X+18,wherey+1);
            end;
        gotoxy(X+18,pos_barraV);
        textbackground(black+7);
        textcolor(black);
        write(c_S);   // #9
        {$endif}
        {$ifdef TxtVideo}
        for i:=0 to righe-2 do outtextxy(x+17,y+6+i,c_B,255,3,white);  // '±'
        outtextxy(x+17,pos_barrav-1,c_S,255,black+7,black);   // #9
        updatescreen(false);
        {$endif}
        end;
if topo then showmouse;
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

procedure Dettagli(const topo:boolean; var pos_barraV:byte; const ifiles:string; data,ora,attributi:string);
var dt : DateTime;      {UnpackTime }
    F: TSearchRec;
    nome,str2:shortstring;
    str:string;
    skip_:boolean;
    {$ifdef TxtCrt}
    i:byte;
    {$endif}
{$ifndef Linux} label skip; {$endif}
begin
skip_:=false;
data:=copy_end(data,2);
ora:=copy_end(ora,2);
attributi:=copy_end(attributi,2);
{$ifdef Linux}
nome:=PathOf(percorso)+nomefile;
{$else}
if (length(nomefile)=2)and(nomefile[1] in ['A'..'Z'])and(nomefile[2]=':')
   then
    begin
    nome:=nomefile+pathdelim;
    f.time:=0;
    f.attr:=directory;
    f.size:=0;
    doserror:=0;
    skip_:=true;
    goto skip;
    end
   else nome:=PathOf(percorso)+nomefile;
{$endif}

GetshortName(nome);
if FindFirst(nome, Anyfile, F)=0  then DosError:=0
                                  else DosError:=1;
if (DosError<>0) or ( (nomefile='.') and {$ifdef Linux} (nome=pathdelim) {$else} (length(nome)=3) and (nome[2]=':') and ( upcase(nome[1]) in ['A'..'Z'] ) and (nome[3]=pathdelim) {$endif} ) then
                 begin
                 f.time:=0;
                 f.attr:=directory;
                 f.size:=0;
                 DosError:=0;
                 end;
FindClose(F);

{$ifndef Linux} skip: {$endif}
HideMouse;
cursoroff;
if DosError<>0 then NonTrovato;
{$ifdef TxtCrt}
if DosError=0 then if Char_VideoXY(x+20,y+17) in ['T',' '] then else
                      begin
                      textbackground(3);
                      gotoxy(x+20,y+17);
                      write('                     ');
                      end;
textbackground(3);
textcolor(blue);
gotoxy(X+10,Y+2);
if A[iesimo][1]<>'D' then
                      begin
                      str2:=nomefile;
                      GetLongName(str2);
                      nomefile:=NameOf(str2);
                      write(copy(nomefile,1,36));
                      end
                     else write(copy(nomefile+pathdelim+ifiles,1,36));
str:='';
for i:=wherex to X+45 do str:=str+' ';
write(str);
textcolor(0);
gotoxy(X+20,Y+8);
write(attributi);  // 'Attributi: '
{$endif}
{$ifdef TxtVideo}
if DosError=0 then
   if GetCharXY(x+19,y+16) in ['T',' '] then
           else outtextxy(x+19,y+16,'                     ',255,3,255);

if A[iesimo][1]<>'D' then
                      begin
                      str2:=nomefile;
                      GetLongName(str2);
                      nomefile:=NameOf(str2);
                      str:=(copy(nomefile,1,36))
                      end
                     else str:=copy(nomefile+pathdelim+ifiles,1,36);
while length(str)<36 do str:=str+' ';
outtextxy(x+9,y+1,str,255,3,blue);
outtextxy(x+19,y+7,attributi,255,3,0);  // 'Attributi: '
{$endif}
if DosError=0 then
   begin
   if (f.attr and archive)  <>0 then str:='A'     else str:='_';
   if (f.attr and readonly) <>0 then str:=str+'R' else str:=str+'_';
   if (f.attr and hidden)   <>0 then str:=str+'H' else str:=str+'_';
   if (f.attr and sysfile)  <>0 then str:=str+'S' else str:=str+'_';
   if (f.attr and directory)<>0 then str:=str+'D' else str:=str+'_';
   end
  else str:='???? ';
{$ifdef TxtCrt}
textcolor(white);
write(str);
textcolor(0);
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

gotoxy(X+20,Y+9);
write('Byte: ');
textcolor(white);
gotoxy(X+26,Y+9);
if DosError=0 then if (f.attr and directory)<>0 then write('_')
                                                else write(Dim_punto(f.size))
              else write('?');
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

UnpackTime(f.time,dt);
textcolor(0);
gotoxy(X+20,Y+10);
write(data);  // 'Data: '
textcolor(white);
if DosError=0 then
              begin
              str:='';
              if dt.day<10 then str:='0';
              str:=str+inttostr(dt.day)+'/';
              if dt.month<10 then str:=str+'0';
              str:=str+inttostr(dt.month)+'/';
              if dt.year<10 then str:=str+'0';
              str:=str+inttostr(dt.year);
              end
             else str:='??/??/????';
write(str);
gotoxy(X+20,Y+11);
textcolor(0);
write(ora);  // 'Ora : '
textcolor(white);
if DosError=0 then
   begin
   str:='';
   if dt.hour<10 then str:='0';
   str:=str+inttostr(dt.hour)+':';
   if dt.min<10 then str:=str+'0';
   str:=str+inttostr(dt.min)+':';
   if dt.sec<10 then str:=str+'0';
   str:=str+inttostr(dt.sec);
   end
  else str:='??:??:??';
write(str);

gotoxy(X+20,Y+12);
textcolor(0);
write('LFN : ');
if not skip_ then nome:=fexpand2(nome);
if not skip_ then GetLongName(nome);
textcolor(white);
gotoxy(X+26,Y+12);
write(copy(nome,1,23));
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

gotoxy(X+20,Y+13);
write(copy(nome,24,29));
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

gotoxy(X+20,Y+14);
write(copy(nome,53,29));
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

gotoxy(X+20,Y+15);
write(copy(nome,82,29));
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

gotoxy(X+20,Y+16);
write(copy(nome,111,29));
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

gotoxy(X+20,Y+17);
write(copy(nome,140,29));
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

gotoxy(X+20,Y+18);
write(copy(nome,169,29));
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

gotoxy(X+20,Y+19);
write(copy(nome,198,29));
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);

gotoxy(X+20,Y+20);
write(copy(nome,227,29));
str:='';
for i:=wherex to X+49 do str:=str+' ';
write(str);
{$endif}
{$ifdef TxtVideo}
outtextxy(x+19+length(attributi),y+7,str,255,3,white);
outtextxy(X+19,Y+8,'Byte: ',255,3,0);
outtextxy(X+25,Y+8,'                    ',255,3,white);
if DosError=0 then if (f.attr and directory)<>0 then outtextxy(X+25,Y+8,'_',255,3,white)
                                                else outtextxy(X+25,Y+8,Dim_punto(f.size),255,3,white)
              else outtextxy(X+25,Y+8,'?',255,3,white);
UnpackTime(f.time,dt);
outtextxy(X+19,Y+9,data,255,3,0); // 'Data: '
if DosError=0 then
              begin
              str:='';
              if dt.day<10 then str:='0';
              str:=str+inttostr(dt.day)+'/';
              if dt.month<10 then str:=str+'0';
              str:=str+inttostr(dt.month)+'/';
              if dt.year<10 then str:=str+'0';
              str:=str+inttostr(dt.year);
              end
             else str:='??/??/????';
outtextxy(X+19+length(data),Y+9,str,255,3,white);
outtextxy(X+19,Y+10,ora,255,3,0); // 'Ora : '
if DosError=0 then
   begin
   str:='';
   if dt.hour<10 then str:='0';
   str:=str+inttostr(dt.hour)+':';
   if dt.min<10 then str:=str+'0';
   str:=str+inttostr(dt.min)+':';
   if dt.sec<10 then str:=str+'0';
   str:=str+inttostr(dt.sec);
   end
  else str:='??:??:??';
outtextxy(x+19+length(ora),y+10,str,255,3,white);
WindowsStr(x+19,y+11,x+47,y+19,' ',255,3,white);
outtextxy(X+19,Y+11,'LFN : ',255,3,0);
if not skip_ then nome:=fexpand2(nome);
if not skip_ then GetLongName(nome);
outtextxy(X+25,Y+11,copy(nome,1,23),255,3,white);
outtextxy(X+19,Y+12,copy(nome,24,29),255,3,white);
outtextxy(X+19,Y+13,copy(nome,53,29),255,3,white);
outtextxy(X+19,Y+14,copy(nome,82,29),255,3,white);
outtextxy(X+19,Y+15,copy(nome,111,29),255,3,white);
outtextxy(X+19,Y+16,copy(nome,140,29),255,3,white);
outtextxy(X+19,Y+17,copy(nome,169,29),255,3,white);
outtextxy(X+19,Y+18,copy(nome,198,29),255,3,white);
outtextxy(X+19,Y+19,copy(nome,227,29),255,3,white);
updatescreen(false);
{$endif}
cursoron;
if topo then showmouse;
BarraV(topo,pos_barraV);
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

procedure Mostra(primo:word);
var s:string;
    i:word;
begin
{$ifdef TxtCrt}
textbackground(3);  {*** la stampa}
textcolor(blue);
{$endif}
for i:=primo to righe+primo do
    begin
    if i<=count then
                begin
                s:=copy(copy_end(A[i],2),1,12);
                if A[i][1]='D' then s:=s+pathdelim;
                end
               else s:='            ';
    while length(s)<13 do s:=s+' ';
    {$ifdef TxtCrt}
    gotoxy(X+4,Y+i+1-primo+5);
    write(s);
    {$endif}
    {$ifdef TxtVideo}
    outtextxy(X+3,Y+i-primo+5,s,255,3,blue);
    {$endif}
    end;
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

procedure GreenZona(const topo:boolean);   {*** da aggiornare quello selezionato}
var str:string;
    i:byte;
begin
str:=copy(copy_end(A[iesimo],2),1,12);
if A[iesimo][1]='D' then str:=str+pathdelim;
for i:=length(str) to 12 do str:=str+' ';
nomefile:=copy_end(A[iesimo],2);
gotoxy(X+4,Y+selezionato+5);
if topo then hidemouse;
{$ifdef TxtCrt}
textbackground(green);
textcolor(white);
write(str);
{$endif}
{$ifdef TxtVideo}
outtextxy(X+3,Y+selezionato+4,str,255,green,white);
updatescreen(false);
{$endif}
showmouse;
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

function Sfoglia(files:boolean; XX,YY:byte; all,ordina,topo,mancino:boolean; testo,percorso_:string; var ifiles:string;
         CD,num_righe:longint; nome,lista,elementi,data,ora,attributi,Ricerca_files:string; nome_char,lista_char:char):string;
var stato:byte;  {0= Nome | 1= Lista | 2= OK | 3= ESCI}  { CD= click delay}
    i,primo:word;
    mox,moy,tasto,posto,pos_barraV,ii,iii,x_:byte;
    c,str,stringa{$ifndef Linux},lettere_unita_{$endif}:string;
    str2:shortstring;
    scrivo:tipo1;
    cliccato,insert:boolean;
    Doppio_Click:More_Click;

label next2,next,restart,escoReadStr,readStr,giu,iniziocase,alt_l,shift_tab,shift_tab_2;
begin
InitKeyboard;
initvideo;
Doppio_Click.init;
Doppio_Click.set_mancino(mancino);
Doppio_Click.Set_Num_Click_Max(3);
righe:=num_righe;
if righe<20 then righe:=20
            else if righe>20 then dec(righe);
if righe>ScreenHeight-YY then righe:=ScreenHeight-YY;
if righe=0 then runerror(0); // bisogna fare prima: initvideo
righe:=righe-8;  // numero di righe riservate alla lista dei files (minimo=21-8=13)
if cd>100 then cd:=100;
percorso:=percorso_;
if pos(pathdelim,ifiles)<>0 then Exit('');
insert:=false;
stato:=0;
scrivo:='';
if XX>31 then XX:=31;
if XX=0  then XX:=1;
if YY>5 then YY:=5;
if YY=0 then YY:=1;
X:=XX;
Y:=YY;
if length(testo)>49 then setlength(testo,49);
hidemouse;
restart:

percorso:=fexpand2(percorso);
{$I-}
chdir(percorso);
{$I-}
if IOResult<>0 then;
if percorso[length(percorso)]<>pathdelim then percorso:=percorso+pathdelim;
Count:=0;
pos_barraV:=0;
{$ifdef TxtCrt}
gotoxy(X,Y);
textbackground(white);
str:='';
for ii:=1 to 50 do str:=str+' ';
write(str);
textcolor(black);
gotoxy(25+X-(length(testo)div 2),Y);
write(testo);
textbackground(3);
for ii:=Y+1 to Y+righe+8 do
    begin
    gotoxy(X,ii);
    write(str);
    end;
gotoxy(X,Y+2);
write(nome+'[                                    ]');
gotoxy(X+pos(nome_char,nome)-1,Y+2);
textcolor(white);
write(nome_char);  //'N'
gotoxy(X+3,Y+4);
write(lista_char); // 'L'
textcolor(black);
gotoxy(X+4,Y+4);
write(copy_end(lista,2));  // 'ista:'
if files then
   begin
   gotoxy(X+3,Y+righe+8);
   write('File:');
   end;
gotoxy(X+3,Y+5);
write(c_UL1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_UR1);   // 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿'
for i:=1 to righe+1 do
    begin
    gotoxy(x+3,y+5+i);
    write(c_U1);  // '³'
    end;
for i:=1 to righe do
    begin
    gotoxy(x+18,y+5+i);
    write(c_B);   //  '±'
    end;
gotoxy(X+3,Y+righe+7);
write(c_DL1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_DR1);   // 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ'
textbackground(3);
textcolor(white);
gotoxy(X+9,Y+righe+8);
if files then
   if length(ifiles)<10 then write(Copy(ifiles,1,9)+'             ')
                        else write(Copy(ifiles,1,6)+'...             ');
gotoxy(X+18,Y+6);
write(c_FU);   // #24
gotoxy(X+18,Y+righe+6);
write(c_FD);   // #25
textbackground(lightgreen);
gotoxy(X+24,Y+6);
write('   Ok   ');
gotoxy(X+37,Y+6);
write('  Esc   ');              {grafica finita}
{$endif}
{$ifdef TxtVideo}
outtextxy(x-1,y-1,' ',255,7,black,50);
ForceUpdateXY(24+X-(length(testo)div 2),Y-1,length(testo)); // ver 3.40
outtextxy(24+X-(length(testo)div 2),Y-1,testo,255,7,black);
for ii:=Y+1 to Y+num_righe do
                    begin
                    ForceUpdateXY(x-1,ii-1,50);
                    outtextxy(x-1,ii-1,' ',255,3,black,50);
                    end;
outtextxy(x-1,y+1,nome+'[                                    ]',255,255,255);
outtextxy(x-1-1+pos(nome_char,nome),y+1,nome_char{'N'},255,255,white);
outtextxy(x+2,y+3,lista,255,255,black);
outtextxy(x+2-1+pos(lista_char,lista),y+3,lista_char{'L'},255,255,white);

if files then outtextxy(x+2,y+righe+7,'File:');
outtextxy(x+2,y+4,c_UL1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_UR1);   // 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿'
for i:=1 to righe+1 do outtextxy(x+2,y+4+i,c_U1);  // '³'
for i:=1 to righe+1 do outtextxy(x+17,y+4+i,c_B,255,255,white);   //  '±'
outtextxy(x+2,y+righe+6,c_DL1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_D1+c_DR1);  // 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ'
if files then
   if length(ifiles)<10 then outtextxy(x+8,y+righe+7,Copy(ifiles,1,9)+'             ',255,3,white)
                        else outtextxy(x+8,y+righe+7,Copy(ifiles,1,6)+'...             ',255,3,white);
outtextxy(x+17,y+5,c_FU,255,3,white);  // #24
outtextxy(x+17,y+righe+5,c_FD,255,3,white);  // #25
outtextxy(x+23,y+5,'   Ok   ',255,2,white);
outtextxy(x+36,y+5,'  Esc   ',255,2,white);          {grafica finita}
{$endif}

c:=#1;                          {inizializzo e cerco}
nomefile:=NameOf(ifiles);
iesimo:=1;  {a cui punta}
primo:=1;   {in alto}
selezionato:=1;

{$ifdef TxtCrt}
textbackground(11);
gotoxy(X+22,y+12);
write(Ricerca_files+#8);  // si pulisce da solo con NFL // 'Ricerca files in corso... '
{$endif}
{$ifdef TxtVideo}
outtextxy(x+21,y+11,Ricerca_files,255,255,white);  // si pulisce da solo con NFL // 'Ricerca files in corso... '
setCursorpos(x+21+length(Ricerca_files),y+11);
updatescreen(false);
{$endif}

FindAllFiles(not files,percorso,ifiles,all);
if ordina then
          begin
          app:=CercaFile('.');
          A[app]:=A[1];
          A[1]:='D.';
          app:=CercaFile('..');
          if app>0 then
                   begin
                   A[app]:=A[2];
                   A[2]:='D..';
                   QuickSort(A,3,count);
                   end
                  else QuickSort(A,2,count); {era la root: non ha radice}
          end;
{$ifndef Linux}
// if (length(percorso)=3)and(percorso[1] in ['A'..'Z'])and(percorso[2]=':')and(percorso[3]=pathdelim) then
    begin
    lettere_unita_:=lettere_unita;
    for i:=1 to length(lettere_unita_) do
          begin
          if count>=maxx then break;
          count:=count+1;
          A[count]:='D'+lettere_unita_[i]+':';
          end;
    end;
{$endif}
for i:=count+1 to maxx do A[i]:='';
posto:=length(A[1]);
x_:=posto;
{$ifdef TxtCrt}
gotoxy(X+19,Y+4);
textcolor(white);
textbackground(3);
write(dim_punto(count));
textcolor(black);
write(elementi);  // ' elementi trovati     '
{$endif}
{$ifdef TxtVideo}
outtextxy(x+18,y+3,dim_punto(count),255,255,white);
outtextxy(x+18+length(dim_punto(count)),y+3,elementi,255,255,black); // ' elementi trovati     '
updatescreen(false);
{$endif}

if count=maxx then
   begin
   if (length(percorso)>3)and(a[1]<>'D.') then
      begin
      a[1]:='D.';
      a[2]:='D..';
      end;
   {$ifdef TxtCrt}
   textcolor(white);
   textbackground(3);
   gotoxy(x+20,y+9);
   write('Troppi files nella directory:');
   gotoxy(x+20,y+10);
   write('ve ne sono piu'' di ',dim_punto(maxx));
   gotoxy(x+20,y+12);
   write('Alcuni non postranno essere');
   gotoxy(x+20,y+13);
   write('visualizzati.');
   gotoxy(x+20,y+15);
   write('Premere su  OK  o  ESC');
   gotoxy(x+20,y+16);
   write('per continuare ... ');
   gotoxy(wherex-1,wherey);
   {$endif}
   {$ifdef TxtVideo}
   outtextxy(x+19,y+8,'Troppi files nella directory:',255,255,white);
   outtextxy(x+19,y+9,'ve ne sono piu'' di '+dim_punto(maxx),255,255,white);
   outtextxy(x+19,y+11,'Alcuni non postranno essere',255,255,white);
   outtextxy(x+19,y+12,'visualizzati.',255,255,white);
   outtextxy(x+19,y+14,'Premere su  OK  o  ESC',255,255,white);
   outtextxy(x+19,y+15,'per continuare ... ',255,255,white);
   setcursorpos(x+37,y+15);
   updatescreen(false);
   {$endif}
   sound(300);
   delay2(0);
   nosound;
   if topo then showMouse;
   Tast_Vuota;
   repeat
    if (PollKeyEvent<>0) or (not topo) then
                   begin
                   c:=KeyEventToString(TranslateKeyEvent(GetKeyEvent));
                   if (c=#13)or(c=#27)or(c=#32) then Break;
                   end
                  else // topo==true
                   begin
                   Sleep(5);
                   {$ifdef Go32v2}
                    cliccato:=Doppio_Click.Mouse_Up(mox,moy,stato);
                   {$else}
                    cliccato:=Doppio_Click.Mouse_Down(mox,moy,stato);
                   {$endif}
                   if cliccato then tasto:=1
                               else tasto:=0;
                   if (tasto=1)and(moy=Y+6)and(mox>X+23)and(mox<X+32) then Break; {OK}
                   if (tasto=1)and(moy=Y+6)and(mox>X+36)and(mox<X+45) then Break; {ESCI}
                   end;
   until false;
   end;
hidemouse;
Mostra(primo);
showmouse;
nomefile:=Copy_end(A[1],2);  {serve solo per dettagli della riga successiva}
Dettagli(topo,pos_barraV,ifiles,data,ora,attributi);
nomefile:=NameOf(ifiles);
GreenZona(topo);
gotoxy(X+4,Y+selezionato+5);
repeat
if stato=0 then
           begin
           YellowZona;
           {$ifdef TxtCrt}
           textbackground(green);
           gotoxy(X+24,Y+6);
           write(' ');
           gotoxy(X+31,Y+6);
           write(' ');
           gotoxy(X+37,Y+6);
           write(' ');
           gotoxy(X+44,Y+6);
           write(' ');
           gotoxy(x+10,y+2);
           textbackground(3);
           textcolor(blue);
           {$endif}
           {$ifdef TxtVideo}
           outtextxy(X+23,Y+5,' ',255,green,255);
           outtextxy(X+30,Y+5,' ',255,green,255);
           outtextxy(X+36,Y+5,' ',255,green,255);
           outtextxy(X+43,Y+5,' ',255,green,255);
           setcursorpos(x+9,y+1);
           updatescreen(false);
           textbackground(3);
           textcolor(blue);
           {$endif}
           readStr:
           scrivo:='';
           showmouse;
           if insert then CursorBig else cursorOn;
           posto:=byte(max(mox-x-9,1));
           x_:=posto;
           stringa:=nomefile;
           if A[iesimo][1]='D' then
                      begin
                      nomefile:=ReadString2(nomefile+pathdelim+ifiles,X+10,X+46,0,topo,true,mancino,false,insert,moy,mox,posto,x_);
                      if (not files)and(mox=13)and(moy=0) then exit(fexpand2(nomefile)); // ver 3.40
                      end
                      else nomefile:=ReadString2(nomefile,X+10,X+46,0,topo,true,mancino,false,insert,moy,mox,posto,x_);
           if (nomefile='') and
              ( ((mox=13)and(moy=0)) or ((moy=Y+6)and(mox>X+23)and(mox<X+32)) ) then
                           begin
                           nomefile:=stringa;
                           goto readStr;
                           end;
           {$ifndef Linux}
           if (upcase(percorso[1]) in ['A'..'Z']) and (percorso[2]=':') and
              (percorso[3]=pathdelim) and (nomefile=pathdelim) then
              begin
              percorso:=percorso[1]+':'+pathdelim;
              goto restart;
              end;
           if (exist(ExpandEnvironment(percorso+nomefile))>-1) or isdir(ExpandEnvironment(percorso+nomefile)) then
                                                                                                              else nomefile:=fexpand2(nomefile);
           {$endif}
           cursoron;
           if (mox=27)and(moy=0) then Exit(''); {ESC 2 volte esce totalmente}
           if (mox=13)and(moy=0) then       {INVIO}
               begin
               next:  {emula INVIO quando si preme su OK}
               stringa:=fExpand2(percorso+nomefile); {'\\' finali deve dare la root}
               {$ifndef Linux}
               if (stringa[length(stringa)]=pathdelim)and(length(stringa)>1)and
                  (stringa[length(stringa)-1]=pathdelim) then stringa:=Copy(stringa,1,2)+pathdelim; {U:\}
               {$endif}
               if nomefile='.' then
                               begin
                               showMouse;
                               Continue;
                               end;
               ii:=byte(pos('*',nomefile));
               if ii=0 then ii:=255;
               iii:=byte(pos('?',nomefile));
               if iii=0 then iii:=255;
               ii:=byte(Trunc(min(ii,iii)));
               if posrl(pathdelim,nomefile,length(nomefile))<ii then
               if (pos('*',nomefile)>0)or(pos('?',nomefile)>0) then {l'input era una directory + files}
                   begin
                   stato:=0;
                   if (Copy(nomefile,2,1)=':')or(Copy(nomefile,1,1)=pathdelim) then
                                                                               else nomefile:=fexpand2(percorso+nomefile);
                   percorso:=copy(nomefile,1,posrl(pathdelim,nomefile,255));
                   ifiles:=copy_end(nomefile,posrl(pathdelim,nomefile,length(nomefile))+1);
                   goto restart;
                   end;
               if posrl(pathdelim,nomefile,length(nomefile))>ii then Exit(fExpand2(nomefile));
               if Exist(stringa)>=0 then Exit(fExpand2(stringa)); {era un file}
               if isDir(stringa) then  {era una directory}
                  begin
                  stato:=1;
                  percorso:=stringa;
                  goto restart;
                  end;
               stringa:=fExpand2(nomefile);
               if Exist(stringa)>=0 then Exit(fExpand2(stringa)); {l'input era un file}
               if isDir(stringa) then  {l'input era una directory}
                  begin
                  stato:=1;
                  percorso:=stringa;
                  goto restart;
                  end;
               {$ifndef Linux}
               if (Copy(nomefile,2,1)=':')or(Copy(nomefile,1,1)=pathdelim) then
                   Sfoglia:=fExpand2(nomefile)
                  else
                   Sfoglia:=fExpand2(percorso+nomefile);
               {$else}
                Sfoglia:=fExpand2(percorso+nomefile);
               {$endif}
               Exit;  {qualunque cosa sia, esce: potrebbe crearla (salva) }
               end;
           if ( (mox=9)or(mox=7) ) and(moy=0) then       {TAB}
              begin
              stato:=1;
              GreenZona(topo);
              {$ifdef TxtCrt}
              textbackground(3);           {aggiorno il readstring}
              textcolor(blue);
              gotoxy(X+9,Y+2);
              if A[iesimo][1]<>'D' then
                                    begin
                                    str2:=nomefile;
                                    GetLongName(str2);
                                    nomefile:=NameOf(str2);
                                    write(copy('['+nomefile,1,36));
                                    end
                                   else write(copy('['+nomefile+pathdelim+ifiles,1,36));
              str:='';
              for i:=wherex to X+45 do str:=str+' ';
              write(str+']');
              {$endif}
              {$ifdef TxtVideo}                   {aggiorno il readstring}
              if A[iesimo][1]<>'D' then
                                    begin
                                    str2:=nomefile;
                                    GetLongName(str2);
                                    nomefile:=NameOf(str2);
                                    str:='['+copy(nomefile,1,36);
                                    end
                                   else str:='['+copy(nomefile+pathdelim+ifiles,1,36);
              while length(str)<>37 do str:=str+' ';
              outtextxy(x+8,y+1,str+']',255,3,blue);
              updatescreen(true);
              {$endif}
              gotoxy(X+4,Y+selezionato+5);
              showmouse;
              if (mox=7)and(moy=0) then       {shift+TAB}
                   begin
                   stato:=3;
                   goto shift_tab;
                   end;
              end;
           if (moy=255)and(mox=byte(lista_char){76}) then
              begin               {ALT + L}
   ALT_L:
              stato:=1;
              GreenZona(topo);
              c:=#1;
              {$ifdef TxtCrt}
              textbackground(3);
              textcolor(blue);
              gotoxy(X+9,Y+2);
              write('['+copy(nomefile,1,36));
              str:='';
              for i:=wherex to X+45 do str:=str+' ';
              write(str+']');
              gotoxy(X+4,Y+selezionato+5);
              {$endif}
              {$ifdef TxtVideo}
              str:='['+copy(nomefile,1,36);
              while length(str)<>37 do str:=str+' ';
              outtextxy(X+8,Y+1,str+']',255,3,blue);
              updatescreen(false);
              {$endif}
              end;
           if  ( (mox=X+18)and(moy>Y+5)and(moy<=Y+6+righe)and(count>righe) )or
               ( (mox>X+3)and(mox<X+17)and(moy>Y+5)and(moy<=Y+righe+6) ) then
                             goto next2;   {area lista files e freccine}
           if (moy>0)and(moy<26) then {mouse che clicca fuori da readstring}
              begin
              tasto:=1;
              goto escoReadStr;
              end;
           end;
if (PollKeyEvent<>0) or (not topo) then
               c:=KeyEventToString(TranslateKeyEvent(GetKeyEvent))
              else
               begin
               Sleep(5);
               {$ifdef Go32v2}
               cliccato:=Doppio_Click.Mouse_Up(mox,moy,tasto);
               if cliccato then tasto:=1
                           else tasto:=0;
               {$endif}
               escoReadStr:
               if tasto=1 then
                  begin
                  if (moy=Y+6)and(mox>X+36)and(mox<X+45) then Exit(''); {ESCI}
                  if (moy=Y+6)and(mox>X+23)and(mox<X+32) then  {OK}
                     case stato of
                        1,2: begin
                             if (not files)and(stato=1) then exit(fexpand2(nomefile)); // ver 3.40
                             c:=#13;
                             stato:=1;
                             cursoron;
                             end;
                          3: begin
                             {$ifdef TxtCrt}
                             gotoxy(X+37,Y+6);
                             write(' ');
                             gotoxy(X+44,Y+6);
                             write(' ');
                             {$endif}
                             {$ifdef TxtVideo}
                             outtextxy(x+36,y+5,' ');
                             outtextxy(x+43,y+5,' ');
                             updatescreen(false);
                             {$endif}
                             GreenZona(topo);
                             gotoxy(X+4,Y+selezionato+5);
                             c:=#13;
                             stato:=1;
                             cursoron;
                             end;
                          0: goto Next;
                          end; {del case}
                  end;
               if Doppio_Click.More_Click(2) then
                       begin
                       tasto:=1;
                       Doppio_Click.empty_mouse;
                       end
                      else tasto:=0;
               if (tasto=1)and(stato=1)and(count>0)and(selezionato=moy-Y-5)and
                  (mox>X+2)and(mox<X+17) then goto next;
               cliccato:=Doppio_Click.Mouse_down(mox,moy,tasto);
               if cliccato then tasto:=1
                           else tasto:=0;
               if tasto=1 then      {Gestione mouse}
                  begin
                  Next2: {esce da readstring e controlla area file e freccine}
                  if (moy=Y+2)and(mox>X+9)and(mox<X+46) then
                     begin
                     stato:=0;
                     Continue;            {ritorna al readstring}
                     end;
                  if (mox=X+18) and (moy=Y+6) then  {freccina alta}
                                              begin
                                              stato:=1;
                                              c:='Up';  // #72;
                                              Doppio_Click.Empty_Mouse;
                                              delay2(CD);
                                              goto iniziocase;
                                              end;
                  if (mox=X+18) and (moy=Y+righe+6) then {freccina bassa}
                                              begin
                                              stato:=1;
                                              c:='Down';  // #80;
                                              Doppio_Click.Empty_Mouse;
                                              delay2(CD);
                                              goto iniziocase;
                                              end;
                  if (mox=X+18)and(moy>Y+6)and(moy<=Y+righe+6)and(count>righe-8) then
                     begin  {barra}
                     stato:=1;
                     i:=count div (righe-2);
                     if i<>0 then i:=iesimo div i;
                     i:=i+2;
                     if i>righe then i:=byte(righe);
                     if iesimo=1 then i:=2;
                     if i+y+5<>moy then
                        begin
                        iesimo:=(count div (righe-2))*(moy-7-y)+2;
                        primo:=iesimo;
                        posto:=length(A[iesimo]);
                        selezionato:=1;
                        mostra(primo);
                        dettagli(topo,pos_barraV,ifiles,data,ora,attributi);
                        c:='Up';  // #72;
                        goto iniziocase;
                        end;
                     end;
                  if (mox>X+3)and(mox<X+17)and(moy>Y+5)and(moy<=Y+righe+6) then
                     if (count>0) then
                        begin {file selezionato}
                        if stato<>1 then
                                    begin
                                    {$ifdef TxtCrt}
                                    textbackground(green);
                                    gotoxy(X+24,Y+6);
                                    write(' ');
                                    gotoxy(X+31,Y+6);
                                    write(' ');
                                    gotoxy(X+37,Y+6);
                                    write(' ');
                                    gotoxy(X+44,Y+6);
                                    write(' ');
                                    {$endif}
                                    {$ifdef TxtVideo}
                                    outtextxy(x+23,y+5,' ',255,green,255);
                                    outtextxy(x+30,y+5,' ',255,green,255);
                                    outtextxy(x+36,y+5,' ',255,green,255);
                                    outtextxy(x+43,y+5,' ',255,green,255);
                                    updatescreen(false);
                                    {$endif}
                                    end;
                        cursoron;
                        ii:=moy-Y-5;
                        if (selezionato=ii)and(stato=1) then Continue;
                        stato:=1;
                        if selezionato>ii then   {verso sopra}
                               begin
                               str:=copy(copy(A[iesimo],2,255),1,12);
                               if A[iesimo][1]='D' then str:=str+pathdelim;
                               while length(str)<13 do str:=str+' ';
                               {$ifdef TxtCrt}
                               textbackground(3);    {*** da aggiornare quello selezionato precedentemente}
                               textcolor(blue);
                               gotoxy(X+4,Y+selezionato+5);
                               write(str);
                               {$endif}
                               {$ifdef TxtVideo}          {*** da aggiornare quello selezionato precedentemente}
                               outtextxy(X+3,Y+selezionato+4,str,255,3,blue);
                               updatescreen(false);
                               {$endif}
                               iesimo:=iesimo-(selezionato-ii);
                               posto:=length(A[iesimo]);
                               selezionato:=ii;
                               end
                              else if count<>iesimo then
                               begin  {verso sotto}  {*** da aggiornare quello selezionato precedentemente}
                               str:=copy(copy(A[iesimo],2,255),1,12);
                               if A[iesimo][1]='D' then str:=str+pathdelim;
                               while length(str)<13 do str:=str+' ';
                               {$ifdef TxtCrt}
                               textbackground(3);
                               textcolor(blue);
                               gotoxy(X+4,Y+selezionato+5);  {*** da aggiornare quello selezionato}
                               write(str);
                               {$endif}
                               {$ifdef TxtVideo}                  {*** da aggiornare quello selezionato}
                               outtextxy(X+3,Y+selezionato+4,str,255,3,blue);
                               updatescreen(false);
                               {$endif}
                               if count-primo>=ii then
                                                  begin
                                                  selezionato:=ii;
                                                  iesimo:=primo+selezionato-1;
                                                  end
                                                 else
                                                  begin
                                                  selezionato:=count-primo+1;
                                                  iesimo:=count;
                                                  end;
                               posto:=length(A[iesimo]);
                               end;
                        GreenZona(topo);
                        Dettagli(topo,pos_barraV,ifiles,data,ora,attributi);
                        gotoxy(X+4,Y+selezionato+5);
                        end;
                  end;
               if stato=0 then
                          begin
                          nomefile:=stringa;
                          goto readStr;
                          end;
               end;
iniziocase:
if ( stato in [1..3] ) and (from_alt_to_char(c)=nome_char{'N'}) then  { ALT + N }
           begin
           stato:=0;
           c:=#1;  // serve per rendere non valido il carattere da aggiungere a SCRIVO (cioe' non verra' aggiunto)
           Continue;
           end;
if  ( ( (stato=2) or (stato=3) ) and ((from_alt_to_char(c)=lista_char{'L'})) )
    or ( (stato=2) and ( (c='Left') or (c='Up') ) ) then
                 begin { ALT + L }
                 {$ifdef TxtCrt}
                 if stato=2 then gotoxy(X+24,Y+6)
                            else gotoxy(X+37,Y+6);
                 write(' ');
                 if stato=2 then gotoxy(X+31,Y+6)
                            else gotoxy(X+44,Y+6);
                 write(' ');
                 {$endif}
                 {$ifdef TxtVideo}
                 if stato=2 then outtextxy(X+23,Y+5,' ')
                            else outtextxy(X+36,Y+5,' ');
                 if stato=2 then outtextxy(X+30,Y+5,' ')
                            else outtextxy(X+43,Y+5,' ');
                 updatescreen(false);
                 {$endif}
                 cursorOn;
                 moy:=255;
                 goto ALT_L;
                 end;
if (count>0)and(stato=1) then
        if c='Home' then
                    begin
                    scrivo:='';
                    if iesimo>1 then     { inizio #71 }
                             begin
                             iesimo:=1;
                             primo:=1;
                             selezionato:=1;
                             Mostra(primo);
                             GreenZona(topo);
                             Dettagli(topo,pos_barraV,ifiles,data,ora,attributi);
                             gotoxy(X+4,Y+6);
                             posto:=length(A[iesimo]);
                             end;
                    end else
        if c='End' then
                   begin
                   scrivo:='';
                   if iesimo<count then     { fine #79 }
                      begin
                      iesimo:=count;
                      primo:=(count div righe) *righe +1;
                      selezionato:=count mod righe;
                      if selezionato=0 then
                                     begin
                                     selezionato:=byte(righe);
                                     primo:=primo-righe;
                                     end;
                      Mostra(primo);
                      GreenZona(topo);
                      Dettagli(topo,pos_barraV,ifiles,data,ora,attributi);
                      gotoxy(X+4,Y+selezionato+5);
                      posto:=length(A[iesimo]);
                      end;
                   end else
        if (c='PgDn')or(c='Right') then
                begin
                scrivo:='';
                if (iesimo<count-(righe-1))and(count>righe) then  { pag giu' | destra : #81,#77 }
                    begin
                    iesimo:=iesimo+righe;
                    primo:=primo+righe;
                    if iesimo>count then iesimo:=count;
                    if primo>count then
                                begin
                                selezionato:=selezionato-(count-primo)-1;
                                primo:=count;
                                end;
                    Mostra(primo);
                    dec(iesimo);
                    dec(selezionato);
                    posto:=length(A[iesimo]);
                    goto giu;
                    end
                   else
                    begin
                    c:='End';  // #79
                    goto iniziocase;
                    end;
                end else
        if (c='Down') then
               begin
               scrivo:='';
               if iesimo<count then  { giu' #80 }
                    begin                             Giu:
                    inc(iesimo);
                    if selezionato<righe+1 then inc(selezionato)
                                     else
                                      begin
                                      inc(primo);
                                      Mostra(primo);
                                      end;
                    GreenZona(topo);
                    if whereY>y+6 then
                       begin     {*** da aggiornare quello selezionato precedentemente}
                       str:=copy(copy(A[iesimo-1],2,255),1,12);
                       if A[iesimo-1][1]='D' then str:=str+pathdelim;
                       while length(str)<13 do str:=str+' ';
                       {$ifdef TxtCrt}
                       gotoxy(X+4,Y+selezionato+4);
                       textbackground(3);
                       textcolor(blue);
                       write(str);
                       {$endif}
                       {$ifdef TxtVideo}
                       outtextxy(X+3,Y+selezionato+3,str,255,3,blue);
                       updatescreen(false);
                       {$endif}
                       posto:=length(A[iesimo]);
                       end;
                    Dettagli(topo,pos_barraV,ifiles,data,ora,attributi);
                    gotoxy(X+4,Y+selezionato+5);
                    end;
               end else
        if (c='Up') then
                    begin
                    scrivo:='';
                    if iesimo>1 then   { su #72 }
                       begin
                       dec(iesimo);
                       if selezionato>1 then dec(selezionato)
                                        else
                                         begin
                                         dec(primo);
                                         Mostra(primo);
                                         end;
                       GreenZona(topo);
                       str:=copy(copy_end(A[iesimo+1],2),1,12);
                       if A[iesimo+1][1]='D' then str:=str+pathdelim;
                       while length(str)<13 do str:=str+' ';
                       {$ifdef TxtCrt}
                       gotoxy(X+4,Y+selezionato+6);
                       textbackground(3);    {*** da aggiornare quello selezionato precedentemente}
                       textcolor(blue);
                       write(str);
                       {$endif}
                       {$ifdef TxtVideo}          {*** da aggiornare quello selezionato precedentemente}
                       outtextxy(X+3,Y+selezionato+5,str,255,3,blue);
                       updatescreen(false);
                       {$endif}
                       Dettagli(topo,pos_barraV,ifiles,data,ora,attributi);
                       gotoxy(X+4,Y+selezionato+5);
                       posto:=length(A[iesimo]);
                       end;
                    end else
        if (c='PgUp')or(c='Left') then
                begin
                scrivo:='';
                if iesimo>righe then  { pag su | sinistra : # 73,#75}
                    begin
                    iesimo:=byte(max(iesimo-righe,0));
                    primo:=byte(max(primo-righe,0));
                    if iesimo<righe then
                                 begin
                                 selezionato:=byte(iesimo);
                                 primo:=1;
                                 end;
                    Mostra(primo);
                    dec(iesimo);
                    dec(selezionato);
                    if iesimo=0 then posto:=length(A[1])
                                else posto:=length(A[iesimo]);
                    goto giu;
                    end
                   else
                    begin
                    c:='Home';   // #71
                    goto iniziocase;
                    end;
                end;
if ( (stato=2)or(stato=3) ) and ( (c='Down')or(c='Right') ) then c:=#9;
if (stato=3) and (c='SHIFT Key with scancode 3840') then // da ESC ad OK premendo Shift+Tab
   begin
   stato:=1;
   c:=#9;
   end;
if (stato=1) and (c='SHIFT Key with scancode 3840') then // da ESC ad OK premendo Shift+Tab
   begin
   c:='';
   stato:=0;
   continue;
   end;
if (stato=3) and ( (c='Left') or (c='Up') ) then
   begin
   stato:=1;
   c:=#9;
   end;
if (stato=2)and(c='SHIFT Key with scancode 3840') then goto shift_tab_2;  // da OK a lista, premendo Shift+Tab
if (c=#13) then
           begin
           case stato of
                    3: Exit('');  {ESCI}
                  2,1: begin      {OK o selezionato}
                       if (not files)and(stato=2) then exit(fexpand2(nomefile)); // ver 3.40
                       if A[iesimo]='D.' then
                                         begin
                                         showmouse;
                                         c:=#1;
                                         Continue;
                                         end;
                       cursoron;
                       scrivo:='';
                       if Copy(A[iesimo],1,1)='D' then
                             begin
                             {$ifndef Linux}
                             if (length(nomefile)=2)and(nomefile[1] in ['A'..'Z'])and(nomefile[2]=':')
                                  then percorso:=nomefile+pathdelim
                                  else
                             {$endif}
                             if Copy_end(A[iesimo],2)='..' then
                                  begin
                                  i:=PosRL(pathdelim,percorso,length(percorso)-1);
                                  if i>0 then percorso:=Copy(percorso,1,i)
                                         else
                                          begin
                                          if topo then showmouse;
                                          c:=#1;
                                          Continue; {unita' Subst}
                                          end;
                                  end
                                 else percorso:=percorso+nomefile+pathdelim;
                             stato:=1;
                             goto restart;
                             end;
                       if Copy(A[iesimo],1,1)='f' then Exit(fExpand2(percorso+nomefile));
                       end;
                end;  {del case}
           end else
        if (c=#9) then
                  begin         {cambia stato con TAB}
                  inc(stato);
        shift_tab:
                  scrivo:='';
                  if stato>3 then stato:=0;
                  if (stato=3) then
                     begin
                     YellowZona;
                     cursoroff;
                     {$ifdef TxtCrt}
                     textbackground(green);
                     textcolor(white);
                     gotoxy(X+24,Y+6);
                     write(' ');
                     gotoxy(X+31,Y+6);
                     write(' ');
                     gotoxy(X+37,Y+6);
                     write('[');
                     gotoxy(X+44,Y+6);
                     write(']');
                     {$endif}
                     {$ifdef TxtVideo}
                     outtextxy(X+23,Y+5,' ',255,green,white);
                     outtextxy(X+30,Y+5,' ',255,green,white);
                     outtextxy(X+36,Y+5,'[',255,green,white);
                     outtextxy(X+43,Y+5,']',255,green,white);
                     updatescreen(false);
                     {$endif}
                     end;
                  if stato=2 then
                     begin
                     YellowZona;
                     cursoroff;
                     {$ifdef TxtCrt}
                     textbackground(green);
                     textcolor(white);
                     gotoxy(X+24,Y+6);
                     write('[');
                     gotoxy(X+31,Y+6);
                     write(']');
                     gotoxy(X+37,Y+6);
                     write(' ');
                     gotoxy(X+44,Y+6);
                     write(' ');
                     {$endif}
                     {$ifdef TxtVideo}
                     outtextxy(X+23,Y+5,'[',255,green,white);
                     outtextxy(X+30,Y+5,']',255,green,white);
                     outtextxy(X+36,Y+5,' ',255,green,white);
                     outtextxy(X+43,Y+5,' ',255,green,white);
                     updatescreen(false);
                     {$endif}
                     end;
                  if stato=1 then
                             begin
                             GreenZona(topo);
                             cursoron;
                             end;
                  if stato=0 then
                     begin
                     c:=#1;   {readstring}
                     Continue;
                     end;
                  end else
        if (c=#27) then Exit('') {tasto ESC}
                   else
        if (from_alt_to_char(c)=lista_char{'L'}) then   {ALT + L  LISTA}
                     begin
         shift_tab_2:
                     scrivo:='';
                     stato:=1;
                     {$ifdef TxtCrt}
                     textbackground(green);
                     gotoxy(X+24,Y+6);
                     write(' ');
                     gotoxy(X+31,Y+6);
                     write(' ');
                     gotoxy(X+37,Y+6);
                     write(' ');
                     gotoxy(X+44,Y+6);
                     write(' ');
                     {$endif}
                     {$ifdef TxtVideo}
                     outtextxy(X+23,Y+5,' ',255,green,255);
                     outtextxy(X+30,Y+5,' ',255,green,255);
                     outtextxy(X+36,Y+5,' ',255,green,255);
                     outtextxy(X+43,Y+5,' ',255,green,255);
                     updatescreen(false);
                     {$endif}
                     GreenZona(topo);
                     gotoxy(X+4,Y+selezionato+5);
                     cursoron;
                     end else
        if (from_alt_to_char(c)=nome_char{'N'}) then  {ALT + N  NOME}
                     begin
                     scrivo:='';
                     stato:=0;
                     continue;
                     end;
if (stato=1) then  {in ogni altro stato, azzerarlo}
           begin
           stringa:=scrivo;
           if c=#8 then if length(scrivo)>0 then setlength(scrivo,length(scrivo)-1);
           if (pos('SHIFT ',c)<>0)and(length(c)=7) then c:=upcase(c[7]);
           if (length(c)=1)and(ord(c[1]) in [32..255]) then if length(scrivo)<13 then scrivo:=scrivo+c;
           if scrivo<>stringa then
              begin
              i:=CercaFile2(scrivo);
              if (i<>iesimo)and(i>0) then
                 begin
                 iesimo:=i;
                 if iesimo<7 then
                    begin
                    primo:=1;
                    selezionato:=byte(i);
                    end
                   else
                    begin
                    primo:=iesimo-6;
                    selezionato:=iesimo-primo+1;
                    end;
                 Mostra(primo);
                 GreenZona(topo);
                 Dettagli(topo,pos_barraV,ifiles,data,ora,attributi);
                 end;
              if (i=0)and(ord(c[1]) in [32..255])
                 and (length(scrivo)>0) then setlength(scrivo,length(scrivo)-1);
              gotoxy(X+4+length(scrivo),Y+selezionato+5);
              end;
           end;
showmouse;
c:=#1;
until false;
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

function ReadString(stringa:string; Xstart,Xtot,status:byte; topo,avanzate,mancino:boolean;
                    var ins:boolean; var lastD,lastU,posto:byte):string;
var i,old_x,mox,moy,mtasto,y,x,maxx:byte;
    c,str:string;
    cliccato:boolean;
    Doppio_Click:More_Click;

{---------------------------------------------------------------------------}

procedure Tasto(var x:byte; var stringa:string; c:char; Xtot,Xstart:byte; ins:boolean);
begin
if ins then
        if whereX<Xtot then
                       begin
                       setlength(stringa,length(stringa)+1);
                       stringa[length(stringa)]:=#0;
                       stringa[x-Xstart+1]:=c;
                       inc(x);
                       if stringa[length(stringa)]=#0 then setlength(stringa,length(stringa)-1);;
                       end else
       else { ins=false }
        if length(stringa)+xstart<Xtot then
                       begin
                       Insert(c,Stringa,x-Xstart+1);
                       inc(x);
                       end;
end;

{---------------------------------------------------------------------------}

begin
Doppio_Click.init;
Doppio_Click.set_mancino(mancino);
initKeyboard;
initvideo;
maxX:=byte(screenWidth);                   {status: 0 = normale}
if Xstart<1 then Xstart:=1;                {status: 1 = maiuscolo}
xstart:=byte(min(Xstart,maxX-1));          {status: 2 = minuscolo}
if Xtot=0 then Xtot:=1;                    {status: altro = normale}
xtot:=byte(min(Xtot,maxX-1));

if topo then hidemouse;
if status>2 then status:=0;
gotoxy(xstart,whereY);
write(stringa);
y:=WhereY;
if posto>length(stringa) then posto:=length(stringa)+1;
if posto=0 then posto:=1;
str:='';
for i:=wherex to Xtot do str:=str+' ';
write(str);
x:=Xstart-1+posto;
gotoxy(x,wherey);
old_x:=255;
c:=#1;
if ins then CursorBig
       else CursorOn;
if topo then
        begin
        hidemouse;
        showmouse;
        showmouse;
        showmouse;
        end;
repeat
if (PollKeyEvent<>0) or (not topo) then
   begin
   c:=KeyEventToString(TranslateKeyEvent(GetKeyEvent));
   if (from_alt_to_char(c)<>#0) and avanzate then
             begin
             lastU:=ord(upcase(from_alt_to_char(c)));  {esce alla pressione del tasto ALT + qualcosa}
             lastD:=255;
             break;
             end else
   if c='Left' then
               begin
               if x>Xstart then dec(x);       { sinistra #75 }
               end else
   if c='Delete' then
               begin
               if longint(x)-longint(length(stringa))-longint(xstart)=0 then Continue;
               delete(stringa,x-Xstart+1,1);  { canc #83 }
               c:=#1;  // forza il refresh
               old_x:=255; {forza showmouse}
               end else
   if c='End' then
               x:=length(stringa)+Xstart     { fine #79 }
              else
   if c='Home' then
               x:=Xstart                     { inizio #71 }
              else
   if c='Right' then
               begin
               if x<length(stringa)+Xstart then inc(x);  { destra #77 }
               end else
   if c='Insert' then
               begin
               ins:=not ins;                  { insert #82 }
               if ins then CursorBig
                      else CursorOn;
               Continue;
               end;
   if (c='Right')or(c='Left')or(c='Home')or(c='End') then
         begin
         gotoxy(x,y);
         Continue;
         end;
   if (pos('SHIFT ',c)<>0)and(length(c)=7) then c:=upcase(c[7]);
   if c=#7 then continue;
   if (length(c)>1)and not (c='SHIFT Key with scancode 3840') then continue;
   if (c='SHIFT Key with scancode 3840') then
                                          begin
                                          lastU:=7; // simula Shift+Tab
                                          c[1]:=#7;
                                          end
                                         else lastU:=ord(c[1]); {il valore del tasto}
   lastD:=0;
   case status of
           0: ;
           1: c:=UpCase(c[1]);
           2: c:=LowCase(c[1]);
           end;
   case c[1] of
        #27 : if stringa<>'' then
                 begin   {Esc}
                 gotoxy(Xstart,y);
                 str:='';
                 for i:=1 to length(stringa) do str:=str+' ';
                 write(str);
                 stringa:='';
                 x:=Xstart;
                 end
                else c:=#13;
        #32..#255 : begin
                    str:=stringa;
                    Tasto(x,stringa,c[1],Xtot,Xstart,ins);
                    if str=stringa then continue;
                    end;
        #9,#7: if avanzate then c:=#13;
        #8: if x>Xstart then  {back-space}
                begin
                dec(x);
                Delete(stringa,x-Xstart+1,1);
                end
               else Continue;
        end;
   gotoxy(Xstart,y);
   write(stringa);
   if whereX<maxx then write(' ');
   gotoxy(x,y);
   hidemouse;
   showmouse;
   end
  else  {not keypressed}
   if topo then
       begin
       Sleep(5);
       {$ifdef Go32v2}
        cliccato:=Doppio_Click.Mouse_Up(mox,moy,mtasto);
       {$else}
        cliccato:=Doppio_Click.Mouse_Down(mox,moy,mtasto);
       {$endif}
       if cliccato then mtasto:=1
                   else mtasto:=0;
       if mtasto=1 then
          begin
          if moy=y then
             if (mox>=xstart)and(mox<=xstart+length(stringa)-1) then x:=mox else
                if mox<=xtot then if mox>=length(stringa)+xstart then x:=xstart+length(stringa);
          if avanzate and ( (moy<>y)or(x>mox)or(mox>xtot) ) then
             begin
             c:=#13;
             lastU:=mox;
             lastD:=moy;
             Break;
             end;
          end;
       end;
if x<>old_x then
          begin
          old_x:=x;
          gotoxy(x,y);
          showmouse;
          end;
until c=#13;
posto:=wherex-xstart+1;
ReadString:=stringa;
Doppio_Click.destroy;
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

function ReadString2(stringa:string; Xstart,Xtot,status:byte; topo,avanzate,mancino,asterischi:boolean;
                    var ins:boolean; var lastD,lastU,cursore_,x_:byte):string;
var old_x,mox,moy,mtasto,y,maxX,l:byte;
    diff:integer;
    c,old_str_app,str_app:string;
    cliccato,quadra:boolean;
    Doppio_Click:More_Click;

{---------------------------------------------------------------------------}

function converti_in_asterischi(str_app:string; l:integer):string;
var i:integer;
begin
if asterischi then
              for i:=2 to min(l+1,length(str_app)) do str_app[i]:='*';
converti_in_asterischi:=str_app;
end;

{---------------------------------------------------------------------------}

procedure Tasto(var x,x_:byte; var stringa:string; c:char; Xtot:byte; ins:boolean);
begin
if ins and (x_<=length(stringa)) then
                       begin
                       stringa[x_]:=c;
                       inc(x_);
                       inc(x);
                       end
       else { ins=false }
        if length(stringa)<254 then
                       begin
                       Insert(c,Stringa,x_);
                       if x<xtot then inc(x);
                       inc(x_);
                       end;
end;

{---------------------------------------------------------------------------}

begin
Doppio_Click.init;
Doppio_Click.set_mancino(mancino);
Doppio_Click.Set_Num_Click_Max(2);
initkeyboard;
initvideo;
maxX:=byte(screenWidth);                   {status: 0 = normale}
if Xstart<2 then Xstart:=2;                {status: 1 = maiuscolo}
xstart:=byte(trunc(min(Xstart,maxX-1)));   {status: 2 = minuscolo}
if Xtot=0 then Xtot:=1;                    {status: altro = normale}
xtot:=byte(min(Xtot,maxX-1));
if xtot-xstart<3 then RunError(201);
if x_>length(stringa)+1 then x_:=length(stringa)+1;
if x_=0 then x_:=1;
if status>2 then status:=0;
y:=WhereY;
cursore_:=byte(min(cursore_,xtot-xstart+1));
if cursore_>length(stringa) then cursore_:=length(stringa)+1;
if cursore_=0 then cursore_:=1;
if cursore_>x_ then cursore_:=x_;
cursore_:=Xstart-1+cursore_;

gotoxy(xstart-1,Y);
str_app:=copy(stringa,x_-(cursore_-xstart),xtot-xstart);
l:=length(str_app);
quadra:=(length(str_app)=length(copy_end(stringa,x_-(cursore_-xstart))));

while length(str_app)<xtot-xstart do str_app:=str_app+' ';
str_app:=' '+str_app+' ';
if quadra then str_app[length(str_app)]:=']'
          else str_app[length(str_app)]:=c_FR;

if cursore_-x_=xstart-1 then str_app[1]:='['
                        else str_app[1]:=c_FL;
hidemouse;
write(converti_in_asterischi(str_app,l));
showmouse;
gotoxy(cursore_,y);

old_x:=255;
c:=#1;
if ins then CursorBig;

repeat
if (PollKeyEvent<>0) or (not topo) then
   begin
   c:=KeyEventToString(TranslateKeyEvent(GetKeyEvent));
   if (from_alt_to_char(c)<>#0) and avanzate then
               begin
               lastU:=ord(upcase(from_alt_to_char(c)));  {esce alla pressione del tasto ALT + qualcosa}
               lastD:=255;
               break;
               end else
   if c='Left' then
               begin
               if cursore_>Xstart then dec(cursore_);       {sinistra #75}
               if x_>1 then dec(x_);
               c:=#1;  // forza il refresh
               end else
   if c='Delete' then
               begin
               delete(stringa,x_,1);  {canc #83}
               c:=#1;  // forza il refresh
               end else
   if c='End' then
               begin
               x_:=length(stringa)+1;  {fine #79}
               if x_>(xtot-xstart) then cursore_:=xtot
                                   else cursore_:=length(stringa)+xstart;
               c:=#1;  // forza il refresh
               end else
   if c='Home' then
               begin
               cursore_:=Xstart;              {inizio #71}
               x_:=1;
               c:=#1;  // forza il refresh
               end else
   if c='Right' then
               begin
               if x_<=length(stringa) then
                                      begin     {destra #77}
                                      inc(x_);
                                      if cursore_<Xtot then inc(cursore_);
                                      c:=#1;  // forza il refresh
                                      end;
               end else
   if c='Insert' then
               begin
               ins:=not ins;                  {insert #82}
               if ins then CursorBig
                      else CursorOn;
               Continue;
               end;
   if (pos('SHIFT ',c)<>0)and(length(c)=7) then c:=upcase(c[7]);
   if c=#7 then continue;
   if (length(c)>1)and not (c='SHIFT Key with scancode 3840') then continue;
   if (c='SHIFT Key with scancode 3840') then
                                          begin
                                          lastU:=7; // simula shift+tab
                                          c:=#7;
                                          end
                                         else lastU:=ord(c[1]); {il valore del tasto}
   lastD:=0;
   case status of
           0: ;
           1: c:=UpCase(c[1]);
           2: c:=LowCase(c[1]);
           end;
   if (c=#27) then
              begin
              if stringa<>'' then
                 begin   {Esc}
                 gotoxy(Xstart,y);
                 stringa:='';
                 cursore_:=Xstart;
                 x_:=1;
                 end
                else c:=#13;
              end else
   if (c>=#32)and(c<=#255) then Tasto(cursore_,x_,stringa,c[1],Xtot,ins)
              else
   if (c=#9)or(c=#7) then
              begin
              if avanzate then c:=#13;   // TAB o Shift+Tab
              end
             else
   if (c=#8) then
             begin
             if x_>1 then
                 begin                     {back-space}
                 Delete(stringa,x_-1,1);
                 dec(x_);
                 if cursore_>xstart then dec(cursore_);
                 end;
             end;
   old_str_app:=str_app;
   str_app:=copy(stringa,x_-(cursore_-xstart),xtot-xstart);
   l:=length(str_app);
   quadra:=length(str_app)=length(copy(stringa,x_-(cursore_-xstart),255));
   while length(str_app)<xtot-xstart do str_app:=str_app+' ';
   str_app:=' '+str_app+' ';
   if quadra then str_app[length(str_app)]:=']'
             else str_app[length(str_app)]:=c_FR;
   if cursore_-x_=xstart-1 then str_app[1]:='['
                           else str_app[1]:=c_FL;
   if old_str_app<>str_app then
        begin
        cursoroff;
        gotoxy(Xstart-1,y);
        hidemouse;
        write(converti_in_asterischi(str_app,l));
        showmouse;
        gotoxy(cursore_,y);
        if ins then cursorbig else cursoron;
        end;
   ShowMouse;
   end
  else  // il mouse
   if topo then
       begin
       Sleep(5);
       {$ifdef Go32v2}
        cliccato:=Doppio_Click.Mouse_Up(mox,moy,mtasto);
       {$else}
        cliccato:=Doppio_Click.Mouse_Down(mox,moy,mtasto);
       {$endif}
       if cliccato then mtasto:=1
                   else mtasto:=0;
       if mtasto=1 then
          begin
          if (moy=y)and(mox>=xstart)and(mox<=xtot) then
                   begin
                   diff:=mox-whereX;
                   if diff<0 then
                             begin
                             cursore_:=cursore_+diff;
                             x_:=x_+diff;
                             end;
                   if diff>0 then
                             begin
                             cursore_:=cursore_+diff;
                             x_:=x_+diff;
                             diff:=x_-length(stringa);
                             if diff>0 then
                                 begin
                                 dec(x_,diff-1);
                                 dec(cursore_,diff-1);
                                 end;
                             end;
                   end;
          if avanzate and ( (moy<>y)or(cursore_>mox)or(mox>=xtot) ) then
             begin
             c:=#13;
             lastU:=mox;
             lastD:=moy;
             Break;
             end;
          end;
       end;
if x_<>old_x then
          begin
          old_x:=x_;
          gotoxy(cursore_,y);
          ShowMouse;
          end;
until c=#13;
cursore_:=cursore_-xstart+1;
ReadString2:=stringa;
Doppio_Click.destroy;
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

function SfogliaFile(XX,YY:byte; all,ordina,topo,mancino:boolean; testo,percorso_:string; var ifiles:string;
         CD,num_righe:longint; nome,lista,elementi,data,ora,attributi,Ricerca_files:string; nome_char,lista_char:char):string;
begin
exit( Sfoglia(true, XX,YY,all,ordina,topo,mancino,testo,percorso_,ifiles,CD,num_righe,
              nome,lista,elementi,data,ora,attributi,Ricerca_files,nome_char,lista_char) );
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

function  SfogliaDirectory(XX,YY:byte; all,ordina,topo,mancino:boolean; testo,percorso_:string; CD,num_righe:longint;
                      nome,lista,elementi,data,ora,attributi,Ricerca_files:string; nome_char,lista_char:char):string;
var ifiles:string;
begin
ifiles:={$ifdef Linux}'*'{$else}'*.*'{$endif};
exit( Sfoglia(false,XX,YY,all,ordina,topo,mancino,testo,percorso_,ifiles,CD,num_righe,
              nome,lista,elementi,data,ora,attributi,Ricerca_files,nome_char,lista_char) );
end;

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}

end.
