From 0e4bb3e35267b6575cf9858af17004a6e6cdcfc5 Mon Sep 17 00:00:00 2001 From: TAO Cheng Date: Thu, 30 Oct 2014 15:40:07 +0800 Subject: [PATCH] Add RW data. --- .../Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp | 145 ++++++++++++++---- .../Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h | 15 +- .../Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc | 10 +- .../UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp | 73 ++++++++- .../Hsi/Tools/UsbUtility/UsbUtil/resource.h | 3 +- .../Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo | Bin 150016 -> 150016 bytes 6 files changed, 198 insertions(+), 48 deletions(-) diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp index 1c95dcf..b38ed55 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp @@ -7,9 +7,26 @@ const int WSA_MAJOR_VERSION = 1; const int WSA_MINOR_VERSION = 1; #define WSA_VERSION MAKEWORD(WSA_MAJOR_VERSION, WSA_MINOR_VERSION) #define SOCKADDR_LEN sizeof(SOCKADDR_IN) -const char BufferHeader[4]={0x46,0x49,0x4E,0x53}; -const char HandShaking[]={0x46,0x49,0x4E,0x53,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +const BYTE CommHeader[]={0x46,0x49,0x4E,0x53}; +const BYTE HandShaking[]={0x46,0x49,0x4E,0x53,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +const BYTE DRW_SData[]={0x46,0x49,0x4E,0x53,0x00,0x00,0x00,0x1A,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x80,0x00,0x02,0x00,0x05,0x00,0x00,0x03,0x00,0xFF,0x01,0x01,0x82,0x00,0x0A,0x00,0x00,0x01}; +const int DRW_SDataIndexDA1=20; +const int DRW_SDataIndexSA1=23; +const int DRW_SDataIndexCMD1=26; +const int DRW_SDataIndexCMD2=27; +const int DRW_SDataIndexAddr1=29; +const int DRW_SDataIndexAddr2=30; +const int DRW_SDataIndexCh1=32; +const int DRW_SDataIndexCh2=33; +const int DRW_SDataIndexData=34; +const int DRW_SDataCCLen=0x1A; + +const int DRW_RSDataIndexBufSize1=6; +const int DRW_RSDataIndexBufSize2=7; + +const int DRW_RDataIndexData=30; +const int DRW_RDataCCLen=0x16; HANDLE CSo7_TCPIP::m_Thread_Id=NULL; HANDLE CSo7_TCPIP::m_Thread_Mutex=NULL; @@ -40,12 +57,14 @@ CSo7_TCPIP::CSo7_TCPIP() m_TCPIPBuf[i]._hProtoPending = false; m_TCPIPBuf[i]._event = NULL; }; - m_TCPIPData.s_status._handshaking=false; + m_TCPIPData.s_status._HandshakingSucceed=false; + m_TCPIPData.s_status._WriteDataCompleted=false; + m_TCPIPData.s_status._ReadDataCompleted=false; m_TCPIPData.s_status._SendReturnCode=TCPIP_CONNECT_OK; m_TCPIPData.s_status._RecvReturnCode=TCPIP_CONNECT_OK; m_TCPIPData.s_recv_data._type=0; m_TCPIPData.s_recv_data._DataSize=0; - m_TCPIPData.s_recv_data._dbBuff=(double *)malloc(TCPIP_MAX_DAT_SIZE); + m_TCPIPData.s_recv_data._iData=(int *)malloc(TCPIP_MAX_DAT_SIZE); } @@ -58,8 +77,8 @@ CSo7_TCPIP::~CSo7_TCPIP() free(m_TCPIPBuf[i]._buffer); m_TCPIPBuf[i]._buffer=NULL; } - free(m_TCPIPData.s_recv_data._dbBuff); - m_TCPIPData.s_recv_data._dbBuff=NULL; + free(m_TCPIPData.s_recv_data._iData); + m_TCPIPData.s_recv_data._iData=NULL; } //================================================================ void CSo7_TCPIP::Create_Thread() @@ -103,14 +122,8 @@ void CSo7_TCPIP::_do_single_threaded_tcpip_comm(bool _bWaitForRsponse) Sleep(3); } m_TCPIPBuf[CH_SEND]._hProtoPending = TRUE; - if (_bWaitForRsponse) - { - m_TCPIPBuf[CH_RECV]._hProtoPending = TRUE; - } - else - { - m_TCPIPBuf[CH_RECV]._hProtoPending = FALSE; - } + UNREFERENCED_PARAMETER(_bWaitForRsponse); + m_TCPIPBuf[CH_RECV]._hProtoPending = FALSE; SetEvent(m_TCPIPBuf[CH_SEND]._event); while ((m_TCPIPBuf[CH_SEND]._hProtoPending == TRUE) || (m_TCPIPBuf[CH_RECV]._hProtoPending == TRUE)) { @@ -258,27 +271,72 @@ TCPIP_RETURN_CODE CSo7_TCPIP::Handshaking() } //================================================================ -TCPIP_RETURN_CODE CSo7_TCPIP::Send(int _Addr,int _Data) +TCPIP_RETURN_CODE CSo7_TCPIP::_Send_Cmd_Write_D_Data(const short& _Addr,short* _Data,int _DataSize) { - _Addr=0; - _Data=0; if(m_Socket == INVALID_SOCKET) { return TCPIP_INVAILD_SOCKET; } - return TCPIP_CONNECT_OK; + WaitForSingleObject(m_Thread_Mutex, INFINITE); + m_ClearSendBuf(); + memcpy(m_TCPIPBuf[CH_SEND]._buffer,DRW_SData,sizeof(DRW_SData)); + + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDA1]=m_SreverIPAddress.S_un.S_un_b.s_b4; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexSA1]=m_ClientIPAddress.S_un.S_un_b.s_b4; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCMD1]=0x01; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCMD2]=0x02; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexAddr1]=(_Addr>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexAddr2]=_Addr & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCh1]=(_DataSize>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCh2]=_DataSize & 0x0ff; + for (int i=0;i<_DataSize;i++) + { + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i]=(_Data[i]>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i+1]=_Data[i] & 0x0ff; + } + short sTmpData(0); + sTmpData=static_cast(DRW_SDataCCLen+2*_DataSize); + m_TCPIPBuf[CH_SEND]._buffer[DRW_RSDataIndexBufSize1]=(sTmpData>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_RSDataIndexBufSize2]=sTmpData & 0x0ff; + + m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData+2*_DataSize; + m_TCPIPBuf[CH_SEND]._save_send_cmd=TCPIP_CMD_WRITE_D_DATA; + m_TCPIPData.s_status._WriteDataCompleted=false; + + m_Thread_State=TCPIP_THREAD_RUNNING; + _do_single_threaded_tcpip_comm(); + ReleaseMutex(m_Thread_Mutex); + return m_TCPIPData.s_status._SendReturnCode; } //================================================================ -TCPIP_RETURN_CODE CSo7_TCPIP::Recv(int _Addr,int& _Data,bool _bWait) +TCPIP_RETURN_CODE CSo7_TCPIP::_Send_Cmd_Read_D_Data(const short& _Addr,const short& _DataSize) { - _Addr=0; - _Data=0; - _bWait=false; if(m_Socket == INVALID_SOCKET) { return TCPIP_INVAILD_SOCKET; } - return TCPIP_CONNECT_OK; + WaitForSingleObject(m_Thread_Mutex, INFINITE); + m_ClearSendBuf(); + memcpy(m_TCPIPBuf[CH_SEND]._buffer,DRW_SData,sizeof(DRW_SData)); + + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDA1]=m_SreverIPAddress.S_un.S_un_b.s_b4; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexSA1]=m_ClientIPAddress.S_un.S_un_b.s_b4; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCMD1]=0x01; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCMD2]=0x01; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexAddr1]=(_Addr>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexAddr2]=_Addr & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCh1]=(_DataSize>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCh2]=_DataSize & 0x0ff; + + + m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData; + m_TCPIPBuf[CH_SEND]._save_send_cmd=TCPIP_CMD_READ_D_DATA; + m_TCPIPData.s_status._ReadDataCompleted=false; + + m_Thread_State=TCPIP_THREAD_RUNNING; + _do_single_threaded_tcpip_comm(); + ReleaseMutex(m_Thread_Mutex); + return m_TCPIPData.s_status._SendReturnCode; } //================================================================ LRESULT CSo7_TCPIP::OnSocket(WPARAM wParam, LPARAM lParam) @@ -295,7 +353,7 @@ LRESULT CSo7_TCPIP::OnSocket(WPARAM wParam, LPARAM lParam) { case FD_CONNECT: { - + } break; case FD_READ: @@ -426,15 +484,40 @@ void CSo7_TCPIP::m_ProcessSocketReadEvent(SOCKET s) switch (m_TCPIPBuf[CH_SEND]._save_send_cmd) { case TCPIP_CMD_HANDSHAKING: - if (m_TCPIPBuf[CH_RECV]._CompletedSize==24) { - m_TCPIPData.s_status._handshaking=true; - } - else - { - m_TCPIPData.s_status._handshaking=false; + if (m_TCPIPBuf[CH_RECV]._CompletedSize==24) + { + m_TCPIPData.s_status._HandshakingSucceed=true; + } + else + { + m_TCPIPData.s_status._HandshakingSucceed=false; + } + break; + } + case TCPIP_CMD_READ_D_DATA: + { + int _BufferSize(0); + BYTE _bData[2]={0,0}; + + _BufferSize=static_cast(static_cast(m_TCPIPBuf[CH_RECV]._buffer[DRW_RSDataIndexBufSize2])); + _BufferSize-=DRW_RDataCCLen; + m_TCPIPData.s_recv_data._DataSize=0; + for (int i=0;i<_BufferSize;i+=2) + { + _bData[0]=static_cast(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexData+i]); + _bData[1]=static_cast(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexData+i+1]); + m_TCPIPData.s_recv_data._iData[m_TCPIPData.s_recv_data._DataSize]=static_cast(_bData[0]*256+_bData[1]); + m_TCPIPData.s_recv_data._DataSize++; + } + m_TCPIPData.s_status._ReadDataCompleted=true; + break; + } + case TCPIP_CMD_WRITE_D_DATA: + { + m_TCPIPData.s_status._WriteDataCompleted=true; + break; } - break; default:break; } m_TCPIPBuf[CH_RECV]._CompletedSize = 0; diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h index 0d71cfc..8568674 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h @@ -31,8 +31,8 @@ enum TCPIP_CMD { TCPIP_CMD_NONE=0, TCPIP_CMD_HANDSHAKING, - TCPIP_CMD_READ_DATA, - TCPIP_CMD_WRITE_DATA, + TCPIP_CMD_READ_D_DATA, + TCPIP_CMD_WRITE_D_DATA, TCPIP_CMD_TATAL }; @@ -67,13 +67,15 @@ struct struct_so7_tcpip_data { int _type; int _DataSize; - double *_dbBuff; + int* _iData; } s_recv_data; struct s_status { TCPIP_RETURN_CODE _SendReturnCode; TCPIP_RETURN_CODE _RecvReturnCode; - bool _handshaking; + bool _HandshakingSucceed; + bool _WriteDataCompleted; + bool _ReadDataCompleted; } s_status; }; #pragma pack(pop) @@ -93,11 +95,12 @@ public: static int m_Thread_State; TCPIP_RETURN_CODE Connect(const HWND& _hWnd,const in_addr& _IPAddress,const u_short& _nPortNumber); - TCPIP_RETURN_CODE Send(int _Addr,int _Data); - TCPIP_RETURN_CODE Recv(int _Addr,int& _Data,bool _bWait); TCPIP_RETURN_CODE DisConnect(); TCPIP_RETURN_CODE GetHostIPAddr(in_addr& _IPAddress); TCPIP_RETURN_CODE Handshaking(); + TCPIP_RETURN_CODE _Send_Cmd_Write_D_Data(const short& _Addr,short* _Data,int _DataSize); + TCPIP_RETURN_CODE _Send_Cmd_Read_D_Data(const short& _StartAddr,const short& _DataSize); + LRESULT OnSocket(WPARAM wParam, LPARAM lParam); private: diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc index f7a9ed6..9878b5b 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc @@ -1050,11 +1050,13 @@ BEGIN PUSHBUTTON "Read Data",IDC_BUTTON_PLC_TCPIP_READ,203,30,63,18 PUSHBUTTON "Write Data",IDC_BUTTON_PLC_TCPIP_WRITE,203,62,63,18 GROUPBOX "TCP/IP Control",IDC_STATIC,110,12,174,81 - EDITTEXT IDC_EDIT_PLC_TCPIP_ADDR,141,32,40,14,ES_AUTOHSCROLL - LTEXT "Addr",IDC_STATIC,116,35,16,8 - EDITTEXT IDC_EDIT_PLC_TCPIP_Data,141,61,40,14,ES_AUTOHSCROLL - LTEXT "Data",IDC_STATIC,116,64,16,8 + EDITTEXT IDC_EDIT_PLC_TCPIP_ADDR,144,28,40,14,ES_AUTOHSCROLL + LTEXT "Addr",IDC_STATIC,120,30,16,8 + EDITTEXT IDC_EDIT_PLC_TCPIP_Data,144,74,40,14,ES_AUTOHSCROLL + LTEXT "Data",IDC_STATIC,120,76,16,8 PUSHBUTTON "Handshaking",IDC_BUTTON_PLC_TCPIP_HANDSHAKING,28,49,63,18 + EDITTEXT IDC_EDIT_PLC_TCPIP_DATA_SIZE,144,51,40,14,ES_AUTOHSCROLL + LTEXT "Size",IDC_STATIC,120,53,14,8 END diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp index a6eda6c..b39639b 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp @@ -73,20 +73,54 @@ void CSo7_Util_PLC_TCPIP::OnBnClickedButtonPlcTcpipDisconnect() void CSo7_Util_PLC_TCPIP::OnBnClickedButtonPlcTcpipRead() { - ; + CString str; + UpdateData(TRUE); + USES_CONVERSION; + GetDlgItem(IDC_EDIT_PLC_TCPIP_ADDR)->GetWindowText(str); + const char* cTempValue=T2A(str); + short sAddr=static_cast(atoi(cTempValue)); + + GetDlgItem(IDC_EDIT_PLC_TCPIP_DATA_SIZE)->GetWindowText(str); + cTempValue=T2A(str); + short sSize=static_cast(atoi(cTempValue)); + + TCPIP_RETURN_CODE rCode=g_pSo7_TCPIP->_Send_Cmd_Read_D_Data(sAddr,sSize); + m_csMSG.Format(_T(">> Read ReturnCode:%d."),rCode); + OutputWithScroll(m_csMSG,m_edMSG); } void CSo7_Util_PLC_TCPIP::OnBnClickedButtonPlcTcpipHandshaking() { TCPIP_RETURN_CODE rCode=g_pSo7_TCPIP->Handshaking(); - m_csMSG.Format(_T("[Handshaking] Send ReturnCode:%d."),rCode); + m_csMSG.Format(_T(">> Handshaking ReturnCode:%d."),rCode); OutputWithScroll(m_csMSG,m_edMSG); } void CSo7_Util_PLC_TCPIP::OnBnClickedButtonPlcTcpipWrite() { - TCPIP_RETURN_CODE rCode=g_pSo7_TCPIP->Send(1001,0); - m_csMSG.Format(_T("Write ReturnCode:%d."),rCode); + CString str; + UpdateData(TRUE); + USES_CONVERSION; + GetDlgItem(IDC_EDIT_PLC_TCPIP_ADDR)->GetWindowText(str); + const char* cTempValue=T2A(str); + short sAddr=static_cast(atoi(cTempValue)); + + GetDlgItem(IDC_EDIT_PLC_TCPIP_Data)->GetWindowText(str); + cTempValue=T2A(str); + int sData=(atoi(cTempValue)); + + GetDlgItem(IDC_EDIT_PLC_TCPIP_DATA_SIZE)->GetWindowText(str); + cTempValue=T2A(str); + int sSize=(atoi(cTempValue)); + + short* _Data=new short[sSize]; + for(int i=0;i(sData); + } + TCPIP_RETURN_CODE rCode=g_pSo7_TCPIP->_Send_Cmd_Write_D_Data(sAddr,_Data,(int)sSize); + delete []_Data; + m_csMSG.Format(_T(">> Write ReturnCode:%d."),rCode); OutputWithScroll(m_csMSG,m_edMSG); } @@ -141,12 +175,39 @@ LRESULT CSo7_Util_PLC_TCPIP::OnTCPIPRecv(WPARAM w, LPARAM p) { if (g_pSo7_TCPIP) { - m_csMSG.Format(_T(">> Handshaking status:%d."),g_pSo7_TCPIP->m_TCPIPData.s_status._handshaking); + m_csMSG.Format(_T("<< Handshaking status:%d."),g_pSo7_TCPIP->m_TCPIPData.s_status._HandshakingSucceed); OutputWithScroll(m_csMSG,m_edMSG); } m_csMSG=_T("[Handshaking]"); break; } + case TCPIP_CMD_READ_D_DATA: + { + if (g_pSo7_TCPIP) + { + CString csTmp; + m_csMSG=_T(""); + m_csMSG.Format(_T("<< Read status:%d;Data:"),g_pSo7_TCPIP->m_TCPIPData.s_status._ReadDataCompleted); + for (int i=0;im_TCPIPData.s_recv_data._DataSize;i++) + { + csTmp.Format(_T("%0X,"),g_pSo7_TCPIP->m_TCPIPData.s_recv_data._iData[i]); + m_csMSG+=csTmp; + } + OutputWithScroll(m_csMSG,m_edMSG); + m_csMSG=_T("[Read]"); + } + break; + } + case TCPIP_CMD_WRITE_D_DATA: + { + if (g_pSo7_TCPIP) + { + m_csMSG.Format(_T("<< Write status:%d."),g_pSo7_TCPIP->m_TCPIPData.s_status._WriteDataCompleted); + OutputWithScroll(m_csMSG,m_edMSG); + } + m_csMSG=_T("[Write]"); + break; + } default: { m_csMSG=_T("[Unknown]"); @@ -163,7 +224,7 @@ LRESULT CSo7_Util_PLC_TCPIP::OnTCPIPRecv(WPARAM w, LPARAM p) m_csMSG+=_T("RecvData:"); for (int i=0;im_TCPIPBuf[CH_RECV]._size;i++) { - csTmp.Format(_T("0x%X "),g_pSo7_TCPIP->m_TCPIPBuf[CH_RECV]._buffer[i]); + csTmp.Format(_T("0x%02X "),static_cast(g_pSo7_TCPIP->m_TCPIPBuf[CH_RECV]._buffer[i])); m_csMSG+=csTmp; } } diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h index 699d3c5..1d29563 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h @@ -1054,8 +1054,9 @@ #define IDC_EDIT_PLC_TCPIP_ADDR 1887 #define IDC_EDIT_MSG 1888 #define IDC_EDIT_PLC_TCPIP_Data 1889 -#define IDC_BUTTON_PLC_TCPIP_CONNECT2 1890 #define IDC_BUTTON_PLC_TCPIP_HANDSHAKING 1890 +#define IDC_EDIT_PLC_TCPIP_ADDR2 1891 +#define IDC_EDIT_PLC_TCPIP_DATA_SIZE 1891 #define IDC_BUTTON_DIY_EXIT_BUTTON 32740 #define ID_EDIT_SO7_CONFIG_MOTION 32741 diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo index 9e0d9f1c459f2ab5a579f0787cfa5bd17efb9b10..30ac501d851b6b98d69813af9b44ee3a2b551210 100644 GIT binary patch delta 3225 zcmb7G4^&iT7XR+!%{T)C3^RGq*oz9GBhFTHN~vP`BE%?VEGw-FLtH zec%0l_uuE;V)Sk?)=!nefOa`b@7?`$ouwO#4OY6NO*(Q-0k7hX>o&sUSmK;657dVH53L`{ zUkgg{hI2BWh?s!h(QYGXwuIkaWORsLpI<73QQ+vUmvBv1EiTQA#m@1QYf=q3W4s5u z_6Ol98q1yY@{!;;rza&P<$iZo zV%Au;CNyhXq(f7v0 ztv%NHw}ejL6U+}_^1RDdZ^J0J5u3M-#iCIWO2m$YP(v7xX^!f3O!2ENvK({!vrYzS zULvm8x5mywej)@&LPSFEmk^1*Fy^&D@%Yi;lc8+st#@H@|x`UU~QMvjNb6khvT8G+Dx`Ewh$JMSXaGhWkW&)rs-H z6`1+?K&8DY25{g0ss2d0xjGO_*SnR7W65yfWPC`N`@Z1D7k_@CbRoeBO*fMuOF`4mg> z<<6Ifoar0ZRL=GBE!ul?{$Tl{rnUHrP5wq>)?b-zyV0le9l!t8$7}m*PvuuLm6=!T zbhJN9N>G-5^g;kVIZisL9PF-w12+zVe1na|!{3h78QAwd%IDt>mLMIW=M(sXo=%mH zP+bB9#^#FxE<5>RG2=0f-}A*nMx}sJNn*Z`e?p{@y#hv|_fyB~4(JG=nH6w975o(p z#APuMFZFcN>Wxr9R|ZLDj^YHK(oXg;7+b67;nol0@sYMN9?(jjkH7-!C}%2|Y0hwWPl`7xD3g(tpZE~ z)5Q`->oLYILj;RJwoIs-vtY>pI$HrhqeTXgBIOuiJY%ILZi@!q zyJY$p3{|)8jc%Pi?sn30o-4Al*yR6Cjmxi@=AT zo&vR?7%GFw{0wx_p#&I4!z$n!c?%#$jad!tMl7;gDy;@ec#aQrSu_3!`rfwCqKyzq zF%>XgTP}f?ZU6@~vG-=xZsOkg@UVDtxxq?>`yhlmp92dmH-IUCD*~6EN}m!&!X3FL=L3m|6NTp|=hgfu6u&J(km_5L}xvzpO>U*oNs4zQ{3Rl2d-rmC7|5(WH30%WBlvFW? zZzx!OAc6Lckz&;uEwC&==7o9_QSJTpmtvX6R@kl7wVyh zH8XkTJWibgQA+!F!mlakJO8ERZb3Z*VULyvHV%D%WS_E22DP{y_Ci2~m`}XraMjTP z9|cfz7&t>Oes8&nmmm|(zpwkTa`G@7;@BKTj;S20Q;i&2uFK$}M~o21VDx4a?1RU! z@Ma2nTjQy48f-$iFH+r=E=>Te{`ytS&8Yk-X?-I^44?pnaRm3v(DqH z!d*(&H)g2)3?!^C3BvNmcp7^Z231`HkKrhzIl3QF-9kpZg|456yD7#b*|0HUoW7Q2 zA%ONH+2r{%$C zMjKCq4t0)DJoer?VyN|M%=p+4 zQ$nT7zBVm?RBPn)#R9Nat%9}xN9Q>xMN7d!+{FT!LYaEhL`gcQqudI3@IM++9Gpcs zIZ^c)Bp+bS85bPKRTC!G21x_d>@F?KH@c;43X>sGve;RX8TbuOUXrSbs793DLCaHvBMaOlxjr(p_t?UFaZ!%*(G4$%OQ zAz!rQ!?OwA28VPKZWD#(t{y!!GF9ZWxN*YjK{w`UslEp!m-KH!;|A9N delta 2836 zcmb7G3s6*7620f~W|+Yd2IQkMCIcDCD1HVdDMiH*h?b&)#%!!L>xU%9{1gd(mm=e5 ztu0L{&Q+Vls00mu)-O+a#`W{c#e~FN|C?w+DMn+;S|tWqOHCHG->|sWW~;XLPW5~J z`u6SHxBGP839PXP*4X!sR^gFJ>XX*OsQRJJcV&@!PUg6M(nwG@&$mFGt_Y!(SnE32 zo)kiKV4^e0@XF$trKr*##H_#|D+?V=uZp=$Get4;u}p7^DdL@wV3HA8nt}n%xcy~lXU4>u$jbZX$cMg>c0@8C-M&~Br{&2%scBksTBOzbhdDxo3pp-( zhkVkAk}27#QXe={mX6Jlg<70E`M&u*qB6rKrvc$kkZ^Dm#f@vX9Y&HQ(nIc3HNsM@I;R3;o#}7hCVF^*_EPinOug z&tiXzhl4KhTAA(<|(EexjO%(IV(@^yC1#B%x7q%8V8y0FB|r4klnJ= zO%2z2w9h(?-T&ev!WBn+>T*Aud7l;Svgt|>n^R=wZt!pt)t=nkas&TBn-LVU_z8Ii%F9UH;@F6%8_J z-F6Ob0ZgYK?Iu-`S0Gq> zFna1U@0K)f8Pvr#%d`CA)gE<14!hY&tFQHdGJk+u`|?Tys_S}2M$e6Gc(-R>)2NF6 zc^d*H(eET^gT8#uA~z;}?TGiV)U1Tp8Nv&=HeThLm>_0}@yxx< z^tza(`yWiEUMs&vn4odF z7@`esthLaa&no-1H}0>4^iAukR}5B$fL^?b?ZMY9x}_2OQ2p>A+BQ7=lh+b5qTT!{ zK|zK@%Qf<3!4+)XL2e6DD0T^a`=O|mHV|XOh3L+^)l+mVj!ENdSC|m-G`k$L>2{pr z>FZJO>eZvM zA2j!SET^fPpwi_$Wa7HH?Gb5w&dzOw(>{Z(+nFxV>4kR~<3~y@E2wpqC#15o&;Kk0efd=^7lYXtvPz9%XIE$LNEL zp#+hU%ZVs+!bzDQGsg#=NxfqgC&Ru!rESG}oNH4oJsw}km z$$y=*b7nAu{y(amd}DaVe}f-|V{k82B3o;I;GSTNLe~FTH}Y)i^GeYyne=v?^dEnM z{`Mo{WcqZk?rp|J$g+T4x5p^Eu&#;kom$mrnZb@;plCn(lG_g#<=kcTFy{_E_+C?~ z_AXwLXBzBeWGj9eovozHz~4L5r+)6r?=Fp?ZJm{4w9lvH$wuc_G`XKrLQ9TfiaZfL zh*q73MOu=hblk^KtNb?APk|ObY10^FnensAx)#^tjW&MW0eB90l%LVj?CBAFGeb(`^yrpB?|ENB~Y!uxndI{!H;XOuVzKRHh+Hnuvuqg)Qxt@L;my3oBt?HnJQ(=E4 zOM4;N3TiroVtMVU99nc0y>$lh`7r8r8e_C#&wHRtU6iNMqNA(Q3cb*!l(n^J9ArrP zWlVCmJeHiSCss3d=!etDWvrrZDEV{Yk2C#k8%D;YuUm(g6zv)@$h?AS`mfQM47XxX z(=Lpqv2LYbO|nu4^^