From db036a7bd87bdf15d8c38ab2f723a1c3af65a9e7 Mon Sep 17 00:00:00 2001 From: f1iwq2 Date: Wed, 23 Dec 2020 12:12:19 +0100 Subject: [PATCH] V2.3B --- UnitConfig.dcu | Bin 60394 -> 66082 bytes UnitConfig.dfm | 47 +- UnitConfig.pas | 238 ++++++- UnitDebug.dcu | Bin 16681 -> 17277 bytes UnitDebug.dfm | 87 ++- UnitDebug.pas | 55 +- UnitPrinc.dcu | Bin 208655 -> 209138 bytes UnitPrinc.dfm | 61 +- UnitPrinc.pas | 175 ++--- UnitPrinc.~dfm | 1609 ------------------------------------------ UnitPrinc.~pas | 1674 +++++++++++++++++++++++++------------------- UnitSimule.dcu | Bin 7826 -> 7826 bytes UnitTCO.dcu | Bin 134597 -> 134593 bytes verif_version.pas | 7 +- verif_version.~dfm | 35 - verif_version.~pas | 210 ------ 16 files changed, 1434 insertions(+), 2764 deletions(-) delete mode 100644 UnitPrinc.~dfm delete mode 100644 verif_version.~dfm delete mode 100644 verif_version.~pas diff --git a/UnitConfig.dcu b/UnitConfig.dcu index d713f2d1d300402b869642b1b9857b6401252d54..0949d3e82e71c9e18178a77767af2431c7280054 100644 GIT binary patch delta 21346 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 delta 16574 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 diff --git a/UnitConfig.dfm b/UnitConfig.dfm index a43f772..9c952d9 100644 --- a/UnitConfig.dfm +++ b/UnitConfig.dfm @@ -1776,7 +1776,7 @@ object FormConfig: TFormConfig Top = 8 Width = 585 Height = 441 - ActivePage = TabSheetSig + ActivePage = TabSheetAct Font.Charset = DEFAULT_CHARSET Font.Color = clBackground Font.Height = -11 @@ -2783,7 +2783,7 @@ object FormConfig: TFormConfig Top = 48 Width = 129 Height = 21 - ItemHeight = 13 + ItemHeight = 0 TabOrder = 1 OnChange = ComboBoxDecChange end @@ -2895,31 +2895,13 @@ object FormConfig: TFormConfig 'Liste de mod'#233'lisation des actionneurs du fichier config.cfg - cl' + 'iquez sur une ligne pour afficher la description de l'#39'action' end - object MemoAct: TMemo - Left = 0 - Top = 24 - Width = 289 - Height = 369 - Color = clInfoText - Font.Charset = DEFAULT_CHARSET - Font.Color = clAqua - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - ParentFont = False - ReadOnly = True - ScrollBars = ssVertical - TabOrder = 0 - WordWrap = False - OnClick = MemoActClick - end object GroupBox13: TGroupBox Left = 304 Top = 32 Width = 257 Height = 345 Caption = 'Description de l'#39'actionneur ' - TabOrder = 1 + TabOrder = 0 object GroupBox14: TGroupBox Left = 16 Top = 24 @@ -2957,7 +2939,7 @@ object FormConfig: TFormConfig end object GroupBoxAct: TGroupBox Left = 8 - Top = 200 + Top = 216 Width = 225 Height = 145 Caption = 'Actionneur fonction de locomotive ' @@ -3011,6 +2993,7 @@ object FormConfig: TFormConfig Height = 21 TabOrder = 0 Text = 'EditAct' + OnChange = EditActChange end object EditTrain: TEdit Left = 112 @@ -3019,6 +3002,7 @@ object FormConfig: TFormConfig Height = 21 TabOrder = 1 Text = 'EditTrain' + OnChange = EditTrainChange end object EditEtatFoncSortie: TEdit Left = 160 @@ -3027,6 +3011,7 @@ object FormConfig: TFormConfig Height = 21 TabOrder = 2 Text = 'EditEtatFoncSortie' + OnChange = EditEtatFoncSortieChange end object EditFonctionAccess: TEdit Left = 112 @@ -3035,6 +3020,7 @@ object FormConfig: TFormConfig Height = 21 TabOrder = 3 Text = 'EditFonc' + OnChange = EditFonctionAccessChange end object EditTempo: TEdit Left = 112 @@ -3043,6 +3029,7 @@ object FormConfig: TFormConfig Height = 21 TabOrder = 4 Text = 'EditTempo' + OnChange = EditTempoChange end object EditEtatActionneur: TEdit Left = 184 @@ -3051,6 +3038,7 @@ object FormConfig: TFormConfig Height = 21 TabOrder = 5 Text = 'EditEtat' + OnChange = EditEtatActionneurChange end object CheckRAZ: TCheckBox Left = 48 @@ -3059,11 +3047,12 @@ object FormConfig: TFormConfig Height = 17 Caption = 'Remise '#224' 0 apr'#232's pilotage' TabOrder = 6 + OnClick = CheckRAZClick end end object GroupBoxPN: TGroupBox - Left = 72 - Top = 8 + Left = 56 + Top = 56 Width = 225 Height = 193 Caption = 'Actionneurs gestion passage '#224' niveau' @@ -3207,6 +3196,16 @@ object FormConfig: TFormConfig end end end + object RichAct: TRichEdit + Left = 0 + Top = 32 + Width = 289 + Height = 369 + Color = clBlack + ScrollBars = ssVertical + TabOrder = 1 + OnMouseDown = RichActMouseDown + end end end end diff --git a/UnitConfig.pas b/UnitConfig.pas index 1652e09..eb08a7b 100644 --- a/UnitConfig.pas +++ b/UnitConfig.pas @@ -77,7 +77,6 @@ type Label15: TLabel; TabSheetAct: TTabSheet; Label16: TLabel; - MemoAct: TMemo; CheckBoxSrvSig: TCheckBox; Memo1: TMemo; Memo2: TMemo; @@ -185,12 +184,12 @@ type GroupBox15: TGroupBox; EditNbDetDist: TEdit; Label31: TLabel; + RichAct: TRichEdit; procedure ButtonAppliquerEtFermerClick(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormActivate(Sender: TObject); procedure FormCreate(Sender: TObject); procedure MemoSignauxClick(Sender: TObject); - procedure MemoActClick(Sender: TObject); procedure PageControlChange(Sender: TObject); procedure RichAigMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); @@ -213,6 +212,15 @@ type procedure EditSuiv3Change(Sender: TObject); procedure EditDet4Change(Sender: TObject); procedure EditSuiv4Change(Sender: TObject); + procedure EditActChange(Sender: TObject); + procedure RichActMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure EditEtatActionneurChange(Sender: TObject); + procedure EditTrainChange(Sender: TObject); + procedure EditFonctionAccessChange(Sender: TObject); + procedure EditEtatFoncSortieChange(Sender: TObject); + procedure EditTempoChange(Sender: TObject); + procedure CheckRAZClick(Sender: TObject); private { Déclarations privées } public @@ -267,7 +275,7 @@ var temps : integer; begin if SocketCDM_connecte=false then begin envoi_CDM:=false;exit;end; //Affiche('Envoi à CDM rail',clRed);Affiche(s,ClGreen); - if trace then affiche(s,clLime); + if traceTrames then afficheDebug(s,clLime); Formprinc.ClientSocketCDM.Socket.SendText(s); // attend l'ack ackCDM:=false;nackCDM:=false; @@ -333,7 +341,7 @@ begin end; procedure connecte_CDM; -var s , ss : string; +var s : string; i : integer; begin // déconnexion de l'ancienne liaison éventuelle @@ -389,7 +397,7 @@ end; // teste si une adresse IP V4 est ok function Ipok(s : string) : boolean; -var i,k,posp,n,octet,erreur : integer; +var i,k,octet,erreur : integer; begin for k:=1 to 3 do begin @@ -405,7 +413,7 @@ end; // vérifie si la config de la com série/usb est ok function config_com(s : string) : boolean; var sa : string; - j,i,erreur : integer; + i,erreur : integer; begin sa:=s; protocole:=-1; @@ -414,19 +422,15 @@ begin if i<>0 then begin delete(s,1,i); - j:=i; i:=pos(',',s); - j:=j+i; if i<>0 then begin delete(s,1,i); i:=pos(',',s); - j:=j+i; if i<>0 then begin delete(s,1,i); i:=pos(',',s); - j:=j+i; if i<>0 then begin delete(s,1,i); @@ -564,6 +568,30 @@ begin encode_sig:=s; end; +// transforme l'actionneur type loco ou actionneur du tableau en texte +// paramètre d'entrée : index +function encode_act_loc(i : integer): string; +var s : string; + c : char; + adresse : integer; +begin + // adresse + + adresse:=Tablo_Actionneur[i].actionneur; + if adresse=0 then begin encode_act_loc:='';exit;end; + if Formconfig.radioButtonLoc.Checked then + s:=IntToSTR(adresse)+','+IntToSTR(Tablo_Actionneur[i].Etat)+','+Tablo_Actionneur[i].train+',F'+IntToSTR(Tablo_Actionneur[i].fonction)+','+intToSTR(Tablo_Actionneur[i].tempo); + if FormConfig.RadioButtonAccess.Checked then + begin + s:=IntToSTR(adresse)+','+IntToSTR(Tablo_Actionneur[i].Etat)+','+Tablo_Actionneur[i].train+ + ',A'+IntToSTR(Tablo_Actionneur[i].accessoire)+','+intToSTR(Tablo_Actionneur[i].sortie)+','; + if Tablo_Actionneur[i].Raz then s:=s+'Z' else s:=s+'S'; + end; + + encode_act_loc:=s; +end; + + // modifie les fichiers de config en fonction du paramétrage procedure genere_config; var s: string; @@ -1040,7 +1068,10 @@ begin // actionneurs for i:=1 to maxTablo_act do - MemoAct.Lines.Add(mod_Act[i]); + begin + RichAct.Lines.Add(mod_Act[i]); + RE_ColorLine(RichAct,RichAct.lines.count-1,ClAqua) + end; PageControl.ActivePage:=TabSheetCDM; // force le premier onglet sur la page for i:=1 to NbDecodeur do @@ -1415,9 +1446,12 @@ var i,v, ligne,etatact,erreur, adresse,sortie,fonction,tempo,access : integer; s,s2,ss : string; trouve : bool; begin - with formConfig.MemoAct do + with formConfig.RichAct do begin ligne:=Perform(EM_LINEFROMCHAR,-1,0); // numéro de la lignée cliquée + AncLigneCliquee:=Ligne; + ligneCliquee:=ligne; + //affiche(intToSTR(ligne),clLime); s:=Uppercase(Lines[ligne]); if s='' then exit; SelStart:=Perform(EM_LINEINDEX,Ligne,0); // début de la sélection @@ -1578,11 +1612,6 @@ begin Aff_champs_sig; end; -procedure TFormConfig.MemoActClick(Sender: TObject); -begin - Aff_champs_act; -end; - procedure TFormConfig.PageControlChange(Sender: TObject); begin if PageControl.ActivePage=TabSheetAig then @@ -2114,6 +2143,181 @@ begin end; end; +procedure TFormConfig.EditActChange(Sender: TObject); +var s : string; + act,erreur : integer; +begin + if clicliste then exit; + if FormConfig.PageControl.ActivePage=FormConfig.TabSheetAct then + with Formconfig do + begin + s:=EditAct.Text; + if radioButtonLoc.Checked or RadioButtonAccess.Checked then + begin + Val(s,act,erreur); + if erreur<>0 then + begin + LabelInfo.caption:='Erreur adresse actionneur';exit + end else LabelInfo.caption:=' '; + + tablo_actionneur[lignecliquee+1].actionneur:=act; + s:=encode_act_loc(lignecliquee+1); + RichAct.Lines[lignecliquee]:=s; + end; + end; +end; + + + +procedure TFormConfig.RichActMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + clicliste:=true; + LabelInfo.caption:=''; + Aff_champs_Act; + clicliste:=false; +end; + +procedure TFormConfig.EditEtatActionneurChange(Sender: TObject); +var s : string; + etat,erreur : integer; +begin + if clicliste then exit; + if FormConfig.PageControl.ActivePage=FormConfig.TabSheetAct then + with Formconfig do + begin + s:=EditEtatActionneur.Text; + if radioButtonLoc.Checked or RadioButtonAccess.Checked then + begin + Val(s,etat,erreur); + if (erreur<>0) or (etat<0) or (etat>1) then + begin + LabelInfo.caption:='Erreur état actionneur';exit + end else LabelInfo.caption:=' '; + + tablo_actionneur[lignecliquee+1].etat:=etat; + s:=encode_act_loc(lignecliquee+1); + RichAct.Lines[lignecliquee]:=s; + end; + end; +end; + +procedure TFormConfig.EditTrainChange(Sender: TObject); +var s,train : string; +begin + if clicliste then exit; + if FormConfig.PageControl.ActivePage=FormConfig.TabSheetAct then + with Formconfig do + begin + if radioButtonLoc.Checked or RadioButtonAccess.Checked then + begin + train:=editTrain.Text; + if train='' then + begin + LabelInfo.caption:='Erreur train';exit + end else LabelInfo.caption:=' '; + + tablo_actionneur[lignecliquee+1].train:=train; + s:=encode_act_loc(lignecliquee+1); + RichAct.Lines[lignecliquee]:=s; + end; + end; +end; + +procedure TFormConfig.EditFonctionAccessChange(Sender: TObject); +var s : string; + fonction,erreur : integer; +begin + if clicliste then exit; + if FormConfig.PageControl.ActivePage=FormConfig.TabSheetAct then + with Formconfig do + begin + s:=EditFonctionAccess.Text; + if radioButtonLoc.Checked or RadioButtonAccess.Checked then + begin + Val(s,fonction,erreur); + if erreur<>0 then + begin + LabelInfo.caption:='Erreur fonction actionneur';exit + end else LabelInfo.caption:=' '; + + if radioButtonLoc.Checked then tablo_actionneur[lignecliquee+1].fonction:=fonction; + if RadioButtonAccess.Checked then Tablo_Actionneur[lignecliquee+1].accessoire:=fonction; + + s:=encode_act_loc(lignecliquee+1); + RichAct.Lines[lignecliquee]:=s; + end; + end; +end; + +procedure TFormConfig.EditEtatFoncSortieChange(Sender: TObject); +var s : string; + Etat,erreur : integer; +begin + if clicliste then exit; + if FormConfig.PageControl.ActivePage=FormConfig.TabSheetAct then + with Formconfig do + begin + s:=EditEtatFoncSortie.Text; + if radioButtonAccess.Checked then + begin + Val(s,etat,erreur); + if (erreur<>0) or (etat<0) or (etat>2) then + begin + LabelInfo.caption:='Erreur Etat actionneur';exit + end else LabelInfo.caption:=' '; + + tablo_actionneur[lignecliquee+1].sortie:=etat; + s:=encode_act_loc(lignecliquee+1); + RichAct.Lines[lignecliquee]:=s; + end; + end; + +end; + +procedure TFormConfig.EditTempoChange(Sender: TObject); +var s : string; + tempo,erreur : integer; +begin + if clicliste then exit; + if FormConfig.PageControl.ActivePage=FormConfig.TabSheetAct then + with Formconfig do + begin + s:=EditTempo.Text; + if radioButtonLoc.Checked then + begin + Val(s,tempo,erreur); + if erreur<>0 then + begin + LabelInfo.caption:='Erreur Tempo actionneur';exit + end else LabelInfo.caption:=' '; + + tablo_actionneur[lignecliquee+1].tempo:=tempo; + s:=encode_act_loc(lignecliquee+1); + RichAct.Lines[lignecliquee]:=s; + end; + end; +end; + + + +procedure TFormConfig.CheckRAZClick(Sender: TObject); + var s : string; + Etat,erreur : integer; +begin + if clicliste then exit; + if FormConfig.PageControl.ActivePage=FormConfig.TabSheetAct then + with Formconfig do + begin + if radioButtonAccess.Checked then + begin + tablo_actionneur[lignecliquee+1].raz:=CheckRAZ.checked; + s:=encode_act_loc(lignecliquee+1); + RichAct.Lines[lignecliquee]:=s; + end; + end; +end; + end. diff --git a/UnitDebug.dcu b/UnitDebug.dcu index 31654a367ea0f1f8062e07ffc7ce32c81e5b08c3..2e0909d4d11ecdc20661cc239140b59940ffe3d8 100644 GIT binary patch delta 6203 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 delta 5720 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' - TabOrder = 4 + TabOrder = 3 WordWrap = True OnClick = ButtonRazTamponClick end object ButtonCherche: TButton - Left = 474 + Left = 487 Top = 432 Width = 97 Height = 25 Anchors = [akTop, akRight] Caption = 'Chercher erreurs' - TabOrder = 5 + TabOrder = 4 OnClick = ButtonChercheClick end object ButtonAffEvtChrono: TButton - Left = 474 + Left = 487 Top = 392 Width = 97 Height = 33 Anchors = [akTop, akRight] Caption = 'Affiche Evts d'#233'tecteurs et aig' - TabOrder = 6 + TabOrder = 5 WordWrap = True OnClick = ButtonAffEvtChronoClick end object ButtonCop: TButton - Left = 474 + Left = 487 Top = 344 Width = 97 Height = 41 @@ -169,34 +157,40 @@ object FormDebug: TFormDebug Font.Name = 'MS Sans Serif' Font.Style = [] ParentFont = False - TabOrder = 7 + TabOrder = 6 WordWrap = True OnClick = ButtonCopClick end object RichEdit: TRichEdit - Left = 578 + Left = 591 Top = 160 Width = 239 Height = 185 Anchors = [akTop, akRight] + Font.Charset = DEFAULT_CHARSET + Font.Color = clWhite + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [] HideScrollBars = False + ParentFont = False PopupMenu = PopupMenuRE ScrollBars = ssVertical - TabOrder = 8 + TabOrder = 7 end object ButtonRazLog: TButton - Left = 474 + Left = 487 Top = 496 Width = 97 Height = 33 Anchors = [akTop, akRight] Caption = 'Raz Tampon Log <-----' - TabOrder = 9 + TabOrder = 8 WordWrap = True OnClick = ButtonRazLogClick end object GroupBox1: TGroupBox - Left = 472 + Left = 485 Top = 576 Width = 353 Height = 145 @@ -210,7 +204,7 @@ object FormDebug: TFormDebug Font.Style = [] ParentColor = False ParentFont = False - TabOrder = 10 + TabOrder = 9 object GroupBox3: TGroupBox Left = 8 Top = 16 @@ -332,7 +326,7 @@ object FormDebug: TFormDebug end end object GroupBox2: TGroupBox - Left = 472 + Left = 485 Top = 20 Width = 345 Height = 137 @@ -346,7 +340,7 @@ object FormDebug: TFormDebug Font.Style = [] ParentColor = False ParentFont = False - TabOrder = 11 + TabOrder = 10 object CheckAffSig: TCheckBox Left = 8 Top = 16 @@ -455,6 +449,19 @@ object FormDebug: TFormDebug OnClick = CheckBoxAffDebDecSigClick end end + object RichDebug: TRichEdit + Left = 8 + Top = 8 + Width = 470 + Height = 705 + Anchors = [akLeft, akTop, akRight, akBottom] + Lines.Strings = ( + 'RichDebug') + PopupMenu = PopupMenuRD + ScrollBars = ssBoth + TabOrder = 11 + OnChange = RichDebugChange + end object SaveDialog: TSaveDialog Left = 768 Top = 488 @@ -467,4 +474,12 @@ object FormDebug: TFormDebug OnClick = copier1Click end end + object PopupMenuRD: TPopupMenu + Left = 808 + Top = 360 + object Copier2: TMenuItem + Caption = 'Copier' + OnClick = Copier2Click + end + end end diff --git a/UnitDebug.pas b/UnitDebug.pas index 857fcae..d6d274d 100644 --- a/UnitDebug.pas +++ b/UnitDebug.pas @@ -15,7 +15,6 @@ type SaveDialog: TSaveDialog; ButtonEcrLog: TButton; Label3: TLabel; - MemoDebug: TMemo; ButtonRazTampon: TButton; ButtonCherche: TButton; ButtonAffEvtChrono: TButton; @@ -44,6 +43,9 @@ type EditActuel: TEdit; Button1: TButton; Button2: TButton; + RichDebug: TRichEdit; + PopupMenuRD: TPopupMenu; + Copier2: TMenuItem; procedure FormCreate(Sender: TObject); procedure ButtonEcrLogClick(Sender: TObject); procedure EditNivDebugKeyPress(Sender: TObject; var Key: Char); @@ -65,6 +67,8 @@ type procedure ButtonCanSuivSigClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); + procedure Copier2Click(Sender: TObject); + procedure RichDebugChange(Sender: TObject); private { Déclarations privées } public @@ -113,11 +117,6 @@ uses UnitPrinc; {$R *.dfm} -procedure AfficheDebug(s : string;lacouleur : TColor); -begin - FormDebug.MemoDebug.Lines.add(s); -end; - procedure RE_ColorLine(ARichEdit : TRichEdit;ARow : Integer;AColor : TColor); begin with ARichEdit do @@ -129,6 +128,13 @@ begin end; end; +procedure AfficheDebug(s : string;lacouleur : TColor); +begin + FormDebug.RichDebug.Lines.add(s); + RE_ColorLine(FormDebug.RichDebug,FormDebug.RichDebug.lines.count-1,lacouleur); +end; + + procedure TFormDebug.FormCreate(Sender: TObject); var s: string; i : integer; @@ -138,14 +144,14 @@ begin s:=s+'comportement du programme. Positionner le niveau de 1 à 3 pour'; s:=s+' afficher des informations plus ou moins détaillées.'; Label3.caption:=s; - MemoDebug.WordWrap:=false; // interdit la coupure des chaînes en limite du composant - MemoDebug.color:=$33; + RichDebug.WordWrap:=false; // interdit la coupure des chaînes en limite du composant + RichDebug.color:=$33; initform:=false; - MemoDebug.clear; + RichDebug.clear; s:=DateToStr(date)+' '+TimeToStr(Time)+' '; if IsWow64Process then s:=s+' OS 64 Bits' else s:=s+' OS 32 Bits'; RichEdit.color:=$111122; - MemoDebug.Lines.add(s); + RichDebug.Lines.add(s); end; procedure TFormDebug.ButtonEcrLogClick(Sender: TObject); @@ -163,7 +169,7 @@ begin assignFile(fte,s); rewrite(fte); writeln(fte,s); - with MemoDebug do + with RichDebug do for i:=0 to Lines.Count do begin writeln(fte,Lines[i]); @@ -186,7 +192,7 @@ begin end else EditNivDebug.text:='0'; end; - MemoDebug.Lines.add('Niveau='+intToSTR(NivDebug)); + RichDebug.Lines.add('Niveau='+intToSTR(NivDebug)); end; @@ -208,7 +214,7 @@ var i : integer; trouve : boolean; begin - with MemoDebug do + with RichDebug do begin i:=0; repeat @@ -229,7 +235,7 @@ procedure TFormDebug.ButtonAffEvtChronoClick(Sender: TObject); var i,j,etat : integer; s : string; begin - MemoDebug.Clear; + RichDebug.Clear; if N_event_tick=0 then begin AfficheDebug('Il n''y a aucun évènement détecteur ou aiguillage',clyellow); @@ -269,17 +275,15 @@ end; procedure TFormDebug.CheckTrameClick(Sender: TObject); begin - trace:=CheckTrame.Checked; + traceTrames:=CheckTrame.Checked; end; procedure TFormDebug.ButtonCopClick(Sender: TObject); var i : integer; begin - MemoDebug.Lines:=Formprinc.ListBox1.Items + RichDebug.Lines:=Formprinc.FenRich.lines; end; - - procedure TFormDebug.copier1Click(Sender: TObject); begin RichEdit.SelectAll; @@ -289,7 +293,7 @@ end; procedure TFormDebug.ButtonRazLogClick(Sender: TObject); begin - MemoDebug.Clear; + RichDebug.Clear; end; procedure TFormDebug.CheckBoxActClick(Sender: TObject); @@ -376,4 +380,17 @@ begin NivDebug:=AncDebug; end; +procedure TFormDebug.Copier2Click(Sender: TObject); +begin + RichDebug.SelectAll; + RichDebug.CopyToClipboard; + RichDebug.SetFocus; +end; + +// pour déplacer l'ascenseur de l'affichage automatiquement en bas +procedure TFormDebug.RichDebugChange(Sender: TObject); +begin + SendMessage(RichDebug.handle, WM_VSCROLL, SB_BOTTOM, 0); +end; + end. diff --git a/UnitPrinc.dcu b/UnitPrinc.dcu index 475d18418e37199752a10eb6050092ac7d2d0361..663993cf9747904d5ab742ff98516c5016b6ed90 100644 GIT binary patch delta 78393 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 z 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
  • & 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 delta 77729 zcmce<3t-gMl|TNy-+5#*nM@`y49Vo-BqlM$0h16A5R{OIfJt~wXt04eOlHVnUL+HQ zR{Vw{E)r32w4+^hrK`Kz)h>t{z(=7~D_!k^wp-lQR=U+cu1KM4x47l;`<#2f-*sV}{` zI~-Zq7w!&BY7cdd*|uZ%b!+94sW(?Xy2>`mSKrguRnyZQ3a`pL{)Dp1nkd&Exara8 zFXYFfn+*kfh7DKC#TmW@w{-{mYWw`REs6Le!5^+zxo%b3Bp($9`seuj2EYH*>S(69 zC?k~WTO1B_)U}5rul{t`clS&&f6US?zJ_prWKPezcV8Q~DC)M<*;6NJp#6)tOpdOw zEW5((s~PBz^mM7Hla>S{zMkHB-R;43Cqgg28-3AIH*r<&myza0f?aci;Z+@xkAW64 z`5J>=J)d~~y>ZV~smFenCrpye;-yNY&MBA>YaojZ% zR@vj=nx4*{zFSSNyuT{LSL5$q>+hfB3$BYS7>F#o>FDY`lgGWq@&fHCpxxecTmPFi z@BCK6|Iq#7U?5U-??aRJ6pX)8-qW64$kIb83wy%dkzn5+9{PLRp1a)d$a{i$-!&Gc zw+B}atZHiy2HN_=tAcA|(^lE4Lm}udSW7j_$2I$-vkFU%kEPzWHX1H$&9p79YvY_X zgu8|tzm!d-rT)IKzdO<|nNUip>Gb#a1M##0RX6tedpp8`erY3>R1Nk^AIX6#6ZOCOC)$zrnn)jLzlFkr&fscM+K*D*x`-(JL!ipIx;MB=dV*8!63~aJ zbw{wXvwGn?=>ZgcopXboy^|}YE$Cxj*D5j#=`O+w+#0Fr>FSkwsSxQC!gNL}if$}E z|G)Pgze6gsa!qi{-!i@{&pcRcii9J5!L1X@UPx<+K3a55;9HWkgB6<_{p+d&fvutJ z6Cd0uNz7B6(%|n~h3>YFfAqr-fYe@Wnj4|=Y*FrF#c6?_?*2$ydtXmDvi1Lagrgbb z(BRr|aO=kejb2miX5Wg=FLvjEkg+&J*RHLmwsGr697`!4H}ft@N=f-cMzOJGy}x_w zo2P%Zf*|Jq$tbo2I@gAKI)jm|tM2E}KV+QBC^p^L7w)g$`t&;mEAEOOE*>`>%>VHR zhGJ8FaG3Fw7;I<{W=mIYeRyKAwP|H-FwoNu)U79k^!BSPuwf4R^-C8n6y8%& zS!VIg>GOBPlD8cAm9pmEvNWGRylNoa*$GSBa{TYF*tWgc0La!=+2zf7_haf58$!W> ztsU9rRFVll5P;$Kg!_V9GJ0Q%++S>7>+cM=2e&@)^TH<|pcd#=1wAQ1a+$%`SiPme z`~9;IL~U2)E8pI1@YqQN%&%^LXH9SCx{v!dFuxS3@0E>EBk`b=ejt=+UxJ{3--bqf^nFoy1lQKY(PMWR7xn=9fbA8acoUJ zU7$6uizcOjZZmjNH5Szl0J5(XDr|%A8d$3m*cLr^RgU6AwYfSF83=a9DcEV8{GDz6 z1L3up({Xq@ao*M!3=Fgd+PegJhryHKgNQwCfsR#?HmF|h78SmKOMqabf#A(O-9Z8=91W)5*Tu`cnBME}ThbG_ zH5h3Kc7G$@((Di1S_2)#i7)I6c7=m|^|f(ON)zEg0*>-F zglgBuA?a}97#oNIC*2nZrxG~43WBSk=&1==(^}Dml?y~JPL<$Ezyh6+xhFy+$you+ z*bUy)Qgn8iOKAm={1I01rU9rqj%jJYVz_0sni*lS8FaRSU@$n$S0w)kjQIVpDuO6qgzOL243`GSX zX?*pD$X%K-0BDN%S9bP%{Qh3+x$hhzrB3Eb{SLfPcVBQ7Mi>Sc#E@>Ak$tq~ZG*=a z=zzZsw$*j7?FoMgN|qH=;$ZW<^4u#+V; zaB&<%L-n$FA-&7L4jx(c(PCQu9HZSH{ZH>0#fPkkJcjDAP_zmM5{3(nW2Y?9J0BpW z_}2FZZwz+FF*3-5aNoC(3|w^z??Dq(p)ML~CxBXc1X!scN>Y1C0NcQ>pbJ=<<}CGy zsl0VkTgyC{6D@$E*sa%4n+DtZhrNVKRh#m(5CUqXFL|6h=olb@9QXC`TdE;GQ*_u3SPMjXw!M_Igd@C ziAdt(+28%+@19>ys1*YBMbJ@bb%7TYYF=aX*cSV{R{>DdGtj4wFQCSzwwkpG9E8)s zbx8vRoV2D|P5eYdOH&)XX1F^Ef^{;YuBnO-EiHUHw$&{C_{LM$RO}sqrqnR!X@Glx&E6 zssac!QYkdD-(%Iyt>@Ms-1YJfbj8=*|2%usz^e}va+N?nfb0~J{UNebMfNphuNB!h zkew#7Zz4NgWPgI}WRZQV%%Dsv7Y_YZkGVcfvBt-2<#(sMvrQh0I?I|qt~W&X{xr|z z!N^sH4og+3v}NR52&o_?P?Zk%9uBqPUs{tT6F^qJsSJ1aM1s-|vsxB*Al;2}3f03A zOG=$NP-=&-8))NupO8Ngl%&U{cM9ajYS#mj$AH+))e5A{M7Tbwwr4J|2ftCCRwhld zyi;IY66_4Q2BiY?k|0c@&$U<%l$z&+BTWNclC;q1D`4HO6_UriIM_eX8FBd}4-30| zMvqw$L6fT$4eS)0wnZ?(`+G4HC229(fF;0#htb?zXzdkoz{+sMwZc+}sxH(7T`R00 zX9j&kS5E{f`VIv90-ca#JCUdsTSM0zO95Nw@>vVm`jGETfvL~G-qF+T@|md@9#)sk zj?S*kR;W#YZzn@@&Y(@mcZ#<;USJ6IwUmU)DP2|)@)TIL$lKppvLdS>t)~yJ1d%KT zqQvL$7|HpPxYQRMyYE9!%DSa|tAK7jDa*9H#baJKrxVct*z+jn^*kT)9rdI%V50-G z2>A|sQfQNdyvrwh48cH0D0IMMB>jX|yi8MuYa_H`Z=lrH4hKjJ7EE{YV1v_ICS|5^ zRa}l(%AX^baov(&7YSut)=wFdXuf}-8=N2Yn3t^<*~1=F3q>O#-|qn6J<>pu0TTB^B4HM!&9e*Q=v> z*kf$L2$Q77Wf*fMN2if335_UZ zm>``O`FFYU%TLR)l;H!AL}II}8W8%8+jhV2gQf@M4-%giGKv zXN2mGo!4~t-g%w!j+{?ukCZoE^$^*Ait>Wmeq9;W^9hGXqxD5%cbGp|i`- zBk8smc&E>Eg;N%a;!tS(hzdpaAk?Q>tLBGC+NiwlYB;mq=RNXzq&v^6&T3;^^Xv7R zkG?d`os(EyTyxC&6~wh7dTN^9pM9y`q8qsOaNm?c|1Z4@rPF%X{#9+JiZ)+3k_KDH zhY<_@is(JlzlxC*b)z^)2cXjLK#ui?TFw-tcKX%T)HU1UVUt|>h#u4sAI3KL*i~Z- zq*lZPDSi>B)B5=3$RN_E&~b{03~Ce0SzFh-!S794nkF@-pi8S*+EE`Fxx5?dlb7m5 zcjhmx(-e&$Y#6VLaprYJADxk=e3N3FjcJJ>$C?Oo%pNYW$G)&FOp~y!mq%PKH!467 zrXR$TFwh5g94NI0`hr1$CrLYLsu^)^w2J#b+I`gr2jILp#Z$$`V1Ms2D^C2BeA1ws z>(RsiErShMYC3{}Tl*=v%9D*PLh)B>I&1+Rx|cmB9P9;db=?B}Th$Hh+`1M?IxHIfVz_=NxGRV)0Euowcp2$I#~{d?Nm8}Z*eW_yt)e}G0MuiOhz`(o zhAIr5O4JW@2P7%e0xeiVJ>C2~2ZRfZ=kKEq_36Vh1<6P&_ zM`z|tX(>oq8^+e8A0d|c%Pn1`S=cx=MEm2See|=LJ}U>x{R+NCmx0oBVO?#Q_dGf-FhQ@0UabYD9&BGDu3Kawe5m!j$Gi%AtzJlD z@g#b=Mc6F{IHNZleRtLvig)AOOBx**(50H6fl;X(;S6~2=E?ror2_6$;-sK_&Qj=> z^92T+5V`Khl+ZY`#z$28dV;yoEoU`(Z3*h-6_T{ZoFs0X&08+bX7mTwkAr;1&Yl37 zS<(O-`*DovYBlm6Ax{d1K7w6~B$bm1(w3#b(%aJ?rf{Anls3a!X^VklFOKUmuDBE~ zwj)X@_Cuj=OLv?Zs_ zYC(?F{$MBOLbylihL;l_EO4vVF%Tu`AbB6ny5Wem?sV!qp;Mo524vfU`KHFj)ffVc zjtIFey5xXkC&h5Cl|W?VFsNd|uad{W?p6@Q#v3uSKZJX%Yey2r!35+XqCz_qYls!* z%R2g8$MmVdO>voPeUcug3J<|rAdW+sL$Ccy}uuqNeEzc%K=}dyG zDxyP(C=7RwzoT1{cBUo?X-zagn`oXOf5u}*+}r0@ddcM*uxWI)N}g1l&~b2YsP%tv zVBH-+MX2?2&hBx{TlM5wl1z6>?|3XYb!fv11Wn2wtKf$2lw3X=HxaWZ6~{&W{9KC2 zGe334R)#1a03=WvT~b3jP;FWmmM39FXFLWR4f5gfQ}n`Ca_=DQm(Lb-2Jm|NS6)}n zllA3fektOnr6uG$uH~1}PAhFe;^csK%$9jPuBWKLeb__C4z$~+V~0>^7Z>~~oXO}E zKCq5tl%$o=08L~mS#$_xTO00Mg<}qW^(0CEh7e5d@1&58!8O9DwbL0W<5tY;Rkc?t zzJj!FXj45zgTw{qo=~Wtgoo+t8muM?az90Yfz_p{SfV;`1k(}3RL#Rw#jMN_r-o1* zrYt6pB)td@NRg1gAdLo1?S|qYL0jQL0t=Jo$R&~1%;Lx>)cVVdbmR~nB~J20Pi8o% z>hP+IcQ#62sqxODJLiJ`$H{zJ!Y|jgj#mtsswhm z3MWCKmZxCcp_~85W9$WMp_~7~W57U!TAx6=x;@nTT}t~yt&f9BWvKNrP0ut#poMTR zJQJpgA}&RD#@k=zIpX+OY0UdnYW+`e9xQm66mvA9p^?B})uy|-IB+dl6H>kii8yN^#0D3}t z6f)7EGvs4P(ADX49&;0)SlH;F^Q0o86ZQE&?{mlcIVg@|fflj(d##xClm+OWv}7U}ZlZ z*$j|dJ|f(*O?`;a=I>lJc`$l-z6DO-h?904MOzB2M8B?qitxRKxS6NN3?N=$<29YQ zDgvOymsMZ@0Xp;6bO3u4?2#GKN=gi;AjRSfVn;oxoOw|??8)TTLfm7oimfzfAnLzq zd^Qdm$HptEPGcgv0RhJ3r|sRWtGQ=YggC0JM+ zc6xoPAwP~ujF!0bS{bY$=a(qL7e1o8$nU5w@*xkacHIo|s(br9kmcrY!$T4ab3!*i zAhMOn-p>ahIipZ8~YS^{WiQ$!7d;<7)KZdVnirm3e+!kfu|^7 z2=P+fo{y_oRKuMiu*!wBA9`%_=t?q<3-1NxT0Mr^FwE|-$4qko0by&@(R77UKygQq zj$F?aScqXThyu>cgLLM4JPxcJVb7WRUda8T)rX!hL1BQBXY9(PXF)3VQNWciRqzIa zV^T71dLWw+?ajE35?VQci(7Cl5cZ0KrWH91o_4`&Rnm|pc3Gw-;($*A`w~?d7*dM& zuUk-{T*Qr0R72C2ktgC#*zB=3VexOTp;K4x^87rkB5hj{RU;ViN9ueOsK<*7nsvdt zjbDz4$0D7BKblzc2Z`AfogbzCv{^!NIge#YE!ew}sqq+)EF?If8H;9*ahv}T&mN$m zx(1=6qqqvEqUxd!i zBC;NSgh!ld4AUY_0W(4$jZYXC-{ulkG8c+NIqyQbw9vW~XipVR3_eN3*H>*%{F-hP zHe&p_sAA6XQNoz+!v4Qn1fW5TJ6^isE_7!magX6rxlb@{RybEGrz(S7;Rz2wx(25S zMzMc^ByrUX2DlGN80S$j4#~_N4wO2Q&a%QiCEen5;vp=1@q>hJJni5DsTM$o6N|FL z0wV-=j7^Y{+&RMNufDKpM3f|uz}<@%C&CwSQf^QbgbA4_Vj}aRo#r; zqE^*&D}05r_zK;`7-5&1@JV*5o0qByYNBH|i+GqEXxvEQmcW;09(CM2-b|PWKao|q zKs>yHDT_U8Ih`ze(#W*uAqK|F-Vhc+E7ju-A{}k<~RC_ z)hm86b8*El7B#4o`S^N;u1SCbBQo%|m_*1-=HY9iEgp?x3i4$J!678$eg(S5IcQuF zqygbUHeLY-61UqV|B=}1!zU@KbqIq=t3@ZYjo>Og?n#4Kh&tQEUDR_9&9meAmurE#wXwgVIFDS+0(-|1( zZ2JaYrS?k_yBfUc%!d2~h8F|HXEnVoBWg-o6J1652k1F0X@|%kPnad)kP*YIMF!^Z zA&0=Mao+)|!lYn5ZnIvE6%{U1*Z^g_&l;{ynCcMB3I*d2^NJ504zLIp+;jgXNbWA z9$PPFI6seTTi8Uh%f5cs{aA`KxYtq;^Wz;IJu;W1o!GYUW;moZ2XPKN0AN0Br!+%I zfHBeznEYl?Z%#r7$2!Xe`vsfCP?UvSz< z5=FdFrq{QUR7n2hs+4*CU+cMTYE^x!bZe9Dai9tpKdWf{I? zB6_!X-+;*e9nPzD z^}_rYizRYC#PQ+AXNuh5TR*uny#KXZ*>scgALaqOcuAv`#=he3KCP~_D#~9OlX5A>$-Ke?H6sZx+EkRBbBs-!czNTXSD0*=#E4`#bBy_=N;YYD8m(pW+YNv9|I2(zXHo zWGiS6VTG*;!;g#6G|!JNUtUnSfOueLjR)5tuHNFWCAk8kk1x-@Y9XN=kw-@>q#u*e zUF3}Dhs(2_WNG9qg!_ONp_OR*iX3GT5!q3s5g8$GVpABu`=e>egAurL&`G|%;PZ8T zId^z-_(KQ2c*VUAR($nRgRgcz{|x#q32rqIQR&`8@~r`Hj`h{$#^yZKw=NXommBNp za)YyfY=x&_F|mJK<39OaslY01yK=@7!txsuXh{kc=Pj6Q+D#qCP4gX5r42C!*U?23 z9VpGwS(5r=$BJ6~vXXwtIM_^WHzu{kVJ83aqU(COz{HOUcxbyAOHpX{?~XvDWf9bG*J9>#$_|&5m8@XPaj|ZO6*yM zsk~UjuWrRc5N*4qXnugm9ke9K;czi-f`2NxoM>;mv0`!1-#*wvbk8Kn>IXtcRt#O9 z|B9Stmyr8w{wuD%{o?gF`d1Ft{kQ*H;;6JVKk8WJiY{N7n$vo5{-PUKmgOv``n`!RbP9?7 zc%^sF3aXF0qhtez2M%C?hik*~KFUKKv35tN1PW%|LS)t$6aDB#;p>mk5iR)ft140$ zpJ~xR=^Q^%D9~9%G6i*OLetvBkKTDMDM*Q)3zU0T5*dHS#TemEihI^TX<_upEjg1h zS?IS!gYDGtbkal`)gl9>1!y-u`f7Wc5~MbnI;nNq)lUj8C4$7U^KgsOhX^x*$K~`p zAil0_oQbuKezk_ZE&#Ngs4kEnA83)-DUS)U*%BTzQLefM&pnTGV6Bfl8n3>QG)%b` zcs(5G+)BZsI5Ueo9USDrTuFiIjl}`6jiaVKYDSbs`}o8QBy4<#Ehp3LOpgzDoi?~LR3;|388jD*(mi7=I_=_xRNmE~#5{?kC zywH<-FhOf6Zj31rOsI=1bx8{z!*YC^|qF4WjdTQjT#%EdJ~-^usOfR1{}S+VPWqsnn((y&tQ@QhiNFS;?)` znPc?6bbKito}5lX^^A%d-QVGv-9`0lbc3OLs)!#9aO+Ecx}q(JV!sh}hYJh3iO40_ z-sRyeuet-n5)SK#?8eP=fL{p2S6eK+8u94P@Ks6=ksW>f;B@ti?VN!~q^G+f9I07~ zANB@r9qgl~i*zqA_48d!a_AEm-`Hb-o%#sIg$Fa7ClLWS@ZNy5pJ3{1tMhVtFV0l- zzSTLoYpC8gs>0>y`9Oa3du!67zg=xs`U!E(xY04yAdPRt5Dd_rhPp}ShX}ajRUa*4 z%3@l7h>^lmIoOr#UqC#|{(4GqQKS9RnoA;XG`PF5BJRUJo7>bKw-)6@h@CB?aua>! z)=6apR9~SBD@M_%7}@B!&cedAgg$jtaU6L%*=bpn?#)3^8xBP?+g*y& z;!lTU^zeE*&S%y+-D|Y+wW7RHD^C&S9a_0cly_?7$)dblD_4s0LF%^(GN)s#)S$2r zYa*NxL1Ke1lF=7omS)|y#_^TfD_yQ%r-J7AeCh+34uCaU5>gjMb*hfG8b6Pe6Am&M3 zps!}Bvt)=u6=#5rlF9Rh>gZo79(15Ta>@W_X^Zx7Zi1^giJm-yEP34cb< zDrfl-YB0rVIcE1-77c_W2(*B9+U_+&Uw9zow6F}VPwvv4C7BuC=SH#_>) zt=SmKiVUxLp}!k7)PPw6=%uL3~z=&smA>!{$>XBqLl2;@Y)5G%$5#S zoh1h~mMWdON08^!uEOa#hE90CX{C=Mr+%mBG&trUvR+I8hu5a|fdkN*1(4aH(dS1S zG&&^(4)0hoCsqgXI0#;X|56?5t8j?P6%NqfvT>GHJ0^<1`@;`2oF~U+TP9{E%`oEH zd2$}${I3GkboM~@lgm&}6Ap?0>pZzWy0PD7It2LGXhqxDdgsaakhiH`q>kcb=gHFm zIW(`PZF!w1&jDmeiZ#xBwuDZ(F>8{+=84Dd}28Ge%X1lIy!qGk4=fL7|3OH(Qgi9 z&pZa?aUl|QdVs5FBRLHE7O9V~MlRpQdC;FW=IS5cp zg)kbRIY(H&N?{SI@-Y$fb1+h*LA~*+IBTMdZp$`qL~Zo%?sh9Dw;`t*xma_ZC!Yk! zEPfd*o!ntXJ$Hf&x;Y8s$wTQFema)KX)}J7f)%cQj`8FMwqLWJ&tvhmDeBqQ&4f&7nILqfheE zu{#}v8*$swDEV0h)$-jc)v8xosPx7kwHbX5tW52F;yswrm*q9_pP3ka9&f66+6JFv z^p$$?z=V7)N*HFv=qvYX8#SYEn%7)iOV8SjzS&@cXXhAio=af5dpG(P5}2|8w;(TG z$r*jOcr9uk6&+r4txBdBzFi};j=+KpV+0SbRXCwc=A~yx_$4;(^-&}8D~&f-pitdT zO)8DPYKA^U0evh&6?XFB5V&e>W`UYp$T#NQM(W(fnjt z^e1VkJ1Q&~SldVT<4xRp8e1K(rV9D@z_$qtQ}AmowNbjZXI3E=4JW9Qa(Lq?DkRIB z(zKHQ%?e`LNIB#GmO@RNwv3ewXJ2fTJm*NK^tTL*D!+BprS+#k()xhMI2I)t#OEQ?`?G0rHslabFq{?q$*3?-IWFYEX!OWn8jqobt z&6Yr2y=9&?U2Z5VZ?qaR8nWd#8|P%o%L(7Fqb{DX5bp;3 zjV`0x;Wad@>@<2X*|;Y#mU+CE`rrWn0kW~R)EoahRW!}$Z#B`qcLmKewV*^`*t4}# zWU|pWH(scs*+%1}-P@yKOA-KWZ%G26eMb@iGAaj42f&I!L_n8Z4BRf~JtjRLAZdzSn=}@nT%=4u}8@~_J0Qj{- z9enLO+y~1JxM1?d?h7|bW%%1&@&r&OfK31)i7Vdjm#9|39o{(rkFa1!e*LSF0pBjeD4q#qdhxM(N*C zK7(~mlHyy;vnVo2-D64y`~fyex5+dDV32g1ObY-;=}Wsz8^9(hvCVX#Y?k!ccAM&Evy=nAwA=J@@QCeZIR|3DS!L!qzT=GE zu+glHr`@V9(5j1IABn%#HWPTMkQmV(|NE8|vjNcfuBt`BDkX14=W@!4y=Vh3e|a;y zki*A{-Dpm~emm;pRoIWVP$qhCW1iBATpGlVZ$)p>0r+0DT?gQs(GDGe??yXy0KOgV z)dBc^Gy;G{!iIDm&m?xFbWw_(NayVwKFXGKkdsR6N$=E^X;ZpISEgO*J-RY&OSkLF zv@d-CWs4Nwm@4F;w4LcgyiVJhK7x`_8o4!noa5;CrcVH3lk}U@rvOQpbi31Mcq432 zckzsFf7*-zJ@})ZyrLwN!8I^oAOfL z;)r6GdKmc(N!_OYj5kW`Q;+hpexv$6hwz>1hdis>s{V!plJ}~|^+>c?J;4F--Kx?j zwyUQ&c*J(~a{x8oD$k&x&4P-vypX(O#gG6Yv1K))Y?G4qtQHPZd*PebYhYzIKrNEG zZB5#>I#A;fQ&DVNz0ttt?c>LD-}a^530XaHtNA;d-9=OgBoxjf!Js-Vt&!e$}hUn_pwR;}? zTV{%W2hi@nov`O$A0L-FAD3}b`-SrMyFGVLp>72EhsZ$>{dB1L?9iqx%9dYPI#bPp z59iR~`9nYAY)w9J^Ri{_cRM;FdnP|uWn#u?$MDt6xaWc45M#a3<@<9CpL~l&Pwy>> z-motXtU02c`)%?kmC@Pzu8Q6V(CQcm89w>76y33}B>F4B#_Z2EeR4n8iI(p#ie9td z5^dd|$L2=AvHwczr&p>f*iO`=kM92`bUN=PAO3yprB3{t_HrK>xZ~xW238yO9H_y+ z?FYV&e-9i8;oqwc&R~{3D-Tw*_({c3>8C4Hik)h?NiBD%M<&xo zWPfc%Y_Lgo#b#g0#g?jn|DT3-J~-M-kGGBz%@ zy_i|P_Vs?@lA zaBeczg<>|n$g5Rvd$5*>wrJ%cUe*x>dRFY75>`;uso`vUa5lAhL@N*RvS@RpgnjGk zXSABV#5Y&Xr};d;e{WLN{?}r6T*dN>4r|bD56&dgXSMPWFYDMjdKH`GbWDy5H!WGX z%2HO(JhAnq>>B5^1Xg)6*3U{=opWKL+M8TmH-TO2>_}9XCRaZ-flYNr64gb?)z&gp z4<@QT$<>`@5a6Cfb#8L?8)dA@`Bb7hE4jMlYEk&L(LfG(zzMe)rnZSnE_4TCC5%oXR*OR>`)hmM=4(bue!jljNHyqH{lQoa1 z|AD@q>|sRxtNMB}2z|XG4Q_Zvk3eItM?n3{`g$_z5%n+W>&ae6)bH2Vlez2a$4Ka4 zpB`aLEOio_=AMS}=0-93Ky$}3Tik8-R;g~YmYHH}C&72#8M|i^Tgje@{dN-bIQDAo zg!g?vcEvTUVO-ovW!(8{Dwe$FvwNi}vB7Itm28_5d+{1}E!@Y+YuI(HC{|X^=4Y2< z!QA%X=jY*5f6Upq@B$S&8e-eZSs`nW?J8%}ve$8}<9aMAblekT73`-nx;Rq7iYWa< z1zXIXip{TNb8WAo6{k70`NP}sgjL{OMJJIEhOX*rm>l^wNscq)-#zEGiU6< z$*fzYmKDpZV%M-~vBoNv#cE@rDmF)+HkCTcihWqcjL8MTLRRd26`P?aJ(+dHzBh%f zBG}len2yt8ZBseHbyG(Y)M)%}D)X>=Vq>pmmF%Hd{k81fIK{6`V|S{BHdjK~oB#9o z7cPi_cp|oVI%{KRW6w=z``K%;t{LpV@^qM)(A!OS=aDBC4Gza5*D)^|?7WW6B-+2a zjL^?C^XNbDEav$pKL9P4pC78N>9#1`DZ%82$iZ-DBbiT%?JY$A%o|9%7O!f#Ti z49}}(ZU##l4$fhF83ruBmX%Y3g|%#{TZ)hOnavjlspcX6b!q~5B z*$r%a?20;e1qR}VI@UprpRQv&!P`ys>`Jyb)>F@}BIrZ)z&#r~TF-8lrRlM%8`)h1 z&Y#N)GvfLjYJQ&#{Gvb*sGf^)2F~WWY(;j0#iN`5Bje812vgKKa&|6TN@xpjVl!E3 zY{xt{mx})}kIkkuZ$4W|>BjkN1*OO4vvHK3nXhYB729?bt0nNeH?bx*J66~rERP%Q zZ*O8_W2+n3xYUMk4N|X3){I6R%i4&^IeWOikxgcf+0)e-wE4ggmV>jgyPMd!~QZCv8-&{b%a%} z$D%?&5Ka*!PXHYk1-k7N~@g?bytgGE40EW;P|oa-r_T z($y?hau>VTM$zSU%Re7*4b@p<2kv6csXu^?Y^yuGKPC3h=h%4T53!dTzV>g}8pFzW z5D1EG2M?7uO_OiGwc`YU+nV3Ra0vki-t2JT5NTWUYeRKsRM2Z3xg3N+{aghdP_bS{ zzbfeEj?$QQ2$P^8Hh%~)WG`>CH$i!C$6##h5Q5A*VlNFLMtXoFJf9%?yoMmhuDyrN zS^5MJIPpyzj^3YXx82LGFwrLC<=Efe%RERdvdWnYw>96R&WWMMd#I~3T30Gt_-|BX3MLXfaVBmjCQ4&}cONTCqy59CS>(G} z>=*a30@-1Sl~0tNG5dCA#>5%7on2Ayv#0`Js5=ft8!|RudG^AEmuy$*Sj`Z=f0~9G z-+{hI=2Lg)erGK62`qH?Z)ZQSpCv}{XB{1}KR(Aw)ta{wHE*Hj+C9+iYH;vI z-5;e_q1uFQD>`oHv|bx}Lmm0oI=08YwTIn<+2ns7OTm#ntT0yhJj+P}#F7C8X&XM5 zGVZKFV2c^|`{&uCx4g;e!tS*R^K!@M90W_(X2)LD@L=1=)$X5HK`_tXs34treyD<; z=`hBA_X7JDrvt;it@-hxy7$$Z$5C_SMON$d@|p*R>a;cwpk~4_YUc8qEr|}cpk^a# z-0f8J;O(%6I72T`3H84kX0r+gQP2DNR2}GtG(i2P^QMe@N@BD2!o}{2t=-F}V2AL` zURK0r#E$G`#lvUzvgcWTUEH^Hv~rJfLUZW@Cpy-}ezKocvEkT-{a98Xjpe_@%Dqo< zG;y?|%6PovO#;@PN^B%944mpXYKpN&IXCw0m*6CS6MOb0);fMSMr1$KE~(vc3ZMLK z%=0pHIyRy*v}xvYR7;+WJNsg_FN6D2u?;UH{40)x}2U$`_2QAKpdx{V>=)1qjC9;c03>Ry~4`JRDjlgvO=}$6Hn~hudu4IKjRG! z$6d|gj^nWpUSZ#xGYQE1E!035>755M?sO9jp>Ui?DgZlCmUJAR(Kw8~`zkx1+Q7AT zcz;Sri%XHOeTp_*9!8!Tto^#;N|RuNnK zV+1#u!{7cf7I5}K>?d!sJJ^cYyhCi-=o!KKd{0 zCJS@KihjnT?4O4B{*2wnYAQf~n{n;n%+1sXW}63qA?~#{U&z2|ovwFuf!>c_H*h>- z^9i;0jBUS;ZT&ZPS8U8LSO@#>;cxzeJ;B&>G0%If6s`zne!&COSiu1{ZaDZJn=lr^ z+kGe4KeF24Yd>QL8KU(sPO^VCN~D{&bL4#Hjh)Dm;|GMd5C8VJtiT~l#uvuOcE*gc z0tTe_W3!oj2Ug`DFnOF}L1SSwP|;w#^f-E!tQa3jicH%{$96hPY@90SxW8Jb`h{?M{mVX2xhL;-Tk4flRCOH>6 zxY;E8S$-`@@m6neW~HG`k7$sgO_t&J%<^~Sn1{*6;oDN>EO`MP<9*s7INM8Sc%R;& z7U%%)(@M3_PK9E%Ku33zHzC~h7jUz6!TL(b`^H*RbG90#Pa*T=|LWAQmXM(#jz^H_+L6}xRL#waWH?XmKF zrFrPYrq_-yS^Blf|8e*7<3j_sZ5vKJiT~Z*cy{P0ZDhA&U_@v%^b$XY9WJF4*uUZD zusD##SY-_z9;&zTj<+=)AKJvx1~r7N3rlS9tqX@5Pi;DA9BMwHPHDbSdg!b+hAy_L z%fXL6Axrr5RNIQL4}G-!hnC@Ajg^nfvSb)O^0J)h`st-mS5~eF4;)e0rDKQWq4tpyf4N3 z1gP+dg*ms0W>vgEQ&VW_PHM49GQ_47%a38KVm~jIy``mEJ?7yil8Yl#fkfg3qIvu9 zgcAATj0vkH?f+nn!uA${9btPH_|)4*7XXjMelex;V>dx#Zs=NUrdOo1Mu&wUILbc`4zwl*C#W|6{iKS1K z^X3no;jtBrcj3^#W&HEI@m6YsVs7H~hn?@+~HKjVou$6Oc5{l*hv%1bJ!rzM1krG3QelBW!Isn?kI?r(#Xl%j2`D zX48RN_P?nad%XIN>t#24YWU&n<;ez+eY={d5C5TBZnMm#RzfSA1cAu@Eo=nnmi-ST zgNAUsGn3Z-`ym=1{ilW>n=cPB_g-gQ0el_9vM;RF}?}-CgOVm@G1Dt;hT$Pnu#xne6~Tcusjr=L}4GkSMY7d z*NATszV-OF;d>O{)A*jnw_CPBJ9SPr4*!|PdD-P`SvG#wlwHIQWlv)7WmmD&*(K~8 z^4ab(R_va}mb<62HEu6^5Z_Lece|_DEABb$kh`8K59fK{w0}%gmj|@^WXg3AwY`bbR65Ic$CIB(@pf&fH3N2zBRjOId1O5&Jn{y>DR$A;vlj`=x~`A6i(*!a6MMF$-(4 zuw54RYYY2d3p;CJ&*2KpVtyOO@ivTu45L^sGUr)ln+q%t8_g3ejk0-`MPjooRrtK- zdC1SR6yckRXL=H2sUG%)(PCbN{G!xSmTt;5zmELt9PTh5LS8w9!t1FP^9Lw=pjI41 z{uuHf0R9Q`pQP5}37N#ETMIeCdC1SR)|(rVHUc)!YB4t>-wfC?q{{$n25dR<%aL!i zIskK+{V4lUUXHrWRy#ALx)ph~mC})k&Ah{EG`x-NqW5=uxx!B|Yy+V1P!L6nb$^d%smEtR*k9}k*mk(LX z@F{K-W+O8VU!i$onwL#XE92BArs=6=snix3K%r3g>8VzNNG=F!=_Hh?gE=G8>v?%% znoU+Fm`cr?(**yUNA2;8i}gq{5hpX$Ua2>I@5IH$dM9xSUnwykOPeON$9w;dDyJsz zp^?4oW!L9RAt!0H1Rrrh`H?AcL)>auiFvIvb6|J0m$W>PA7& z$yenyPKi7G1)wjpO(KjYMlEo?YF(MyPUCiDN>XW(m74e2O4vRwMIm&ZF2_Ytgsnbp z`ZHx2DXU(#(L^Je^>Af0ISFYJJ~9%meq@>I2ye7BS@ybgGIyGA^vz7pE2CD}&5M#6 zjcoYWC=(64Sy}$2jz%N?e*v?b!|C;kP94;V_SNe08jRAvHeAsYzf=cy^FUlv+8Ao7 z-Mle9U#@`X-I$)m3asSOm&(W8C_3aRCYwCL&;K5m&!ZRy~ummlj&Ih zpG^Ntzf!iyQYas@R`PUWnn*XR=`l5}vw3;_KARJ%T^>kBsvuKG8KjHUbh(;_)3eNn z(u)j7%m~NQbJ;Gd?8ib9gq(-ct@12WnOrw&zDjO1x#VV(&G5F_P9FqzvG>eYY>@5p zA-PCiW+;-E8*1f!ioq@)G?ZYua>{QT^5y4qp%@p6W%ADr4&FA;=;Hl_(YN1V1&r9W z5zD|Wl7ncL_}m=VZz$BksGi_%xyz&t$aCh8(kt0VN_r`X(30sU`CcTF!~zZBB(@{f z309p*-C)c$Fh*qblulDqGJGn}L<(gp(B|GT@{{Sr zw41$emH$f{0!`IIePNT6Mju#}a@de1cd5gY7#_R4#z1Xp<#w|ZR{5kx$p(mrZE!m= za75LKfuK4JsFH5K46<04#RunF;&oh*!yvdr1` zGLDmN&xH$c0IweZArc462F@C83U10PYJ;ifiE4w1_AHi}nk#49o$|(XH=7tI>M~Ea z%WPw+6>*_mejD3>jj0ZEwY`dWRE>7w)G@3Jwz|e-0}ThOwmaAa)n2RZF3=>Kbc3#q zrKe^Y%rg|Z*vM^Cez`?X1%J?#{OTC6I|;3=z_c37P6PgWS-Mu~Bmn(C=$Pgv8fk1< z4HkqeQ1m_vkt>zI0b8(-VLLE_4?+`}Momix%*~2Di*w%$?w_{g%hh%pOHH-2PcXsL zQ*EFzMwOOmTGZp zU%^x%CD`5U6^)WHx2YVWx~MmWL@*oRW`xVp^Fp zgr%4=a9U^-3Yn0SFYg2myNeZnMH7Xl4{wdr}Yc~M5W z*`MJtugP$mH)eR)#tho7P(S(jidccgD(}Qp-!7oI(a%H7w}y6Ea*M0 zTBS&ZRgx>8nBq*XQ{pDuB%3m51hPh?o)KlO-u)-SiP>^6&7&)^=DXR`N?c=o=6w)i zpH7HJ42=CLOutp47BUZlM2uF^nol^??gYDWdoCq@b&=tW^ z6rmIPN=EtM5#ybN%%8z_Y3W&%Q3hN)`;6NxwbSxG^A{OP5&Ht%EV8)31Wu|{M!v{! z@%8VEi!wr{QYC)|CjazrQlgE*2@qi9mkY-9vwVd)(^14S9c1K=B&}sSgbSv0bgg;N z4yUf8e9D)B8x7Er8`zqatTazV&l6GJ!FNWJx0rZ#r^yrLh>8R!HD z$(QwE34nSMA6cLF{Rwmw$E67U83ZqjUS(WJ<*TK=7=vWWe}bf=GlunttL?8s?9ZTu z{r|+#Ir}q+T@I}V(A5kPsWPf3sRGgn#Q!5aWpr0|xeRD-@N)49Piw;kr196(p;hQp zeFN;pxKGgHj$U)411@tEkJPC81WHHu2@k3L;{4GB*JsKo$45Sutes#Z^R%*PaDDzS z#24eQt^0pT2X1I0;W5L|OgOF?XMAA^tD2#dG=une6G_nu|0aDJ|;M31YrDv+d@m z9X9s!R4W4BY#Ddu-vbhk)iO$vr?WRJ@)XZeI#r}f9553|D*?>aA=8__ z156W4(Ig}F={cm}oyw$c4Ox>+OG&~p=n((?Bi!m$s6Vn zRE{*A;9i?^sFi1;9i6lj*IJ!VEo(ME(yHdF^_mWwH2c>8WY5|R*IdR(;)FwrUq(tM zeP|{_4X8p4tA}i|fZv}xr ze-t0icm(bLoIzCnDx(PL^tMX_q>Tls_7VfB@R1yMIU}hJl4dG2f*MR4II`uN0Uv1* z+62&B18=M8pUg(D|B(ZDv00=sqcPw#A9B>QLs%1OuhhtoHt2?h_CQ&H<8e>Yhxj)E zu*+cwj-K%yfnRMz`UTQVq!Y2Qet@$OL9pI1&zz6_Dei?FbUY~zwDWMhh5I0QAveB4 zd{!J4T7e^?g+ut0{NnK2BX3rZ5$)>vOQYp_v{kPnY-}PVZ8n; z%2wdIfKzD*dk2$0?b3Hf0$D;T!W$P_= z^P_;R83B7Xvyc@-pl37l<)=+{`B{@y-iIT)iAE%_b+sA_iUWYEb|MQ zwd@5*{%j_lG~1D>J)|F(l>=hhP?n9^RO{F}=B{EVDgH%@eAZ(h_L+IcG z6Ruf+ivuG07!Es0;vnpXU=xkGJPqRjbQT`|V0h@h7D8CrPH4}RI+g8IFmCS|Yyf1* zr!Lu!)0$;+8JvZXIbS7ZGq`Y|cJbcgt=!42a>p3lR#d|N*JB5;569k@pdx#Ucr{%C z(^*&{8P{ms=BrYY>TL$R1ry4-II4o-XrE|U(18&~b*K8|n) zsA&G(RU=G5=kP;JgHAgmti()WvH+LNr4B-5M#&|t0 zl-F}>)exx@fk52P!dmj>FAFeSHSupI(h_t=mv)*K3gIF>D)YF7=7y{nj(c|n;S2X^ zoZF4ywmEeMZ=}H!V>O9zbagJ?2EW0Yg$IR+erf3;;WZ`FVoZxOk)BF<9f=Z!R|ZW* zU^Z8tLv-}CNCq8PuY0jLeVI$@#!0J#Dmsz4Sl-PP;_WXI0jn`i1nMxRoRlVko>kI1 zt$m}QD4Kcwx#Bq0?)Ck70du22J*)~ap%!AZ8KDs`EAZOQsboIHc%_=sJuR8t7*&TC z8`3dE1Rr0GkrH8H_vEt3B(%LTBgj=wrQUDgr#OJO$B;=(q@}#$c`ra{{M?@2`^W+RU#+0}A+PWf0HA1TGPqgik+FsZ4nFXp@f@;a2$*-XXnv znt{41d~@*8)0$e|C!abBym7)m<*I&4W57)jr^*B#(8m2(3HMzhFeKkNhot00p#c?N z6ReO6R*lEFLKCzTBcV85rqDCQ%lpcp)&?{bUVRo^Ml*LCRcMdLLh-K^`EuRoMH`Ko zdgMuy@p=V?IeGx{6lIMhN?wFi*pX0O(mJLwMR>#v_h(3jR%WT8wD495+rjwLn2`pA zwa8zog(HjtWuMljEN#a?4PiLzo$AEp%oD%V==x2jveisXcrIoxgfJl(^PF~bh%b& z{u7s^#-s`rp05(aB>@&tc(1=QqlkaL%xU>07}7HuXG)bY7eixbyAk{BP9*~rxVvd+ zaS-xZs-`_MQngNrS84`Gm72j&-U?zG0WwNqgdYKCH-<-ah#UQQhlJ}wnc5OVqGOTL zRHTj*IN1M;hQuXPr4mN<5jOYF!e=MK5i1O~9B%n3b)nLnmli`&*{eFLau|3y@Vua@ zuXoY@M{B4}7YeFK0~(wfXoRxlM>8>7AXS2p)~;0E7O&H{)lbEdI0{v29BG6qFN4tK z;L!TuQC~!n@zUG3uB**Q#u%~5r$ed|{QeEr@=B`R{DBUr!9E$|WuJ`k;H(3Yv!#qL zi(zX6^!^%PV*tzIp5~J=;*lPu1N=11uC}onD)3}vLW&!7v}1=m&6#7ZY#UC#jRBCk-Qnspf8biWTiCOA=WBNC^b_Ou;lqFyGWZ7 z)Zvw?rHa}rw88)}pA(vpG8!TGMF=gt2%Kzyv@(*}(oyggQjumfBO7SaeHDX6suuKk z2Mr^*(1_Dmmhc7xSlkuTAD-{2fJ8+yoD5^Tj{OpBB85wukg`Q5s%9uO9W<$Eno#HZ zHZF_-jnM=}R;gYJ%PnV)ZMjT5myR2~$fO(Y3BcK|1TE#FtU1x?iUi^%@${p8u}-&w zmQXK6VG~jw;VMwJrMCYSJ9*?XX~hLoE-^TyfyiD{X;!$5;yA`A*np(vzWKNn9m&o_zd zCeO)(2~8T#U81dq3o}!oNFi3qS0ksa1EE4NMHhRyJSEpn7?jB(v@(s? z7<{x8^1wskh{8-tRP!0xv1dfbT8DNJT8Pg9Vl;DII$DA`{IEdRxqfKez@@QPXr>HU z%^RHMYy$>)2md{sRsPJh7Bhyo=9D*ZHBirVE=8MMnh2EMfo}}(-RQ{;8e(iHrLhqy zwZjjvc#m2jJjGys+F3^Xe>_)L%?v3wv!{V6ypRJNeGa{ZAZMYxW9)qN;w5|)PfIm? zyRJ@yl>?^PwaI8c=A6Nf@eVNp3bb}CE*temGCBTVZ|?)t$aUxYwvMD$t49)&Q0otp zCZq8%879MAn2fkq)=Wl@Wh1Zg4vv`^+wzWVGi&A=d*m!xlNk4qXW5ZAq=N4%6LO>M zkh|oCt*~{;U6LiWWQ|{Ng;bOqQXv&wORhGQ8opFVv=9?UbW?WKfAx5wT^PdC=UJM>iaGiY-3=KGy-?T118r<2u^ zN`a0ekZKuH$P+RYFX*Uf_Y>)XJIzehju`xLmD%@m7~zoNN|5R^+|9anAP$N@hQp;J zU)ylfBYTlhVyNV(#KO>@geMjGPPsxQeDF%S1@YC@8qnSFN1vk}!$LiLpJrYJfUy6n=QLWMMyWa_Cb1-N7RN%JM=rpV`4O_N-Udf%zmI}crH zq0P{=;sW7PD-i43ju3F@-xqyMwCa3A*#s_=B1{Io7Jpz4EqZgU1GVJPvwfOE6}!1i7Gz zO%AU$?Ko}CAhL|(D{?%DJz|11putTz$lXFb$Q5SaUb~W`A|ALGDZd>&rbB2!pxVh_ zkyAmc8D2{&h&;q+Eh?S2185x&!r8(PhcyH3iM{XzN> zoQ%pNyvM_P3E^5nZd_BS&L1`X?AalkwFLFwJ}t}r!4^w@Fo=UouiwmU`d*AWAo|vf zZe?Ln(6G-yzzcngxe~iSh_N$XE74ty!w_p9#?hr8ew&?Y8{NSIViNuGn2xWKG#@P) zCDN^rR+QZwwTo1cPDYW?WqJ@OATUmW?&zM58qmo-nL0Y2{m1&)w}h)`e%J%>cklvH z|529@td|RmM$Np^clFGE={|503HE@8!P>HM`qYZ$F?@Q(>uL`sV&9!tW}YPfwEm73 z@?l|SNQT{h zVJ?%*g~FC)TtP0x zwT?-bY2K{x)&$$K;oW~PHcME?BT)|VtmB2G=}$+;nM3679yliEJlK5}cSE~+`+>k8 zIN+bca`k@eiRptP3U>nUfKKCm(6>--LHMP1O$noq2Txn{x1N|HtKDYF!^5VXbE1|T z?N+&hJm*8jK!Aqi7^;{7X<1-}gh8T+8EH0}kMo3cXDsdT`K+1eaw9&jo2z#WcE`NwW;e?!j@` zn$gkvn^Zq6E(~P?dnEgDQ3+9Gw2+uy*3yP1kC?ZG$-RR9-K<@}k(=#m-*3&0+Ld4E z{lVjVCkdkiK5EUO@52=%0Uk43`HJ~Ush`7mY_FrnRU%P?*x0Te@9^J#0(x=$b{!30 z=M|Sg<3$|DC^vZiKZQpt8X+P8`X{foAp6CDjL);*(hQ~@@@nWd%W8;T64CM!x&zYP za6f-nIe+12zsy$m%9m+g3EX*lU{yB-D(It7*1Bh|pWLmt?UluWLVMRTtCbzT(z|&D zK`{|(K)eSVbCZy_QT4V%c(iq1(NVfsB#g^?CmW!@AXZTeXfKuRy;9%4*+9H&v?`hA&-;*5FsV$xf7+Ij&W zhKEm>`|B`kJwwf%)}36&ZZNeI2Wzr!rfA>ct*P5T@$b^pmC^b=ERS{9PIdt&J8fR= zFg^{7<2LKWv82$lAxi8y@VM9xk$=6W2FFhEWDhHv$qOxBNTU+aO5kp+M#t@0$Nl*jl7rsW z3|za(w8{Cfz`Z0Wo>S%Cu#o#uxq8D`-b~?fBkK#}`v9;P_JR%F6;`$PhVPe$!lx`l z;h^=77($1wM?J975-IP#7_5m;1+Ds?2Z%MvV<|WrU_)~K5LK~@g+Q-j#w_f$-oc&n z5E23xQ-$5l_U}a4Ea|v-&1;oo;ub=dgGkPAA0cN5tz##cQ;;k)M)j z!TyKG#p|@d*4*z1i}<~83z~_hL7E${3Ey&JzI|Zn7pH}N(hfbf(HAzq5?AOp{0>l7 z9JmBCChGqipywXaBGYtm!X}S|4~rq2OAO-U*I|5A8}oiXTyHWIu<=`;t6sCg|LA-l)xzx@||MBc0^u8y_&Qg!*LwPonqG3ws*up zI$93sg7Rkgl$r8Pv*YrjPEJ@Yn_+x^fXPk>|9>#Bcb*z!c>f{OPBk=2MFyMX#MBx% zwT#W1&1%sqV^?3~i`Qa_U`{4tcBo=JZ0=1YrW#anXAEoRRnv*%@I&?=(BW$W*+uT= zf%=Clx4OjVPMTq8ndiUe|EBkV>D@SO={3)WWg4h(w1pP=z(#FI412-sAikOQB9T-X zTw=kd?(OL17qelV49rWKM@@b^!>9!=QMJ`-LIWbK`FS@t<8JG zZ=QeO@tx%8M#)rcS_I=i8Y1^%s7zZcE{KzsQ9RA{p+dot zI{Q7UB4fkuY#8U0z7ulRlxsIyyeEe~k4^b{9kk7(3*$)&Yo2ItCV_U^^U#wZp8SJ& zs&QGePTgZ^LW))u7ryDkP~7R+s~mWNwHJ|w8JZbfMI5z0kEiwyTE*!;akN;?M3g8FqgMvo1M5-M8r z#!fD4?1*^YWo z4;xo3lTMFL`}1Lhi>WtUPc!xQ<~ErwjKMv0V7ts(`f7Qs;>n}|39FTOw=B~(;MvG2 z@!b!I?_oL#m#m?9I*~|{ld=k#Ug{kOz36E0oCiBz(COybHXGR=u9HlT2lonWr6(Zh z=%IqxgtknikwVr?hZo!W`OTB1%zMZKau0eKDmJ>)x#=cn-ps^vbVs)i%Q0+Q?y>af z$YzTOh@$*yxexo8_eE+?^CZ_ExakoGtHdMxfZZ3l`S54@q4$jBm)=@o16Dk?)@s37 z=xe#;7V==^3^qy+BgjoGnP)~OVg+s=>TtK|hBb#M zBR6hJ-JzK22lZJL5!o;z8%AdLz+Vsi^dJtB*Kz&pxB;Tz@$^XF)be~@ZKANN4(p%T za-O%uI!Sc^-<}@Fx2IlwdwK$&ZidCG^;U%CxxxLgwV`LLyc@D`P#RswQot!V;|Q2iOY8;$}cQA8-481ns?zYK`XnTtoRxF~h5%R#S8S?jLJ8F?v@Vf&m zkrQIbO2hcGkZIoU$e#Vwp55G>3UaOeot3u`_m&wBtqteErzJukveqmfC@G=_uombZ zc{g%9e$3#0v0=R^HsQ7#sipX^3~w~8DmOM9#t$9f^{KhTD_);AP(?WgdT<=Yfu9a| z$3gzk|5NV);a{OSjfZ;{y$YdTpCYa$Fk_X|4ae}S33#&EJ9~QX>}i}mjkBk5=64=m z=x|aUXE%l4$=X~9-LkkhoyDXWPH2{NFRC6kJBGcMqIIjBYlz`TAI^#w=y92LlBGDj z=(W*{-}D!h3&=hlvzjt~=*FCyD>u0CBN5c;2L4}WT$RTgY5Cw_IP z<_RCD><6TYw^|oOYjH4=GQ(rEZIa6R1CVPMgiU7?(bM>C54@Fw2P#`8)(JaL(E4vm z3VEPZH0&|*_<0h(3?jG43sg;#NKD@Pnw*Ko@arXXnBADkKFo`tXF+`Y`YM5DaRrqN z?|)3dQ|%--m#!AJpucF4`VZOe8U9)|BAnwH;VS(;EiKzS35AV zNR{+QIB181TVapw>F$I50ew$V%VqjhF38EHudL`IDRrFL$UgHzC>u`tC z+~Dm$j^M`ZvP3Yx>)C61OtTK+(((RbKMVIxTr1JNvvH1cI%>WTB(vswFNrnlUL81) z;XDVMw!ZNU!{ zh2i0Zc)?3ggV<@odJjE}(CrSdq@(+zxV0#r7iq%}FHVBBZOBOOqW#v67-|vPKb~o< z9bq)6J)bA79oT!ue3Xb$SY*B#uHRf#{An4VC5by#IS%A;D{G43=bvKK^WZTe#vK!p zIwrn3^Nssvk0Y+UET`~8NvRkXZ^SVFgaqILftD>$PGI3ntkw^bOggHpC-(HDql>7y z)kuEY;Kui*cPCbu+>8(JmQmzM-F`civ_gqKPpCys9?gi%M@Bj!CyY*fX3veL<~{&D z&0D=a+(}#%mYX0B?q$wFredu1v9q$=7qijhlr9g(gmpwdEEi)fmSU_nsyqjo<`a(Z zjVfz)JUkErTv3=@(u9b2R0L~kGNj++5! zGPFgWj-9eh$ME2W8D@I984)I-Gpioy4#;ih;3ba9h}Pi|ng(sb*?rPSW9 zr#*qa=^NTF5nH_D@sIo;%wG6G%EGk!INY)S4WEEcM1@8Pz}$~H#38xXV5#8np506g z#%pHzkgisx2Cecgu4GlHvNNt)F3=>DYQ68U^*)cO)Z(Y{+hp_&BYpgc>618J7WQ9Z zfxfamviF)EJJ#FJLC?)`pP2iKa}rrcCFB1$`lC+m=-!)n^*|WB|KW;Ck=NQf-)!l1 zJteLW&1>K7piKU-l;UPWe^*==;OAiTTg7jp#bxv9QLjBdcA5FnA?M;J@!M@w+c6CU zT`wwC1V2YgGJWsQ#M-^L)NtHpZ`N>175Y*dvv|>a*6QHln{_Z3ueHK)q05E1FyA*X zp}1(it6){-;kdxuohpyOEr}Q5izwAGTta)DDo?}(eoRh9%%|k(IGPX&wI8Ek`qn## zYE#C8c@pxDjpfz@@;aWC>19F+6JjeE#;-cj|55-N(=Wh*WK5rE}0 zIW^t$d*q2Q)zY(P@7`l=_Ki-qiwAU05Sn0|`W3H?AL12ZtVqMaNSGRj`0PM-&OZ5j z*L(j?oVMBm@;5*CccRhiR%LO!aN#w~5!>VbZ+_=B@xM83;)Htao3q~+7X*H5RsC<` zJr?DgC;yvxMp(MPSy>YQC|a;J+JoXvo8|cR$A2m?^?7~try>^?XOtIg9hl_16?d{QzFWBs&HrA- zcU@T#%a+5}f3_lSvGiOQZ-{xzk?Y@iLnJL@-~8X-!0SKNb`dY2T5O+H{MY}-e;1Fx zUmR92P3sY=BJc*lBTgeN9{fn&G5WI|Q_i8H2wd24L4QG;M~Qv&l{dxrEb%*VvA2r= zR=cX=SK_FMA!9m(z>A58)ob7E`?>fg=AwiM$U8RAgZQ0c_n%6y+A@^wi{+Wh#5+fJM98X3zW z20zFtq_b5_#7k{ehf7GeR?!-z4^*)@C)f&6|0G*^Hr=5lWwo#hb*K!s`z$H zy0eP)Z&F7U&neQ~`29v9-BWcO71F&`%%eybs#sqm-B)$sXMFFkI!+4dV%4Fa64C=z z$7vxwSjGBM>ES9?H%pIH9cP7fsp@DG(xX*u@h?4I#h&}p<*MU0Aw5xboDbPG>*Q$<-x{y9ubvz)X7pjg2h4f<8@vx9SRdqZfq?fCXOG5f|)$yp1K2vo(E~L*^ z9hZglO4ad%kp8UdxFV#_RUJGM^`Q$qSe)p1owU#vQw5z?2cjz1RCjjH2gLi%#m z@vM;kqU!j#kiJrNJSU{DRvpg^=`X8}YeJX4R&{(*NPkszydb3iQgys2q_0;UpAynv zR~;`4=^ItYr-k%4RmW$9^ertS$+mC*ZTCRc@mV4LZI-OBetYvzs*YEL^z9z9zV>P> zF89xb^y(m4zw_Dxte+FoYl~!k{X0{is5(9`r0=Yd^}DYx>9Bu6NUv{^{d?a{Ab-9n zr0?#M^#|W;hxJQB`d*{~)*t?$7uFj>`avUEfBeHDtX~$=4|8Pw$&VX{s*b-9(vJ&d z{pn9Kuzp2IKPi*-jh_y|`c)zQbeybz|Hdq=e<`Fl^l7sH?C%pOlCKHr@8`(+=FgI_ z{*{n^wn)~WznO>izX<8gu{f;1`1uTq=IcWG`8v7&@)u)p{c9op!V-n`SHE0=^&3L^ zWrD1~{#8b=I{rpTzel? z>%aVV2-V_MA^p}DgVp$#by!~$(!a#XY7xc`?B5ZR(L{D9UTV0DRmbZ>vWOIE+`=g` z(0o@&PSHmiO}Iq{mF#;$a*IJ|bX!DdA_vv?g`|lhd5YuaTY%;VLW+oS(j;)}-GJtY zLW+w;(lm;MSbVAK_>qtjVwW^cqERfP=KfenjlxM8)hwFC1~fkrQj=IFKdqu!tRmD; zh14uG@}nn3t8kX8jyHtVD!NFO5=pTP&EE?tDRQJ~7b&p~&Ci6C5(UzvMZ3tM6y6k4 zyBH=-Mx@0MG(Q(oT8xk;D>7mnnqLShBPK}GDY9Z2nqLYjD@IjldUVl^*Zft-uY}Ys z7Tr+wioD4As*Ya^DKCbo(E3EL$f3UcgOGZ~67^eyVwo@`RtUpll~5FGjCDduY%n$n zBVvm%Dz*t_u|pUWyAB&}kUD{r=zn^^Q$orC zr-jsK#jooMX~3Ffq!?Mkpf%0NFggiEYZs%NP_p(ga*RBqm(j=QCyZDN1bxIhz}7*= z5M!88B#c^1j1k5tqs$m%R0w73IAek_NvK$-7}Jay#;gh5I>**|#sXp7y2z+9mKe*7 z6~-!KjWA(dXKXMw8C#5P#tvc1x=Wb0;(m-8WYwL-IjfuDV`z*BBhE-L8VU2(CPp)( zm62qm810NSVZoYVWEq`=MQgWCtXg{*IYyq*%jhF4S^F6U#sFiGuxuS-3^R(15@Uoh zN?5U$8Dor!liJ^kb)2mej7h?(b&4^~m|@H^<_K%ndBVDN!HHJ237}PN0Ww;XwMuRl z+Y-TUTP8SdD+IS~l>%sh4egJJ5Ck+s0-9k2Kr}!Z+DA3C*@`iY5u* zyeR;&v;&AG4Iq{bfLOA&E%Mn3z$XDdyKFm%MVE56U2^ON;MfPik$`CWY!($~D%k7{ zC&SI~F*HVm5ho1T5`;lpBVowaL>RU;Gg=8HTauucZ0*ERTbeLt%V9u_0c}o2VhBjg zIDo`V0Jx?}0M|4HAZMll$vgPI4>K`j92pcVmiP*ngO)Dmz6RYwPp zq6z@VQ0TyM6fAH81q+-+cL|__+62%+Z2>JPUt5L}x&t7gyHK7%G26RH=>(v3+k5Gf zBKAH)+&=1-Y*-GqC?0~U-QKLMk&w10oEaB{j6JE&l906* z4-HWGPJ70iA)(9O>h2<;+dkpWkLBFpU6EnZ^x7-lMK6Rtd*Mt@ zgV1j;KR6VYQ2z?{#;a2ePz~6ZhWenwGxYq^6BKO7Zui+KqG7u`v=)F+v`>6QtA|js zS32UP8L<~XT%j08?R^iWf)L8~tw)B)Y0SRdJxM~vUbtAKOqj8k7$byPds(ISCykM9 z!(JiS<#EOY!6{ENrU-8QB0110&oE{gbBuXHm%PAOB=pNw#u8(hvBFpdbof~(>!iHF z*ko)mwi!E&U54cl0!+zvhLhoD_!t@^LYS80j09muZY0dgO$2>bZYAa&Nk)p%&PX#d zj4Y#*(Cg@8bTfJwIYyq*%jjeD6Z#wl#sHyTcMK8>jv>N;W0+AQG%F*FQAU|D#;7pH z854w7Ws)()m}bl{W*Kvgd4|5gTx3)UNo9$#Oh_p!gmz_>u}(-hHyE3YEygxuhq24B zxDcSxX=gYYZiY{1YK#aY&PXsC8BK&HXEURfkz}L@&CYg0t252W5|U~sql?ka=waks zRR5D|o~^xvl-kGWXA~F%j6uc_W0+B7lo%t7QAU|D#;6e5)p5pzOTzu9U7cj>6d|on z6Ef-yV~$WfG|yOIEHbK$CB`yig-|-QN*Fn`##m=;Fg6)mfDS*~Y~5k(GAwR0yq)1> zxEVf%Mi@O5VZ<2;MkAw%P(IYmXk{cBDS|$BsGV3jlxAcJt?o`nH(|ov!^jizo?b>j zp|!5S7$ju8LyRJ!;w>@CgeC77VcA<@j1yKY-s|1}EE2liH%E56Z=SJ0aQdnQX^G67 zZ<&zytq^*BtAsw^8e^Rh_ir#Z2?_req0zrhX!6@VK)&9|a1(m#eGFYA_SHuS<@z`y zK^UuVWHb>f_05FE`c_7gks_?sw=>cNcOb*a5`2M9Mi---uo~!LKFz6~;JWNt^IcGhEUp**Zm7)}|RVj9JDU zp*=XySYRwNs)TfKiO?ThW~?w)8Eb?>aGfv^+#n1FH$Bu0r-NH$oepj@b_g@UUBYb8 zQU}ZhodkEt&G0caf-e+d#0gp`L5PGJ3HERkqnXi4aE6lvcQ^&;k}up&)}e5kkzr&R zorK|V7hy5n&FEp|2-R?&uo~`V^fCGgYvBT6D?Gp$WDF6u!@~sK87UH-krKfj8DWev z$^>7eLgUqmz)hrHj!`XuPF|kz?d_W-p=XmOjG9 zE&YrFVe6Iw#vo&euzkxgA$zRIC=oi3jW9+TWkT1nF-C`T|LXq`_viy>cF8ty#^N(!Ck&o(5{AyW89u`B8I9mP8zH#Q z#u*7h>TDyUiP21GKikSk5(dwv810NSVMsrlF?lvi7(UxYm^<6e=wajt^JnvnUPd2b z;cO>i@oa(6oE%^bGKL7P$zev3Q6eOh{e)EVi4o#ha+FafRFY$i3Sl`p&X^#qBqtfO z1b5pU!Php=SYRwNssycV$;9;scf~!aNSnnEWu(o{a1!EeZibJcF(Qn(iR=G;S458` z+FHq$XiG9ugvPdZM%u*n!-jaeuBoj^wx+g{iR)i9L`H9Jn;~0s+bm;_(AqZ7SYRwN zrYP0PwrN7DZHAC*TOzm0UCWFW!uVaQgqge680&=DyEX{RcWpAZOnmUJZMNEF0zTTbuOFt~Ii3cC8b(x;7Y_gt_~+7~6#T`*s++3`@XN z+8IuUo8e<z9wsbz7YQrfCB_J2lu>4kF)D=B?s3KhVXb?LP`Efv z7`Qk?7`!;km}AT{7Ifw!qsmxfEE9$!!xz^H6Cc@NY!W6vvc=eD>@ap27R~fx zXE+&dhEJpM)zn8cvQB*@LYV$YoRJ{Re58?3>1kp#6UKX58A(Qp(auOSGK?&vlhH+( z=;>zkXf(c>?8%e0{9rGmk1+ONKchfcdT@X-NLYSwh%wA4GD?gQ#wepqSb1=au=?OQ zq3@vyLjOaPfG!mtnj&lAp=rhpW0o<;m}e|778zB>5@VUM!dN8?JhaAGCk#HcL72&H z5@vJT1brvBL)^*j5_WTzAP{-P&Tul^3?Cu>h{lKz5|6|Q?HqGkO>~MxN2j=wtK~@|OyX0YdMkLB4kF)D<dG{cx>%n=Hg<{1lwflG^oj?XUV+f~}2= zCPp)1>9JPA@?#l7>*Xw?laRdJMMz!lCX8P0A(SuY2=kZoj9x|`qo1&Fxxg3*QTtoC zJjm7|#xSGEC^1GDqlCrFWkU7x7-8vhg|P8Q%rIsNtxwDW zIyleP1;!$y%2;A7Ggb)6Csql*D{G8(#s*`Ppk3J_M6PTT)~@U@b{Up1lZWFw=Au=`Xqqm^KJI>|^8>`%8d(uB^ZGmI>u`{_;- z`qN!(?Pl~4dY;Y^a!=<8<)`}z3r`mai%$;_mYyCYEI-{#Sbch!&~&xP7$IndQAU{% zDU2~Hgm__`&|A7#Z+^GBTwH=*^TK0@-N5rPyavwI*x$PF|y znh5!UW=1O`$w(1;2ihZ4|9c10WbGTs5c&r?33!@?x%nsEgsnfxnYuigtk`@iQp$+q-d7o(fe zLs)(;Pmp@aObqoA8i)D`O+y2w(;%6dp<&ZfBr`WuBIJig7^8&Vp)rC~A#-SG!n924 zgxR4P(>6gvOp%5o0yg*GV{+b69%4NVXP7cpI>8a5Ts2q$DZFJRG!~v>@ao- z~fj z>tb{heAjvinQJ*l9?+%iwO+Djuk|td83o1wV~{b#7-ke1CB_J2lu>4kF)D=4YvYUw z#w0=Syf($wX~qm=me6%=jxodKjAh0Oq37BvW1WD>BbY-kY%;b8!!K+z z^d06dq4B@71J_K=FH2Jre%uE<(H=kn=k*_c&w;ik|eKG!VB{e)g|jC)n$yRUo=M5 z^Ai4*RXR=?74;f<8>jc`s%)E5kBD)#!p&OT4uKN2AeM>DI`X|wSC@bV17)s&Ltkvj0v}H5853Q(1 z4;jTnH?AV;>Y*>GONV|crpWU&d0slSWi_gY@^%9{mjRv2SUYq>e-^&i4;@vSU6uu6ZGnu3?+e>PpK-vnx?&tRI4raozYlJZD`;m2r5UaLoz4AZxXXNms#cOt_{U z#<;6BU}VXdb=~+bJkP=NitBc{$=z&Ko89A9(d_P$jV8CnX{@-G!iGLaX2yL$`a45i` z;GXgr{q9Y#F~AOka2SHako$i%2Hh217{l&MiqvwZ;aNkhq0^LXDN%v7@%6(K_aJNVcZl^G&+-r7Y&W*C0 zBxBM2>JjOxzv}K#m)srliuh3Nfuezs&vFgSq>{WNa6;jS&th;Y? zAkc>UPI<@usFRnnQ-&bIprOaC| z3!~R_>5|fNrq6R(?)O|)`aC1T=qID-x%2>Kx#w|R9`!t~l*sp}Cu=vxJ=Y$wTGB!OoPQc@~=bYH`oWt|K=P6~^^F?{f^F?FZ^A%&qW49T* zWZ3K8{3?7p>nnda{*`Qjo$y!}jRwH#-d=aVJRSm6fzy;TY$MBKS zSZAiGx$X|pRCfp7h`y>c*ZtaP!jY`|wcJ`4u^W1l%=Wr#N2C^irtX}at~;k>>(1G- zbx#_Zy6+fi99?yns59!R6Qa8gx7WH;MmLT;sWCLGlcYYpJL#=EZ1mwMuzCP$dZ9E> z7d8fQ4A-Fwc>Tq?vr?(LTJYMHj#_Kw5#zbA84Vnd# zU`*CsYC-y@kiKc8Z@Lb(daACd7_;m!4~IE8%-40J;*+t!4vTQ8!eOy)$Zk~0SgN~3 zm%3cnCa>0gOwm{C{?S;jYqlGkllEoXx-{)Q;hOV4AkTXLL7MaagE8xE6~>%*$0pBtH;|j&Ne85E#hCW4lYwoUroBG& z;NC`;Yu1}`OS9f#H>}%!7|wb`)*GM@8p5`RD3%Z$y23E9XWO)QDgtRfg0OfD(dS^| z-0cnIn~bq2f=ossRSrW+z6VlI0@75%nDOo$m1n#Yw;+bhF&I6^5Mk*!q{?wb*!Nx} zCUFAR_V>Z)dLMMjQ_u~af_3-|jPe=i*3aTnlWjP!KGKHxVN81?=U_CSL;6R~!DZ%y z@H6v4G(fJ_+j@*F=SMNZu{thH-Aq%PNZh65w_xlvD2(|>;n4RO9F`x0b@4Kc)yvQo|A>1fsB;_M4kH>qMrE^vJS!+ z{5X=@^9e}(pMY!XIk@gV2W$BnjLB>Q>)u(XvhKC`4b69+?$mMLaU6FW2_NpA-ZM?U^Kz^2 z38~5Vgwg8zw2|~(Q*fSk-&rN)JF8}V_si|R9~mhe8Q-8VI(uB6^&i4q8 zuNnQUF8HX)%R|r(K|A6@|I{Ll`V^(?^UGttW03DO%D(%IG2g>Rg`LOYJOSrPIFG}5 z0?w0gp7PLJYrA>o$ZKr9@Ew0;y)?Nh&mwzee(R98%+Zku&-C8jJqL_ZnG$DJf_Dkv3z)x7#N7_#-KG z!`FBY4%KsTaDEU{?*}1e&qM0DL)NqYjXMz6R2FeqS)d zE0C&J5TgG{gvfu?81w6;k3vihK%9CGQgR5=;-?_lOOTpghLrhJNP~Y0X_}V9KKZg@ru0v|S4rzfT%jY4LJ`brfrbAr& z0>t=#g4F(>APtgK`68s1FG4C;AT3oOZIQJ7B}nN%hqU|Wkg_)*jf_KD`Z6Tfj zpCR>;H1Zda7XJcLaRSo(1oqh{H`@$f{Slni zrqx@5TeA0RFjD`hGFbnpJXrtNMx=fT1Kaw%6`H&is-hj%f(&C!hHgxj)Adubl&){Z zFrdETFb2tp)Xyn!om1pUeUqv~*`ylH^;H+_Yc8c326Ss=?Quhb(Olo`g*EMkYuXE4 znyd>xNHCh~2mG*>{BSM#p)2{37)X(NcM#Ti7}k-nk%xh0W{Y8j$VX%Zix`7?eQylT z%P}}F$KdRXQwrlsq`vPxkhT+$;ztopr4jzz$KlU?9R9M$5zX3hM6-RILcCY$s-HX| zy6YED*t+VQP8!|y>GvVn+Gz^*?;th*J4i*6CP->;g_P4lE*OY%hbouwgUnU8Mt|ZRco5VTW+b9N%f$A$HZIHA}Qug0NYEHp(Dur13Qi!E5 zg%IN@xX!2Gy7YT+UHv^-Z?1RW2AAb_T<6p|IHRK&tY1A3XL}lfBWVPVq~WD24c9^% zuEQUK>*R-!j=2xPp_oC~+?{Z3y$h~|yCBVxv_w+815&92A<7+yZ?XgNO?DvIS_fQp zOBT+)--mPR_Yq;|@54pwM1%{Sa9;0(>-HbOHGTnsTQ4AR>jik}y8zeH1-Opg2iN)g z5O$fQ(*5vPxgY*2_rqVQ8~)rE;cwz1T&ox1x^@w+YZu{K{Rq{+t_R?}@c^8+A3!vX zJ#blg5J|{91lQJw;X3{>%66$#&<#8S-TEWYtv>=?;t!#ly#!rT9=fJHbiH}R z*Y`M1H}p78H}p6no$Q6Nbr~^FKLKf{Pl@RDv;P5s(@!Dr^iv2t{S*RkK4py7zo|%X zV#%XRt<(oy6ZN;+ChPB!rs^+=@%k^@ChEUzOyZcrQLg{CQK|otF^*%VJ}vOf=U=KX zV*;vvT!@YO1);3f+pY2v3}c;)rTQV8v{7HQ8TvX*_?fgR8}*HNJRoD8jJ5g{8KZU? zfgQ#sB7Op63SS^)Rd?!pt&%+u!DAQzFmfwysSh5>$0#1 z5QmS92pKyR<#zp)LpS1qwDq^jRevrpt}2W;HbvXbl>z zfx)2M8tB(U#!%o*dUPEQ+#wAI?l;PTYtl&IWo0z*W4Rpou`w2K3Uw^dWiv(tgElxj z?Qn0hLxM3G7`9$QPrDSjSD6X?M4Aaitj017X(@o=%Q6|$fmURGAY)agVHgX6id9|+ ztfCkKt2#Mjm$HSx4*A(3KRe{oZiA7xDf0n53C;&fHe)_8L6T-SR$w506w(SA3xT*| ztOe%n)A-caAJ^_x;@WSF&A>Y5vot(kZ3ggs71w;|-2-@Xj%yY>beK7?YjNGK#x+bI z*~!=pv^wCNcPMrk>SiGCK)7xfj1d7TyR<|4e+-~@DyWyqL4cApST({hC zO?cp%@W2(1;=6$+kGzYewvZM`>hr=g41G6H^vZUv=v8+EIStPJnjF^_gK&ni8E}S_ z-N14f5{yRe&1<;CZtYGbt^JkSu675OP|(e^lNQWzjndMYp)o+I0_owKd(wd+GTlA`?46* z{zfWlZzzM>8^(x+Jx|Koun?o#q))_B_hp^3c#-f(2Q>$7JNideRl22LIcKisDs#g}ZLcO}E73<+TS+CA$ zJN0nb(aD|<;3OLw;@Z&QaYKX0sRO|&mr)LuJ@BlT1IA+T2<6lg0Yf~(RohDN(g~?W-Uxm{ z+6aElSP%Y4UZ=C~1m~^8R-`ZW(FFt6 z3Cxj)&eK))gw88Hp^HW?^y&{WwW$w<#)UEzs>ntuG$|`%p&mslg-VJsMn*A&?;4At zU8hkFX{uBXRaB!AI^vZi|3nD+gjYGCYi}Z+sn8Xr8v2x64fV;!aww}x%b_0Cm(&d%%iYl3vNQak;tqcm>&|~;xWjh5a|z>d z)g7KCDT^_3xZetC+iKXutv1yj?sGzi?;hRZ0Tt4i3aRN3q|QT-R!PG5KJM@^<|M=8 z=sLr5E_F9Fj(Q)?`VC)r*m_>lTh2tVQGX=dkHK?z*bb=&_sDR+1CrAPDejUR!}!Xj zF^rLLB)m(8&jZ(F9i(g>q*gDa493LaW*?-q57G$6zu|GeoCvS_l|(pE593$Pqo94jN5iJd;aj(qWY1)iYh;D{5!>1tk~$g`5k=FdYc!!c7jBT}!ws&5@YmG2@N33G_?N~!j>YgL#oHp5 z!a-#%tbagW3Qr4TEljt^FxuSJGuz<{>Q4AG%1*dTHMYZ+Lxv@C1C7ydkNmN0k9^JW zMSdguA{&?tjcf@>7AvGt8>DHQp+&Bd-$Z24BPSvg9wQO4)IloOK^iA%s?NwpE_J|D zXGFh4?u`7>=#IpN(jA!)Mo;8C%{AvD_`S-=D@I@BJZ?n(Lga7MLL^}|1|#zV?Z!VE zDcRJ~h)*^qB5_5Uz%bnyjT9B=G}S0Y5~@^+Y^layamwb);)G@^u{F zfc+cFM&wu0dPEb(1{tf7ZegrPasv7s#-I^o>;@TI5!^7m{_RMMydCigV>fcC#j9WS zTN*CPTEkO{r6DH_jf_ZxS>gUT=%PyWv(j({QVjX~>~h zX~0{m96TcCd_#+zZ+O5caPT2UnK90oVoWpU8gw(a=Nn{szTq>*Vgsy_gf$O1g2pmV zh<6>U4HuNPhRgC=!#^0SIM(TOc!kmMpt9Z2D-27N+Kt~Gy;sqq_o-SmjrtJnw5q=7 zn$2)WSM5e3dgNJnNk+}nrJ}N&ihkS3M9<^<2CqLGZIQE4)Tf^4@FBWeof(N^`q0B@#tVTYXwizR2xf*AZXJQHH34gX0)b}}h=1u8gi9TR&fbV%_C}nf z)QDIX8W9#oKH7C04qe9)cKtYXF!IsDd!Z}57rLes(7`~;Psl|bCY1e6P{PPZcbedF zrwO|0lhDD)N88^AUHki>+kPK(F!IsiQ_u~cf-chx9gNke<+L;sO`L`VV=a241x3Cd zy+dA)zGCb|zb9`;*R1MRbla-zL?>;=77X3kCear=LKQF0Xo{KDq&X(b&9Pq^so0yJ zM@-!@O;)>NO|sG%o08RT7)EDo9wE@2aq7XMsq)GE)%8g0s4Y)Uca$ynqwF2~;NzzJ7k7v!zjkCd(0 zKN~BtW?^jUu{0h~VtDns8Jj{699y(OO52SsHi~w59+Hh+$`VPk#OY8CXZ#3RwfLp) zBHCm;CDi6Px}4^?hH+1P!ftf2k6iqG+ChCo{G6PRH)8b0`eDY%QRWz9f-!Bvi$?(5 H=JNk19qBVg diff --git a/UnitPrinc.dfm b/UnitPrinc.dfm index 71b5e25..e79bb56 100644 --- a/UnitPrinc.dfm +++ b/UnitPrinc.dfm @@ -1,6 +1,6 @@ object FormPrinc: TFormPrinc - Left = 12 - Top = 210 + Left = 1296 + Top = 222 Width = 1212 Height = 664 Caption = 'Client TCP-IP CDM Rail ou USB - syst'#232'me LENZ' @@ -1201,24 +1201,6 @@ object FormPrinc: TFormPrinc Font.Style = [] ParentFont = False end - object ListBox1: TListBox - Left = 8 - Top = 48 - Width = 609 - Height = 505 - Style = lbOwnerDrawFixed - Anchors = [akLeft, akTop, akRight, akBottom] - Color = clBlack - Font.Charset = ANSI_CHARSET - Font.Color = clBlue - Font.Height = 16 - Font.Name = 'Arial' - Font.Style = [] - ItemHeight = 16 - ParentFont = False - TabOrder = 0 - OnDrawItem = ListBox1DrawItem - end object ScrollBox1: TScrollBox Left = 631 Top = 168 @@ -1231,7 +1213,7 @@ object FormPrinc: TFormPrinc Anchors = [akTop, akRight, akBottom] Color = clWhite ParentColor = False - TabOrder = 1 + TabOrder = 0 end object GroupBox1: TGroupBox Left = 631 @@ -1240,7 +1222,7 @@ object FormPrinc: TFormPrinc Height = 129 Anchors = [akTop, akRight] Caption = 'Commande d'#39'accessoires' - TabOrder = 2 + TabOrder = 1 object Label2: TLabel Left = 7 Top = 16 @@ -1339,7 +1321,7 @@ object FormPrinc: TFormPrinc Width = 281 Height = 129 Anchors = [akTop, akRight] - TabOrder = 5 + TabOrder = 4 object BoutonRaf: TButton Left = 8 Top = 8 @@ -1439,7 +1421,7 @@ object FormPrinc: TFormPrinc Height = 25 Anchors = [akTop, akRight] Caption = 'Panel2' - TabOrder = 6 + TabOrder = 5 object Label1: TLabel Left = 16 Top = 4 @@ -1468,7 +1450,26 @@ object FormPrinc: TFormPrinc Height = 17 Anchors = [akLeft, akRight, akBottom] Caption = 'xx' + TabOrder = 6 + end + object FenRich: TRichEdit + Left = 8 + Top = 48 + Width = 617 + Height = 497 + Anchors = [akLeft, akTop, akRight, akBottom] + Color = clBlack + Font.Charset = DEFAULT_CHARSET + Font.Color = clYellow + Font.Height = -13 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ParentFont = False + PopupMenu = PopupMenuFenRich + ReadOnly = True + ScrollBars = ssBoth TabOrder = 7 + OnChange = FenRichChange end object Timer1: TTimer Interval = 100 @@ -1499,6 +1500,10 @@ object FormPrinc: TFormPrinc Caption = 'Etat des aiguillages' OnClick = Etatdesaiguillages1Click end + object Etatdessignaux1: TMenuItem + Caption = 'Etat des signaux' + OnClick = Etatdessignaux1Click + end object N3: TMenuItem Caption = '-' end @@ -1611,4 +1616,12 @@ object FormPrinc: TFormPrinc Left = 888 Top = 16 end + object PopupMenuFenRich: TPopupMenu + Left = 208 + Top = 24 + object Copier1: TMenuItem + Caption = 'Copier' + OnClick = Copier1Click + end + end end diff --git a/UnitPrinc.pas b/UnitPrinc.pas index efd3488..a996a5f 100644 --- a/UnitPrinc.pas +++ b/UnitPrinc.pas @@ -20,7 +20,6 @@ uses type TFormPrinc = class(TForm) - ListBox1: TListBox; Timer1: TTimer; LabelTitre: TLabel; ScrollBox1: TScrollBox; @@ -91,6 +90,10 @@ type ButtonLanceCDM: TButton; Affichefentredebug1: TMenuItem; StaticText: TStaticText; + FenRich: TRichEdit; + PopupMenuFenRich: TPopupMenu; + Copier1: TMenuItem; + Etatdessignaux1: TMenuItem; procedure FormCreate(Sender: TObject); procedure MSCommUSBLenzComm(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); @@ -98,8 +101,6 @@ type procedure BoutVersionClick(Sender: TObject); procedure ButtonCommandeClick(Sender: TObject); procedure EditvalEnter(Sender: TObject); - procedure ListBox1DrawItem(Control: TWinControl; Index: Integer; - Rect: TRect; State: TOwnerDrawState); procedure BoutonRafClick(Sender: TObject); procedure ClientSocketLenzError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); @@ -143,7 +144,9 @@ type procedure ButtonAffTCOClick(Sender: TObject); procedure ButtonLanceCDMClick(Sender: TObject); procedure Affichefentredebug1Click(Sender: TObject); - procedure Button1Click(Sender: TObject); + procedure FenRichChange(Sender: TObject); + procedure Copier1Click(Sender: TObject); + procedure Etatdessignaux1Click(Sender: TObject); private { Déclarations privées } procedure DoHint(Sender : Tobject); @@ -236,7 +239,7 @@ var branche : array [1..100] of string; FormPrinc: TFormPrinc; - ack,portCommOuvert,trace,AffMem,AfficheDet,CDM_connecte,SocketCDM_connecte, + ack,portCommOuvert,traceTrames,AffMem,AfficheDet,CDM_connecte,SocketCDM_connecte, Raz_Acc_signaux,AvecInit,AvecTCO,terminal,Srvc_Aig,Srvc_Det,Srvc_Act, Srvc_PosTrain,Srvc_Sig,debugtrames : boolean; tablo : array of byte; // tableau rx usb @@ -414,10 +417,8 @@ begin begin brush.Color:=couleur; Pen.Color:=clBlack; - //Affiche('clignote '+IntToSTR(x)+' '+intToSTR(y),clyellow); Ellipse(x-rayon,y-rayon,x+rayon,y+rayon); end; - //Affiche(IntToSTR(y),clyellow); end; // dessine les feux sur une cible à 2 feux dans le canvas spécifié @@ -1045,7 +1046,7 @@ begin cercle(ACanvas,12,13,6,GrisF); cercle(ACanvas,25,13,6,GrisF); end; - if EtatSignal=1 then + if EtatSignal=1 then begin cercle(ACanvas,12,13,6,clWhite); cercle(ACanvas,25,13,6,GrisF); @@ -1058,19 +1059,18 @@ begin end; - -// affiche un texte dans la fenêtre procedure Affiche(s : string;lacouleur : TColor); begin - couleur:=lacouleur; - with formprinc.ListBox1 do + with formprinc do begin - Items.addObject(s,pointer(lacouleur)); - TopIndex:= Items.Count - 1; + FenRich.lines.add(s); + RE_ColorLine(FenRich,FenRich.lines.count-1,lacouleur); + //FenRich.SetFocus; + //FenRich.SelStart := FenRich.GetTextLen; + //FenRich.Perform(EM_SCROLLCARET, 0, 0); end; end; - - + // renvoie l'index du feu dans le tableau feux[] en fonction de son adresse //si pas de feu renvoie 0 function Index_feu(adresse : integer) : integer; @@ -1265,7 +1265,7 @@ end; // Affiche une chaîne en Hexa Ascii procedure affiche_chaine_hex(s : string;couleur : Tcolor); begin - if trace then Affiche(chaine_HEX(s),couleur); + if traceTrames then AfficheDebug(chaine_HEX(s),couleur); end; // temporisation en x 100 ms (0,1 s) @@ -1285,7 +1285,7 @@ var i,timeout,valto : integer; begin // com:=formprinc.MSCommUSBLenz; s:=entete+s+suffixe; - if Trace then Affiche('Tick='+IntToSTR(tick)+'/Env '+chaine_Hex(s),ClGreen); + if traceTrames then AfficheDebug('Tick='+IntToSTR(tick)+'/Env '+chaine_Hex(s),ClGreen); // par port com-usb if portCommOuvert then @@ -3570,10 +3570,9 @@ begin trouve_fonte:=true; delete(s,i,length(sa)); TailleFonte:=StrToINT(s); - with FormPrinc.ListBox1 do + with FormPrinc.FenRich do begin - Font.Height:=TailleFonte; - ItemHeight:=TailleFonte+1; + Font.Size:=TailleFonte; end; end; @@ -4041,8 +4040,7 @@ begin s:=lit_ligne; mod_Branches[Nligne]:=s;inc(Nligne); //Affiche(s,clWhite); - //adresse:=pos('0',s); - //s:='A16B,557,0' ; + if s<>'0' then begin branche[i]:=s; @@ -4077,6 +4075,7 @@ begin begin //Affiche(IntToSTR(detect),clyellow); //Affiche(s,clorange); Affiche(IntToStr(detect),clorange); + //if detect=0 then affiche('buttoir'+sOrigine,clyellow); BrancheN[i,j].adresse:=detect; // adresse BrancheN[i,j].btype:=1;// ident détecteur if detect=0 then begin BrancheN[i,j].btype:=4;end; // buttoir @@ -5239,7 +5238,8 @@ end; // renvoie l'adresse du détecteur suivant des deux éléments contigus // TypeElprec/actuel: 1= détecteur 2= aiguillage 4=Buttoir -function detecteur_suivant(prec : integer;TypeElPrec : integer;actuel : integer;TypeElActuel : integer) : integer ; +// algo= type d'algorythme pour suivant_alg3 +function detecteur_suivant(prec : integer;TypeElPrec : integer;actuel : integer;TypeElActuel,algo : integer) : integer ; var actuelCalc,PrecCalc,etat,i,j,AdrSuiv , TypeprecCalc,TypeActuelCalc : integer; begin @@ -5253,7 +5253,7 @@ begin // étape 1 trouver le sens repeat inc(j); - AdrSuiv:=suivant_alg3(precCalc,TypeprecCalc,actuelCalc,TypeActuelCalc,1); + AdrSuiv:=suivant_alg3(precCalc,TypeprecCalc,actuelCalc,TypeActuelCalc,algo); if (typeGen=2) and false then // si le précédent est une TJD/S et le suivant aussi begin if ((aiguillage[AdrSuiv].modele=2) or (aiguillage[AdrSuiv].modele=3)) and @@ -5270,6 +5270,7 @@ begin TypeActuelCalc:=typeGen; //Affiche('Suivant signalaig='+IntToSTR(AdrSuiv),clyellow); until (j=10) or (typeGen=1) or (AdrSuiv=0) or (AdrSuiv>=9996); // arret si détecteur + // si trouvé le sens, trouver le suivant if AdrSuiv=actuel then begin @@ -5398,7 +5399,7 @@ begin if j=2 then i1:=IndexBranche_det1-1; if NivDebug=3 then begin - s:='Test 1 en '; + s:='Test en '; if (j=1) then s:=s+'incrément ' else s:=s+'décrément '; s:=s+'- départ depuis élément '+IntToSTR(el1)+' trouvé en index='+intToSTR(IndexBranche_det1)+' Branche='+intToSTR(branche_trouve_det1); AfficheDebug(s,clyellow); @@ -5434,7 +5435,7 @@ begin sortie:=((typeDet2=TypeGen) and (Adr=el2)) or (Adr=0) or (Adr>=9996) or (i=15) or (N_Det=Nb_det_dist); until sortie ; if (i=15) and (Nivdebug=3) then afficheDebug('Pas trouvé',clyellow); - if (N_det=Nb_det_dist) and (Nivdebug=3) then afficheDebug('Détecteurs trop distants',clyellow); + if (N_det=Nb_det_dist) and (Nivdebug=3) then afficheDebug('Détecteurs trop distants',clred); end else @@ -5443,7 +5444,7 @@ begin adr:=el2;typeGen:=TypeDet2; end; - if (typeDet2=TypeGen) and (Adr=el2) then + if (typeDet2=TypeGen) and (Adr=el2) and (N_Det<>Nb_det_dist) then begin if Nivdebug=3 then AfficheDebug('614 : Trouvé '+intToSTR(el2),clYellow); i:=0; @@ -5458,6 +5459,7 @@ begin case typeGen of 1 : s:=s+' detecteur'; 2 : s:=s+' aiguillage'; + 4 : s:=s+' buttoir'; end; AfficheDebug(s,clorange); end; @@ -5468,7 +5470,7 @@ begin sortie:=(TypeGen=1) or (Adr=0) or (Adr>=9996) or (i=10); until sortie; - if TypeGen=1 then + if (TypeGen=1) or (TypeGen=4) then begin if NivDebug=3 then begin @@ -5482,7 +5484,7 @@ begin if (i=10) then if NivDebug=3 then AfficheDebug('201 : Itération trop longue',clred); inc(j); //AfficheDebug('j='+intToSTR(j),clyellow); - until j=3; + until j=3; // boucle incrément/décrément detecteur_suivant_el:=9996; if NivDebug=3 then affichedebug('------------------',clyellow); @@ -5866,7 +5868,7 @@ begin ife:=1; // index feu de 1 à 4 pour explorer les 4 détecteurs d'un feu repeat j:=0; - if NivDebug=3 then AfficheDebug('Boucle de test feu '+intToSTR(ife)+'/4',clred); + if NivDebug=3 then AfficheDebug('Boucle de test feu '+intToSTR(ife)+'/4',clOrange); if (ife=1) then begin prec:=feux[i].Adr_det1; @@ -5934,7 +5936,7 @@ begin end; - if NivDebug=3 then AfficheDebug('130 - suivant='+IntToSTR(adrsuiv),clred); + if NivDebug=3 then AfficheDebug('132 - suivant='+IntToSTR(adrsuiv),clYellow); if actuel=0 then begin // si c'est un buttoir @@ -6072,13 +6074,13 @@ begin test_route_valide:=10 ; end; + // présence train 3 détecteurs avant le feu function PresTrainPrec(AdrFeu : integer) : boolean; var PresTrain : boolean; j,i,Det_initial,Adr_El_Suiv,Btype_el_suivant,DetPrec1,DetPrec2,DetPrec3,DetPrec4 : integer; begin i:=index_feu(Adrfeu); - //memZone[518,520]:=true; if i=0 then begin Affiche('Erreur 602 - feu '+IntToSTR(adrFeu)+' non trouvé',clred); @@ -6104,27 +6106,27 @@ begin if (j=2) then begin det_initial:=feux[i].Adr_det2;Adr_El_Suiv:=feux[i].Adr_el_suiv2; - if feux[i].Btype_suiv1=1 then Btype_el_suivant:=1; - if feux[i].Btype_suiv1=2 then Btype_el_suivant:=2; - if feux[i].Btype_suiv1=4 then Btype_el_suivant:=2; + if feux[i].Btype_suiv2=1 then Btype_el_suivant:=1; + if feux[i].Btype_suiv2=2 then Btype_el_suivant:=2; + if feux[i].Btype_suiv2=4 then Btype_el_suivant:=2; end; if (j=3) then begin det_initial:=feux[i].Adr_det3;Adr_El_Suiv:=feux[i].Adr_el_suiv3; - if feux[i].Btype_suiv1=1 then Btype_el_suivant:=1; - if feux[i].Btype_suiv1=2 then Btype_el_suivant:=2; - if feux[i].Btype_suiv1=4 then Btype_el_suivant:=2; + if feux[i].Btype_suiv3=1 then Btype_el_suivant:=1; + if feux[i].Btype_suiv3=2 then Btype_el_suivant:=2; + if feux[i].Btype_suiv3=4 then Btype_el_suivant:=2; end; if (j=4) then begin det_initial:=feux[i].Adr_det4;Adr_El_Suiv:=feux[i].Adr_el_suiv4; - if feux[i].Btype_suiv1=1 then Btype_el_suivant:=1; - if feux[i].Btype_suiv1=2 then Btype_el_suivant:=2; - if feux[i].Btype_suiv1=4 then Btype_el_suivant:=2; + if feux[i].Btype_suiv4=1 then Btype_el_suivant:=1; + if feux[i].Btype_suiv4=2 then Btype_el_suivant:=2; + if feux[i].Btype_suiv4=4 then Btype_el_suivant:=2; end; if (det_initial<>0) then begin - DetPrec1:=detecteur_suivant(Adr_El_Suiv,Btype_el_suivant,det_initial,1); + DetPrec1:=detecteur_suivant(Adr_El_Suiv,Btype_el_suivant,det_initial,1,2); // 2= algo2 = arret sur aiguillage en talon mal positionné if DetPrec1<1024 then // route bloquée par aiguillage mal positionné begin DetPrec2:=detecteur_suivant_El(det_initial,1,DetPrec1,1); @@ -6295,6 +6297,8 @@ begin // si le signal suivant est rouge begin if AffSignal then AfficheDebug('pas d''aiguille déviée',clYellow); + // effacer la signbalisation combinée + EtatSignalCplx[adrFeu]:=EtatSignalCplx[adrFeu] and not($3c00); if TestBit(etat,carre) or testBit(etat,semaphore) or testBit(etat,semaphore_cli )then Maj_Etat_Signal(AdrFeu,jaune) else begin @@ -6505,7 +6509,7 @@ begin if (AdrDetFeu=Det3) and (feux[i].aspect<10) then begin AdrSuiv:=Feux[i].Adr_el_suiv1;TypeSuiv:=Feux[i].Btype_suiv1; - AdrPrec:=detecteur_suivant(AdrSuiv,typeSuiv,AdrDetFeu,1) ; // détecteur précédent le feu + AdrPrec:=detecteur_suivant(AdrSuiv,typeSuiv,AdrDetFeu,1,1) ; // détecteur précédent le feu ; algo 1 if AdrPrec=0 then begin if TraceListe then Affiche('FD - Le feu '+IntToSTR(AdrFeu)+' est précédé d''un buttoir',clyellow); @@ -6726,7 +6730,7 @@ begin begin AdrSuiv:=Feux[i].Adr_el_suiv1;TypeSuiv:=Feux[i].Btype_suiv1; if AffSignal then AfficheDebug('Pour Feu '+intToSTR(AdrFeu)+' detecteursuivant('+intToSTR(AdrSuiv)+','+IntToSTR(typeSuiv)+','+intToSTR(AdrDetFeu)+',1)',clyellow); - AdrPrec:=detecteur_suivant(AdrSuiv,typeSuiv,AdrDetFeu,1) ; // détecteur précédent le feu + AdrPrec:=detecteur_suivant(AdrSuiv,typeSuiv,AdrDetFeu,1,1) ; // détecteur précédent le feu, algo 1 if AdrPrec=0 then begin If traceListe then AfficheDebug('Le feu '+IntToSTR(AdrFeu)+' est précédé d''un buttoir',clyellow); @@ -6885,22 +6889,22 @@ begin if (valeur and $C)=$8 then begin Event_Aig(adraig+3,const_droit,0); - if trace then begin s:='accessoire '+intToSTR(adraig+3)+'=2';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+3)+'=2';AfficheDebug(s,clYellow);end; end; if (valeur and $C)=$4 then begin Event_Aig(adraig+3,const_devie,0); - if trace then begin s:='accessoire '+intToSTR(adraig+3)+'=1';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+3)+'=1';AfficheDebug(s,clYellow);end; end; if (valeur and $3)=$2 then begin Event_Aig(adraig+2,const_droit,0); - if trace then begin s:='accessoire '+intToSTR(adraig+2)+'=2';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+2)+'=2';AfficheDebug(s,clYellow);end; end; if (valeur and $3)=$1 then begin Event_Aig(adraig+2,const_devie,0); - if trace then begin s:='accessoire '+intToSTR(adraig+2)+'=1';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+2)+'=1';AfficheDebug(s,clYellow);end; end; end; end; @@ -6941,22 +6945,22 @@ begin if (valeur and $C)=$8 then begin Event_Aig(adraig+1,const_droit,0); - if trace then begin s:='accessoire '+intToSTR(adraig+1)+'=2';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+1)+'=2';AfficheDebug(s,clYellow);end; end; if (valeur and $C)=$4 then begin Event_Aig(adraig+1,const_devie,0); - if trace then begin s:='accessoire '+intToSTR(adraig+1)+'=1';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+1)+'=1';AfficheDebug(s,clYellow);end; end; if (valeur and $3)=$2 then begin Event_Aig(adraig,const_droit,0); - if trace then begin s:='accessoire '+intToSTR(adraig)+'=2';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig)+'=2';AfficheDebug(s,clYellow);end; end; if (valeur and $3)=$1 then begin Event_Aig(adraig,const_devie,0); - if trace then begin s:='accessoire '+intToSTR(adraig)+'=1';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig)+'=1';AfficheDebug(s,clYellow);end; end; end; end; @@ -6982,8 +6986,8 @@ begin #5 : begin nack:=true;msg:='plus de time slot';end; #6 : begin nack:=true;msg:='débordement tampon LI100';end; end; - if trace and (chaineINT[2]=#4) then Affiche(msg,clYellow); - if trace and (chaineINT[2]<>#4) then Affiche(msg,clRed); + if traceTrames and (chaineINT[2]=#4) then AfficheDebug(msg,clYellow); + if traceTrames and (chaineINT[2]<>#4) then AfficheDebug(msg,clRed); delete(chaineINT,1,3); decode_chaine_retro:=chaineINT; exit; @@ -7682,7 +7686,7 @@ begin begin chaine_recue:=chaine_recue+char(tablo[i]); end; - if trace then Affiche('Tick='+IntToSTR(tick)+'/Rec '+chaine_Hex(chaine_recue),Clwhite); + if traceTrames then AfficheDebug('Tick='+IntToSTR(tick)+'/Rec '+chaine_Hex(chaine_recue),Clwhite); if terminal then Affiche(chaine_recue,clLime); interprete_reponse(chaine_recue); chaine_recue:=''; @@ -7946,17 +7950,6 @@ begin if (Editval.Text<>'1') and (Editval.Text<>'2') then editval.text:='1'; end; -// gestion de la couleur des textes de la list box -procedure TFormPrinc.ListBox1DrawItem(Control: TWinControl; Index: Integer; - Rect: TRect; State: TOwnerDrawState); -begin - //with control as Tlistbox do - with listbox1.Canvas do - begin - Font.color:=Tcolor(ListBox1.Items.Objects[index]); - TextOut(Rect.Left,Rect.Top+4,ListBox1.Items[index]); - end; -end; procedure TFormPrinc.BoutonRafClick(Sender: TObject); begin @@ -8010,7 +8003,7 @@ procedure TFormPrinc.ClientSocketLenzRead(Sender: TObject; var s : string; begin s:=ClientSocketLenz.Socket.ReceiveText; - if trace then affiche(chaine_hex(s),clWhite); + if traceTrames then afficheDebug(chaine_hex(s),clWhite); interprete_reponse(s); end; @@ -8035,7 +8028,6 @@ begin Affiche('en circulation sur le réseau',ClYellow); Affiche('Il est nécessaire de renseigner les fichiers config.cfg et config-gl.cfg',ClOrange); Affiche('En vert : Trames envoyées à l''interface',ClWhite); - Affiche('En blanc : Trames reçues de l''interface',ClWhite); Affiche('En violet : Trames brutes reçues de l''interface',ClWhite); Affiche('En rouge : erreurs et défauts',ClWhite); Affiche('En orange : pilotage des signaux / erreurs mineures',ClWhite); @@ -8078,6 +8070,7 @@ procedure TFormPrinc.MenuConnecterEthernetClick(Sender: TObject); begin if AdresseIP<>'0' then begin + Affiche('Demande de connexion de l''interface Lenz en ethernet '+AdresseIP+':'+IntToSTR(Port),clyellow); ClientSocketLenz.port:=port; ClientSocketLenz.Address:=AdresseIP; ClientSocketLenz.Open; @@ -8484,20 +8477,19 @@ begin inc(Nbre_recu_cdm); //if Nbre_recu_cdm>1 then Affiche('Empilement de trames CDM: '+intToSTR(Nbre_recu_cdm),clred); recuCDM:=ClientSocketCDM.Socket.ReceiveText; // commandeCDM est le morceau tronquée de la fin de la réception précédente - //if residuCDM<>'' then Affiche(recuCDM,clLime); + residuCDM:=''; - if trace then - begin + if traceTrames then AfficheDebug(recuCDM,clWhite); + + {begin n:=80; - Affiche('recu de CDM Tick='+IntToSTR(tick)+' '+IntToSTR(length(recuCDM))+' car',clWhite);Affiche(copy(recuCDM,1,n),clWhite); - AfficheDebug(recuCDM,clWhite); l:=length(recuCDM); - i:=1; + i:=0; repeat - Affiche(copy(recuCDM,i*n,n),clWhite); + AfficheDebug(copy(recuCDM,(i*n)+1,n),clWhite); inc(i); until l - SimplePanel = True - end - object MSCommUSBLenz: TMSComm - Left = 720 - Top = 144 - Width = 32 - Height = 32 - OnComm = MSCommUSBLenzComm - ControlData = { - 2143341208000000ED030000ED03000001568A64000006000000010000040000 - 00020000802500000000080000000000000000003F00000011000000} - end - object Panel1: TPanel - Left = 887 - Top = 5 - Width = 281 - Height = 129 - Anchors = [akTop, akRight] - TabOrder = 5 - object BoutonRaf: TButton - Left = 8 - Top = 8 - Width = 89 - Height = 33 - Caption = 'Rafraichissement' - TabOrder = 0 - OnClick = BoutonRafClick - end - object BoutVersion: TButton - Left = 102 - Top = 8 - Width = 83 - Height = 33 - Caption = 'Dem version' - TabOrder = 1 - OnClick = BoutVersionClick - end - object loco: TButton - Left = 190 - Top = 88 - Width = 83 - Height = 33 - Caption = 'loco' - TabOrder = 2 - OnClick = locoClick - end - object ButtonInfo: TButton - Left = 104 - Top = 48 - Width = 81 - Height = 33 - Caption = 'Informations' - TabOrder = 3 - OnClick = ButtonInfoClick - end - object ButtonReprise: TButton - Left = 190 - Top = 48 - Width = 83 - Height = 33 - Hint = - 'Relance du bus DCC apr'#232's une '#233'criture d'#39'un CV ou une mise hors t' + - 'ension de la centrale' - Caption = 'Reprise DCC' - TabOrder = 4 - OnClick = ButtonRepriseClick - end - object ButtonTest: TButton - Left = 8 - Top = 48 - Width = 89 - Height = 33 - Caption = 'Demande '#233'tat r'#233'trosignalisation' - TabOrder = 5 - WordWrap = True - OnClick = ButtonTestClick - end - object ButtonArretSimu: TButton - Left = 104 - Top = 88 - Width = 81 - Height = 33 - Caption = 'Arret simulation' - TabOrder = 6 - Visible = False - OnClick = ButtonArretSimuClick - end - object ButtonAffTCO: TButton - Left = 8 - Top = 88 - Width = 89 - Height = 33 - Caption = 'Affiche TCO' - TabOrder = 7 - OnClick = ButtonAffTCOClick - end - object ButtonLanceCDM: TButton - Left = 192 - Top = 8 - Width = 81 - Height = 33 - Caption = 'Lance CDM rail' - TabOrder = 8 - OnClick = ButtonLanceCDMClick - end - end - object Panel2: TPanel - Left = 631 - Top = 136 - Width = 153 - Height = 25 - Anchors = [akTop, akRight] - Caption = 'Panel2' - TabOrder = 6 - object Label1: TLabel - Left = 16 - Top = 4 - Width = 89 - Height = 13 - Caption = 'Nombre de trains : ' - end - object LabelNbTrains: TLabel - Left = 120 - Top = 2 - Width = 9 - Height = 19 - Caption = '0' - Font.Charset = ANSI_CHARSET - Font.Color = clBlack - Font.Height = -16 - Font.Name = 'Arial' - Font.Style = [fsBold] - ParentFont = False - end - end - object StaticText: TStaticText - Left = 16 - Top = 560 - Width = 14 - Height = 17 - Anchors = [akLeft, akRight, akBottom] - Caption = 'xx' - TabOrder = 7 - end - object Timer1: TTimer - Interval = 100 - OnTimer = Timer1Timer - Left = 888 - Top = 80 - end - object ClientSocketLenz: TClientSocket - Active = False - ClientType = ctNonBlocking - Port = 0 - OnConnect = ClientSocketLenzConnect - OnDisconnect = ClientSocketLenzDisconnect - OnRead = ClientSocketLenzRead - OnError = ClientSocketLenzError - Left = 320 - end - object MainMenu1: TMainMenu - Left = 560 - object Afficher1: TMenuItem - Caption = 'Afficher' - object Etatdesdtecteurs1: TMenuItem - Caption = 'Etat des d'#233'tecteurs' - Hint = 'Affiche l'#39#233'tat des d'#233'tecteurs' - OnClick = AffEtatDetecteurs - end - object Etatdesaiguillages1: TMenuItem - Caption = 'Etat des aiguillages' - OnClick = Etatdesaiguillages1Click - end - object N3: TMenuItem - Caption = '-' - end - object Codificationdesaiguillages1: TMenuItem - Caption = 'Codification des aiguillages' - OnClick = Codificationdesaiguillages1Click - end - object Codificationdesfeux1: TMenuItem - Caption = 'Codification des feux' - OnClick = Codificationdesfeux1Click - end - object Codificationdesactionneurs1: TMenuItem - Caption = 'Codification des actionneurs' - OnClick = Codificationdesactionneurs1Click - end - object N5: TMenuItem - Caption = '-' - end - object Quitter1: TMenuItem - Caption = 'Quitter' - OnClick = Quitter1Click - end - end - object Interface1: TMenuItem - Caption = 'Interface' - object MenuConnecterUSB: TMenuItem - Caption = 'Connecter USB' - Hint = 'Connecter l'#39'interface en USB' - OnClick = MenuConnecterUSBClick - end - object DeconnecterUSB: TMenuItem - Caption = 'D'#233'connecter USB' - Hint = 'D'#233'connecter l'#39'interface USB' - OnClick = DeconnecterUSBClick - end - object N2: TMenuItem - Caption = '-' - end - object MenuConnecterEthernet: TMenuItem - Caption = 'Connecter Ethernet' - Hint = 'Connecter l'#39'interface par Ethernet' - OnClick = MenuConnecterEthernetClick - end - object MenuDeconnecterEthernet: TMenuItem - Caption = 'D'#233'connecter Ethernet' - Hint = 'D'#233'connecter l'#39'interface par Ethernet' - OnClick = MenuDeconnecterEthernetClick - end - object N4: TMenuItem - Caption = '-' - end - object ConnecterCDMrail: TMenuItem - Caption = 'Connecter CDM rail' - OnClick = ConnecterCDMrailClick - end - object DeconnecterCDMRail: TMenuItem - Caption = 'D'#233'connecter CDM rail' - OnClick = DeconnecterCDMRailClick - end - end - object Divers1: TMenuItem - Caption = 'Divers' - object Config: TMenuItem - Caption = 'Configuration' - Hint = 'Modifie les variables de configuration sans sauvegarde' - OnClick = ConfigClick - end - object FichierSimu: TMenuItem - Caption = 'Ouvrir un fichier de simulation' - Hint = - 'Ouvre un fichier de simulation des d'#233'tecteurs pour simuler un fo' + - 'nctionnement' - OnClick = FichierSimuClick - end - object OuvrirunfichiertramesCDM1: TMenuItem - Caption = 'Ouvrir un fichier trames CDM' - OnClick = OuvrirunfichiertramesCDM1Click - end - object Affichefentredebug1: TMenuItem - Caption = 'Affiche fen'#234'tre debug' - OnClick = Affichefentredebug1Click - end - object N1: TMenuItem - Caption = '-' - end - object LireunfichierdeCV1: TMenuItem - Caption = 'Lire un fichier de CV vers un accessoire' - Hint = - 'Ouvre un fichier de CV pour l'#39'envoyer vers un accessoire branch'#233 + - ' sur la voie de programmation' - OnClick = LireunfichierdeCV1Click - end - end - end - object ClientSocketCDM: TClientSocket - Active = False - ClientType = ctNonBlocking - Port = 0 - OnConnect = ClientSocketCDMConnect - OnDisconnect = ClientSocketCDMDisconnect - OnRead = ClientSocketCDMRead - OnError = ClientSocketCDMError - Left = 352 - end - object OpenDialog: TOpenDialog - Left = 888 - Top = 152 - end - object SaveDialog: TSaveDialog - Left = 888 - Top = 16 - end -end diff --git a/UnitPrinc.~pas b/UnitPrinc.~pas index 441f035..a996a5f 100644 --- a/UnitPrinc.~pas +++ b/UnitPrinc.~pas @@ -20,7 +20,6 @@ uses type TFormPrinc = class(TForm) - ListBox1: TListBox; Timer1: TTimer; LabelTitre: TLabel; ScrollBox1: TScrollBox; @@ -91,6 +90,10 @@ type ButtonLanceCDM: TButton; Affichefentredebug1: TMenuItem; StaticText: TStaticText; + FenRich: TRichEdit; + PopupMenuFenRich: TPopupMenu; + Copier1: TMenuItem; + Etatdessignaux1: TMenuItem; procedure FormCreate(Sender: TObject); procedure MSCommUSBLenzComm(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); @@ -98,8 +101,6 @@ type procedure BoutVersionClick(Sender: TObject); procedure ButtonCommandeClick(Sender: TObject); procedure EditvalEnter(Sender: TObject); - procedure ListBox1DrawItem(Control: TWinControl; Index: Integer; - Rect: TRect; State: TOwnerDrawState); procedure BoutonRafClick(Sender: TObject); procedure ClientSocketLenzError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); @@ -143,6 +144,9 @@ type procedure ButtonAffTCOClick(Sender: TObject); procedure ButtonLanceCDMClick(Sender: TObject); procedure Affichefentredebug1Click(Sender: TObject); + procedure FenRichChange(Sender: TObject); + procedure Copier1Click(Sender: TObject); + procedure Etatdessignaux1Click(Sender: TObject); private { Déclarations privées } procedure DoHint(Sender : Tobject); @@ -157,13 +161,13 @@ const titre='Signaux complexes GL '; tempoFeu=100; MaxAcc=2048; -LargImg=50;HtImg=91; +LargImg=50;HtImg=91; // image des feux const_droit=2;const_devie=1; // positions aiguillages transmises par la centrale LENZ const_devieG_CDM=3; // positions aiguillages transmises par cdm const_devieD_CDM=2; // positions aiguillages transmises par cdm const_droit_CDM=0; // positions aiguillages transmises par cdm ClBleuClair=$FF7070 ; -Cyan=$FFA0A0; +Cyan=$FF6060; clviolet=$FF00FF; GrisF=$414141; clOrange=$0077FF; @@ -175,7 +179,7 @@ EtatSign : array[0..13] of string[20] =('carr 'blanc','blanc cli','jaune','jaune cli','ral 30','ral 60','rappel 30','rappel 60'); NbDecodeur = 7; decodeur : array[0..NbDecodeur-1] of string[20] =('rien','digital Bahn','CDF','LDT','LEB','NMRA','Unisemaf'); - + type TBranche = record BType : integer ; // 1= détecteur 2= aiguillage 4=Buttoir Adresse : integer ; // adresse du détecteur ou de l'aiguillage @@ -197,7 +201,7 @@ type TBranche = record ADevie : integer ; // (TJD:identifiant extérieur) adresse de l'élément connecté en position déviée ADevieB : char; // caractère (D ou S)si aiguillage de l'élément connecté en position déviée - APointe : integer; // adresse de l'élément connecté en position droite ; + APointe : integer; // adresse de l'élément connecté en position droite ; APointeB : char; DDroit : integer; // destination de la TJD en position droite @@ -206,45 +210,52 @@ type TBranche = record DDevie : integer; // destination de la TJD en position déviée DDevieB : char ; - - tjsint : integer; + tjsint : integer; // pour TJS tjsintb : char ; // éléments connectés sur la branche déviée 2 (cas d'un aiguillage triple) Adevie2 : integer; Adevie2B : char ; - // modifié + // si modifié en mode config modifie : boolean ; end; Taccessoire = (aig,feu); TMA = (valide,devalide); -var ancien_tablo_signalCplx,EtatsignalCplx : array[0..MaxAcc] of word; +var + ancien_tablo_signalCplx,EtatsignalCplx : array[0..MaxAcc] of word; AvecInitAiguillages,tempsCli,NbreFeux,pasreponse,AdrDevie,fenetre, NombreImages,signalCpx,branche_trouve,Indexbranche_trouve,Actuel,Signal_suivant, Nbre_recu_cdm,Tempo_chgt_feux,Adj1,Adj2,NbrePN,ServeurInterfaceCDM, - ServeurRetroCDM,TailleFonte : integer; - - Hors_tension2,traceSign,TraceZone,Ferme,parSocket,ackCdm,PremierFD, - NackCDM,MsgSim,succes,recu_cv,AffActionneur,AffAigDet, + ServeurRetroCDM,TailleFonte,Nb_Det_Dist : integer; + + Hors_tension2,traceSign,TraceZone,Ferme,parSocketLenz,ackCdm,PremierFD, + NackCDM,MsgSim,succes,recu_cv,AffActionneur,AffAigDet,Option_demarrage, TraceListe,clignotant,nack,Maj_feux_cours,configNulle,LanceCDM : boolean; CDMhd : THandle; branche : array [1..100] of string; FormPrinc: TFormPrinc; - ack,portCommOuvert,trace,AffMem,AfficheDet,CDM_connecte,SocketCDM_connecte, - DebugOuv,Raz_Acc_signaux,AvecInit,AvecTCO,terminal,Srvc_Aig,Srvc_Det,Srvc_Act, - Srvc_PosTrain,Srvc_Sig : boolean; + ack,portCommOuvert,traceTrames,AffMem,AfficheDet,CDM_connecte,SocketCDM_connecte, + Raz_Acc_signaux,AvecInit,AvecTCO,terminal,Srvc_Aig,Srvc_Det,Srvc_Act, + Srvc_PosTrain,Srvc_Sig,debugtrames : boolean; tablo : array of byte; // tableau rx usb Enregistrement,chaine_Envoi,chaine_recue,Id_CDM,Af, entete,suffixe,ConfStCom,LAY : string; maxaiguillage,detecteur_chgt,Temps,Tempo_init,Suivant,TypeGen, NbreImagePligne,NbreBranches,Index2_det,Index2_aig,branche_det,Index_det, I_simule,maxTablo_act,NbreVoies,AdresseFeuSuivant,El_suivant : integer; - Ancien_detecteur,detecteur : array[0..1024] of boolean; // anciens état des détecteurs et adresses des détecteurs et leur état + Ancien_detecteur : array[0..1024] of boolean; // anciens état des détecteurs et adresses des détecteurs et leur état + detecteur : array[0..1024] of + record + etat : boolean; + tempo : integer; + train : string; + end; + Adresse_detecteur : array[0..60] of integer; // adresses des détecteurs par index mem : array[0..1024] of boolean ; // mémoire des états des détecteurs MemZone : array[0..1024,0..1024] of boolean ; // mémoires de zones @@ -282,7 +293,7 @@ var ancien_tablo_signalCplx,EtatsignalCplx : array[0..MaxAcc] of word; mod_branches,mod_act : array[1..100] of string; // l'indice du tableau aiguillage est son adresse aiguillage : array[0..MaxAcc] of Taiguillage; - // signaux de la fenêtre de droite - L'index du tableau n'est pas l'adresse du feu + // signaux - L'index du tableau n'est pas l'adresse du feu feux : array[1..MaxAcc] of record adresse, aspect : integer; // adresse du feu, aspect (2 feux..9 feux 12=direction 2 feux .. 16=direction 6 feux) Img : TImage; // Pointeur sur structure TImage du feu @@ -346,6 +357,9 @@ function etat_signal_suivant(Adresse,rang : integer) : integer; function suivant_alg3(prec : integer;typeELprec : integer;var actuel : integer;typeElActuel : integer;alg : integer) : integer; function detecteur_suivant_El(el1: integer;TypeDet1 : integer;el2 : integer;TypeDet2 : integer) : integer ; function test_memoire_zones(adresse : integer) : boolean; +function PresTrainPrec(AdrFeu : integer) : boolean; +function cond_carre(adresse : integer) : boolean; +function carre_signal(adresse : integer) : boolean; implementation @@ -396,23 +410,6 @@ begin combine:=BitNum(CodeBin and $fc00); end; -procedure Xcode_to_aspect(codebin : word;var premierbit,combine : word) ; -var i,mot : word; -begin - mot:=codebin; - i:=0;premierbit:=0;Combine:=0; - - while (i<15) do - begin - if (mot and 1)=1 then // si bit 0 du mot est à 1 - begin - if (premierbit=0) then premierbit:=i+1 else Combine:=i+1; - end; - mot:=mot shr 1; //décaler à droite - inc(i); - end; -end; - // dessine un cercle plein dans le feu procedure cercle(ACanvas : Tcanvas;x,y,rayon : integer;couleur : Tcolor); begin @@ -422,10 +419,9 @@ begin Pen.Color:=clBlack; Ellipse(x-rayon,y-rayon,x+rayon,y+rayon); end; - //Affiche(IntToSTR(y),clyellow); end; -// dessine les feux sur une cible à 2 feux +// dessine les feux sur une cible à 2 feux dans le canvas spécifié // x,y : offset en pixels du coin supérieur gauche du feu // frX, frY : facteurs de réduction procedure dessine_feu2(Acanvas : Tcanvas;x,y : integer;frX,frY : real;EtatSignal : word;orientation : integer); @@ -434,13 +430,13 @@ var Temp,rayon,xViolet,YViolet,xBlanc,yBlanc, ech : real; code,combine : word; begin - code_to_aspect(Etatsignal,code,combine); // et aspect + code_to_aspect(Etatsignal,code,combine); rayon:=round(6*frX); // récupérer les dimensions de l'image d'origine du feu LgImage:=Formprinc.Image2feux.Picture.Bitmap.Width; HtImage:=Formprinc.Image2feux.Picture.Bitmap.Height; - + XBlanc:=13; YBlanc:=11; xViolet:=13; yViolet:=23; @@ -451,7 +447,7 @@ begin Temp:=HtImage-yViolet;YViolet:=XViolet;XViolet:=Temp; Temp:=HtImage-yBlanc;YBlanc:=XBlanc;XBlanc:=Temp; end; - + if (orientation=3) then begin //rotation 90° vers la droite des feux @@ -460,10 +456,10 @@ begin Temp:=LgImage-XBlanc;Xblanc:=Yblanc;Yblanc:=Temp; Temp:=LgImage-Xviolet;Xviolet:=Yviolet;Yviolet:=Temp; end; - + XBlanc:=round(xBlanc*Frx)+x; YBlanc:=round(Yblanc*Fry)+Y; XViolet:=round(XViolet*FrX)+x; YViolet:=round(YViolet*FrY)+Y; - + // extinctions if not((code=blanc_cli) and clignotant) then cercle(ACanvas,xBlanc,yBlanc,rayon,GrisF); cercle(ACanvas,xViolet,yViolet,rayon,GrisF); @@ -486,7 +482,7 @@ begin LgImage:=Formprinc.Image3feux.Picture.Bitmap.Width; HtImage:=Formprinc.Image3feux.Picture.Bitmap.Height; - + Xvert:=13; Yvert:=11; xSem:=13; ySem:=22; xJaune:=13; yJaune:=33; @@ -498,7 +494,7 @@ begin Temp:=HtImage-ySem;YSem:=XSem;XSem:=Temp; Temp:=HtImage-yvert;Yvert:=Xvert;Xvert:=Temp; end; - + if (orientation=3) then begin //rotation 90° vers la droite des feux @@ -507,11 +503,11 @@ begin Temp:=LgImage-XSem;XSem:=YSem;YSem:=Temp; Temp:=LgImage-Xvert;Xvert:=Yvert;Yvert:=Temp; end; - + XJaune:=round(Xjaune*Frx)+x; YJaune:=round(Yjaune*Fry)+Y; Xvert:=round(Xvert*FrX)+x; Yvert:=round(Yvert*FrY)+Y; XSem:=round(XSem*FrX)+x; YSem:=round(YSem*FrY)+Y; - + // extinctions if not((code=jaune_cli) and clignotant) then cercle(ACanvas,xJaune,yJaune,rayon,GrisF); if not((code=vert_cli) and clignotant) then cercle(ACanvas,xVert,yVert,rayon,GrisF); @@ -524,7 +520,7 @@ begin end; // dessine les feux sur une cible à 4 feux -// orientation=1 vertical +// orientation=1 vertical procedure dessine_feu4(Acanvas : Tcanvas;x,y : integer;frX,frY : real;EtatSignal : word;orientation : integer); var Temp,rayon,xSem,Ysem,xJaune,Yjaune,Xcarre,Ycarre,Xvert,Yvert, LgImage,HtImage : integer; @@ -536,7 +532,7 @@ begin LgImage:=Formprinc.Image4feux.Picture.Bitmap.Width; HtImage:=Formprinc.Image4feux.Picture.Bitmap.Height; - + Xcarre:=13; ycarre:=11; Xvert:=13; Yvert:=22; xSem:=13; ySem:=33; @@ -740,7 +736,7 @@ end; // dessine les feux sur une cible à 9 feux procedure dessine_feu9(Acanvas : Tcanvas;x,y : integer;frX,frY : real;etatsignal : word;orientation : integer); -var rayon, +var rayon, XBlanc,Yblanc,xJaune,yJaune,Xsem,YSem,Xvert,YVert,Xcarre,Ycarre,Xral1,Yral1,Xral2,YRal2, Xrap1,Yrap1,Xrap2,Yrap2,Temp : integer; LgImage,HtImage,xt,yt : integer; @@ -763,7 +759,7 @@ begin LgImage:=Formprinc.Image9feux.Picture.Bitmap.Width; HtImage:=Formprinc.Image9feux.Picture.Bitmap.Height; - + if (orientation=2) then begin //rotation 90° vers la gauche des feux @@ -791,7 +787,7 @@ begin Temp:=LgImage-Xral1;Xral1:=Yral1;Yral1:=Temp; Temp:=LgImage-Xral2;Xral2:=Yral2;Yral2:=Temp; Temp:=LgImage-Xrap1;Xrap1:=Yrap1;Yrap1:=Temp; - Temp:=LgImage-Xrap2;Xrap2:=Yrap2;Yrap2:=Temp; + Temp:=LgImage-Xrap2;Xrap2:=Yrap2;Yrap2:=Temp; end; XJaune:=round(Xjaune*Frx)+x; YJaune:=round(Yjaune*Fry)+Y; @@ -836,7 +832,7 @@ begin if ((code=vert_cli) and clignotant) or (code=vert) then cercle(ACanvas,xvert,yvert,rayon,clGreen); if ((code=blanc_cli) and clignotant) or (code=blanc) then cercle(ACanvas,xBlanc,yBlanc,rayon,clWhite); if (code=violet) then cercle(ACanvas,xblanc,yblanc,rayon,clViolet); - + if code=carre then begin cercle(ACanvas,xcarre,yCarre,rayon,clRed); @@ -1003,7 +999,7 @@ begin cercle(ACanvas,53,13,6,GrisF); cercle(ACanvas,63,13,6,GrisF); end; - if EtatSignal=3 then + if EtatSignal=3 then begin cercle(ACanvas,11,13,6,clWhite); cercle(ACanvas,22,13,6,clWhite); @@ -1050,7 +1046,7 @@ begin cercle(ACanvas,12,13,6,GrisF); cercle(ACanvas,25,13,6,GrisF); end; - if EtatSignal=1 then + if EtatSignal=1 then begin cercle(ACanvas,12,13,6,clWhite); cercle(ACanvas,25,13,6,GrisF); @@ -1063,19 +1059,18 @@ begin end; - -// affiche un texte dans la fenêtre procedure Affiche(s : string;lacouleur : TColor); begin - couleur:=lacouleur; - with formprinc.ListBox1 do + with formprinc do begin - Items.addObject(s,pointer(lacouleur)); - TopIndex:= Items.Count - 1; + FenRich.lines.add(s); + RE_ColorLine(FenRich,FenRich.lines.count-1,lacouleur); + //FenRich.SetFocus; + //FenRich.SelStart := FenRich.GetTextLen; + //FenRich.Perform(EM_SCROLLCARET, 0, 0); end; end; - - + // renvoie l'index du feu dans le tableau feux[] en fonction de son adresse //si pas de feu renvoie 0 function Index_feu(adresse : integer) : integer; @@ -1192,14 +1187,14 @@ begin 5 : picture.bitmap:=Formprinc.Image5feux.picture.Bitmap; 7 : picture.bitmap:=Formprinc.Image7feux.picture.Bitmap; 9 : picture.bitmap:=Formprinc.Image9feux.picture.Bitmap; - + 12 : picture.bitmap:=Formprinc.Image2Dir.picture.Bitmap; 13 : picture.bitmap:=Formprinc.Image3Dir.picture.Bitmap; 14 : picture.bitmap:=Formprinc.Image4Dir.picture.Bitmap; 15 : picture.bitmap:=Formprinc.Image5Dir.picture.Bitmap; 16 : picture.bitmap:=Formprinc.Image6Dir.picture.Bitmap; end; - + // mettre rouge par défaut if TypeFeu=2 then EtatSignalCplx[feux[rang].adresse]:=violet_F; if TypeFeu=3 then EtatSignalCplx[feux[rang].adresse]:=semaphore_F; @@ -1270,7 +1265,7 @@ end; // Affiche une chaîne en Hexa Ascii procedure affiche_chaine_hex(s : string;couleur : Tcolor); begin - if trace then Affiche(chaine_HEX(s),couleur); + if traceTrames then AfficheDebug(chaine_HEX(s),couleur); end; // temporisation en x 100 ms (0,1 s) @@ -1290,7 +1285,7 @@ var i,timeout,valto : integer; begin // com:=formprinc.MSCommUSBLenz; s:=entete+s+suffixe; - if Trace then Affiche('Tick='+IntToSTR(tick)+'/Env '+chaine_Hex(s),ClGreen); + if traceTrames then AfficheDebug('Tick='+IntToSTR(tick)+'/Env '+chaine_Hex(s),ClGreen); // par port com-usb if portCommOuvert then @@ -1333,7 +1328,7 @@ begin end; // par socket (ethernet) - if parSocket then Formprinc.ClientSocketLenz.Socket.SendText(s); + if parSocketLenz then Formprinc.ClientSocketLenz.Socket.SendText(s); end; // envoi d'une chaîne à la centrale Lenz par USBLenz ou socket, puis attend l'ack ou le nack @@ -1345,7 +1340,7 @@ begin envoi_ss_ack(s); // attend l'ack ack:=false;nack:=false; - if portCommOuvert or ParSocket then + if portCommOuvert or parSocketLenz then begin temps:=0; repeat @@ -1383,6 +1378,20 @@ begin chaine_CDM_Func:=so+s; end; +// chaîne pour vitesse train +function chaine_CDM_vitesse(vitesse:integer;train:string) : string; +var s,so,sx: string; +begin + { C-C-00-0002-CMDTRN-SPEED|0xx|02|NAME=nomdutrain;UREQ=vitesse; } + so:=place_id('C-C-01-0004-CMDTRN-SPEED'); + s:=s+'NAME='+train+';'; + s:=s+'UREQ='+intToSTR(vitesse)+';'; + sx:=format('%.*d',[2,2])+'|'; // 2 paramètres + so:=so+ '|'+format('%.*d',[3,length(s)+length(sx)])+'|'+sx; + + chaine_CDM_vitesse:=so+s; +end; + // prépare la chaîne de commande pour un accessoire via CDM Function chaine_CDM_Acc(adresse,etat1 : integer) : string; var so,sx,s : string; @@ -1477,17 +1486,18 @@ begin s:=chaine_CDM_Acc(adresse,octet); envoi_CDM(s); if (acc=feu) and not(Raz_Acc_signaux) then exit; - if debug_dec_sig and (acc=feu) then AfficheDebug('Tick='+IntToSTR(Tick)+' signal '+intToSTR(adresse)+' '+intToSTR(octet),clorange); + if debug_dec_sig and (acc=feu) then AfficheDebug('Tick='+IntToSTR(Tick)+' signal '+intToSTR(adresse)+' 0',clorange); s:=chaine_CDM_Acc(adresse,0); envoi_CDM(s); exit; end; - // pilotage par USB ou par réseau de la centrale - // test si pilotage inversé + // pilotage par USB ou par éthernet de la centrale + // Affiche('Accessoire '+intToSTR(adresse),clLime); - if hors_tension2=false then + if (hors_tension2=false) and (portCommOuvert or parSocketLenz) then begin + // test si pilotage aiguillage inversé if aiguillage[adresse].inversion=1 then begin if octet=1 then octet:=2 else octet:=1; @@ -1504,14 +1514,14 @@ begin envoi(s); // envoi de la trame et attente Ack // si l'accessoire est un feu et sans raz des signaux, sortir if (acc=feu) and not(Raz_Acc_signaux) then exit; - + // si aiguillage, faire une temporisation //if (index_feu(adresse)=0) or (Acc=aig) then if Acc=Aig then begin temps:=aiguillage[adresse].temps;if temps=0 then temps:=4; - if portCommOuvert or ParSocket then tempo(temps); + if portCommOuvert or parSocketLenz then tempo(temps); end; sleep(50); @@ -1547,7 +1557,7 @@ begin // si l'accessoire est un feu, fixer l tempo à 1 //if index_feu(adresse)<>0 then temps:=1; - //if portCommOuvert or ParSocket then tempo(temps); + //if portCommOuvert or parSocketLenz then tempo(temps); // pilotage à 0 pour éteindre le pilotage de la bobine du relais s:=#$52+Char(groupe)+char(fonction or $80); // désactiver la sortie s:=checksum(s); @@ -1557,10 +1567,19 @@ end; procedure vitesse_loco(loco : integer;vitesse : integer;sens : boolean); var s : string; begin - if sens then vitesse:=vitesse or 128; - s:=#$e4+#$13+#$0+char(loco)+char(vitesse); - s:=checksum(s); - envoi(s); + if portCommOuvert or parSocketLenz then + begin + if sens then vitesse:=vitesse or 128; + s:=#$e4+#$13+#$0+char(loco)+char(vitesse); + s:=checksum(s); + envoi(s); + end; + if cdm_connecte then + begin + //s:=chaine_CDM_vitesse(0,'BB25531'); + s:=chaine_CDM_vitesse(1,'CC406526'); // 0 n'arrete pas le train + envoi_CDM(s); + end; end; // fonctions sur les bits @@ -1579,17 +1598,15 @@ begin SetBit:=n or (1 shl position); end; - - // renvoie la chaîne de l'état du signal function chaine_signal(etat : word) : string; var aspect,combine : word; s : string; begin - code_to_aspect(etat,aspect,combine); - s:=''; + code_to_aspect(etat,aspect,combine); + s:=''; if aspect=16 then s:='' else s:=etatSign[aspect]; - if combine<>16 then + if combine<>16 then begin if aspect<>16 then s:=s+'+'; s:=s+etatSign[combine]; @@ -1602,7 +1619,9 @@ end; // Aspect : code représentant l'état du signal de 0 à 15 procedure Maj_Etat_Signal(adresse,aspect : integer); var i : integer; -begin +begin +// ('0carré','1sémaphore','2sémaphore cli','3vert','4vert cli','5violet', +// '6blanc','7blanc cli','8jaune','9jaune cli','10ral 30','11ral 60','12rappel 30','13rappel 60'); if testBit((EtatSignalCplx[adresse]),aspect)=false then // si le bit dans l'état du signal n'est pas allumé, procéder. begin // effacement du motif de bits en fonction du nouvel état demandé suivant la règle des signaux complexes @@ -1650,7 +1669,7 @@ begin end; // mise à jour de l'état du signal dans le tableau Feux i:=Index_feu(adresse); - feux[i].EtatSignal:=EtatSignalCplx[adresse]; + feux[i].EtatSignal:=EtatSignalCplx[adresse]; end; @@ -1762,7 +1781,7 @@ begin end; {========================================================================== -envoie les données au décodeur CDF pour un signal +envoie les données au décodeur CDF ===========================================================================*} procedure envoi_CDF(adresse : integer); var index : integer; @@ -1773,11 +1792,11 @@ begin begin ancien_tablo_signalCplx[adresse]:=EtatSignalCplx[adresse]; code:=EtatSignalCplx[adresse]; - code_to_aspect(code,aspect,combine); + code_to_aspect(code,aspect,combine); s:='Signal CDF: ad'+IntToSTR(adresse)+'='+chaine_signal(code); if traceSign then affiche(s,clOrange); - if Affsignal then afficheDebug(s,clOrange); - + if Affsignal then afficheDebug(s,clOrange); + if (aspect=carre) then pilote_acc(adresse,2,feu) ; if (aspect=semaphore) then pilote_acc(adresse,1,feu) ; if (aspect=vert) then pilote_acc(adresse+1,1,feu) ; @@ -1792,7 +1811,7 @@ begin end; {========================================================================== -envoie les données au décodeur LEB pour un signal +envoie les données au décodeur LEB ===========================================================================*} procedure envoi_LEB(adresse : integer); var code,aspect,combine : word; @@ -1937,7 +1956,7 @@ var modele,index: integer ; begin index:=Index_feu(adresse); // tranforme l'adresse du feu en index tableau - if (ancien_tablo_signalCplx[adresse]<>EtatSignalCplx[adresse]) then + if (ancien_tablo_signalCplx[adresse]<>EtatSignalCplx[adresse]) then begin ancien_tablo_signalCplx[adresse]:=EtatSignalCplx[adresse]; code:=EtatSignalCplx[adresse]; @@ -2230,9 +2249,9 @@ procedure envoi_LDT(adresse : integer); var code,aspect,combine,mode : word; s : string; begin - //***if (ancien_tablo_signalCplx[adresse]<>EtatSignalCplx[adresse]) then //; && (stop_cmd==FALSE)) + if (ancien_tablo_signalCplx[adresse]<>EtatSignalCplx[adresse]) then //; && (stop_cmd==FALSE)) begin - //***ancien_tablo_signalCplx[adresse]:=EtatSignalCplx[adresse]; + ancien_tablo_signalCplx[adresse]:=EtatSignalCplx[adresse]; code:=EtatSignalCplx[adresse]; code_to_aspect(code,aspect,combine); s:='Signal LDT: ad'+IntToSTR(adresse)+'='+chaine_signal(code); @@ -2305,9 +2324,8 @@ var aspect,code,combine : word; ralrap, jau ,Ancralrap,Ancjau : boolean; s : string; begin - //***if (ancien_tablo_signalCplx[adresse]<>EtatSignalCplx[adresse]) then //; && (stop_cmd==FALSE)) + if (ancien_tablo_signalCplx[adresse]<>EtatSignalCplx[adresse]) then //; && (stop_cmd==FALSE)) begin - code:=EtatSignalCplx[adresse]; code_to_aspect(code,aspect,combine); s:='Signal Bahn: ad'+IntToSTR(adresse)+'='+chaine_signal(code); @@ -2324,7 +2342,7 @@ begin Ancjau:=(TestBit(ancien_tablo_signalCplx[adresse],jaune)) or (TestBit(ancien_tablo_signalCplx[adresse],jaune_cli)) ; //***ancien_tablo_signalCplx[adresse]:=EtatSignalCplx[adresse]; - + // si état demandé du signal=ralentissement ou rappel ralrap:=(TestBit(code,ral_30)) or (TestBit(code,ral_60)) or (TestBit(code,rappel_30)) or (TestBit(code,rappel_60)) ; @@ -2349,7 +2367,7 @@ begin sleep(40); pilote_ACC(adresse+Combine,2,feu) ; end; - + ancien_tablo_signalCplx[adresse]:=EtatSignalCplx[adresse]; end; end; @@ -2519,7 +2537,7 @@ else signalCplx:=232; if ((aiguillage[1].position<>2) and (aiguillage[3].position=2) and (aiguillage[4].position=2) and (aiguillage[6].position<>0)) then begin - if detecteur[516] then Maj_Etat_Signal(signalCplx,blanc) + if detecteur[516].etat then Maj_Etat_Signal(signalCplx,blanc) else Maj_Etat_Signal(signalCplx,blanc_cli) end else Maj_Etat_Signal(signalCplx,violet); @@ -2716,7 +2734,7 @@ signalCplx:=316; if ( (aiguillage[5].position=2) and (aiguillage[3].position<>2) and (aiguillage[1].position<>2) ) or ( feux[index_feu(signalCplx)].check.checked) then begin - if detecteur[518] then Maj_Etat_Signal(signalCplx,blanc_cli) else Maj_Etat_Signal(signalCplx,blanc) ; + if detecteur[518].etat then Maj_Etat_Signal(signalCplx,blanc_cli) else Maj_Etat_Signal(signalCplx,blanc) ; end else begin @@ -3208,15 +3226,16 @@ end; // de la proc // pilotage d'un signal procedure envoi_signal(Adr : integer); -var i,adresse,a,aspect,x,y,x0,y0,TailleX,TailleY,Orientation : integer; +var i,adresse,det,a,b,aspect,x,y,x0,y0,TailleX,TailleY,Orientation : integer; ImageFeu : TImage; frX,frY : real; + s : string; begin - i:=index_feu(Adr); + i:=index_feu(Adr); if (ancien_tablo_signalCplx[adr]<>EtatSignalCplx[adr]) then //*** begin if feux[i].aspect<10 then // si signal non directionnel - begin + begin // envoie la commande au décodeur case feux[i].decodeur of 0 : envoi_virtuel(Adr); @@ -3228,11 +3247,38 @@ begin 6 : envoi_UniSemaf(Adr); end; + // vérifier si on quitte le rouge + if Option_demarrage then + begin + a:=ancien_tablo_signalCplx[adr]; + b:=EtatSignalCplx[adr]; + if ((a=semaphore_F) or (a=carre_F) or (a=violet_F)) and ((b<>semaphore_F) and (b<>carre_F) and (b<>violet_F)) then + if not(Diffusion) then Affiche('On quitte le rouge du signal '+intToSTR(adr),clyellow); + // y a t il un train en face du signal + if cdm_connecte then + begin + det:=feux[i].Adr_det1; + if det<>0 then + begin + // test si train sur le détecteur det + if detecteur[det].etat then + begin + detecteur[det].tempo:=20; // armer la tempo à 2s + // arreter le train + s:=detecteur[det].train; + Affiche('et son détecteur '+IntToSTR(det)+'=1 tempo démarrage '+s,clYellow); + s:=chaine_CDM_vitesse(1,s); // 0% + envoi_cdm(s); + end; + end; + end; + end; + ancien_tablo_signalCplx[adr]:=EtatSignalCplx[adr]; //*** // allume les signaux du feu dans la fenêtre de droite - Dessine_feu_mx(Feux[i].Img.Canvas,0,0,1,1,adr,1); - + Dessine_feu_mx(Feux[i].Img.Canvas,0,0,1,1,adr,1); + // allume les signaux du feu dans le TCO if AvecTCO then begin @@ -3260,7 +3306,7 @@ begin Orientation:=TCO[x,y].FeuOriente; // réduction variable en fonction de la taille des cellules calcul_reduction(frx,fry,round(TailleX*LargeurCell/ZoomMax),round(tailleY*HauteurCell/ZoomMax),TailleX,TailleY); - + // décalage en X pour mettre la tete du feu alignée sur le bord droit de la cellule pour les feux tournés à 90G if orientation=2 then begin @@ -3410,12 +3456,13 @@ begin IndexBranche_trouve:=i; end; - - procedure lit_config; var s,sa,chaine,SOrigine: string; c,paig : char; - tec,tjd,tjs,s2,trouve,triple,debugConfig,multiple,fini,finifeux : boolean; + tec,tjd,tjs,s2,trouve,triple,debugConfig,multiple,fini,finifeux,trouve_NbDetDist,trouve_ipv4_PC,trouve_retro, + trouve_sec_init,trouve_init_aig,trouve_lay,trouve_IPV4_INTERFACE,trouve_PROTOCOLE_SERIE,trouve_INTER_CAR, + trouve_Tempo_maxi,trouve_Entete,trouve_tco,trouve_cdm,trouve_Serveur_interface,trouve_fenetre, + trouve_NOTIF_VERSION,trouve_verif_version,trouve_fonte : boolean; bd,virgule,i_detect,i,erreur,aig,aig2,detect,offset,index, adresse,j,position,temporisation,invers,indexPointe,indexDevie,indexDroit, ComptEl,Compt_IT,Num_Element,k,modele,adr,adr2,erreur2,l,t,Nligne,postriple, postjd,postjs,nv,it : integer; @@ -3439,7 +3486,7 @@ var s,sa,chaine,SOrigine: string; begin begin adresse:=StrToINT(copy(s,1,j-1));Delete(s,1,j); // adresse aiguillage - if (adresse>0) and (AvecInitAiguillages=1) then + if (adresse>0) and (AvecInitAiguillages=1) then begin j:=pos(',',s); position:=StrToInt(copy(s,1,j-1));Delete(S,1,j);// position aiguillage @@ -3463,6 +3510,26 @@ var s,sa,chaine,SOrigine: string; begin debugConfig:=false; + trouve_NbDetDist:=false; + trouve_ipv4_PC:=false; + trouve_retro:=false; + trouve_sec_init:=false; + trouve_init_aig:=false; + trouve_INTER_CAR:=false; + trouve_entete:=false; + trouve_IPV4_INTERFACE:=false; + trouve_lay:=false; + trouve_Tempo_maxi:=false; + trouve_PROTOCOLE_SERIE:=false; + trouve_TCO:=false; + trouve_Serveur_interface:=false; + trouve_cdm:=false; + trouve_NOTIF_VERSION:=false; + trouve_fenetre:=false; + trouve_verif_version:=false; + trouve_Fonte:=false; + + Nb_Det_Dist:=3; // initialisation des aiguillages avec des valeurs par défaut for i:=1 to MaxAcc do begin @@ -3475,7 +3542,8 @@ begin end; for i:=1 to 1024 do begin - Detecteur[i]:=false; + Detecteur[i].etat:=false; + Detecteur[i].train:='0'; Ancien_detecteur[i]:=false; end; //ChDir(s); @@ -3494,26 +3562,27 @@ begin repeat s:=lit_ligne; //affiche(s,cllime); - sa:='FONTE='; + sa:=uppercase(Fonte_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); + trouve_fonte:=true; delete(s,i,length(sa)); TailleFonte:=StrToINT(s); - with FormPrinc.ListBox1 do + with FormPrinc.FenRich do begin - Font.Height:=TailleFonte; - ItemHeight:=TailleFonte+1; + Font.Size:=TailleFonte; end; end; - + // adresse ip et port de CDM - sa:='IPV4_PC='; + sa:=uppercase(IpV4_PC_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); + trouve_ipv4_PC:=true; delete(s,i,length(sa)); i:=pos(':',s); if i<>0 then begin adresseIPCDM:=copy(s,1,i-1);Delete(s,1,i);portCDM:=StrToINT(s);end; @@ -3521,57 +3590,62 @@ begin // adresse ip et port de la centrale // AfficheDet:=true; - sa:='IPV4_INTERFACE='; + sa:=uppercase(IPV4_INTERFACE_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); + trouve_IPV4_INTERFACE:=true; delete(s,i,length(sa)); i:=pos(':',s); if i<>0 then begin adresseIP:=copy(s,1,i-1);Delete(s,1,i);port:=StrToINT(s);end - else begin adresseIP:='0';parSocket:=false;end; + else begin adresseIP:='0';parSocketLenz:=false;end; end; - + // configuration du port com - sa:='PROTOCOLE_SERIE='; + sa:=uppercase(PROTOCOLE_SERIE_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); + trouve_PROTOCOLE_SERIE:=true; delete(s,i,length(sa)); if not(config_com(s)) then Affiche('Erreur port com mal déclaré : '+s,clred); portcom:=s; end; - + // temporisation entre 2 caractères - sa:='INTER_CAR='; + sa:=uppercase(INTER_CAR_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); delete(s,i,length(sa)); + trouve_INTER_CAR:=true; val(s,TempoOctet,erreur); if erreur<>0 then Affiche('Erreur temporisation entre 2 octets',clred); end; - + // temporisation attente maximale interface - sa:='TEMPO_MAXI='; + sa:=uppercase(TEMPO_MAXI_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); delete(s,i,length(sa)); + trouve_Tempo_maxi:=true; val(s,TimoutMaxInterface,erreur); if erreur<>0 then Affiche('Erreur temporisation maximale interface',clred); end; - + // entete - sa:='ENTETE='; + sa:=uppercase(ENTETE_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); delete(s,i,length(sa)); + trouve_Entete:=true; val(s,Valeur_entete,erreur); entete:=''; case Valeur_entete of @@ -3579,41 +3653,44 @@ begin 1 : begin entete:=#$FF+#$FE;suffixe:='';end; 2 : begin entete:=#228;suffixe:=#13+#13+#10;end; end; - if (erreur<>0) or (valeur_entete>2) then Affiche('Erreur déclaration variable entete',clred); + if (erreur<>0) or (valeur_entete>2) then Affiche('Erreur déclaration variable '+entete_ch,clred); end; // avec ou sans initialisation des aiguillages - sa:='INIT_AIG='; + sa:=uppercase(INIT_AIG_ch)+'='; + i:=pos(sa,s); + if i<>0 then + begin + trouve_init_aig:=true; + inc(nv); + delete(s,i,length(sa)); + AvecInitAiguillages:=StrToINT(s); + end; + + sa:=uppercase(fenetre_ch)+'='; i:=pos(sa,s); if i<>0 then begin inc(nv); - delete(s,i,length(sa)); - AvecInitAiguillages:=StrToINT(s); - end; - - sa:='FENETRE='; - i:=pos(sa,s); - if i<>0 then - begin - inc(nv); + trouve_fenetre:=true; delete(s,i,length(sa)); val(s,fenetre,erreur); if fenetre=1 then Formprinc.windowState:=wsMaximized; end; - sa:='SECTION_INIT'; - i:=pos(sa,s); - if i<>0 then + i:=pos(uppercase(section_init),s); + if i<>0 then begin - inc(nv); + inc(nv); + trouve_sec_init:=true; compile_section_init; end; - sa:='VERIF_VERSION='; + sa:=uppercase(verif_version_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin + trouve_verif_version:=true; inc(nv); delete(s,i,length(sa)); // vérification de la version au démarrage @@ -3621,36 +3698,39 @@ begin val(s,i,erreur); if erreur=0 then verifVersion:=i=1; end; - - sa:='NOTIF_VERSION='; + + sa:=uppercase(NOTIF_VERSION_ch)+'='; i:=pos(sa,s); if i<>0 then begin inc(nv); delete(s,i,length(sa)); + trouve_NOTIF_VERSION:=true; // vérification de la version au démarrage i:=0; val(s,i,erreur); notificationVersion:=i=1; end; - sa:='TCO='; + sa:=uppercase(TCO_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); delete(s,i,length(sa)); + trouve_TCO:=true; // vérification de la version au démarrage i:=0; val(s,i,erreur); AvecTCO:=i=1; end; - sa:='CDM='; + sa:=uppercase(CDM_ch)+'='; i:=pos(sa,s); if i<>0 then begin inc(nv); + trouve_CDM:=true; delete(s,i,length(sa)); // vérification de la version au démarrage i:=0; @@ -3658,43 +3738,79 @@ begin LanceCDM:=i=1; end; - sa:='LAY='; + sa:=uppercase(LAY_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); + trouve_lay:=true; delete(s,i,length(sa)); lay:=s; end; - sa:='SERVEUR_INTERFACE='; + sa:=uppercase(SERVEUR_INTERFACE_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); + trouve_serveur_interface:=true; delete(s,i,length(sa)); i:=0; val(s,i,erreur); ServeurInterfaceCDM:=i; end; - sa:='RETRO='; + sa:=uppercase(RETRO_ch)+'='; i:=pos(sa,s); - if i<>0 then + if i<>0 then begin inc(nv); + trouve_retro:=true; delete(s,i,length(sa)); i:=0; val(s,i,erreur); ServeurRetroCDM:=i; end; + sa:=uppercase(nb_det_dist_ch)+'='; + i:=pos(sa,s); + if i<>0 then + begin + inc(nv); + trouve_NbDetDist:=true; + delete(s,i,length(sa)); + i:=0; + val(s,i,erreur); + if i<2 then begin i:=2;Affiche('Attention '+nb_det_dist_ch+' ramené à '+IntToSTR(i),clOrange); end; + Nb_Det_Dist:=i; + end; inc(it); - until (Nv>=17) or (it>30); - //affiche(IntToSTR(Nv)+' variables',clblue); - if it>30 then - begin affiche('ERREUR: manque variables dans config-gl.cfg',clred);exit;end; + until (Nv>=18) or (it>30); + + //affiche(IntToSTR(Nv)+' variables',cyan); + s:=''; + if (it>30) then s:='ERREUR: manque variables dans config-gl.cfg :'; + + if not(trouve_NbDetDist) then s:=s+' '+nb_det_dist_ch; + if not(trouve_ipv4_PC) then s:=s+' '+IpV4_PC_ch; + if not(trouve_retro) then s:=s+' '+retro_ch; + if not(trouve_sec_init) then s:=s+' '+section_init; + if not(trouve_init_aig) then s:=s+' '+INIT_AIG_ch; + if not(trouve_lay) then s:=s+' '+LAY_ch; + if not(trouve_INTER_CAR) then s:=s+' '+INTER_CAR_ch; + if not(trouve_Tempo_maxi) then s:=s+' '+Tempo_maxi_ch; + if not(trouve_Entete) then s:=s+' '+Entete_ch; + if not(trouve_TCO) then s:=s+' '+TCO_ch; + if not(trouve_CDM) then s:=s+' '+CDM_ch; + if not(trouve_Serveur_interface) then s:=s+' '+Serveur_interface_ch; + if not(trouve_fenetre) then s:=s+' '+fenetre_ch; + if not(trouve_NOTIF_VERSION) then s:=s+' '+NOTIF_VERSION_ch; + if not(trouve_verif_version) then s:=s+' '+verif_version_ch; + if not(trouve_fonte) then s:=s+' '+fonte_ch; + + if s<>'' then affiche(s,clred); + //Affiche('Valeurs d''initialisation des aiguillages',clyellow); closefile(fichier); @@ -3924,8 +4040,7 @@ begin s:=lit_ligne; mod_Branches[Nligne]:=s;inc(Nligne); //Affiche(s,clWhite); - //adresse:=pos('0',s); - //s:='A16B,557,0' ; + if s<>'0' then begin branche[i]:=s; @@ -3960,6 +4075,7 @@ begin begin //Affiche(IntToSTR(detect),clyellow); //Affiche(s,clorange); Affiche(IntToStr(detect),clorange); + //if detect=0 then affiche('buttoir'+sOrigine,clyellow); BrancheN[i,j].adresse:=detect; // adresse BrancheN[i,j].btype:=1;// ident détecteur if detect=0 then begin BrancheN[i,j].btype:=4;end; // buttoir @@ -4038,7 +4154,7 @@ begin repeat //Affiche('Boucle de direction',clyellow); //Affiche(s,clOrange); - if s[1]<>'A' then begin Affiche('Erreur a la ligne',clred);exit;end; + if s[1]<>'A' then begin Affiche('Erreur a la ligne '+s,clred);exit;end; delete(s,1,1); val(s,adr,erreur); // adresse c:=s[erreur]; // type @@ -4465,26 +4581,14 @@ end; // front descendant sur un détecteur function detecteur_0(adresse : integer) : boolean; begin - detecteur_0:=(Ancien_detecteur[adresse]=true) and ((detecteur[adresse])=false); - Ancien_detecteur[adresse]:=detecteur[adresse]; + detecteur_0:=(Ancien_detecteur[adresse]=true) and ((detecteur[adresse].etat)=false); + Ancien_detecteur[adresse]:=detecteur[adresse].etat; end; function detecteur_1(adresse : integer) : boolean; begin - detecteur_1:=(Ancien_detecteur[adresse]=false) and ((detecteur[adresse])=true); - Ancien_detecteur[adresse]:=detecteur[adresse]; -end; - -function virgule_prec(sl : string;o : integer) : integer; -var k : integer; -begin - o:=o-1; - for k:=o downto 1 do - begin - //Affiche(intToSTR(k)+'/'+sl[k],clGreen); - if sl[k]=',' then begin result:=k;exit;end; - end; - result:=0; + detecteur_1:=(Ancien_detecteur[adresse]=false) and ((detecteur[adresse].etat)=true); + Ancien_detecteur[adresse]:=detecteur[adresse].etat; end; // trouve un élément dans les branches à partir de la branche offset renvoie branche_trouve IndexBranche_trouve @@ -4526,7 +4630,6 @@ begin end; - // renvoie élément suivant entre deux éléments quels qu'ils soient mais contigus // et en variables globales: typeGen le type de l'élément // s'ils ne sont pas contigus, on aura une erreur @@ -4539,7 +4642,6 @@ end; // 9998= arret sur aiguillage en talon mal positionnée // 9997: arrêt sur aiguillage dévié // 9996: arrêt sur position inconnue d'aiguillage -// 9995: TJD non résolue // typeGen : 1=detecteur 2=aiguillage 3=aiguillage bis function suivant_alg3(prec : integer;typeELprec : integer;var actuel : integer;typeElActuel : integer;alg : integer) : integer; var Btype,Adr,AdrPrec,BtypePrec,indexBranche_prec,branche_trouve_prec,indexBranche_actuel,branche_trouve_actuel, @@ -4785,19 +4887,19 @@ begin tjscourbe2:=((aiguillage[AdrTjdP].tjsintB='D') and (aiguillage[tjsc2].position=const_droit)) or tjscourbe2; end; + if NivDebug=3 then + begin + s:='137 - TJD '+intToSTR(Adr)+'/'+IntToSTR(AdrTjdP)+' pos='; + if aiguillage[Adr].position=const_droit then s:=s+'droit' + else if aiguillage[Adr].position=const_devie then s:=s+'dévié' + else s:=s+'inconnu' ; + if aiguillage[AdrTJDP].position=const_droit then s:=s+'/droit' + else if aiguillage[AdrTJDP].position=const_devie then s:=s+'/dévié' + else s:=s+'/inconnu' ; + AfficheDebug(s,clyellow); + end; - if NivDebug=3 then AfficheDebug('137 - TJD '+intToSTR(Adr)+'/'+IntToSTR(AdrTjdP),clYellow); - s:='adr='+IntToSTR(adr)+'='; - if aiguillage[Adr].position=const_droit then s:=s+'droit' - else if aiguillage[Adr].position=const_devie then s:=s+'dévié' - else s:=s+'inconnu' ; - s:=s+'/adrTjdP='+IntToSTR(adrTJDP)+'='; - if aiguillage[AdrTJDP].position=const_droit then s:=s+'droit' - else if aiguillage[AdrTJDP].position=const_devie then s:=s+'dévié' - else s:=s+'inconnu' ; - - - // rechercher le port de destination de la tjd + // rechercher le port de destination de la tjd Adr2:=0;A:=#0; if aiguillage[Adr].position=const_droit then begin @@ -4818,26 +4920,29 @@ begin adr2:=aiguillage[adr2].Adevie; //Affichedebug('element connecté:'+inttostr(adr)+A,clred); end - else + else if A='D' then begin A:=aiguillage[adr2].AdroitB; adr2:=aiguillage[adr2].Adroit; end - else - begin - s:='Erreur 1021 TJD '+intToSTR(adr)+' non résolue'; - affichedebug(s,clred); - affiche(s,clred); - suivant_alg3:=9996; - exit; - end; + else + begin + if aiguillage[adr].position<>9 then + begin + s:='Erreur 1021 TJD '+intToSTR(adr)+' non résolue'; + affichedebug(s,clred); + Affiche(s,clred); + suivant_alg3:=9996; + exit; + end; + end; if nivDebug=3 then AfficheDebug('tjd: '+s+' Suiv='+intToSTR(adr2)+A,clYellow); if A='Z' then typeGen:=1 else typeGen:=2; //TypeEL=(1=détécteur 2=aig 3=aig Bis) suivant_alg3:=adr2; exit; - + // determiner la position de la première section de la TJD (4 cas) // cas 1 : droit droit if (( aiguillage[AdrTJdP].position=const_droit) and @@ -5132,12 +5237,13 @@ end; // renvoie l'adresse du détecteur suivant des deux éléments contigus -// TypeElprec/actuel: 1= détecteur 2= aiguillage 3=bis 4=Buttoir -function detecteur_suivant(prec : integer;TypeElPrec : integer;actuel : integer;TypeElActuel : integer) : integer ; +// TypeElprec/actuel: 1= détecteur 2= aiguillage 4=Buttoir +// algo= type d'algorythme pour suivant_alg3 +function detecteur_suivant(prec : integer;TypeElPrec : integer;actuel : integer;TypeElActuel,algo : integer) : integer ; var actuelCalc,PrecCalc,etat,i,j,AdrSuiv , TypeprecCalc,TypeActuelCalc : integer; begin - if NivDebug>=2 then AfficheDebug('cherche détecteur suivant aux '+IntToSTR(prec)+'/'+IntToSTR(typeElPrec)+' - '+intToSTR(actuel)+'/'+intToSTR(TypeElActuel),clyellow); + if NivDebug>=2 then AfficheDebug('Proc Detecteur_suivant '+IntToSTR(prec)+','+IntToSTR(typeElPrec)+'/'+intToSTR(actuel)+','+intToSTR(TypeElActuel),clyellow); j:=0; PrecCalc:=prec; @@ -5146,11 +5252,11 @@ begin TypeActuelCalc:=TypeELActuel; // étape 1 trouver le sens repeat - inc(j); - AdrSuiv:=suivant_alg3(precCalc,TypeprecCalc,actuelCalc,TypeActuelCalc,1); + inc(j); + AdrSuiv:=suivant_alg3(precCalc,TypeprecCalc,actuelCalc,TypeActuelCalc,algo); if (typeGen=2) and false then // si le précédent est une TJD/S et le suivant aussi begin - if ((aiguillage[AdrSuiv].modele=2) or (aiguillage[AdrSuiv].modele=3)) and + if ((aiguillage[AdrSuiv].modele=2) or (aiguillage[AdrSuiv].modele=3)) and ((aiguillage[actuelCalc].modele=2) or (aiguillage[ActuelCalc].modele=3)) then begin if nivDebug=3 then AfficheDebug('501 - Détection Précédent=TJD/S Suivant=TJD/S',clyellow); @@ -5162,8 +5268,9 @@ begin TypeprecCalc:=TypeActuelCalc; actuelCalc:=AdrSuiv; TypeActuelCalc:=typeGen; - //Affiche('Suivant signalaig='+IntToSTR(AdrSuiv),clyellow); - until (j=10) or (typeGen=1) or (AdrSuiv=0) or (AdrSuiv>=9996); // arret si détecteur + //Affiche('Suivant signalaig='+IntToSTR(AdrSuiv),clyellow); + until (j=10) or (typeGen=1) or (AdrSuiv=0) or (AdrSuiv>=9996); // arret si détecteur + // si trouvé le sens, trouver le suivant if AdrSuiv=actuel then begin @@ -5180,7 +5287,7 @@ begin end; } end; - if NivDebug=3 then AfficheDebug('Le suivant est le '+intToSTR(AdrSuiv),clYellow); + if (NivDebug=3) and (AdrSuiv<9996) then AfficheDebug('618 : Le suivant est le '+intToSTR(AdrSuiv),clYellow); detecteur_suivant:=AdrSuiv; end; @@ -5190,6 +5297,7 @@ procedure Det_Adj(adresse : integer); var Adr,BtypePrec,AdrFonc,Branche,BtypeFonc,AdrPrec,IndexBranche,i,Dir : integer; sortie : boolean; begin + if TraceListe then AfficheDebug('Det_Adj '+IntToSTR(adresse),clyellow); trouve_element(adresse,1,1); // branche_trouve IndexBranche_trouve if (IndexBranche_trouve=0) then begin @@ -5215,7 +5323,6 @@ begin begin Adr:=suivant_alg3(AdrPrec,BtypePrec,AdrFonc,BtypeFonc,2); // élément suivant mais arret sur aiguillage en talon mal positionnée end - else begin Adr:=AdrFonc;TypeGen:=BtypeFonc;end; if Adr>9990 then typeGen:=1; @@ -5229,21 +5336,22 @@ begin if (typeGen=1) and (Dir=2) then begin Adj2:=Adr;end; inc(dir); until dir=3; + if TraceListe then AfficheDebug('Fin Det_Adj ',clyellow); end; // renvoie l'adresse du détecteur suivant des deux éléments -// El1 et El2 peuvent être séparés par des aiguillages -// en sortie : 9999= det1 ou det2 non trouvé -// 9996 : non trouvé +// El1 et El2 peuvent être séparés par des aiguillages, mais de pas plus de 3 détecteurs +// en sortie : 9999= det1 ou det2 non trouvé +// 9996 : non trouvé function detecteur_suivant_El(el1: integer;TypeDet1 : integer;el2 : integer;TypeDet2 : integer) : integer ; var IndexBranche_det1,IndexBranche_det2,branche_trouve_det1,branche_trouve_det2,i, - j,AdrPrec,Adr,AdrFonc,TypePrec,TypeFonc,i1,i2,index : integer; + j,AdrPrec,Adr,AdrFonc,TypePrec,TypeFonc,i1,i2,index,N_det : integer; Sortie : boolean; s : string; label reprise; - + begin - if NivDebug>=2 then + if NivDebug>=2 then AfficheDebug('Proc Detecteur_suivant_EL '+intToSTR(el1)+','+intToSTR(Typedet1)+'/'+intToSTR(el2)+','+intToSTR(Typedet2)+'-------------------------',clLime); if (el1>9000) or (el2>9000) then begin @@ -5283,7 +5391,7 @@ begin j:=1; // J=1 test en incrément J=2 test en décrément // étape 1 : trouver le sens de progression (en incrément ou en décrément) - + repeat //préparer les variables AdrPrec:=el1;TypePrec:=typeDet1; @@ -5291,7 +5399,7 @@ begin if j=2 then i1:=IndexBranche_det1-1; if NivDebug=3 then begin - s:='Test 1 en '; + s:='Test en '; if (j=1) then s:=s+'incrément ' else s:=s+'décrément '; s:=s+'- départ depuis élément '+IntToSTR(el1)+' trouvé en index='+intToSTR(IndexBranche_det1)+' Branche='+intToSTR(branche_trouve_det1); AfficheDebug(s,clyellow); @@ -5300,49 +5408,19 @@ begin AdrFonc:=BrancheN[branche_trouve_det1,i1].adresse; typeFonc:=BrancheN[branche_trouve_det1,i1].Btype ; - - i:=0; + + i:=0;N_Det:=0; if AdrFonc<>El2 then // si pas déja trouvé le sens de progression - repeat - //AfficheDebug('Engage '+IntToSTR(AdrPrec)+','+IntToSTR(typePrec)+'/'+IntToSTR(AdrFonc)+','+IntToSTR(typeFonc),clyellow); - Adr:=suivant_alg3(AdrPrec,TypePrec,AdrFonc,TypeFonc,1); - //AfficheDebug('Sortie Alg3: '+IntToSTR(Adr)+'/'+intToSTR(typeGen),clyellow); - - if NivDebug=3 then - begin - s:='613 : trouvé='+intToSTR(Adr); - case typeGen of - 1 : s:=s+' detecteur'; - 2 : s:=s+' aiguillage'; - 3 : s:=s+' aiguillage bis'; - end; - AfficheDebug(s,clorange); - end; - - AdrPrec:=AdrFonc;TypePrec:=TypeFonc; - AdrFonc:=Adr;TypeFonc:=typeGen; - inc(i); - sortie:=((typeDet2=TypeGen) and (Adr=el2)) or (Adr=0) or (Adr>=9996) or (i=20); - until sortie - - else begin - // déja trouvé - adr:=el2;typeGen:=TypeDet2; - end; - - if (typeDet2=TypeGen) and (Adr=el2) then - begin - if Nivdebug=3 then AfficheDebug('614 : Trouvé '+intToSTR(el2),clYellow); - i:=0; repeat //AfficheDebug('Engage '+IntToSTR(AdrPrec)+','+IntToSTR(typePrec)+'/'+IntToSTR(AdrFonc)+','+IntToSTR(typeFonc),clyellow); + if nivDebug=3 then AfficheDebug('i='+IntToSTR(i)+' NDet='+IntToSTR(N_det),clyellow); Adr:=suivant_alg3(AdrPrec,TypePrec,AdrFonc,TypeFonc,1); //AfficheDebug('Sortie Alg3: '+IntToSTR(Adr)+'/'+intToSTR(typeGen),clyellow); - + if TypeGen=1 then inc(N_Det); if NivDebug=3 then begin - s:='614 : trouvé='+intToSTR(Adr); + s:='613 : trouvé='+intToSTR(Adr); case typeGen of 1 : s:=s+' detecteur'; 2 : s:=s+' aiguillage'; @@ -5350,15 +5428,51 @@ begin end; AfficheDebug(s,clorange); end; - - AdrPrec:=AdrFonc;TypePrec:=TypeFonc; - AdrFonc:=Adr;TypeFonc:=typeGen; + + AdrPrec:=AdrFonc;TypePrec:=TypeFonc; + AdrFonc:=Adr;TypeFonc:=typeGen; inc(i); - sortie:=(TypeGen=1) or (Adr=0) or (Adr>=9996) or (i=20); + sortie:=((typeDet2=TypeGen) and (Adr=el2)) or (Adr=0) or (Adr>=9996) or (i=15) or (N_Det=Nb_det_dist); + until sortie ; + if (i=15) and (Nivdebug=3) then afficheDebug('Pas trouvé',clyellow); + if (N_det=Nb_det_dist) and (Nivdebug=3) then afficheDebug('Détecteurs trop distants',clred); + end + + else + begin + // déja trouvé + adr:=el2;typeGen:=TypeDet2; + end; + + if (typeDet2=TypeGen) and (Adr=el2) and (N_Det<>Nb_det_dist) then + begin + if Nivdebug=3 then AfficheDebug('614 : Trouvé '+intToSTR(el2),clYellow); + i:=0; + repeat + //AfficheDebug('Engage '+IntToSTR(AdrPrec)+','+IntToSTR(typePrec)+'/'+IntToSTR(AdrFonc)+','+IntToSTR(typeFonc),clyellow); + Adr:=suivant_alg3(AdrPrec,TypePrec,AdrFonc,TypeFonc,1); + //AfficheDebug('Sortie Alg3: '+IntToSTR(Adr)+'/'+intToSTR(typeGen),clyellow); + + if NivDebug=3 then + begin + s:='614 : trouvé='+intToSTR(Adr); + case typeGen of + 1 : s:=s+' detecteur'; + 2 : s:=s+' aiguillage'; + 4 : s:=s+' buttoir'; + end; + AfficheDebug(s,clorange); + end; + + AdrPrec:=AdrFonc;TypePrec:=TypeFonc; + AdrFonc:=Adr;TypeFonc:=typeGen; + inc(i); + sortie:=(TypeGen=1) or (Adr=0) or (Adr>=9996) or (i=10); until sortie; - if TypeGen=1 then + + if (TypeGen=1) or (TypeGen=4) then begin - if NivDebug=3 then + if NivDebug=3 then begin AfficheDebug('le détecteur suivant est le '+IntToSTR(Adr),clyellow); affichedebug('------------------',clyellow); @@ -5366,16 +5480,18 @@ begin detecteur_suivant_el:=Adr; exit; end; - end; - if (i=20) then if NivDebug=3 then AfficheDebug('201 : Itération trop longue',clred); + end; + if (i=10) then if NivDebug=3 then AfficheDebug('201 : Itération trop longue',clred); inc(j); //AfficheDebug('j='+intToSTR(j),clyellow); - until j=3; + until j=3; // boucle incrément/décrément + detecteur_suivant_el:=9996; if NivDebug=3 then affichedebug('------------------',clyellow); end; +// renvoie vrai si les aiguillages déclarés dans la définition du signal sont mal positionnés function cond_carre(adresse : integer) : boolean; var i,l,k,NCondCarre,adrAig : integer; resultatET,resultatOU: boolean; @@ -5386,7 +5502,7 @@ begin l:=1; resultatOU:=false; - + while NcondCarre<>0 do begin if Ncondcarre<>0 then dec(Ncondcarre); @@ -5395,6 +5511,7 @@ begin begin //s2:=s2+'A'+IntToSTR(feux[i].condcarre[l][k].Adresse)+feux[i].condcarre[l][k].PosAig+' '; AdrAig:=feux[i].condcarre[l][k].Adresse; + if nivDebug=3 then AfficheDebug('Contrôle aiguillage '+IntToSTR(AdrAig),clyellow); resultatET:=((aiguillage[AdrAig].position=const_devie) and (feux[i].condcarre[l][k].PosAig='S') or (aiguillage[AdrAig].position=const_droit) and (feux[i].condcarre[l][k].PosAig='D')) and resultatET; end; @@ -5403,13 +5520,13 @@ begin resultatOU:=resultatOU or resultatET; NCondCarre:=Length(feux[i].condcarre[l]); end; - //if resultatOU then Affiche('VRAI final',clyellow) else affiche('FAUX final',clred); - if NivDebug=3 then + //if resultatOU then Affiche('VRAI final',clyellow) else affiche('FAUX final',clred); + if NivDebug=3 then begin s:='Conditions de carré suivant aiguillages: '; - if ResultatOU then s:=s+'vrai' else s:=s+'faux'; + if ResultatOU then s:=s+'vrai : le signal doit afficher carré' else s:=s+'faux : le signal ne doit pas afficher de carré'; AfficheDebug(s,clyellow); - end; + end; cond_carre:=ResultatOU; end; @@ -5545,32 +5662,17 @@ begin // à la première itération, si "actuel" est déja un détecteur, ne pas faire de recherche sur le suivant if (j=1) and (TypeActuel=1) then begin - // AdrSuiv:=actuel; - // actuel:=prec; - // TypeActuel:=1; - // TypePrec:=1; - // if nivDebug=3 then AfficheDebug('Substitution precedent='+intToSTR(prec)+' Actuel='+IntToSTR(actuel),clyellow); + AdrSuiv:=actuel; end else begin //if nivDebug=3 then AfficheDebug('Engagement j='+IntToSTR(j)+' '+IntToSTR(prec)+'/'+IntToSTR(actuel),clyellow); AdrSuiv:=suivant_alg3(prec,TypePrec,actuel,TypeActuel,1); - {if (typeGen=2) then // si le précédent est une TJD/S et le suivant aussi - begin - if ((aiguillage[Adrsuiv].modele=2) or (aiguillage[AdrSuiv].modele=3)) and - ((aiguillage[actuel].modele=2) or (aiguillage[actuel].modele=3)) then - begin - if nivDebug=3 then AfficheDebug('507 - Détection Précédent=TJD/S Suivant=TJD/S',clyellow); - // subsituer la pointe - Actuel:=aiguillage[Actuel].APointe; - end; - end; } - if Nivdebug=3 then AfficheDebug('Suivant='+intToSTR(AdrSuiv),clyellow); prec:=actuel;TypePrec:=TypeActuel; actuel:=AdrSuiv;TypeActuel:=typeGen; - + if (AdrSuiv=9999) or (AdrSuiv=9996) then begin Etat_signal_suivant:=0; @@ -5600,7 +5702,7 @@ begin begin AdrFeu:=0;j:=10; // on ne trouve pas de suivant end; - + if (AdrFeu<>0) then // si l'adresse est <>0 begin if (Feux[i].Adr_el_suiv1<>prec) then // le feu est-il dans le bon sens de progression? @@ -5626,7 +5728,6 @@ begin etat_signal_suivant:=Etat; AdresseFeuSuivant:=Signal_suivant; if (NivDebug=3) and (adrFeu=0) then AfficheDebug('Pas Trouvé de feu suivant au feu Adr='+IntToSTR(ADresse),clOrange); - //TraceDet:=false; end; @@ -5767,7 +5868,7 @@ begin ife:=1; // index feu de 1 à 4 pour explorer les 4 détecteurs d'un feu repeat j:=0; - if NivDebug=3 then AfficheDebug('Boucle de test feu '+intToSTR(ife)+'/4',clred); + if NivDebug=3 then AfficheDebug('Boucle de test feu '+intToSTR(ife)+'/4',clOrange); if (ife=1) then begin prec:=feux[i].Adr_det1; @@ -5835,7 +5936,7 @@ begin end; - if NivDebug=3 then AfficheDebug('130 - suivant='+IntToSTR(adrsuiv),clred); + if NivDebug=3 then AfficheDebug('132 - suivant='+IntToSTR(adrsuiv),clYellow); if actuel=0 then begin // si c'est un buttoir @@ -5974,9 +6075,100 @@ begin end; +// présence train 3 détecteurs avant le feu +function PresTrainPrec(AdrFeu : integer) : boolean; +var PresTrain : boolean; + j,i,Det_initial,Adr_El_Suiv,Btype_el_suivant,DetPrec1,DetPrec2,DetPrec3,DetPrec4 : integer; +begin + i:=index_feu(Adrfeu); + if i=0 then + begin + Affiche('Erreur 602 - feu '+IntToSTR(adrFeu)+' non trouvé',clred); + if NivDebug=3 then AfficheDebug('Erreur 602 - feu '+IntToSTR(adrFeu)+' non trouvé',clred); + PresTrainPrec:=false; + exit; + end; + + // **** un feu peut être associé à 4 détecteurs (pour 4 voies convergentes) ***** + // il faut donc explorer les 4 détecteurs probables + PresTrain:=FALSE; + j:=1; + + repeat + if NivDebug=3 then afficheDebug('Séquence '+IntToSTR(j)+' de recherche des 4 détecteurs précédents-----',clOrange); + if (j=1) then + begin + det_initial:=feux[i].Adr_det1;Adr_El_Suiv:=feux[i].Adr_el_suiv1; + if feux[i].Btype_suiv1=1 then Btype_el_suivant:=1; + if feux[i].Btype_suiv1=2 then Btype_el_suivant:=2; + if feux[i].Btype_suiv1=4 then Btype_el_suivant:=2; // BType_suiv: 1=détecteur 2=aig ou TJD ou TJS 4=tri + end; // Btye_el_suivant: 1= détecteur 2= aiguillage 4=Buttoir + if (j=2) then + begin + det_initial:=feux[i].Adr_det2;Adr_El_Suiv:=feux[i].Adr_el_suiv2; + if feux[i].Btype_suiv2=1 then Btype_el_suivant:=1; + if feux[i].Btype_suiv2=2 then Btype_el_suivant:=2; + if feux[i].Btype_suiv2=4 then Btype_el_suivant:=2; + end; + if (j=3) then + begin + det_initial:=feux[i].Adr_det3;Adr_El_Suiv:=feux[i].Adr_el_suiv3; + if feux[i].Btype_suiv3=1 then Btype_el_suivant:=1; + if feux[i].Btype_suiv3=2 then Btype_el_suivant:=2; + if feux[i].Btype_suiv3=4 then Btype_el_suivant:=2; + end; + if (j=4) then + begin + det_initial:=feux[i].Adr_det4;Adr_El_Suiv:=feux[i].Adr_el_suiv4; + if feux[i].Btype_suiv4=1 then Btype_el_suivant:=1; + if feux[i].Btype_suiv4=2 then Btype_el_suivant:=2; + if feux[i].Btype_suiv4=4 then Btype_el_suivant:=2; + end; + if (det_initial<>0) then + begin + DetPrec1:=detecteur_suivant(Adr_El_Suiv,Btype_el_suivant,det_initial,1,2); // 2= algo2 = arret sur aiguillage en talon mal positionné + if DetPrec1<1024 then // route bloquée par aiguillage mal positionné + begin + DetPrec2:=detecteur_suivant_El(det_initial,1,DetPrec1,1); + if DetPrec2<1024 then + begin + DetPrec3:=detecteur_suivant_El(DetPrec1,1,DetPrec2,1); + if DetPrec3<1024 then + begin + DetPrec4:=detecteur_suivant_El(DetPrec2,1,DetPrec3,1); + if DetPrec4<1024 then + begin + if AffSignal or (NivDebug=3) then AfficheDebug('Les détecteurs précédents au feu '+IntToSTR(Adrfeu)+' sont:'+intToSTR(Det_initial)+' '+intToSTR(DetPrec1)+' '+intToSTR(DetPrec2)+' '+intToSTR(DetPrec3)+' '+intToSTR(DetPrec4),clyellow); + PresTrain:=MemZone[DetPrec4,detPrec3] or + MemZone[DetPrec3,detPrec2] or MemZone[DetPrec2,detPrec1] or MemZone[DetPrec1,Det_initial] or presTrain ; + if AffSignal or (NivDebug=3) then + begin + if MemZone[DetPrec4,detPrec3] then AfficheDebug('0.présence train '+IntToSTR(DetPrec4)+' '+IntToSTR(detPrec3),clyellow); + if MemZone[DetPrec3,detPrec2] then AfficheDebug('1.présence train '+IntToSTR(DetPrec3)+' '+IntToSTR(detPrec2),clyellow); + if MemZone[DetPrec2,detPrec1] then AfficheDebug('2.présence train '+IntToSTR(DetPrec2)+' '+IntToSTR(detPrec1),clyellow); + if MemZone[DetPrec1,det_initial] then AfficheDebug('3.présence train '+IntToSTR(DetPrec1)+' '+IntToSTR(det_Initial),clyellow); + if PresTrain then AfficheDebug('présence train',clyellow) else afficheDebug('abscence train',clyellow); + end; + end; + //if AffSignal then AfficheDebug('MemZone'+intToSTR(DetPrec3)+' '+IntToSTR(detPrec2) = '+MemZone[DetPrec3,detPrec2] + end; + end; + end; + end; + inc(j); + until (j>=5); + if AffSignal or (NivDebug=3) then + begin + if presTrain Then afficheDebug('présence train feu '+intToSTR(AdrFeu),clorange) + else AfficheDebug('Absence train feu '+intToSTR(AdrFeu),clorange); + end; + PresTrainPrec:=presTrain; +end; + + // mise à jour de l'état d'un feu en fontion de son environnement et affiche le feu procedure Maj_Feu(Adrfeu : integer); -var i,j,k1,k2,BtypeSuiv,Adr_det,etat,Adr,Aig,DetPrec1,DetPrec2,Detprec3,Detprec4,Adr_El_Suiv, +var i,j,k1,k2,BtypeSuiv,Adr_det,etat,Adr,Aig,Adr_El_Suiv, Btype_el_suivant,det_initial,bt,el_suiv,modele : integer ; PresTrain,Aff_semaphore,car : boolean; code,combine : word; @@ -6055,75 +6247,8 @@ begin if (Feux[i].aspect>=3) and (EtatSignalCplx[AdrFeu]<>violet_F) then begin // détecteurs précédent le feu , pour déterminer si leurs mémoires de zones sont à 1 pour libérer le carré - if (Feux[i].VerrouCarre) and (Feux[i].aspect>=4) then - begin - if AffSignal then AfficheDebug('Le feu est verrouillable au carré',clyellow); - // **** un feu peut être associé à 4 détecteurs (pour 4 voies convergentes) ***** - // il faut donc explorer les 4 détecteurs probables - PresTrain:=FALSE; - - j:=1; - repeat - if NivDebug=3 then afficheDebug('Séquence '+IntToSTR(j)+' de recherche des 4 détecteurs précédents-----',clOrange); - if (j=1) then - begin det_initial:=feux[i].Adr_det1;Adr_El_Suiv:=feux[i].Adr_el_suiv1; - if feux[i].Btype_suiv1=1 then Btype_el_suivant:=1; - if feux[i].Btype_suiv1=2 then Btype_el_suivant:=2; - if feux[i].Btype_suiv1=5 then Btype_el_suivant:=3; // 1=détécteur 2=aig 5=bis - end; - if (j=2) then - begin - det_initial:=feux[i].Adr_det2;Adr_El_Suiv:=feux[i].Adr_el_suiv2; - if feux[i].Btype_suiv1=1 then Btype_el_suivant:=1; - if feux[i].Btype_suiv1=2 then Btype_el_suivant:=2; - if feux[i].Btype_suiv1=5 then Btype_el_suivant:=3; // 1=détécteur 2=aig 5=bis - end; - if (j=3) then - begin det_initial:=feux[i].Adr_det3;Adr_El_Suiv:=feux[i].Adr_el_suiv3; - if feux[i].Btype_suiv1=1 then Btype_el_suivant:=1; - if feux[i].Btype_suiv1=2 then Btype_el_suivant:=2; - if feux[i].Btype_suiv1=5 then Btype_el_suivant:=3; // 1=détécteur 2=aig 5=bis - end; - if (j=4) then - begin - det_initial:=feux[i].Adr_det4;Adr_El_Suiv:=feux[i].Adr_el_suiv4; - if feux[i].Btype_suiv1=1 then Btype_el_suivant:=1; - if feux[i].Btype_suiv1=2 then Btype_el_suivant:=2; - if feux[i].Btype_suiv1=5 then Btype_el_suivant:=3; // le type du feu 1=détécteur 2=aig 5=bis - end; - if (det_initial<>0) then - begin - DetPrec1:=detecteur_suivant(Adr_El_Suiv,Btype_el_suivant,det_initial,1); - if DetPrec1<9996 then // route bloquée par aiguillage mal positionné - begin - DetPrec2:=detecteur_suivant_El(det_initial,1,DetPrec1,1); - if DetPrec2<9996 then - begin - DetPrec3:=detecteur_suivant_El(DetPrec1,1,DetPrec2,1); - if DetPrec3<9996 then - begin - //DetPrec4:=detecteur_suivant_det(DetPrec2,DetPrec3); - if AffSignal then AfficheDebug('les détecteurs précédents au feu '+IntToSTR(Adrfeu)+' sont:'+intToSTR(Det_initial)+' '+intToSTR(DetPrec1)+' '+intToSTR(DetPrec2)+' '+intToSTR(DetPrec3)+' ',clyellow); - PresTrain:=//MemZone[DetPrec4,detPrec3] or - MemZone[DetPrec3,detPrec2] or MemZone[DetPrec2,detPrec1] or MemZone[DetPrec1,Det_initial] or presTrain ; - if AffSignal then - begin - if MemZone[DetPrec3,detPrec2] then AfficheDebug('1.présence train '+IntToSTR(DetPrec3)+' '+IntToSTR(detPrec2),clyellow); - if MemZone[DetPrec2,detPrec1] then AfficheDebug('2.présence train '+IntToSTR(DetPrec2)+' '+IntToSTR(detPrec1),clyellow); - if MemZone[DetPrec1,det_initial] then AfficheDebug('3.présence train '+IntToSTR(DetPrec1)+' '+IntToSTR(det_Initial),clyellow); - - //if PresTrain then AfficheDebug('présence train',clyellow) else afficheDebug('abscence train',clyellow); - end; - //if AffSignal then AfficheDebug('MemZone'+intToSTR(DetPrec3)+' '+IntToSTR(detPrec2) = '+MemZone[DetPrec3,detPrec2] - end; - end; - end; - end; - inc(j); - until (j>=5); - if presTrain and AffSignal Then afficheDebug('présence train feu '+intToSTR(AdrFeu),clorange); - end; - + if (Feux[i].VerrouCarre) and (Feux[i].aspect>=4) then presTrain:=PresTrainPrec(AdrFeu); + if AffSignal then afficheDebug('Fin de la recherche des 4 détecteurs précédents-----',clOrange); // si le signal peut afficher un carré et les aiguillages après le signal sont mal positionnées ou que pas présence train avant signal et signal // verrouillable au carré, afficher un carré @@ -6172,6 +6297,8 @@ begin // si le signal suivant est rouge begin if AffSignal then AfficheDebug('pas d''aiguille déviée',clYellow); + // effacer la signbalisation combinée + EtatSignalCplx[adrFeu]:=EtatSignalCplx[adrFeu] and not($3c00); if TestBit(etat,carre) or testBit(etat,semaphore) or testBit(etat,semaphore_cli )then Maj_Etat_Signal(AdrFeu,jaune) else begin @@ -6202,6 +6329,7 @@ end; Procedure Maj_feux; var i : integer; begin + //Affiche('MAJ FEUX',clOrange); Maj_feux_cours:=TRUE; for i:=1 to NbreFeux do begin @@ -6266,6 +6394,7 @@ var AdrFeu,AdrDetFeu,Nbre,Nouveau_Det,i,resultat,det1,det2,det3,AdrSuiv,TypeSuiv begin creer_tableau:=false; det3:=event_det[N_event_det]; // c'est le nouveau détecteur + if det3=0 then exit; // pas de nouveau détecteur FormDebug.MemoEvtDet.lines.add('Le nouveau détecteur est '+IntToSTR(det3)) ; if TraceListe then AfficheDebug('Le nouveau détecteur est '+IntToSTR(det3),clyellow) ; @@ -6273,13 +6402,13 @@ begin for i:=1 to N_trains do begin Nbre:=event_det_train[i].NbEl ; // Nombre d'éléments du tableau courant exploré - if Nbre=2 then + if Nbre=2 then begin if TraceListe or (NivDebug=3) then AfficheDebug('traitement Train n°'+intToSTR(i)+' 2 détecteurs',clyellow); det1:=event_det_train[i].det[1]; det2:=event_det_train[i].det[2]; - resultat:=test_route_valide(det1,det2,det3); - if resultat=10 then + resultat:=test_route_valide(det1,det2,det3); + if resultat=10 then begin AdrSuiv:=detecteur_suivant_el(det2,1,det3,1); // ici on cherche le suivant à det2 det3 if (Adrsuiv>=9996) then @@ -6293,7 +6422,7 @@ begin FormDebug.MemoEvtDet.lines.add(s); if traceListe then AfficheDebug(s,clyellow); With FormDebug.RichEdit do - begin + begin s:='train '+IntToSTR(i)+' '+intToStr(det2)+' à '+intToStr(det3)+' => Mem '+IntToSTR(det3)+' à '+IntTOStr(AdrSuiv); Lines.Add(s); RE_ColorLine(FormDebug.RichEdit,lines.count-1,CouleurTrain[ ((i - 1) mod NbCouleurTrain) +1] ); @@ -6313,7 +6442,7 @@ begin lines.add('Nouveau Tampon train '+intToStr(i)+'--------'); lines.add(intToSTR(event_det_train[i].det[1])); lines.add(intToSTR(event_det_train[i].det[2])); - end; + end; if TraceListe then begin AfficheDebug('Nouveau Tampon train '+intToStr(i)+'--------',clyellow); @@ -6331,14 +6460,14 @@ begin exit; // sortir absolument end; end; - end; + end; end; // traiter pour les cas avec 1 élément for i:=1 to N_trains do begin Nbre:=event_det_train[i].NbEl ; // Nombre d'éléments du tableau courant exploré - if Nbre=1 then + if Nbre=1 then begin if traceListe then AfficheDebug('traitement Train n°'+intToSTR(i)+' 1 détecteur',clyellow); // vérifier si l'élément du tableau et le nouveau sont contigus @@ -6353,8 +6482,8 @@ begin lines.add('Nouveau Tampon train '+intToStr(i)+'--------'); lines.add(intToSTR(event_det_train[i].det[1])); lines.add(intToSTR(event_det_train[i].det[2])); - end; - if TraceListe then + end; + if TraceListe then begin AfficheDebug('Nouveau Tampon train '+intToStr(i)+'--------',clyellow); AfficheDebug(intToSTR(event_det_train[i].det[1]),clyellow ); @@ -6380,7 +6509,7 @@ begin if (AdrDetFeu=Det3) and (feux[i].aspect<10) then begin AdrSuiv:=Feux[i].Adr_el_suiv1;TypeSuiv:=Feux[i].Btype_suiv1; - AdrPrec:=detecteur_suivant(AdrSuiv,typeSuiv,AdrDetFeu,1) ; // détecteur précédent le feu + AdrPrec:=detecteur_suivant(AdrSuiv,typeSuiv,AdrDetFeu,1,1) ; // détecteur précédent le feu ; algo 1 if AdrPrec=0 then begin if TraceListe then Affiche('FD - Le feu '+IntToSTR(AdrFeu)+' est précédé d''un buttoir',clyellow); @@ -6391,7 +6520,7 @@ begin end; end; end; - + if TraceListe then AfficheDebug('Création Train n°'+intToSTR(i),clyellow); Formprinc.LabelNbTrains.caption:=IntToSTR(N_trains); event_det_train[N_trains].det[1]:=det3; @@ -6400,8 +6529,8 @@ begin begin lines.add('Nouveau Tampon train '+intToStr(N_trains)+'--------'); lines.add(intToSTR(event_det_train[N_trains].det[1])); - end; - if TraceListe then + end; + if TraceListe then begin AfficheDebug('Nouveau Tampon train '+intToStr(N_trains)+'--------',clyellow); AfficheDebug(intToSTR(event_det_train[N_trains].det[1]),clyellow ); @@ -6410,14 +6539,14 @@ end; -// demande l'état d'un accessoire à la centrale. Le résultat sera réceptionné sur réception des informations +// demande l'état d'un accessoire à la centrale. Le résultat sera réceptionné sur évènement des informations // de rétrosignalisation. procedure demande_info_acc(adresse : integer); var s : string; n : integer; begin // uniquement si connecté directement à la centrale - if portCommOuvert or ParSocket then + if portCommOuvert or parSocketLenz then begin // envoyer 2 fois la commande, une fois avec N=0 pour récupérer le nibble bas, // une autre fois avec N=1 pour récupérer le nibble haut @@ -6432,7 +6561,7 @@ begin s:=s+char(n or 1); // N=1 (bit 0) s:=checksum(s); envoi(s); - end; + end; end; // demande l'état de tous les accessoires par l'interface @@ -6529,8 +6658,17 @@ begin Formprinc.statictext.caption:=s; end; +procedure evalue; +begin + if not(configNulle) then + begin + //if CDM_connecte // and (length(recuCDM)<1000) then + Maj_feux; // on ne traite pas les calculs si CDM en envoie plusieurs + end; +end; + // traitement sur les évènements détecteurs -procedure Event_Detecteur(Adresse : integer;etat : boolean); +procedure Event_Detecteur(Adresse : integer;etat : boolean;train : string); var i,AdrSuiv,AdrFeu,AdrDetfeu,TrainActuel,Etat01,typeSuiv,AdrPrec : integer; s : string; begin @@ -6543,7 +6681,7 @@ begin begin if (event_det_tick[N_event_tick].etat=etat01) and (event_det_tick[N_event_tick].detecteur=Adresse) then begin - //Affiche(IntToSTR(Adresse)+' déja stocké',clorange); + //Affiche(IntToSTR(Adresse)+' déja stocké',clorange); exit; // déja stocké end; end; @@ -6552,7 +6690,7 @@ begin if AffAigDet then begin //s:='Evt Det '+intToSTR(adresse)+'='+intToSTR(etat01); - s:='Tick='+IntToSTR(tick)+' Det='+IntToSTR(adresse)+'='+intToSTR(etat01); + s:='Tick='+IntToSTR(tick)+' Evt Det='+IntToSTR(adresse)+'='+intToSTR(etat01); Affiche(s,clyellow); if not(TraceListe) then AfficheDebug(s,clyellow); @@ -6560,8 +6698,9 @@ begin //if etat then Mem[Adresse]:=true; // mémoriser l'état à 1 - ancien_detecteur[Adresse]:=detecteur[Adresse]; - detecteur[Adresse]:=etat; + ancien_detecteur[Adresse]:=detecteur[Adresse].etat; + detecteur[Adresse].etat:=etat; + detecteur[Adresse].train:=train; detecteur_chgt:=Adresse; // stocke les changements d'état des détecteurs dans le tableau chronologique @@ -6570,16 +6709,16 @@ begin N_Event_tick:=0; Affiche('Raz Evts détecteurs',clLime); end; - inc(N_Event_tick); + inc(N_Event_tick); event_det_tick[N_event_tick].tick:=tick; event_det_tick[N_event_tick].detecteur:=Adresse; event_det_tick[N_event_tick].etat:=etat01; if (n_Event_tick mod 10) =0 then affiche_memoire; // Affiche('stockage de '+intToSTR(N_event_tick)+' '+IntToSTR(Adresse)+' à '+intToSTR(etat01),clyellow); - + // détection front montant - if not(ancien_detecteur[Adresse]) and detecteur[Adresse] then + if not(ancien_detecteur[Adresse]) and detecteur[Adresse].etat then begin // explorer les feux pour déverrouiller les feux dont le trajets viennent d'un buttoir pour changer le feu qd un train se présente // sur le détecteur @@ -6591,28 +6730,24 @@ begin begin AdrSuiv:=Feux[i].Adr_el_suiv1;TypeSuiv:=Feux[i].Btype_suiv1; if AffSignal then AfficheDebug('Pour Feu '+intToSTR(AdrFeu)+' detecteursuivant('+intToSTR(AdrSuiv)+','+IntToSTR(typeSuiv)+','+intToSTR(AdrDetFeu)+',1)',clyellow); - AdrPrec:=detecteur_suivant(AdrSuiv,typeSuiv,AdrDetFeu,1) ; // détecteur précédent le feu + AdrPrec:=detecteur_suivant(AdrSuiv,typeSuiv,AdrDetFeu,1,1) ; // détecteur précédent le feu, algo 1 if AdrPrec=0 then begin If traceListe then AfficheDebug('Le feu '+IntToSTR(AdrFeu)+' est précédé d''un buttoir',clyellow); - MemZone[0,AdrDetFeu]:=true; - //NivDebug:=3; - // AffSignal:=true; - // Aiguillage[20].position:=const_devie; - // Aiguillage[7].position:=const_droit; + MemZone[0,AdrDetFeu]:=true; maj_feu(AdrFeu); - end; + end; end; - + end; - + end; // détection fronts descendants - if ancien_detecteur[Adresse] and not(detecteur[Adresse]) and (N_Event_detAdresse then + //if event_det[N_event_det]<>Adresse then begin if AffFD then AfficheDebug('index='+intToSTR(N_event_tick)+' FD '+intToSTR(Adresse),clyellow); inc(N_event_det); @@ -6630,19 +6765,19 @@ begin AfficheDebug('Attention : position de l''aiguillage '+IntToSTR(i)+' inconnue',clred); end; end; - end; + end; end; premierFD:=True; - if not(configNulle) then calcul_zones; // en avant les calculs - end; + calcul_zones; + end; end; - if (N_event_det>=Max_event_det) then + if (N_event_det>=Max_event_det) then begin Affiche('Débordement d''évènements FD - Raz tampon',clred); N_event_det:=0; FormDebug.MemoEvtDet.lines.add('Raz sur débordement'); - end; + end; // attention à partir de cette section le code est susceptible de ne pas être exécuté @@ -6656,33 +6791,36 @@ end; // évènement d'aiguillage procedure Event_Aig(adresse,pos,objet : integer); var s: string; + faire_event: boolean; begin // ------------------- traitement du numéro d'objet ------------------------- // init objet - if aiguillage[adresse].objet=0 then + if aiguillage[adresse].objet=0 then begin aiguillage[adresse].objet:=objet; //affiche('stockage Aiguillage '+intToSTR(adresse)+' objet='+intToSTR(objet),clYellow); - end; - + end; + + // ne pas faire l'évaluation si l'ancien état de l'aiguillage est indéterminée (9) + // car le RUN vient de démarrer + faire_event:=aiguillage[adresse].position<>9; aiguillage[adresse].position:=pos; - // ------------- stockage évènement aiguillage dans tampon event_det_tick ------------------------- if (N_Event_tick>=Max_Event_det_tick) then begin N_Event_tick:=0; Affiche('Raz Evts détecteurs',clLime); end; - s:='Evt Aig '+intToSTR(adresse)+'='+intToSTR(pos); + s:='Tick='+IntToSTR(tick)+' Evt Aig '+intToSTR(adresse)+'='+intToSTR(pos); if pos=const_droit then s:=s+' droit' else s:=s+' dévié'; - if AffAigDet then + if AffAigDet then begin if objet<>0 then s:=s+' objet='+IntToSTR(objet); Affiche(s,clyellow); - AfficheDebug(s,clyellow); - end; - FormDebug.MemoEvtDet.lines.add(s) ; + AfficheDebug(s,clyellow); + end; + FormDebug.MemoEvtDet.lines.add(s) ; if (n_Event_tick mod 10) =0 then affiche_memoire; inc(N_Event_tick); event_det_tick[N_event_tick].tick:=tick; @@ -6695,7 +6833,9 @@ begin begin formTCO.Maj_TCO(Adresse); end; - + + // l'évaluation des routes est à faire selon conditions + if faire_event then evalue; end; @@ -6718,27 +6858,27 @@ begin begin // affecter l'état des détecteurs i:=adresse*8+8; - if detecteur[i]<>((valeur and $8) = $8) then // si changement de l'état du détecteur bit 7 + if detecteur[i].etat<>((valeur and $8) = $8) then // si changement de l'état du détecteur bit 7 begin - Event_detecteur(i,(valeur and $8) = $8); + Event_detecteur(i,(valeur and $8) = $8,''); // pas de train affecté sur le décodage de la rétrosignalisation end; i:=adresse*8+7; - if detecteur[i]<>((valeur and $4) = $4) then // si changement de l'état du détecteur bit 6 + if detecteur[i].etat<>((valeur and $4) = $4) then // si changement de l'état du détecteur bit 6 begin - Event_detecteur(i,(valeur and $4) = $4); + Event_detecteur(i,(valeur and $4) = $4,''); end; i:=adresse*8+6; - if detecteur[i]<>((valeur and $2) = $2) then // si changement de l'état du détecteur bit 5 + if detecteur[i].etat<>((valeur and $2) = $2) then // si changement de l'état du détecteur bit 5 begin - Event_detecteur(i,(valeur and $2) = $2); + Event_detecteur(i,(valeur and $2) = $2,''); end; i:=adresse*8+5; - if detecteur[i]<>((valeur and $1) = $1) then // si changement de l'état du détecteur bit 4 + if detecteur[i].etat<>((valeur and $1) = $1) then // si changement de l'état du détecteur bit 4 begin - Event_detecteur(i,(valeur and $1) = $1); + Event_detecteur(i,(valeur and $1) = $1,''); end; end; @@ -6749,22 +6889,22 @@ begin if (valeur and $C)=$8 then begin Event_Aig(adraig+3,const_droit,0); - if trace then begin s:='accessoire '+intToSTR(adraig+3)+'=2';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+3)+'=2';AfficheDebug(s,clYellow);end; end; if (valeur and $C)=$4 then begin Event_Aig(adraig+3,const_devie,0); - if trace then begin s:='accessoire '+intToSTR(adraig+3)+'=1';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+3)+'=1';AfficheDebug(s,clYellow);end; end; if (valeur and $3)=$2 then begin Event_Aig(adraig+2,const_droit,0); - if trace then begin s:='accessoire '+intToSTR(adraig+2)+'=2';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+2)+'=2';AfficheDebug(s,clYellow);end; end; if (valeur and $3)=$1 then begin Event_Aig(adraig+2,const_devie,0); - if trace then begin s:='accessoire '+intToSTR(adraig+2)+'=1';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+2)+'=1';AfficheDebug(s,clYellow);end; end; end; end; @@ -6776,26 +6916,26 @@ begin begin // affecter l'état des détecteurs i:=adresse*8+4; - if detecteur[i]<>((valeur and $8) = $8) then // si changement de l'état du détecteur bit 7 + if detecteur[i].etat<>((valeur and $8) = $8) then // si changement de l'état du détecteur bit 7 begin - Event_detecteur(i,(valeur and $8) = $8); + Event_detecteur(i,(valeur and $8) = $8,''); end; i:=adresse*8+3; - if detecteur[i]<>((valeur and $4) = $4) then // si changement de l'état du détecteur bit 6 + if detecteur[i].etat<>((valeur and $4) = $4) then // si changement de l'état du détecteur bit 6 begin - Event_detecteur(i,(valeur and $4) = $4); + Event_detecteur(i,(valeur and $4) = $4,''); end; i:=adresse*8+2; - if detecteur[i]<>((valeur and $2) = $2) then // si changement de l'état du détecteur bit 5 + if detecteur[i].etat<>((valeur and $2) = $2) then // si changement de l'état du détecteur bit 5 begin - Event_detecteur(i,(valeur and $2) = $2); + Event_detecteur(i,(valeur and $2) = $2,''); end; i:=adresse*8+1; - if detecteur[i]<>((valeur and $1) = $1) then // si changement de l'état du détecteur bit 4 + if detecteur[i].etat<>((valeur and $1) = $1) then // si changement de l'état du détecteur bit 4 begin - Event_detecteur(i,(valeur and $1) = $1); + Event_detecteur(i,(valeur and $1) = $1,''); end; end; @@ -6805,22 +6945,22 @@ begin if (valeur and $C)=$8 then begin Event_Aig(adraig+1,const_droit,0); - if trace then begin s:='accessoire '+intToSTR(adraig+1)+'=2';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+1)+'=2';AfficheDebug(s,clYellow);end; end; if (valeur and $C)=$4 then begin Event_Aig(adraig+1,const_devie,0); - if trace then begin s:='accessoire '+intToSTR(adraig+1)+'=1';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig+1)+'=1';AfficheDebug(s,clYellow);end; end; if (valeur and $3)=$2 then begin Event_Aig(adraig,const_droit,0); - if trace then begin s:='accessoire '+intToSTR(adraig)+'=2';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig)+'=2';AfficheDebug(s,clYellow);end; end; if (valeur and $3)=$1 then begin Event_Aig(adraig,const_devie,0); - if trace then begin s:='accessoire '+intToSTR(adraig)+'=1';Affiche(s,clYellow);end; + if traceTrames then begin s:='accessoire '+intToSTR(adraig)+'=1';AfficheDebug(s,clYellow);end; end; end; end; @@ -6846,8 +6986,8 @@ begin #5 : begin nack:=true;msg:='plus de time slot';end; #6 : begin nack:=true;msg:='débordement tampon LI100';end; end; - if trace and (chaineINT[2]=#4) then Affiche(msg,clYellow); - if trace and (chaineINT[2]<>#4) then Affiche(msg,clRed); + if traceTrames and (chaineINT[2]=#4) then AfficheDebug(msg,clYellow); + if traceTrames and (chaineINT[2]<>#4) then AfficheDebug(msg,clRed); delete(chaineINT,1,3); decode_chaine_retro:=chaineINT; exit; @@ -7046,11 +7186,11 @@ begin With Formprinc.MSCommUSBLenz do begin i:=pos(':',portCom); - j:=pos(',',PortCom); + j:=pos(',',PortCom); j:=posEx(',',PortCom,j+1); j:=posEx(',',PortCom,j+1); j:=posEx(',',PortCom,j+1); - + confStCom:=copy(portCom,i+1,j-i-1); //Affiche(ConfStCom,clred); Settings:=ConfStCom; // COMx:vitesse,n,8,1 Affiche('Demande ouverture COM'+intToSTR(NumPort)+':'+ConfStCom+' protocole '+IntToSTR(protocole),CLYellow); @@ -7124,29 +7264,27 @@ var ProcessEntry32 : TProcessEntry32; // pointeur sur la structure ProcessEntry32 processID : DWord; begin - Result:=false; + Result:=false; + hSnapShot:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); + Win32Check(hSnapShot <> INVALID_HANDLE_VALUE); - hSnapShot:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); - Win32Check(hSnapShot <> INVALID_HANDLE_VALUE); + sExeName:=LowerCase (sExeName); + FillChar(ProcessEntry32,SizeOf(TProcessEntry32),#0); + ProcessEntry32.dwSize:=SizeOf(TProcessEntry32); // contient la structure de tous les process - sExeName:=LowerCase (sExeName); - - FillChar(ProcessEntry32,SizeOf(TProcessEntry32),#0); - ProcessEntry32.dwSize:=SizeOf(TProcessEntry32); // contient la structure de tous les process - - if (Process32First(hSnapShot,ProcessEntry32)) then - repeat - //Affiche(ProcessEntry32.szExeFile,ClYellow); - if (Pos(sExeName,LowerCase(ProcessEntry32.szExeFile))=1) then - begin - processID:=ProcessEntry32.th32ProcessID; - CDMhd:=GetWindowFromID(processID); - Affiche('CDM rail processID='+IntToSTR(ProcessID)+' handle='+IntToSTR(CDMhd),clOrange); - Result:=true; - Break; - end; - until (Process32Next(hSnapShot,ProcessEntry32)=false); - CloseHandle(hSnapShot); + if (Process32First(hSnapShot,ProcessEntry32)) then + repeat + //Affiche(ProcessEntry32.szExeFile,ClYellow); + if (Pos(sExeName,LowerCase(ProcessEntry32.szExeFile))=1) then + begin + processID:=ProcessEntry32.th32ProcessID; + CDMhd:=GetWindowFromID(processID); + Affiche('CDM rail processID='+IntToSTR(ProcessID)+' handle='+IntToSTR(CDMhd),clOrange); + Result:=true; + Break; + end; + until (Process32Next(hSnapShot,ProcessEntry32)=false); + CloseHandle(hSnapShot); end; @@ -7380,10 +7518,10 @@ var V_utile : real; CibleHandle : Thandle; begin - //AvecMaj:=false; + //DoubleBuffered:=true; TraceSign:=True; PremierFD:=false; - // services commIP CDM + // services commIP CDM par défaut Srvc_Aig:=true; Srvc_Det:=true; Srvc_Act:=true; @@ -7408,9 +7546,10 @@ begin N_Trains:=0; NivDebug:=0; TempoAct:=0; - DebugOuv:=True; + debugtrames:=false; AvecInit:=true; //&&&& + Option_demarrage:=false; Diffusion:=AvecInit; Application.processMessages; @@ -7420,6 +7559,7 @@ begin ferme:=false; CDM_connecte:=false; pasreponse:=0; + recuCDM:=''; Nbre_recu_cdm:=0; AffMem:=true; N_routes:=0; @@ -7461,7 +7601,7 @@ begin end; end; - if portCommOuvert or parsocket then + if portCommOuvert or parSocketLenz then With Formprinc do begin ButtonEcrCV.Enabled:=true; @@ -7486,14 +7626,12 @@ begin begin cree_image(i); // et initialisation tableaux signaux end; - Tempo_init:=10; // démarre les initialisation des signaux et des aiguillages dans 1 s + Tempo_init:=5; // démarre les initialisation des signaux et des aiguillages dans 1 s // initialisation de la chronologie des évènements détecteurs for i:=0 to Max_Event_det_tick do begin event_det_tick[i].aiguillage:=-1; - //for j:=1 to 1100 do - //event_det_tick[i].detecteur[j]:=-1; // initialiser les détecteurs à -1 event_det_tick[i].detecteur:=-1; event_det_tick[i].etat:=-1; event_det_tick[i].aiguillage:=-1; @@ -7520,10 +7658,9 @@ begin LabelEtat.Caption:=' '; Affiche_memoire; //--------------------------------- - { + { aiguillage[20].position:=const_droit; aiguillage[21].position:=const_droit; - NivDebug:=3; FormDebug.show; @@ -7549,7 +7686,7 @@ begin begin chaine_recue:=chaine_recue+char(tablo[i]); end; - if trace then Affiche('Tick='+IntToSTR(tick)+'/Rec '+chaine_Hex(chaine_recue),Clwhite); + if traceTrames then AfficheDebug('Tick='+IntToSTR(tick)+'/Rec '+chaine_Hex(chaine_recue),Clwhite); if terminal then Affiche(chaine_recue,clLime); interprete_reponse(chaine_recue); chaine_recue:=''; @@ -7569,28 +7706,27 @@ begin end; +// positionnement des aiguillages au démarrage : seulement en mode autonome procedure init_aiguillages; var i,pos : integer; s : string; begin - Affiche('Positionnement aiguillages',cyan); - for i:=1 to maxaiguillage do + if portCommOuvert or parSocketLenz then begin - if aiguillage[i].modele<>0 then // si l'aiguillage existe + Affiche('Positionnement aiguillages',cyan); + for i:=1 to maxaiguillage do begin - pos:=aiguillage[i].position; - s:='Init aiguillage '+intToSTR(i)+'='+intToSTR(pos); - if pos=1 then s:=s+' (dévié)' else s:=s+' (droit)'; - Affiche(s,cyan); - pilote_acc(i,pos,aig); - application.processMessages; - end; + if aiguillage[i].modele<>0 then // si l'aiguillage existe + begin + pos:=aiguillage[i].position; + s:='Init aiguillage '+intToSTR(i)+'='+intToSTR(pos); + if pos=1 then s:=s+' (dévié)' else s:=s+' (droit)'; + Affiche(s,cyan); + pilote_acc(i,pos,aig); + application.processMessages; + end; + end; end; - with formprinc do - begin - //Menu_interface(valide); - end; - end; // timer à 100 ms @@ -7604,14 +7740,13 @@ begin if Tempo_init>0 then dec(Tempo_init); if (Tempo_init=1) and AvecInit then begin - if not(ConfigNulle) then Affiche('Positionnement des feux',clYellow); - if not(ferme) and not(ConfigNulle) then envoi_signauxCplx; // initialisation des feux if not(ConfigNulle) and not(ferme) and (AvecInitAiguillages=1) then begin - Affiche('Positionnement des aiguillages',clYellow); + Affiche('Positionnement des feux',clYellow); + envoi_signauxCplx; // initialisation des feux init_aiguillages; // initialisation des aiguillages end; - if (AvecInitAiguillages=0) and not(ferme) and (parSocket or portCommOuvert) then + if (AvecInitAiguillages=0) and not(ferme) and (parSocketLenz or portCommOuvert) then begin demande_etat_acc; // demande l'état des accessoires (position des aiguillages) end; @@ -7625,7 +7760,7 @@ begin if tempsCli>0 then dec(tempsCli); if tempsCli=0 then begin - tempsCli:=5; + tempsCli:=4; clignotant:=not(clignotant); // inversion du clignotant //tester chaque feu pour voir s'il y a un code de clignotement for i:=1 to NbreFeux do @@ -7638,6 +7773,7 @@ begin begin //Affiche(IntToSTR(adresse),clOrange); Dessine_feu_mx(Feux[i].Img.Canvas,0,0,1,1,adresse,1); + //Affiche('Clignote feu '+IntToSTR(adresse),clyellow); end; end; @@ -7711,8 +7847,8 @@ begin //simulation if (index_simule<>0) then begin - if not(MsgSim) then - begin + if not(MsgSim) then + begin Affiche('Simulation en cours ',Cyan);MsgSim:=true; N_Event_tick:=0; N_event_det:=0; @@ -7732,7 +7868,7 @@ begin if Tablo_simule[i_simule].detecteur<>0 then begin s:='Simulation '+intToSTR(I_simule)+' Tick='+IntToSTR(tick)+' det='+intToSTR(Tablo_simule[i_simule].detecteur)+'='+IntToSTR(Tablo_simule[i_simule].etat); - Event_Detecteur(Tablo_simule[i_simule].detecteur, Tablo_simule[i_simule].etat=1); // créer évt détecteur + Event_Detecteur(Tablo_simule[i_simule].detecteur, Tablo_simule[i_simule].etat=1,''); // créer évt détecteur StaticText.caption:=s; end; @@ -7755,6 +7891,28 @@ begin StaticText.caption:=''; end; end; + + // temporisations de démarrage des trains au feux + if Option_demarrage then + for i:=1 to 1024 do + begin + if detecteur[i].tempo<>0 then + begin + dec(detecteur[i].tempo); + if detecteur[i].tempo=0 then + begin + //Affiche('tempo 0 Detecteur '+intToSTR(i),clyellow); + s:=detecteur[i].train; + Affiche('Tempo 0 timer train '+s,clOrange); + s:=chaine_CDM_vitesse(100,s); // 100% + envoi(s); + end; + end; + + end; + + + end; // bouton version centrale Lenz @@ -7792,24 +7950,13 @@ begin if (Editval.Text<>'1') and (Editval.Text<>'2') then editval.text:='1'; end; -// gestion de la couleur des textes de la list box -procedure TFormPrinc.ListBox1DrawItem(Control: TWinControl; Index: Integer; - Rect: TRect; State: TOwnerDrawState); -begin - //with control as Tlistbox do - with listbox1.Canvas do - begin - Font.color:=Tcolor(ListBox1.Items.Objects[index]); - TextOut(Rect.Left,Rect.Top+4,ListBox1.Items[index]); - end; -end; procedure TFormPrinc.BoutonRafClick(Sender: TObject); begin rafraichit; end; -// erreur sur socket +// erreur sur socket Lenz procedure TFormPrinc.ClientSocketLenzError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); @@ -7825,7 +7972,7 @@ begin end; affiche(s,clOrange); if nivDebug=3 then afficheDebug(s,clOrange); - parSocket:=false; + parSocketLenz:=false; ErrorCode:=0; end; @@ -7845,7 +7992,7 @@ begin affiche(s,ClOrange); afficheDebug(s,ClOrange); CDM_connecte:=false; - if (portCommOuvert=false) and (parsocket=false) then LabelTitre.caption:=titre; + if (portCommOuvert=false) and (parSocketLenz=false) then LabelTitre.caption:=titre; caption:=AF; ErrorCode:=0; end; @@ -7856,7 +8003,7 @@ procedure TFormPrinc.ClientSocketLenzRead(Sender: TObject; var s : string; begin s:=ClientSocketLenz.Socket.ReceiveText; - if trace then affiche(chaine_hex(s),clWhite); + if traceTrames then afficheDebug(chaine_hex(s),clWhite); interprete_reponse(s); end; @@ -7879,9 +8026,8 @@ begin Affiche('Ce programme pilote des signaux complexes de façon autonome ou avec CDM rail ',ClYellow); Affiche('En fonction des détecteurs mis à 1 ou 0 par des locomotives',ClYellow); Affiche('en circulation sur le réseau',ClYellow); - Affiche('Il est nécessaire de renseigner le fichier config.cfg',ClOrange); + Affiche('Il est nécessaire de renseigner les fichiers config.cfg et config-gl.cfg',ClOrange); Affiche('En vert : Trames envoyées à l''interface',ClWhite); - Affiche('En blanc : Trames reçues de l''interface',ClWhite); Affiche('En violet : Trames brutes reçues de l''interface',ClWhite); Affiche('En rouge : erreurs et défauts',ClWhite); Affiche('En orange : pilotage des signaux / erreurs mineures',ClWhite); @@ -7924,6 +8070,7 @@ procedure TFormPrinc.MenuConnecterEthernetClick(Sender: TObject); begin if AdresseIP<>'0' then begin + Affiche('Demande de connexion de l''interface Lenz en ethernet '+AdresseIP+':'+IntToSTR(Port),clyellow); ClientSocketLenz.port:=port; ClientSocketLenz.Address:=AdresseIP; ClientSocketLenz.Open; @@ -7943,11 +8090,7 @@ begin cde_cdm:='0'+IntToSTR(i)+s; end; -procedure TFormPrinc.locoClick(Sender: TObject); -begin - // vitesse et direction 18 pas - vitesse_loco(3,20,true); -end; + procedure TFormPrinc.AffEtatDetecteurs(Sender: TObject); var j,adr,NBranche : integer; @@ -7955,8 +8098,10 @@ var j,adr,NBranche : integer; begin for j:=1 to NDetecteurs do begin - s:='Dét '+intToSTR(Adresse_detecteur[j])+'='; - if Detecteur[adresse_detecteur[j]] then s:=s+'1' else s:=s+'0'; + adr:=Adresse_detecteur[j]; + s:='Dét '+intToSTR(adr)+'='; + if Detecteur[adr].etat then s:=s+'1' else s:=s+'0'; + s:=s+' '+Detecteur[Adr].train; //s:=s+' Mem='; //if Mem[adresse_detecteur[j]] then s:=s+'1' else s:=s+'0'; Affiche(s,clYellow); @@ -8033,7 +8178,7 @@ procedure TFormPrinc.ClientSocketLenzConnect(Sender: TObject;Socket: TCustomWinS begin Affiche('Lenz connecté ',clYellow); AfficheDebug('Lenz connecté ',clYellow); - parSocket:=True; + parSocketLenz:=True; ButtonEcrCV.Enabled:=true; ButtonLitCV.Enabled:=true; LireunfichierdeCV1.enabled:=true; @@ -8054,220 +8199,297 @@ begin DeConnecterCDMRail.enabled:=true; end; -procedure Interprete_trameCDM(recuCDM : string); -var i,objet,posST,posAC,posDT,posSG,posXY,k,l,erreur, adr,adr2,etat,etataig, - vitesse,etatAig2,name,prv : integer ; +procedure Interprete_trameCDM(trame_CDM:string); +var i,j,objet,posST,posAC,posDT,posSG,posXY,k,l,erreur, adr,adr2,etat,etataig, + vitesse,etatAig2,name,prv,nbre,nbreVir,long : integer ; x,y,x2,y2 : longint ; - s,ss,train : string; + s,ss,train,commandeCDM : string; traite,sort : boolean; begin - //recuCDM:='S-E-08-0530-CMDTRN-SPDXY|063|07|NAME=BB16024;AD=3;SPEED=120;X=10521;Y=2867;X2=18915;Y2=3202;S-E-08-0531-CMDGEN-_STOP|000|'; +{ + trame_CDM:='S-R-14-0004-CMDACC-__ACK|000|S-E-14-5162-CMDACC-ST_DT|052|05|NAME=2756;OBJ=2756;AD=518;TRAIN=CC406526;STATE=1;'; + trame_cdm:=trame_cdm+'S-E-14-5163-CMDACC-ST_DT|049|05|NAME=2757;OBJ=2757;AD=518;TRAIN=_NONE;STATE=1;'; + trame_cdm:=trame_cdm+'S-E-14-5164-CMDACC-ST_DT|049|05|NAME=2758;OBJ=2758;AD=519;TRAIN=_NONE;STATE=0;'; + trame_cdm:=trame_cdm+'S-E-14-5165-CMDACC-ST_DT|049|05|NAME=2759;OBJ=2759;AD=519;TRAIN=_NONE;STATE=0'; + trame_cdm:=trame_cdm+'S-E-14-5166-CMDACC-ST_DT|049|05|NAME=7060;OBJ=7060;AD=520;TRAIN=_NONE;STATE=0'; + trame_cdm:=trame_cdm+'S-E-14-5167-CMDACC-ST_DT|051|05|NAME=7061;OBJ=7061;AD=520;TRAIN=BB25531;STATE=0'; + trame_cdm:=trame_cdm+'S-E-14-5168-CMDACC-ST_DT|049|05|NAME=7057;OBJ=7057;AD=517;TRAIN=_NONE;STATE=0'; + trame_cdm:=trame_cdm+'S-E-14-5169-CMDACC-ST_DT|049|05|NAME=7058;OBJ=7058;AD=517;TRAIN=_NONE;STATE=0'; + } - AckCDM:=recuCDM<>''; - if pos('ACK',recuCDM)=0 then + //debugtrames:=true; + AckCDM:=trame_CDM<>''; + if pos('ACK',trame_CDM)=0 then begin - if pos('ERR=200',recuCDM)<>0 then Affiche('Erreur CDM : réseau non chargé',clred); + if pos('ERR=200',trame_CDM)<>0 then Affiche('Erreur CDM : réseau non chargé',clred); end; + k:=0; + //Affiche('L='+InTToSTR(length(recuCDM)),clyellow); repeat - // Affiche('K='+intToSTR(k)+' longueur='+intToSTR(length(recuCDM)),clyellow); - // évènement aiguillage. Le champ AD2 n'est pas forcément présent - posST:=pos('CMDACC-ST_TO',recuCDM); - if posST<>0 then + // trouver la longueur de la chaîne de paramètres + i:=pos('|',trame_CDM); + val(copy(trame_CDM,i+1,5),long,erreur); + //Affiche('long chaine param='+intToSTR(long),clyellow); + if long=0 then begin - //Affiche(recuCDM,cllime); - objet:=0; - i:=posEx('OBJ=',recuCDM,posST);ss:=copy(recuCDM,i+4,10); - if i<>0 then val(ss,objet,erreur) else Affiche('Erreur pas d''objet ',clred); - - i:=posEx('AD=',recuCDM,posST);ss:=copy(recuCDM,i+3,10); //Affiche('j='+IntToSTR(j)+' i='+intToSTR(i),clred); - if i0 then Ack_cdm:=true; + i:=posEx('|',trame_CDM,i+1); + if i=0 then begin Affiche('Erreur trames CDM manque 2ème |',clred);exit;end; + delete(trame_cdm,1,i); + end; - i:=posEx('STATE=',recuCDM,i);ss:=copy(recuCDM,i+6,10); //Affiche('j='+IntToSTR(j)+' i='+intToSTR(i),clred); - if i0 then begin Delete(recuCDM,posST,i+5-posST) ;end else + if long<>0 then + begin + // trouver le nombre de paramètres + i:=posEx('|',trame_CDM,i+1); + if i=0 then begin - s:='Erreur 95 posST='+IntToSTR(posST)+' i='+intToSTR(i); - Affiche(s,clred); + if debugTrames then AfficheDebug('0 paramètres '+trame_CDM,clyellow); Nbre_recu_cdm:=0; - Affiche(recuCDM,clred); exit; end; - val(ss,etat,erreur); - //Affiche('Aiguillage CDM '+intToSTR(adr)+'='+IntToStr(etat)+' objet='+intToSTR(objet),clLime); - // conversion en position : - // CDM: 0=droit 1=droite 3=gauche - // logiciel : 1=dévié 2=droit - // aiguillage normal - if aiguillage[adr].modele=1 then + val(copy(trame_CDM,i+1,5),nbre,erreur); + //Affiche('nbre='+IntToSTR(nbre),clyellow); + // compter le nombre de virgules qui doit être égal au nombre de paramètres + NbreVir:=0; // nombre de virgules + repeat + i:=posEx(';',trame_CDM,i+1); + if i<>0 then inc(NbreVir); + until (i=0) or (NbreVir=nbre); + if i=0 then begin - //Affiche('Normal',clyellow); - if etat=0 then etatAig:=2 else etatAig:=1; - Event_Aig(adr,etatAig,objet); + if debugTrames then AfficheDebug('tronqué : '+trame_CDM,clyellow); + residuCDM:=trame_CDM; + Nbre_recu_cdm:=0; + exit; end; - // TJD TJS - if (aiguillage[adr].modele=2) or (aiguillage[adr].modele=3) then + + CommandeCDM:=copy(trame_CDM,1,i); + if debugTrames then AfficheDebug(commandeCDM,clorange); + Delete(trame_CDM,1,i); + + // évènement aiguillage. Le champ AD2 n'est pas forcément présent + posST:=pos('CMDACC-ST_TO',commandeCDM); + if posST<>0 then begin - //Affiche('TJD/S',clyellow); - //adr2:=aiguillage[adr].Apointe; // 2eme adresse de la TJD - case etat of - 1 : begin etatAig:=1;EtatAig2:=2;end; - 4 : begin etatAig:=1;EtatAig2:=1;end; - 5 : begin etatAig:=2;EtatAig2:=1;end; - 0 : begin etatAig:=2;EtatAig2:=2;end; - end; - if (aiguillage[adr].inversionCDM=1) or (aiguillage[adr2].inversionCDM=1) then + delete(commandeCDM,posST,12); + objet:=0; + i:=posEx('OBJ=',commandeCDM,posST);ss:=copy(commandeCDM,i+4,10); + if i<>0 then begin val(ss,objet,erreur);delete(commandeCDM,i,6);end else Affiche('Erreur 95 : pas d''objet ',clred); + + i:=posEx('AD=',commandeCDM,posST);ss:=copy(commandeCDM,i+3,10); //Affiche('j='+IntToSTR(j)+' i='+intToSTR(i),clred); + if i=0 then begin Affiche('Erreur 96 : absence AD aig '+intToSTR(adr),clred);Affiche(commandeCDM,clyellow);end; + val(ss,adr,erreur);Delete(commandeCDM,i,4); + + //Affiche(copy(recuCDM,j,i+80),clOrange); + i:=posEx('AD2=',commandeCDM,i);ss:=copy(commandeCDM,i+4,10); // Affiche('i='+intToSTR(i),clOrange); + if i=0 then begin Affiche('Erreur 97 : absence AD2 aig '+intToSTR(adr),clred);Affiche(commandeCDM,clyellow);end; + val(ss,adr2,erreur); //Affiche('adr2='+intToSTR(adr2),clyellow); + Delete(commandeCDM,i,5); + + i:=posEx('STATE=',commandeCDM,i);ss:=copy(commandeCDM,i+6,10); //Affiche('j='+IntToSTR(j)+' i='+intToSTR(i),clred); + if i=0 then begin Affiche('Erreur 98 : absence STATE aig '+intToSTR(adr),clred);Affiche(commandeCDM,clyellow);end; + val(ss,etat,erreur); + Delete(commandeCDM,i,7); + + //Affiche('Aig '+inttostr(adr)+' pos='+IntToSTR(etat),clyellow); + //Affiche(commandeCDM,clyellow); + + // aiguillage normal + if aiguillage[adr].modele=1 then begin - //Affiche('inverse',clyellow); - prv:=adr; - adr:=adr2; - adr2:=prv; + //Affiche('Normal',clyellow); + if etat=0 then etatAig:=2 else etatAig:=1; + Event_Aig(adr,etatAig,objet); end; - Event_Aig(adr,etatAig,objet); - Event_Aig(adr2,etatAig2,objet); + // TJD TJS + if (aiguillage[adr].modele=2) or (aiguillage[adr].modele=3) then + begin + //Affiche('TJD/S',clyellow); + //adr2:=aiguillage[adr].Apointe; // 2eme adresse de la TJD + case etat of + 1 : begin etatAig:=1;EtatAig2:=2;end; + 4 : begin etatAig:=1;EtatAig2:=1;end; + 5 : begin etatAig:=2;EtatAig2:=1;end; + 0 : begin etatAig:=2;EtatAig2:=2;end; + end; + if (aiguillage[adr].inversionCDM=1) or (aiguillage[adr2].inversionCDM=1) then + begin + //Affiche('inverse',clyellow); + prv:=adr; + adr:=adr2; + adr2:=prv; + end; + Event_Aig(adr,etatAig,objet); + Event_Aig(adr2,etatAig2,objet); + end; + if aiguillage[adr].modele=4 then // aiguillage triple + begin + //Affiche('Triple',clyellow); + // état de l'aiguillage 1 + if (etat=0) or (etat=2) then etatAig:=2; + if etat=3 then etatAig:=1; + // état de l'aiguillage 2 + adr2:=aiguillage[adr].AdrTriple; + if (etat=0) or (etat=3) then etatAig2:=2; + if etat=2 then etatAig2:=1; + Event_Aig(adr,etatAig,objet); + Event_Aig(adr2,etatAig2,objet); + end; + // Tempo_chgt_feux:=10; // demander la mise à jour des feux end; - if aiguillage[adr].modele=4 then // aiguillage triple + + + // évènement détecteur + posDT:=pos('CMDACC-ST_DT',commandeCDM); + if posDT<>0 then begin - //Affiche('Triple',clyellow); - // état de l'aiguillage 1 - if (etat=0) or (etat=2) then etatAig:=2; - if etat=3 then etatAig:=1; - // état de l'aiguillage 2 - adr2:=aiguillage[adr].AdrTriple; - if (etat=0) or (etat=3) then etatAig2:=2; - if etat=2 then etatAig2:=1; - Event_Aig(adr,etatAig,objet); - Event_Aig(adr2,etatAig2,objet); + Delete(commandeCDM,posDT,12); + i:=posEx('AD=',commandeCDM,posDT); + if i<>0 then + begin + ss:=copy(commandeCDM,i+3,10);Delete(commandeCDM,i,4); + val(ss,adr,erreur); + end; + i:=posEx('TRAIN=',commandeCDM,posDT); + j:=PosEx(';',commandeCDM,i); + train:=copy(commandeCDM,i+6,j-i-6); + delete(commandeCDM,i,7); + + //Affiche('Train=*'+Train+'*',clOrange); + i:=posEx('STATE=',commandeCDM,posDT);ss:=copy(commandeCDM,i+6,10); + val(ss,etat,erreur); Delete(commandeCDM,i,7); + + if (train='_NONE') then train:=detecteur[Adr].train; + Event_detecteur(Adr,etat=1,train); + //AfficheDebug(IntToSTR(adr)+' '+IntToSTR(etat),clyellow); + if AfficheDet then Affiche('Rétro Détecteur '+intToSTR(adr)+'='+IntToStr(etat),clYellow); + end ; + + // évènement signal - non stocké ni interprété + posSG:=pos('CMDACC-ST_SG',commandeCDM); + if posSG<>0 then + begin + Delete(commandeCDM,posSG,12); + i:=posEx('AD=',commandeCDM,posDT);ss:=copy(commandeCDM,i+3,10); + val(ss,adr,erreur); + i:=posEx('STATE=',commandeCDM,posSG);ss:=copy(commandeCDM,i+6,10); + Delete(commandeCDM,posSG,i+5-posSG); + val(ss,etat,erreur); + //Affiche('SignalCDM '+intToSTR(adr)+'='+IntToStr(etat),clYellow); + end ; + + // évènement actionneur + // attention un actionneur qui repasse à 0 ne contient pas de nom de train + //S-E-03-0157-CMDACC-ST_AC|049|05|NAME=0;OBJ=7101;AD=815;TRAIN=CC406526;STATE=1; + posAC:=pos('CMDACC-ST_AC',commandeCDM); + if posAC<>0 then + begin + Delete(commandeCDM,posAC,12); + i:=posEx('AD=',commandeCDM,posAC);ss:=copy(commandeCDM,i+3,10); + val(ss,adr,erreur); + i:=posEx('NAME=',commandeCDM,posAC);ss:=copy(commandeCDM,i+5,10); + val(ss,name,erreur); + i:=posEx('TRAIN=',commandeCDM,posAC);l:=PosEx(';',commandeCDM,i); + train:=copy(commandeCDM,i+6,l-i-6); + i:=posEx('STATE=',commandeCDM,posAC);ss:=copy(commandeCDM,i+6,10); + val(ss,etat,erreur); + Delete(commandeCDM,posAC,i-posAC); + i:=pos(';',commandeCDM); + if i<>0 then Delete(commandeCDM,1,i); + if AfficheDet then + Affiche('Actionneur AD='+intToSTR(adr)+' Nom='+intToSTR(name)+' Train='+train+' Etat='+IntToSTR(etat),clyellow); + Event_act(adr,etat,train); // déclenche évent actionneur end; - Tempo_chgt_feux:=10; // demander la mise à jour des feux + // évènement position des trains - non stocké ni interprété + posXY:=pos('CMDTRN-SPDXY',commandeCDM); + if posXY<>0 then + begin + Delete(commandeCDM,posXY,12); + i:=posEx('AD=',commandeCDM,posXY);l:=posEx(';',commandeCDM,i); + ss:=copy(commandeCDM,i+3,10); + val(ss,adr,erreur); + //Affiche('AD='+IntToSTR(adr),clyellow); + Delete(commandeCDM,i,l-i+1); - //Affiche(recuCDM,CLOrange); - //if length(recuCDM)>80 then Affiche(copy(recuCDM,80,length(recuCDM)-80),clOrange); + i:=posEx('NAME=',commandeCDM,posXY);l:=posEx(';',commandeCDM,i); + train:=copy(commandeCDM,i+5,l-i-5); + //Affiche('Train='+train,clyellow); + Delete(commandeCDM,i,l-i+1); + + i:=posEx('SPEED=',commandeCDM,posXY);l:=posEx(';',commandeCDM,i); + ss:=copy(commandeCDM,i+6,10); + val(ss,vitesse,erreur); + //Affiche('Vitesse='+intToSTR(vitesse),clyellow); + Delete(commandeCDM,i,l-i+1); + + i:=posEx('X=',commandeCDM,posXY);l:=posEx(';',commandeCDM,i); + ss:=copy(commandeCDM,i+2,10); + val(ss,x,erreur); + //Affiche('X='+IntTostr(x),clyellow); + Delete(commandeCDM,i,l-i+1); + + i:=posEx('Y=',commandeCDM,posXY);l:=posEx(';',commandeCDM,i); + ss:=copy(commandeCDM,i+2,10); + val(ss,y,erreur); + //Affiche('Y='+IntTostr(y),clyellow);; + Delete(commandeCDM,i,l-i+1); + + i:=posEx('X2=',commandeCDM,posXY);l:=posEx(';',commandeCDM,i); + ss:=copy(commandeCDM,i+3,10); + val(ss,x2,erreur); + //Affiche('X2='+IntTostr(x2),clyellow); + Delete(commandeCDM,i,l-i+1); + + i:=posEx('Y2=',commandeCDM,posXY);l:=posEx(';',commandeCDM,i); + ss:=copy(commandeCDM,i+3,10); + val(ss,y2,erreur); + //Affiche('Y2='+IntTostr(y2),clyellow); + Delete(commandeCDM,i,l-i+1); + + Delete(commandeCDM,posXY,12); + end; + + inc(k); + //Affiche('k='+intToSTR(k),clyellow); end; - // évènement détecteur - posDT:=pos('CMDACC-ST_DT',recuCDM); - if posDT<>0 then - begin - i:=posEx('AD=',recuCDM,posDT);ss:=copy(recuCDM,i+3,10); - val(ss,adr,erreur); - i:=posEx('STATE=',recuCDM,posDT);ss:=copy(recuCDM,i+6,10); - Delete(recuCDM,posDT,i+5-posDT); - val(ss,etat,erreur); - Event_detecteur(Adr,etat=1); - //Affiche(IntToSTR(adr)+' '+IntToSTR(etat),clyellow); - if AfficheDet then Affiche('Rétro Détecteur '+intToSTR(adr)+'='+IntToStr(etat),clYellow); - end ; - - // évènement signal - non stocké ni interprété - posSG:=pos('CMDACC-ST_SG',recuCDM); - if posSG<>0 then - begin - i:=posEx('AD=',recuCDM,posDT);ss:=copy(recuCDM,i+3,10); - val(ss,adr,erreur); - i:=posEx('STATE=',recuCDM,posSG);ss:=copy(recuCDM,i+6,10); - Delete(recuCDM,posSG,i+5-posSG); - val(ss,etat,erreur); - //Affiche('SignalCDM '+intToSTR(adr)+'='+IntToStr(etat),clYellow); - end ; - - // évènement actionneur - // attention un actionneur qui repasse à 0 ne contient pas de nom de train - //S-E-03-0157-CMDACC-ST_AC|049|05|NAME=0;OBJ=7101;AD=815;TRAIN=CC406526;STATE=1; - posAC:=pos('CMDACC-ST_AC',recuCDM); - if posAC<>0 then - begin - i:=posEx('AD=',recuCDM,posAC);ss:=copy(recuCDM,i+3,10); - val(ss,adr,erreur); - i:=posEx('NAME=',recuCDM,posAC);ss:=copy(recuCDM,i+5,10); - val(ss,name,erreur); - i:=posEx('TRAIN=',recuCDM,posAC);l:=PosEx(';',recuCDM,i); - train:=copy(recuCDM,i+6,l-i-6); - i:=posEx('STATE=',recuCDM,posAC);ss:=copy(recuCDM,i+6,10); - val(ss,etat,erreur); - Delete(recuCDM,posAC,i-posAC); - i:=pos(';',recuCDM); - if i<>0 then Delete(recuCDM,1,i); - if AfficheDet then - Affiche('Actionneur AD='+intToSTR(adr)+' Nom='+intToSTR(name)+' Train='+train+' Etat='+IntToSTR(etat),clyellow); - Event_act(adr,etat,train); // déclenche évent actionneur - end; - - // évènement position des trains - non stocké ni interprété - posXY:=pos('CMDTRN-SPDXY',recuCDM); - if posXY<>0 then - begin - i:=posEx('AD=',recuCDM,posXY);l:=posEx(';',recuCDM,i); - ss:=copy(recuCDM,i+3,10); - val(ss,adr,erreur); - //Affiche('AD='+IntToSTR(adr),clyellow); - Delete(recuCDM,i,l-i+1); - - i:=posEx('NAME=',recuCDM,posXY);l:=posEx(';',recuCDM,i); - train:=copy(recuCDM,i+5,l-i-5); - //Affiche('Train='+train,clyellow); - Delete(recuCDM,i,l-i+1); - - i:=posEx('SPEED=',recuCDM,posXY);l:=posEx(';',recuCDM,i); - ss:=copy(recuCDM,i+6,10); - val(ss,vitesse,erreur); - //Affiche('Vitesse='+intToSTR(vitesse),clyellow); - Delete(recuCDM,i,l-i+1); - - i:=posEx('X=',recuCDM,posXY);l:=posEx(';',recuCDM,i); - ss:=copy(recuCDM,i+2,10); - val(ss,x,erreur); - //Affiche('X='+IntTostr(x),clyellow); - Delete(recuCDM,i,l-i+1); - - i:=posEx('Y=',recuCDM,posXY);l:=posEx(';',recuCDM,i); - ss:=copy(recuCDM,i+2,10); - val(ss,y,erreur); - //Affiche('Y='+IntTostr(y),clyellow);; - Delete(recuCDM,i,l-i+1); - - i:=posEx('X2=',recuCDM,posXY);l:=posEx(';',recuCDM,i); - ss:=copy(recuCDM,i+3,10); - val(ss,x2,erreur); - //Affiche('X2='+IntTostr(x2),clyellow); - Delete(recuCDM,i,l-i+1); - - i:=posEx('Y2=',recuCDM,posXY);l:=posEx(';',recuCDM,i); - ss:=copy(recuCDM,i+3,10); - val(ss,y2,erreur); - //Affiche('Y2='+IntTostr(y2),clyellow); - Delete(recuCDM,i,l-i+1); - - Delete(recuCDM,posXY,12); - end; - - inc(k); - sort:=(k>200) or (posST=0) and (posDT=0) and (posAC=0) and (posSG=0); + sort:=(length(trame_CDM)<10) or (k>=2000);// or (posST=0) and (posDT=0) and (posAC=0) and (posSG=0); until (sort); - //Affiche('Ligne traitée'+recuCDM,clLime); - if k>=200 then begin Affiche('Erreur 90 : Longrestante='+IntToSTR(length(recuCDM)),clred); Affiche(recuCDM,clred); end; + //Affiche('k='+IntToSTR(k)+' Ligne traitée '+recuCDM,clLime); + //if pos('_ACK',recuCDM)=0 then recuCDM:=''; // effacer la trame sauf si c'est une trame ACK car le trame est utilisée dans le process de connexion de cdm + if k>=2000 then begin Affiche('Erreur 90 : Longrestante='+IntToSTR(length(trame_CDM)),clred); Affiche(trame_CDM,clred); end; + Nbre_recu_cdm:=0; end; // réception d'un message de CDM rail procedure TFormPrinc.ClientSocketCDMRead(Sender: TObject;Socket: TCustomWinSocket); - var i,j,k,l,erreur, adr,adr2,etat,etataig,etatAig2,name : integer ; + var i,l,n : integer ; s,ss,train : string; traite,sort : boolean; begin - inc(Nbre_recu_cdm); - recuCDM:=ClientSocketCDM.Socket.ReceiveText; - if trace then begin Affiche('recu de CDM:',clWhite);Affiche(recuCDM,clWhite);end; + inc(Nbre_recu_cdm); + //if Nbre_recu_cdm>1 then Affiche('Empilement de trames CDM: '+intToSTR(Nbre_recu_cdm),clred); + recuCDM:=ClientSocketCDM.Socket.ReceiveText; // commandeCDM est le morceau tronquée de la fin de la réception précédente + + residuCDM:=''; + if traceTrames then AfficheDebug(recuCDM,clWhite); + + {begin + n:=80; + l:=length(recuCDM); + i:=0; + repeat + AfficheDebug(copy(recuCDM,(i*n)+1,n),clWhite); + inc(i); + until lvn0 diff --git a/UnitTCO.dcu b/UnitTCO.dcu index e7b10ad563eadbd43b78e0f99d1119b8b13ea7d3..462fe43402bc89e520d2385f6fbea0cc992b10e6 100644 GIT binary patch delta 1246 zcmZXTe@s(X6vywmx9>fm{(zE2w9d4PFgk*kY|BC-QF)*NLuQk)VI~Q#CR4YVEwHdn ziIN5r#XodJj@pPpvdqPi*fH0bjAb1onNE_CY#N=wiq?fpZ3_r32K5}U?2q-2`}v;l zIX&;(llS`lX(4}_bwr4zp~X^cI@TVr_DYL>F}AMfn(P{BYZ~3Ov_=Wh*D2`NDq0Wj z>iK0fcjbW($vj-P+VSs4|7B8E?Si#4WmPU%bt&tO1#5fCTD@TLGw0f8{m*Kpr?&R& zdK%4znqW;Xd~nIpbwMlFg%q=G8%DrK`Q!*3QNA_}TmB~Dzb4TZhLg%#ukZp3 zd&0o7Q8-B*hY8a81vcKHP6DS0(q4cKccBT=aPlsN8^6N(2>4{~B1}Xm4h4dZ_u#5V z?;k*=1P8)Hn91>O)2nQBqw+N#M#Y+1#;n4uC^#KmpUclU9$ecr zkLGzCW|&ts^h6>19dU-kDt9NthbCAD5=z#U>-a$jMH0Y1a- zK}N)VlVRrR_(K%d%1tB^TGJj9@{|RSQU*FO7=udMt0hip zyQwfQPJi(Jq43Q(-T0=Cr#a*MRmUGG13CB)$KE;v)5j?m_}V!2OBz^1p;9ddHj|K% z0sQ7UZ!p6H?Gps*=b8YIQkgpLBSZO~8u%rP$KOi)odmp%kLM~am^Vp&Ux$WUNk9hf zo8%cY6n3OUh=n>RF+xJRESUa?40;Q(kc15Xj2GInqnDBjJubB3-r1@BYGF-p@+u4!8L6&>H5hHWx3 zh{0*dUm~k>sJOeNmLV`oHOl*nL}vn4(5tsD0Tr3*yf(n;to47+SDi@EZF%&cSopUn z981u!PYhg~1Xm_~S<9&$HdHY-YPdN`Po_10nxwt@x8S)X?4`M~XCVJ&^NA7XvX;^$ zLtU4%%S57}uS1@5;+~`JDSb z=l*VcF71zJ55}_{ql%I@m@AYO$J@IceM0s8_>#T*2ceJJ_De+>IJt9t8|>@8Httz* zn1ds)m#w<9KcUcHo6`2-zDyKejCNIHUXT&-ap|C2y7T86if|6 z3-Q4Sw8-WI5@$vrM&0I7h>1QG)1z=yBvd?h6OPIOpACz~po8YWVFYd)hYsO+0{u1hu-!t^FhRmjRgPG8NWAvaHW(zCE zEG7v2DGATe=bcW%I&)L*DJZAwtyADCGt}UdbVFxF$fCg_Y_Wq;@D$x3_2&g%nu0nR ze@OvoWdSw_Lc> zD&DjjOQy~K3)2vURro1giPiviljiXwT=2WgdPqgn7Ks&9i0B|Ta^Su!vGpPC-<6MN zO`CCulo!)kXmAntN?bPcUsB1%dP?4;0yK;gBId=M+9_PV$_iNup~WifLIJ=Akw}w%Rtt0|lFYX6$%sp1v@TU!j7g?#x4} z_*!CK3f2^K$UqTI!K?MmzzG#Mr(m6kI80; - if trouve_zip then s3:=s; + if trouve_zip then + s3:=s; end; // Aff(s) end; closefile(fichier); - if trouve_version then + if trouve_version and trouve_zip then begin // isoler le champ version i:=pos('version ',s2); @@ -190,7 +191,7 @@ begin end else begin - if notificationVersion then Affiche('Pas d''accès au site CDM rail',clorange); + if notificationVersion then Affiche('Pas d''accès au site CDM rail ou échec téléchargement',clorange); end; end; diff --git a/verif_version.~dfm b/verif_version.~dfm deleted file mode 100644 index b01d0ea..0000000 --- a/verif_version.~dfm +++ /dev/null @@ -1,35 +0,0 @@ -object FormVersion: TFormVersion - Left = 500 - Top = 341 - Width = 468 - Height = 194 - Caption = 'V'#233'rification de version' - Color = clBtnFace - Font.Charset = ANSI_CHARSET - Font.Color = clBlack - Font.Height = -16 - Font.Name = 'Arial Narrow' - Font.Style = [] - OldCreateOrder = False - Position = poScreenCenter - OnCreate = FormCreate - PixelsPerInch = 96 - TextHeight = 20 - object Memo1: TMemo - Left = 16 - Top = 32 - Width = 425 - Height = 105 - Font.Charset = ANSI_CHARSET - Font.Color = clBlack - Font.Height = -13 - Font.Name = 'Arial Narrow' - Font.Style = [] - ParentFont = False - ScrollBars = ssVertical - TabOrder = 0 - end - object TimerVerif: TTimer - OnTimer = TimerVerifTimer - end -end diff --git a/verif_version.~pas b/verif_version.~pas deleted file mode 100644 index 51c76cd..0000000 --- a/verif_version.~pas +++ /dev/null @@ -1,210 +0,0 @@ -unit verif_version; - -interface - -uses - Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, - Dialogs, StdCtrls , ComCtrls ,WinInet, ExtCtrls; - -type - TFormVersion = class(TForm) - TimerVerif: TTimer; - Memo1: TMemo; - procedure FormCreate(Sender: TObject); - procedure TimerVerifTimer(Sender: TObject); - private - { Déclarations privées } - public - { Déclarations publiques } - end; - -var - FormVersion: TFormVersion; - Lance_verif : integer; - verifVersion,notificationVersion : boolean; - -Const Version='2.11'; // sert à la comparaison de la version publiée - -implementation - -uses UnitPrinc; - -{$R *.dfm} - -Procedure Aff(s : string); -begin - FormVersion.Memo1.lines.add(s); -end; - -function GetCurrentProcessEnvVar(const VariableName: string): string; -var - nSize: DWord; -begin - nSize:=0; - nSize:=GetEnvironmentVariable(PChar(VariableName), nil, nSize); - if nSize=0 then - begin - result:=''; - end - else - begin - SetLength(result,nSize-1); - if GetEnvironmentVariable(PChar(VariableName), PChar(result), nSize) <> nSize - 1 then - raise Exception.Create(SysErrorMessage(GetlastError)) - end; -end; - - -// téléchargement d'une page internet sans cache dans un fichier -function DownloadURL_NOCache(aUrl: string;s : string): Boolean; -var - hSession: HINTERNET; - hService: HINTERNET; - Fs:TFileStream; - lpBuffer: array[0..1024 + 1] of byte; - dwBytesRead: DWORD; - dwTimeout : integer; -begin - Result:=False; - DeleteFile(s); - Try Fs:=TFileStream.Create(s,fmCreate,fmShareDenyNone); - hSession:=InternetOpen('MyApp',INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); - try - if Assigned(hSession) then - begin - // fonction longue - dwTimeout:=2000; //2s - InternetSetOption(hSession,INTERNET_OPTION_CONNECT_TIMEOUT,@dwTimeOut, SizeOf(dwTimeOut)); - hService:=InternetOpenUrl(hSession, PChar(aUrl), nil, 0, INTERNET_FLAG_RELOAD, 0); - if Assigned(hService) then - try - while True do - begin - dwBytesRead:=1024; - InternetReadFile(hService,@lpBuffer,1024,dwBytesRead); - fs.WriteBuffer(lpBuffer,dwBytesRead); - if dwBytesRead=0 then break; - end; - Result:=True; - finally - InternetCloseHandle(hService); - end; - end; - finally - InternetCloseHandle(hSession); - end; - finally - fs.Free; - end; -end; - -procedure verifie_version; -var s,s2,s3,Version_p,Url,LocalFile : string; - trouve_version,trouve_zip : boolean; - fichier : text; - i,j,erreur : integer; - V_publie,V_utile : real; -begin - //Affiche('vérifie version',clLime); - if not(AvecInit) then exit ; - if not(verifVersion) then exit; - Url:='http://cdmrail.free.fr/ForumCDR/viewtopic.php?f=77&t=3906#p50499'; - LocalFile:='page.txt'; - trouve_version:=false; - trouve_zip:=false; - if DownloadURL_NOCache(Url,localFile) then - begin - AssignFile(fichier,LocalFile); - reset(fichier); - while not(eof(fichier)) and (not(trouve_version) or not(trouve_zip)) do - begin - readln(fichier,s); - s:=LowerCase(s); - if not(trouve_version) then - begin - i:=pos('version ',s); - trouve_version:=i<>0; - if trouve_version then s2:=s; - end; - if not(trouve_zip) then - begin - i:=pos('.zip',s); - trouve_zip:=i<>0; - if trouve_zip then s3:=s; - end; - // Aff(s) - end; - closefile(fichier); - if trouve_version then - begin - // isoler le champ version - i:=pos('version ',s2); - delete(s2,1,i+7); - j:=pos(' ',s2); - Version_p:=copy(s2,1,j-1); // version dans version_p - // isoler l'url du zip - i:=pos('href="',s3); - delete(s3,1,i+5); - j:=pos('"',s3); - s3:=copy(s3,1,j-1); - i:=pos('.',s3); - if i<>0 then delete(s3,i,1); // supprimer le . - s3:='http://cdmrail.free.fr/ForumCDR'+s3 ; - aff(s3); // lien dans s3 - - // changer le . en , - s:=Version_p; - // i:=pos('.',s);if i<>0 then s[i]:=','; - s2:=version; - // i:=pos('.',s2);if i<>0 then s2[i]:=','; - - val(s,V_publie,erreur); if erreur<>0 then exit; - val(s2,V_utile,erreur); if erreur<>0 then exit; - - if V_utile0 then dec(lance_verif); - if lance_verif=1 then verifie_version; -end; - -end.