From dcf91d9044b95e90628b2af4d837749a44cdd496 Mon Sep 17 00:00:00 2001 From: firleju Date: Thu, 19 Jan 2017 18:01:44 +0100 Subject: [PATCH] Dodana informacja o wersji --- Console.cpp | 351 ++++++++++++++++++++++++++++++++-------------------- maszyna.rc | Bin 3260 -> 5814 bytes 2 files changed, 220 insertions(+), 131 deletions(-) diff --git a/Console.cpp b/Console.cpp index 438bca1f..3ee5163c 100644 --- a/Console.cpp +++ b/Console.cpp @@ -10,11 +10,12 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "Console.h" #include "Globals.h" -#include "Logs.h" -#include "PoKeys55.h" #include "LPT.h" +#include "Logs.h" +#include "MWD.h" // maciek001: obsluga portu COM +#include "PoKeys55.h" #include "mczapkie/mctools.h" -#include "MWD.h" // maciek001: obsluga portu COM + //--------------------------------------------------------------------------- // Ra: klasa statyczna gromadz�ca sygna�y steruj�ce oraz informacje zwrotne @@ -80,30 +81,31 @@ public static Int32 GetScreenSaverTimeout() */ // static class member storage allocation -TKeyTrans Console::ktTable[ 4 * 256 ]; +TKeyTrans Console::ktTable[4 * 256]; // Ra: do poprawienia -void SetLedState(char Code, bool bOn) -{ // Ra: bajer do migania LED-ami w klawiaturze -// NOTE: disabled for the time being -// TODO: find non Borland specific equivalent, or get rid of it -/* if (Win32Platform == VER_PLATFORM_WIN32_NT) - { - // WriteLog(AnsiString(int(GetAsyncKeyState(Code)))); - if (bool(GetAsyncKeyState(Code)) != bOn) +void SetLedState(char Code, bool bOn){ + // Ra: bajer do migania LED-ami w klawiaturze + // NOTE: disabled for the time being + // TODO: find non Borland specific equivalent, or get rid of it + /* if (Win32Platform == VER_PLATFORM_WIN32_NT) { - keybd_event(Code, MapVirtualKey(Code, 0), KEYEVENTF_EXTENDEDKEY, 0); - keybd_event(Code, MapVirtualKey(Code, 0), KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); + // WriteLog(AnsiString(int(GetAsyncKeyState(Code)))); + if (bool(GetAsyncKeyState(Code)) != bOn) + { + keybd_event(Code, MapVirtualKey(Code, 0), KEYEVENTF_EXTENDEDKEY, 0); + keybd_event(Code, MapVirtualKey(Code, 0), KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, + 0); + } } - } - else - { - TKeyboardState KBState; - GetKeyboardState(KBState); - KBState[Code] = bOn ? 1 : 0; - SetKeyboardState(KBState); - }; -*/ + else + { + TKeyboardState KBState; + GetKeyboardState(KBState); + KBState[Code] = bOn ? 1 : 0; + SetKeyboardState(KBState); + }; + */ }; //--------------------------------------------------------------------------- @@ -113,7 +115,7 @@ int Console::iMode = 0; int Console::iConfig = 0; TPoKeys55 *Console::PoKeys55[2] = {NULL, NULL}; TLPT *Console::LPT = NULL; -MWDComm * Console::MWD = NULL; // maciek001: obiekt dla MWD +MWDComm *Console::MWD = NULL; // maciek001: obiekt dla MWD int Console::iSwitch[8]; // bistabilne w kabinie, za��czane z [Shift], wy��czane bez int Console::iButton[8]; // monostabilne w kabinie, za��czane podczas trzymania klawisza @@ -178,7 +180,8 @@ int Console::On() break; case 5: // maciek001: MWD OK MWD = new MWDComm(); - if(!(MWD->Open())){ + if (!(MWD->Open())) + { delete MWD; iMode = 0; Global::iFeedbackMode = 0; @@ -204,10 +207,8 @@ void Console::Off() PoKeys55[1] = NULL; delete LPT; LPT = NULL; - if(iMode == 5 || MWD->GetMWDState()){ - delete MWD; // maciek001: zamykanie portu COM i takie tam inne ;) - MWD = NULL; - } + delete MWD; // maciek001: zamykanie portu COM i takie tam inne ;) + MWD = NULL; }; void Console::BitsSet(int mask, int entry) @@ -217,8 +218,9 @@ void Console::BitsSet(int mask, int entry) int old = iBits; // poprzednie stany iBits |= mask; BitsUpdate(old ^ iBits); // 1 dla bit�w zmienionych - if (iMode == 4) - WriteLog("PoKeys::BitsSet: mask: " + std::to_string(mask) + " iBits: " + std::to_string(iBits)); + if (iMode == 4) + WriteLog("PoKeys::BitsSet: mask: " + std::to_string(mask) + + " iBits: " + std::to_string(iBits)); } }; @@ -291,56 +293,106 @@ void Console::BitsUpdate(int mask) PoKeys55[0]->Write(0x40, 52 - 1, (iBits & 0x1000) ? 1 : 0); if (mask & 0x2000) // b13 Pr�d na silnikach do odbijania w haslerze PoKeys55[0]->Write(0x40, 53 - 1, (iBits & 0x2000) ? 1 : 0); - if (mask & 0x4000) // b14 Brz�czyk SHP lub CA - PoKeys55[0]->Write(0x40, 16 - 1, (iBits & 0x4000) ? 1 : 0); - } + if (mask & 0x4000) // b14 Brz�czyk SHP lub CA + PoKeys55[0]->Write(0x40, 16 - 1, (iBits & 0x4000) ? 1 : 0); + } break; case 5: // maciek001: MWD lampki i kontrolki /* out3: ogrzewanie sk?adu, opory rozruchowe, poslizg, zaluzjewent, -, -, czuwak, shp - out4: stycz.liniowe, pezekaznikr??nicobwpomoc, nadmiarprzetw, roznicowy obw. g?, nadmiarsilniki, wylszybki, zanikpr?duprzyje?dzienaoporach, nadmiarsprezarki + out4: stycz.liniowe, pezekaznikr??nicobwpomoc, nadmiarprzetw, roznicowy obw. g?, + nadmiarsilniki, wylszybki, zanikpr?duprzyje?dzienaoporach, nadmiarsprezarki out5: HASLER */ - if(mask & 0x0001) if(iBits & 1){ - MWD->WriteDataBuff[4] |= 1<<7; // SHP HASLER te� - if(!MWD->bSHPstate){ - MWD->bSHPstate = true; - MWD->bPrzejazdSHP = true; - }else MWD->bPrzejazdSHP = false; - } - else{ - MWD->WriteDataBuff[4] &= ~(1<<7); - MWD->bPrzejazdSHP = false; - MWD->bSHPstate = false; - } - if(mask & 0x0002) if(iBits & 2) MWD->WriteDataBuff[4] |= 1<<6; // CA - else MWD->WriteDataBuff[4] &= ~(1<<6); - if(mask & 0x0004) if(iBits & 4) MWD->WriteDataBuff[4] |= 1<<1; // jazda na oporach rozruchowych - else MWD->WriteDataBuff[4] &= ~(1<<1); - if(mask & 0x0008) if(iBits & 8) MWD->WriteDataBuff[5] |= 1<<5; // wy??cznik szybki - else MWD->WriteDataBuff[5] &= ~(1<<5); - if(mask & 0x0010) if(iBits & 0x10) MWD->WriteDataBuff[5] |= 1<<4; // nadmiarowy silnik?w trakcyjnych - else MWD->WriteDataBuff[5] &= ~(1<<4); - if(mask & 0x0020) if(iBits & 0x20) MWD->WriteDataBuff[4] |= 1<<0; // styczniki liniowe - else MWD->WriteDataBuff[5] &= ~(1<<0); - if(mask & 0x0040) if(iBits & 0x40) MWD->WriteDataBuff[4] |= 1<<2; // po?lizg - else MWD->WriteDataBuff[4] &= ~(1<<2); - if(mask & 0x0080) if(iBits & 0x80) MWD->WriteDataBuff[5] |= 1<<2; // (nadmiarowy) przetwornicy? ++ - else MWD->WriteDataBuff[5] &= ~(1<<2); - if(mask & 0x0100) if(iBits & 0x100) MWD->WriteDataBuff[5] |= 1<<7; // nadmiarowy spr??arki - else MWD->WriteDataBuff[5] &= ~(1<<7); - if(mask & 0x0200) if(iBits & 0x200) MWD->WriteDataBuff[2] |= 1<<1; // wentylatory i opory - else MWD->WriteDataBuff[2] &= ~(1<<1); - if(mask & 0x0400) if(iBits & 0x400) MWD->WriteDataBuff[2] |= 1<<2; // wysoki rozruch - else MWD->WriteDataBuff[2] &= ~(1<<2); - if(mask & 0x0800) if(iBits & 0x800) MWD->WriteDataBuff[4] |= 1<<0; // ogrzewanie poci?gu - else MWD->WriteDataBuff[4] &= ~(1<<0); - if(mask & 0x1000) if(iBits & 0x1000) MWD->bHamowanie = true; // hasler: ci?nienie w hamulcach HASLER rysik 2 - else MWD->bHamowanie = false; - if(mask & 0x2000) if(iBits & 0x2000) MWD->WriteDataBuff[6] |= 1<<4; // hasler: pr?d "na" silnikach HASLER rysik 3 - else MWD->WriteDataBuff[6] &= ~(1<<4); - if(mask & 0x4000) if(iBits & 0x4000) MWD->WriteDataBuff[6] |= 1<<7; // brz?czyk SHP/CA - else MWD->WriteDataBuff[6] &= ~(1<<7); - //if(mask & 0x8000) if(iBits & 0x8000) MWD->WriteDataBuff[1] |= 1<<7; (puste) - //else MWD->WriteDataBuff[0] &= ~(1<<7); + if (mask & 0x0001) + if (iBits & 1) + { + MWD->WriteDataBuff[4] |= 1 << 7; // SHP HASLER te� + if (!MWD->bSHPstate) + { + MWD->bSHPstate = true; + MWD->bPrzejazdSHP = true; + } + else + MWD->bPrzejazdSHP = false; + } + else + { + MWD->WriteDataBuff[4] &= ~(1 << 7); + MWD->bPrzejazdSHP = false; + MWD->bSHPstate = false; + } + if (mask & 0x0002) + if (iBits & 2) + MWD->WriteDataBuff[4] |= 1 << 6; // CA + else + MWD->WriteDataBuff[4] &= ~(1 << 6); + if (mask & 0x0004) + if (iBits & 4) + MWD->WriteDataBuff[4] |= 1 << 1; // jazda na oporach rozruchowych + else + MWD->WriteDataBuff[4] &= ~(1 << 1); + if (mask & 0x0008) + if (iBits & 8) + MWD->WriteDataBuff[5] |= 1 << 5; // wy??cznik szybki + else + MWD->WriteDataBuff[5] &= ~(1 << 5); + if (mask & 0x0010) + if (iBits & 0x10) + MWD->WriteDataBuff[5] |= 1 << 4; // nadmiarowy silnik?w trakcyjnych + else + MWD->WriteDataBuff[5] &= ~(1 << 4); + if (mask & 0x0020) + if (iBits & 0x20) + MWD->WriteDataBuff[4] |= 1 << 0; // styczniki liniowe + else + MWD->WriteDataBuff[5] &= ~(1 << 0); + if (mask & 0x0040) + if (iBits & 0x40) + MWD->WriteDataBuff[4] |= 1 << 2; // po?lizg + else + MWD->WriteDataBuff[4] &= ~(1 << 2); + if (mask & 0x0080) + if (iBits & 0x80) + MWD->WriteDataBuff[5] |= 1 << 2; // (nadmiarowy) przetwornicy? ++ + else + MWD->WriteDataBuff[5] &= ~(1 << 2); + if (mask & 0x0100) + if (iBits & 0x100) + MWD->WriteDataBuff[5] |= 1 << 7; // nadmiarowy spr??arki + else + MWD->WriteDataBuff[5] &= ~(1 << 7); + if (mask & 0x0200) + if (iBits & 0x200) + MWD->WriteDataBuff[2] |= 1 << 1; // wentylatory i opory + else + MWD->WriteDataBuff[2] &= ~(1 << 1); + if (mask & 0x0400) + if (iBits & 0x400) + MWD->WriteDataBuff[2] |= 1 << 2; // wysoki rozruch + else + MWD->WriteDataBuff[2] &= ~(1 << 2); + if (mask & 0x0800) + if (iBits & 0x800) + MWD->WriteDataBuff[4] |= 1 << 0; // ogrzewanie poci?gu + else + MWD->WriteDataBuff[4] &= ~(1 << 0); + if (mask & 0x1000) + if (iBits & 0x1000) + MWD->bHamowanie = true; // hasler: ci?nienie w hamulcach HASLER rysik 2 + else + MWD->bHamowanie = false; + if (mask & 0x2000) + if (iBits & 0x2000) + MWD->WriteDataBuff[6] |= + 1 << 4; // hasler: pr?d "na" silnikach HASLER rysik 3 + else + MWD->WriteDataBuff[6] &= ~(1 << 4); + if (mask & 0x4000) + if (iBits & 0x4000) + MWD->WriteDataBuff[6] |= 1 << 7; // brz?czyk SHP/CA + else + MWD->WriteDataBuff[6] &= ~(1 << 7); + // if(mask & 0x8000) if(iBits & 0x8000) MWD->WriteDataBuff[1] |= 1<<7; (puste) + // else MWD->WriteDataBuff[0] &= ~(1<<7); break; } }; @@ -355,58 +407,85 @@ void Console::ValueSet(int x, double y) if (iMode == 4) if (PoKeys55[0]) { - x = Global::iPoKeysPWM[x]; - if (Global::iCalibrateOutDebugInfo == x) - WriteLog("CalibrateOutDebugInfo: oryginal=" + std::to_string(y), false); - if (Global::fCalibrateOutMax[x] > 0) - { - y = Global::CutValueToRange(0, y, Global::fCalibrateOutMax[x]); - if (Global::iCalibrateOutDebugInfo == x) - WriteLog(" cutted=" + std::to_string(y),false); - y = y / Global::fCalibrateOutMax[x]; // sprowadzenie do <0,1> je�li podana maksymalna warto�� - if (Global::iCalibrateOutDebugInfo == x) - WriteLog(" fraction=" + std::to_string(y),false); - } - double temp = (((((Global::fCalibrateOut[x][5] * y) + Global::fCalibrateOut[x][4]) * y + - Global::fCalibrateOut[x][3]) * y + Global::fCalibrateOut[x][2]) * y + - Global::fCalibrateOut[x][1]) * y + - Global::fCalibrateOut[x][0]; // zakres <0;1> - if (Global::iCalibrateOutDebugInfo == x) - WriteLog(" calibrated=" + std::to_string(temp)); - PoKeys55[0]->PWM(x, temp); + x = Global::iPoKeysPWM[x]; + if (Global::iCalibrateOutDebugInfo == x) + WriteLog("CalibrateOutDebugInfo: oryginal=" + std::to_string(y), false); + if (Global::fCalibrateOutMax[x] > 0) + { + y = Global::CutValueToRange(0, y, Global::fCalibrateOutMax[x]); + if (Global::iCalibrateOutDebugInfo == x) + WriteLog(" cutted=" + std::to_string(y), false); + y = y / Global::fCalibrateOutMax[x]; // sprowadzenie do <0,1> je�li podana + // maksymalna warto�� + if (Global::iCalibrateOutDebugInfo == x) + WriteLog(" fraction=" + std::to_string(y), false); + } + double temp = (((((Global::fCalibrateOut[x][5] * y) + Global::fCalibrateOut[x][4]) * y + + Global::fCalibrateOut[x][3]) * + y + + Global::fCalibrateOut[x][2]) * + y + + Global::fCalibrateOut[x][1]) * + y + + Global::fCalibrateOut[x][0]; // zakres <0;1> + if (Global::iCalibrateOutDebugInfo == x) + WriteLog(" calibrated=" + std::to_string(temp)); + PoKeys55[0]->PWM(x, temp); } - if(iMode == 5 && MWD) //pwm-y i pr�dko�� + if (iMode == 5 && MWD) // pwm-y i pr�dko�� { - unsigned int iliczba ; - if(x==0){ - iliczba = (unsigned int) floor((y / (Global::fMWDzg[0] * 10) * Global::fMWDzg[1]) + 0.5); // zbiornik g??wny - MWD->WriteDataBuff[12] = (unsigned char)(iliczba>>8); + unsigned int iliczba; + if (x == 0) + { + iliczba = (unsigned int)floor((y / (Global::fMWDzg[0] * 10) * Global::fMWDzg[1]) + + 0.5); // zbiornik g??wny + MWD->WriteDataBuff[12] = (unsigned char)(iliczba >> 8); MWD->WriteDataBuff[11] = (unsigned char)iliczba; - }else if(x==1){ - iliczba = (unsigned int) floor((y / (Global::fMWDpg[0] * 10) * Global::fMWDpg[1]) + 0.5); // przew?d g??wny - MWD->WriteDataBuff[10] = (unsigned char)(iliczba>>8); + } + else if (x == 1) + { + iliczba = (unsigned int)floor((y / (Global::fMWDpg[0] * 10) * Global::fMWDpg[1]) + + 0.5); // przew?d g??wny + MWD->WriteDataBuff[10] = (unsigned char)(iliczba >> 8); MWD->WriteDataBuff[9] = (unsigned char)iliczba; - }else if(x==2){ - iliczba = (unsigned int) floor((y / (Global::fMWDph[0] * 10) * Global::fMWDph[1]) + 0.5); // cylinder hamulcowy - MWD->WriteDataBuff[8] = (unsigned char)(iliczba>>8); + } + else if (x == 2) + { + iliczba = (unsigned int)floor((y / (Global::fMWDph[0] * 10) * Global::fMWDph[1]) + + 0.5); // cylinder hamulcowy + MWD->WriteDataBuff[8] = (unsigned char)(iliczba >> 8); MWD->WriteDataBuff[7] = (unsigned char)iliczba; - }else if(x==3){ - iliczba = (unsigned int) floor((y / Global::fMWDvolt[0] * Global::fMWDvolt[1]) + 0.5); // woltomierz WN - MWD->WriteDataBuff[14] = (unsigned char)(iliczba>>8); + } + else if (x == 3) + { + iliczba = (unsigned int)floor((y / Global::fMWDvolt[0] * Global::fMWDvolt[1]) + + 0.5); // woltomierz WN + MWD->WriteDataBuff[14] = (unsigned char)(iliczba >> 8); MWD->WriteDataBuff[13] = (unsigned char)iliczba; - }else if(x==4){ - iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 1 - MWD->WriteDataBuff[16] = (unsigned char)(iliczba>>8); + } + else if (x == 4) + { + iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + + 0.5); // amp WN 1 + MWD->WriteDataBuff[16] = (unsigned char)(iliczba >> 8); MWD->WriteDataBuff[15] = (unsigned char)iliczba; - }else if(x==5){ - iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 2 - MWD->WriteDataBuff[18] = (unsigned char)(iliczba>>8); + } + else if (x == 5) + { + iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + + 0.5); // amp WN 2 + MWD->WriteDataBuff[18] = (unsigned char)(iliczba >> 8); MWD->WriteDataBuff[17] = (unsigned char)iliczba; - }else if(x==6){ - iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 3 - MWD->WriteDataBuff[20] = (unsigned int)(iliczba>>8); + } + else if (x == 6) + { + iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + + 0.5); // amp WN 3 + MWD->WriteDataBuff[20] = (unsigned int)(iliczba >> 8); MWD->WriteDataBuff[19] = (unsigned char)iliczba; - }else if(x==7) MWD->WriteDataBuff[0] = (unsigned char)floor(y); // pr�dko�� + } + else if (x == 7) + MWD->WriteDataBuff[0] = (unsigned char)floor(y); // pr�dko�� } }; @@ -425,7 +504,7 @@ void Console::Update() Global::iPause |= 8; // tak??? PoKeys55[0]->Connect(); // pr�ba ponownego pod��czenia } - if (iMode == 5)// Obs?uga MWD OK + if (iMode == 5) // Obs?uga MWD OK { MWD->Run(); } @@ -445,24 +524,34 @@ float Console::AnalogCalibrateGet(int x) { float b = PoKeys55[0]->fAnalog[x]; return (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b + - Global::fCalibrateIn[x][3]) * b + Global::fCalibrateIn[x][2]) * b + - Global::fCalibrateIn[x][1]) *b + Global::fCalibrateIn[x][0]; + Global::fCalibrateIn[x][3]) * + b + + Global::fCalibrateIn[x][2]) * + b + + Global::fCalibrateIn[x][1]) * + b + + Global::fCalibrateIn[x][0]; } - if(iMode == 5 && MWD) // maciek001: obs?uga hamulc?w (wej?? analogowych) OK + if (iMode == 5 && MWD) // maciek001: obs?uga hamulc?w (wej?? analogowych) OK { float b = MWD->fAnalog[x]; - //b = b*(Global::fMWDAnalogCalib[x][0]-Global::fMWDAnalogCalib[x][1])/Global::fMWDAnalogCalib[x][3]+Global::fMWDAnalogCalib[x][1]/Global::fMWDAnalogCalib[x][3]; - b = (b-Global::fMWDAnalogCalib[x][1])/(Global::fMWDAnalogCalib[x][1]-Global::fMWDAnalogCalib[x][0]); - switch(x) + // b = + // b*(Global::fMWDAnalogCalib[x][0]-Global::fMWDAnalogCalib[x][1])/Global::fMWDAnalogCalib[x][3]+Global::fMWDAnalogCalib[x][1]/Global::fMWDAnalogCalib[x][3]; + b = (b - Global::fMWDAnalogCalib[x][1]) / + (Global::fMWDAnalogCalib[x][1] - Global::fMWDAnalogCalib[x][0]); + switch (x) { - case 0: return (b*8-2); + case 0: + return (b * 8 - 2); break; - case 1: return (b*10); + case 1: + return (b * 10); break; - default: return 0; + default: + return 0; } } - return -1.0; //odci�cie + return -1.0; // odci�cie }; unsigned char Console::DigitalGet(int x) diff --git a/maszyna.rc b/maszyna.rc index e77e69f612ae57935aa0cecb64095904e478dd8d..e9f489a956c634dc79c628f9bde05d542e745f5e 100644 GIT binary patch literal 5814 zcmdUzZEs>l6vxkN6TicizR{?(bZhi&3lz!Hhm?nC(uC9&x+D}xfpypT+11~Fh67x< zbPH|_hFs>}Gv{f})3$j z8Tf?p0oXI6=%&2g^Pcb}Zao`;leaJJ3#1%|@c`(6**@400XMfspSO3G3)rGO2zcE< zC*G%aZFOr{(@IvgD{I@0m4TLczqFeD3Z%~eg`EMZ@$T}a!~XqTJ0BCPV3$=Jcd^pY zo>>0`>&OlbR{abARaRYOow7$6_%Y9_M?UR?--CT4UE2QpXEE0(M#mIeDU!OZd$-td z%RArw8eO}DxF3=?%F1`F_3PR9U0DA&8D1YRSHsEnX%(l^|W^bX8#x z%V>29v_^c3o7-T&JmcE9c0Q_hszQ$O)e!GET%(>AD{k{&#%}dc!!G$&9-m_wQ7_Lp zT$BkIRjg88!AY!OKVr)xo)i1Y-Y^yd>?BB3?A*Y+giVXsG%exN)GqZrc&UQc7x<@+ zw-aQ3Kwg&_X{h?%o#$ipvD{L&wp(F;*Ws+gMJmx{aa+vR@SbzkN(%NvSkZ6%$6o2UKEBM+v0C_1y+bz0AwfN6L~kG1 zN8<60uMTi!X%3&?v7$ei8SthK)Cm~b^0Otl6-v-9?-F9BY?4$)!y_X6dscqTvx~%Z zPP!!JO&;EPxGHb*^Ss$chJ32s&~va%f6a1F*l9esTpr91Jlja9f&U1Xe(=!(Ixf8@RNjJiZI)bL~0sI_h*^J*qT@hi#hJAEz3g?mRk#9h{QjhrDlJY`=vS+iX_ z>bB88&G+;8zl?sRS*3{)z7A0@TV!hsYdz0xw@db?bF=|B<>wfWXb--eIjY66HYj5Y z8pGH|9TgwxN5#)7bv_6nX-8wn8s+sHJ;^Sye{uE*7yC|HMPjXx7aV{ zt6O&eM)$Rko6dGVuTf6{?{7Kztpn^;2ffZmDOt zM0C2c3!bgfn;kXUR?g;%_?l>QAMIbXxkl1Z?>;7E;yrzM{k$Tq#cUG1s9T7Hsx;(F zJ2~ALRmrr(-cyZqyQ4dbQRq>+6H=wp9ga>#!ks{wgr1{2Ce^G2x>2CeUDTqpB~YdH ziuW7ZQ)y>1hBD6Uye01HWRjt^h-;sp?xa4>W}g`2jfga^hO<|ZT5%aN%DZ3ISY