From 6d6371525988eb3fc263cfd57bb438cd68f0cff2 Mon Sep 17 00:00:00 2001 From: ndaga1603 Date: Sat, 20 May 2023 17:58:51 +0300 Subject: [PATCH] Updating ScreenSharing scripts --- README.md | 16 +++++++++ img/client1.png | Bin 0 -> 20616 bytes img/client2.png | Bin 0 -> 20916 bytes img/server.png | Bin 0 -> 16401 bytes vidstream/streaming.py | 78 +++++++++++++++++++++++++++++++++++++---- 5 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 img/client1.png create mode 100644 img/client2.png create mode 100644 img/server.png diff --git a/README.md b/README.md index 98c90d9..2394838 100644 --- a/README.md +++ b/README.md @@ -36,4 +36,20 @@ client2.start_stream() client3.start_stream() ``` +# Vidstream-Updated- +### Updating Vidstream package +- Making server to handle multiple clients connection +- Server broadcast received frame to all connected clients except the one who send the frame +- The video to be displayed to the client and not server + +#### Example + +![Server Image](./img/server.png) + + +![Client 1 Image](./img/client1.png) + + +![Client 2 Image](./img/client2.png) + Check out: https://www.youtube.com/c/NeuralNine \ No newline at end of file diff --git a/img/client1.png b/img/client1.png new file mode 100644 index 0000000000000000000000000000000000000000..db5a31d702dc949b45625ebe3982953a9b232d5c GIT binary patch literal 20616 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 literal 0 HcmV?d00001 diff --git a/img/client2.png b/img/client2.png new file mode 100644 index 0000000000000000000000000000000000000000..0e3081038f794ed9ca8ed558edcbe9ace6631bbf GIT binary patch literal 20916 zcmbTe1yq|sv@Tk_6iQo)L!m8J+zOQ7h2q8CDee-2Ly%Gm#frNW*Wj+jin|k}cmfIT z@`24)D<8`j9KjVq#+!b3Oln ztI0aDG(QU7Z#|p0MOKgMxhS5=9$g>lm_b_446pao(!etdwwdC@#Ka_$wzef#;*zK` zRU(oNCVYV^p90aC{?%dsr7liHpTOg^G9zYhvc_d^+tu``+KD>#d5bC(J6`m!Z#Vwl zaLnyRZKLlbW5!0_#Xn4 z9^SrkDkpX&{fXAObM8%VFM9`L*oj%BUE4j&#lUSUs65qTW^FvPG)8&W6sJjaeD^0{ zDQkOsu*eb|(Aw|t{rh+9?=9H5nGJ|kvZGpXw=q?3JNQ6kWM426JZm291P@G2 zSp7YYwdBiz2Aj5=Sz|H!X{xkiY%)Lsk}tqy%5w;zUm+)k3$(kr9H77XZ@LB zpoysVclnsFEi^)HFSJ`Q6YsW7(wf}KN75&;vK_>rw1b?Rs*LW4Q&7WoHkbBkEamuR zSF=j{qIG|ZN?>0z&4MXM&e62#o@{GN3Z&`MJl*oy+CZZkoia&Zod8?O56v}3;OUd! zdVN_5$@8J0^QkVaU%Hz2#bkn+SjAAlkQW9V^PG3d!{;!dy~pxU=xw^q8LPPf%s-9zq$ud8MD{n@NOkQF@UVujF%jt@~f z(VwmL9X@j4fvI5w@sw|^jaM9@*Ru5fLOuj}v`fvRqb4g1^|dZM%K+>g*5FSi6?>Bf zs+ci^e|nK7(4Z@5AE(F7Q$ocOdwi)w;wG!{X)@p*TXJf!(t>^C!!o~By+faHk6dqg z^>bkK7d_b>_!gHv{nuo}&x;%ncu^e9*rZAMyWUkEB!hLlf(2*(O*}uD^?U)2>A`b| z;IiwU!hkoH-B|}i^Xc*35JtZ{fc^wz=OFNnD}JQ40FSwERa>5+_JhIMbmmeh_@;T- zLur&AwLxHxM{^&WUc3U|w>!BULm~nc+WVv(>RS~pXTXBPw>e+_Z0bZhxHmzeoic8) zt;asZ;fBzOh|^&)uSvc=N*7*|9mG{V-@JV8Dpt-){Ql9M%0sK8N2JlrjDA5;b^L4h zJFEwN4ITrMK1UNj8^}1;hVHNQd=8GTn^(gA1%slRCoq3Gr#jzj)vZkxB<`|b*bvnhAUalj+Ib4! z-Q6g!qg^rWm-i_W4-Eip#9}DAzj9d!7r_AEBrfDz6>2dv;64F+8Hohht_n;9t#Mu} z@{W36Dd)N6P!oqCb4Ptmq<+HKU_4Q9C{60?e}Am`QpE2*oP7spsZS)YsZX7)`tgPH z!B3TkiN?@J)ZcUkX5XRa;H{w!N~?z#NRFH0{jdFG7@9R9 z57L*Y}!$~+(z$fI&>RduDI6LGT=6`|uly<+g_o}51qAlk@v#i7Zlf4oE% zfwdCv+x|I{%j4A~wY!T61U1FK+PIt>g+mn z`Q`pjA{gZ`F|l*|sbW{xHX<&55m2jle6Rxp>(N6_EdKt8UFjat$I-v-M$jxpG$S24 z1_3LxLoIG(ZVpg;r4musZ@$Y<12>yScRL25ceIxLh6I=mD69Csz?dL%YhMU^BIx0S z9%3&F{H;>ZqsW*O%r=*oX-#@R%iWKQj+T)6q3QXJFxy7H2Qb8W5I)?_Ao zLIDjOA|%rhd#<63Qzps=3(Iap<(5Dw1?yv1Uq(TrMsq~aczpUERpI*mOavL<^B(fnnGKAF;HJu&HOSf#>ck-MNnD9_>Y#rnE*NU7D!H&T(d6 zeU^&(r&;)nesv!c2c3~*-)sbT)Xt^Z`DT2{X}9r#n$HD9jb!(wf|h%s?v`WmzIHsC zKJJVFMPxU#PM`37*Ood)R53uazxG`B&*ZDV3IW=~D(35eNkR(#e5x+RcE_7aXY^EX zN#Gv}WE7R)hm5cM?eKlkHmW;m@xXOtj;Ti@X~n|`#Ze7=%<)Za~L3`BbOYXC-l3O zv9VZ6q)ot4t<&bn&|)jQDX|P&IVN)()%c%XgQsrrrNP-^UtHUCwN5MEWp}+pzXjNk zq7_>BwK$nlD&CYc^O2;2IplO*E{vppQaCTX04$OPkSP?2E`+X3^p)MWFzW9&3kH@5PfDEChzk$f**ZDzjL!k%-l!B ze^FEQRj%)hmCeici+mX|A_rp@0w1?r2DT9Foidsvu&d=9wNk#7yp+Kg^wd9#Mn!n! z7qOH)sHk>udKW3Yd`;TGs<^Mg z5#IHCfE~@@=Ue{tAO%r;>>gP-AYeEO(Otm--yd{tr$JUJ`L?}L4U4jRV^XfAU>NhAgK!NUn&`r1Cm zL?}!~!zWW8`FALp=M4Xs-F%c}*b2vDK>Es4u${UbEEK~XL-a=TysZ}H%fDZ-W9L4& zX(A@K`IjgNqLND%{QyP&@3qB-tPk3?t4*)AaQzr>jkZ<&mpRoOOSx6tdfPc`<~UHl|oIi^?Opr%k;{3 zA6b?s8{4`sS6MrK{JeV7V@2Oh(U4q&+8}D;(BD5lYcrw6Jc-#;_e^AGGbTJJOPl=0 zICRV2hzoahj@uLSlqF9=0?+M<52p75H$fWoXHC_JDIQc{%nQVqDPU`S!APSM&^vn? zE))Odd&W^og7Wn4l}4GK3G~w8ydt&5;R^__qwDNy1n|tXPWZN>G**$Vt~<~mIKb15 zC2XwhG(f@SrT!<2s~0e$uC` z2+rzxTx+FY@{Rn6!Uh`j-aYn07kmq$y|;CsrZqCuj)~y(r5BDvUyAvz#{#Y;MN{I@2%Hm+q&gOAx(==$NWl&<^D2-0Jf{ydC zY^_(ajeH=9_p)8G<}n>7??7hUE~9ydUcmtWAOLY9g8Ex)q;9$9k%K3UjwV0BM_K1c zJa4`p~lD^qtuw*bH~W>yEn`~feBlxj0kns@oO=Ogms=4< zklIxKS+MrZDKe;@&C!sdU!>i|umwmVbLJ`U7MTV&DMxzS&p~KR4UWCOZrsi;G}ak< zuIj?!^A3iNv{+Fr7b!+Ft{orpSK-XV&Up*SRjz!QyYtVS!R>s$*FP&(tVfdNWS1u& z_O`FEv$7hY!z==l?LcJPgSZgRwN1nNOWntAS6u+uGw=IS0rk=i;JK(A0{Y6r8i+E( zRu~)bLQdnrjVCi2_MO>(i!ONT&CR-=HdKM+Eewu%7oCBh@G@lP%k;u+x6CI#CQ4eq z)P!Bl3ZGImg$+8z4@{}AQ@qd49uN+3H<^r7)EDTor*Fcm9=dG;J|oD+-$XdewWhj~ zTFplG)|A=KUp~5CpPgyuqt>{i_f4VYRh1bwJp1ty-$xbvQat@hw}Ouz2qzq z8T*w#^<{8B-lbeK&(FSw?=Q3OXB$H+G^xm1xHg|7vvIk%C2fiz3ztE?da>q+1SMlH zMB+D`Fx{$cl&u}ldvl-b=E-eS6Y#ARzD;*_SYA`!s9oMv`0Y_^q+F!SSzWYKN)m605JZ_kpDdP^kpZ)FlX_LofAbSNJmWlH&7* z_kN+6%F3Xph7MQQUkFA#jElvu(MCmtu)#%EsXVb|=Hxa5aTe_vs9{kx zUS}(Z<~7a#82h&Fro7{7Zq%6T4OX55pA0pM%9faq!W6R{1jQK_R>m&zyY>8R>v9-! zgWv0?+$M{;m6se_cBKx^7bl2OwGQvQ!@Kn%W=UL;RIYnF{`+`*32?)bGry$+? zvW5LNbuqbLi zJ~mC7DfwJFVMo)!F*&H{?lotT10uq{7o^$WJYxd7Mw)zP;GEE>zXl~(!;9O_=l0#e zGRqh`HPQKtj;9Upw@J|JZ~RuJ9a!?+N2Y095NuBmffV5TLec!N(?+16$^3X^!1ieXHs zBxx12v8xx*PoDT335CylOkCWZ?7gosyN(Zjc;}@`G}>;V9?6%FaNSbv%8wJ8RODbm zm;-s9y!Rr-ULVm71vmoeMes@1m*(zu_&euzy|f3s(}W7!E8b1ir%LSwK#1{*Nmg#n zImSe%RWIot!Ylr!EVS5;k9r1rS)6y&-{Hb+1TQh=D+VS1U4F94aGc<86CUpwYi^_6 z(xS7)gz&27!X!>gR?b+c$|qZ3!^30o|0QsGR+Fwf1E;6b+TBz?s?BYJ?x6fIrz=#~ zE_C-2*E|g2qNIvIWTq#m!x{;UbgWu&#*7hKS$Zq=ZK;H?Hz-RR7PJ+~g7wro^R4AI z^-2;I@YvuHbmDpRo#ua9ENoee>GxxIL(G@EX6%HlpH?S&s%{lsBD{(f*dY1oAUd&W zbB9-mDu-n~DRi}*rLs||=2=m8PZiym0_&nvM~v98jiZj^#xw1woi6T%!*1{_;_AAo z51YlyZte#2M!1T;i`G_Lu-{(tfodh5K_emdEOpSBEL9F99WHBxeM5iIpq{9*`<&mm zsp0N_W$L=<0EhRpQP^T%-@#uXWQRQ1j3p9Ql#^|6)qEf{v$Jb|@rpejm5Teqtvmkq zm}=4N*5E@B9R2*O2s<#{9AM^YY=^`zh1vZc7-&x06+B;kKA>#4ZuSZl4IJO@={#LL zkh0{G($C?BbG81$Qfhz?RF1AJ1pZRe>eFMkWj^()Yp&2Du)QEI#;POHbAWVbM_72) zp@PNqQ`S^|;!o+2wM=?ljfVjA5cpzI35#EkiQUA!E`_F`d<4>d8c_wy)5lj0zdY)1 zi)zkusUvWz2NIubi)hkTR0oa3h$n#x6lTJEoYcQ$&(l-yxP`!u_y?xTFj`HZg7$>| zianXTR`n*|_O##`)R^t4H5$hfOc`Ble3AhVAf5T;49S>%=Gvq8NgkstJ&){H!BriJ zP&W3f$3qth`d$R6(W!6N0dRV>gb9OXy?D&}M4Q7x%35BX0$mTK+%?7L{} zGl;2UY2L`Tn%evwQpw(I3dW4ris-gI0ZM>D}b;FGwva-s3Lk3}A>c)fJ`?q?=FPlEU8 zTLXg-&qTq^)-Lkha;XaNOxrQAl6n|HW1qQTr!!l&Zm`#z=-N?4O@G>e8MiVC@>2@b zK>Cdj6#{hEuakD)dCxW#Yg9=QYc@f*1<38on~?A^A(tYEo`{HC`x=ALB&=4oZe{tK zMNV){e$|T*=98vp@oUM~DH~LcE#ucL+e8=$7jlIAa8$~p<05o7fd5504yva_$>LsL zg-6l^Oh>cyRib`Xd8-wtpFQ6%#Qzj1G#Sd&P=DKc;WUgZd*UGdj4~f%J`}ys!yWD3&A+AJQ(` zvn8VTR4HIT_o279@|hlclirZ_2grL1oaDe)sX=yNSVx^*92=(|8t88A5S zaYU7)VoJD+@a(A0mU!H*4-r8NmR-As<=@`5M+kBJUVexQ1qL#0x*Y3E%y+9*<^%r+ zW0m#7ra?*WjTxVQ@?g+05?j0`-M~!W^5cl{4E{AT#{o8;56+u=v&)-~H26XHxIET2 zW8usq%Z|}$((xo5fBFj=D{dRXPD=siqInxLaN>ioQKM!cZ}rgUSvlWi=X!W=SjT!Ncm_TweSW5U5ec*-eYnRDPJ z+@PAus#)c(@bX)RxFkl@6-@c|G#e{X3aV;ZW>__)+tf4?EXGS512;+zQ}f1_c+;GHDZRVYW_M_d}S!YCF^e~J4T_K zkhC>W1vG!fh%EKCkGXxu;NA}PZPd)~isaC784b~O448_yNv^2M$lWe$?*nTSvVM!} zjLG7*PEM7|>Cz41H)|x24;&aXPuox06ph(jiM~p2(F;k9D$q0OSyr8;<;)BXwHC|$ zZU3g#hni&Mk)e-6X2y$PRCv>|N{nJ*d?gmd?p!JjY+)VSY+HM@pf_WxqsH1IqseUJw-(bY)$TNI8sb^KVBWk>9NRRD<<=v4PO z*G&oGGafvx*%jz;PF{}NqG}#me`?#mhY$cp<;j(M(&zUMzI4RX_M#m-@imSZxqj6t zDfG4ki95wTmgv~!o^TXo;Ql_4 zG|f&`+FURnGQbDvbVwHrm>qwk1+E$CyTzWHcrs);D?Hwzp2U`$Q|bvSDQnV`>OZOZ zqboz7RD-f)NJ77KF+Ez|cyZ%$%<7oUa@HU}RRx{$$xQt*4lAzJev8eEh{W9%Ev=L$ z+d4fQ4XEbOg6d1vjJ}PUtvs6|HMXB98z-v|8s#|pPQ$iq6^ds*01dz;`Cy#_c1KYQ zJwh?^K|xPkW>91Cp#Dl`VBh9OtL6ZnnXhAe;G*Vr8O-fm*luyz`2wy8b+OH#V#{4) zOBNQiWX`jGb1PLmGp?X&Q5I07E2d#hnWRr3Ra1)|wj*$(K_6BU>wPNxj;c)6 zs7P2?&#!KkcdrVl$npj6+klVb^{XnMRtGF-u-ehRanYg*$Mr3l;wnMwib+}MvY#)j zTEV6jdmWJ3$Z>DhnF$_kA2se7GCQ!lQfHGc{9=VeV|FqolNG+Lr!=bLRckYTW>%Kd z$W1CATjw7c%WXCXuyH}Eq_a#${b50OsjY4#buBOTj!J6`I+9amE6sC>$D7w~MD$#! zwfLJ~aJXF+?Hwi_wm|Y+0-b3JF*Ci&t0ZTj0W@oG(x15?*))m>9oMUmD4yjcqz0K> zFy1JP9{x1KNp~TCa;;COB0^-0icRv4ES*16Ge1tP?KBk=3XSWA25ZXHU-Fv2V=n(K zXOKTJAkfoP5yD;EjOC4-iv5-E^1M6@r=n)-)9-)^11c0zj=AbwiXG8 z)J-ge8YqM0H|~LeLisI8Au(0;tQ}V+BUTzUiS>YTxn~{CvDy0Q^wn_fJUh`kw>2jp z|L9_tRFz$edbb>^V@~0f=`T1ycHZaxxDL~P5+WzVw{5hQ&Ds|zb-2#n z0+y8?TfO4RQzV}Ao1J@>xl#y!y$1X}Nr5_gvb6ZSUJ+ehFm;}u7mlAYLlK*a3X^!J z)WkaxWVx!eiX%nmIC;fbQ|vsdRhpxAn`MZM+UTnyl6r>ARp#0t_Ej>G8nD}nHLi1?-OUa{?##4!$nVRaU%(;x$5%= zDu6e6)RyrFk2u^<%FjX3MKsUm728i*b#asYFK3>}lWCo|YY9A}>AY@ZUXmZZ9aC$o z+KTzx%esa05ODlPN1h_c7f1%Wg>fLX30CL7Y`p=_P2>`$Lq;ijx?ehmYtbII+u`&u zq3hvFPSb=+SNrHc5p9~WI|qnK4r@&Y~R{hvazI$7of?(?7WYh|T~oV>uO7{EJ- zD)HlHP?LD&eFEBcrJ_kxHB7*LH61)=0ATJ=7tbXXD;8JmI{4^Q@pFZeP{{2sTl0@Q zik!_UYhho#fxDgz0^8l27h8jM%X|YZ##59_M8$;f5(W(}%7!K5Y=Z>{L|i&woSi0} z`sIwX`H@=eYN|Ps;|&A;D14rQ&IPh0et?&#!$yCU>BW&N_T``O~4|gI3S$m>aY-iimOtRi-mxjwv69?b-%W_>4*jMW+#?Xo+j< zh;LT%Opa8CD9hsMnGrN7W%s)W^0EMSF;#}qxh^-_hy*ly`^G~rnlOL5!!#9%UpsK3 z%iSN#&i1Ee$~91UWm=*i->Jk;wMuST-EHqz=awHO`VP|9m6x{@>?|cBy<V*-$j(NnmGQ$T1+vk@>KrZZPqQV9 z<8S>g`$et3WB;Gb34zT6(*D0l@c$&k|L1!D2OpJ~x1C_Zu3hfOb93R8>3VtM0g(lm zv7ex7jq2VY|DzHe-<)Tgk;k76=6$CbRMwJ2?fC(Bsh4`$n2Y<4m#Ri4f&@5b0EXiy zA=OHuMy-o#Fv^KEM?PTNsa?6xf|+7^A2?OB3>Z3<1FtHIaw*}&m>As7b~v>u<(rJL zZmMucF*qNR5|MFAeV4F_op$yb$Ah+yJV{UJ9}oLq<)`$BO`Zp>c&PtD(|Ch*<@-rw zRL7_+HHP9GDC7lg_SgU)dyje946@vRU7x+ha4Y;EBDt<;%tVR#R;__8x01Bdt>;Op z(`2ufD;lxLsliPU=dTThLS#4MDeU^MyKzx&pVP-9SgKuG%XRueu;caYrs!qxADqFL zKXXU~w=`EHEbnpd6i1!Aoz(A;ahWzvpYI&23-EegD0I`3eboZqfPNS3nQHd6^@=R3 zSygUZ+C1H|TMj;I6zy|Ap_)wDB#f)WIEPI06lxJ~1s!VO?V_)SUKJcr!(4;%;B5Db+P6Ek@$t?<}Zob6uuu1m_wQZdv6jI!#oE;X7HazaDB*vy}YZxNG-Y?v>Bg0O3eHY@i*@8)@4$ zjPN6eGiPrLmjFd5*PTOd@cn9k*+8wkY?H!^$Sg($A{CsqS^c5VVuTt|Xl3QoDAonZ{ zW;Gh+FkNss>tfjEq4~}AmJdf0u%(!q z@;>3DsA28kMwj5U@*5J|=Zp(#VKCK9O40T7D!WjQERA|h)@Yu6z+20|Iv$y?@&2CX zvwLd>PSAQS6akAJ^+JzTr_)(hE*-BccTVoR!M^6H8K%m@8Y>ue`eiAag<3`a>Nt79 zvFw?a)6>J%Qo-@3E+||Km{X_JO;}O4wGY+NJpLA4^%SSnZLkUjpeZjgG$ksQ(zU9g z0IQx-HeSU>Kt3w%)%praHmf&$$Ss=&BDw={W zKh0nr3YDJf8TZV1d4gT)GCdTS*pvBB9g**G;{rY-H=lbJO?`;kZ=&bYnSR9{;MMu%2pK5w0tp7>fR9}=Hg+|s?kZq9YN%PKkoczucCWl+Clz|S=t zU)5Oklo1J8lppZ{zX}~Jw&#f6Z@e6WA)HZ;qQtaQ*Va!vId^}!g20EiC7cOd9j6AC*Q`Wvyi$2P_-25f2AlY=*^l(YnV>G&2UMa4@|ST zlGdNEy7QfBs@dXl7>%i@;vfmfjAw}Z(wz%P|CLJ`;>xBSYN}Z#7`u62dpPrUb=!r2 z**qP8$QzU6Ys=lrjd{AE7&!wd9&X+Kt3%+LOiA9a3KEZyY@vrYP^pE)MN|Si?!|(U zUYF*o?nl6c(2c%$#Y80Nmtj!!?9X;~WJA}W_m{#J2D&U*zB;5D(FTsozep+Az&lz2oi9 z>6dbW!bO5Cm1;Z8Og%*DPXP<;THNlAECb3W*ttlNV6XMN@mh|!)iV*2IFaL79!~3t z+^;9wE3VxYey``**DO61VfIup-Me|_h4yWgX-vLJqY=y&+btD zCOOiL(&CR_En-*vAe9Z-^$APB{t!{ieYslnTj7#eSh~QN-{7YTALE!tT4_hg>n+b`Wr3;s|5k{Sto!iqffFzV=SL4TV~<=DhG;3O@B11gHjaT94&Br2kzs0 zn{0BM?_bizqtXx{h3Q2gx-vw*-4bN^#!YgWH*vj~uH9X4IWg+jPk=;gzLL<{ZtLvI z85BA}y3rb3BdvSzmBQ7GVV!y`xEPDqaOS(jh}`A5RO$^kM{j9Jn(^FnR5bus_wPCqh?%9mo%APX{k9xB3dlkD_EtS}rid&!DF*w_cwUPYAZ7I4u`H z6EZJ@mhx zm-m)~79?5>h7KQUj<_OX_KD$2=(3yPh>WufHNLAUPCoc-CFa-0iH;!LOIBG02E zf45-$OL|IjjohKq;p6G)jT!aP<(#Ydx9Uv>ArP zNi0#ox)}SPb|uBJHJCM&y`G+Dp4a&zYA}8yZ62^EN=OAF+%RL&fX+J^0{x(6&8QHo zVD2XT8-%=7qZ|Bvj-vv|nUG;;?CBM_~#9!P) z-0o%E?-szc>YwS;Z(rwmoclPyG`T(4;^Kb2b9-{_%2#+@udJd(WF`iHB>>jRa|gMy zLH1@*zPehqPlk_vSmrGTr!z+nR;CO{Q59=bAVo%pkCipfeP5+Wd!43$ASDZd50sg!Bk7#4SR*0ci3W*+ z_h|Yt8hBAnj8iM|#WAzY`MU0kJ$n9WMEDzgvaewMnEeB>hwh(8e?EJMyfXkPwrA^+ z4x4lPV&{W1r`}mt=T%yQ3SzGssQO3d89ePh*c?W7j_g3^UWFDBS%>=ksqizH&}l{>mHFuV*Rd2DG(NuqgeOEy zYW(gMY|Jc=ex6;*nB?RSzZgNuN9Y@s3^}FY+x$f;r=10aA87Z1jn8UlBE6gVC;V3P z-$R09YG>M^$3VECiFu5w=;2qU%p#>F2{{aLwt<%pZ?%*#A2lshd7n5NfnuA|*QJb` zZ-SR8*~R`|7+D&BoAs4b-$_f50qK3a9GdX~V)tDZ72pD*4@+Qr0jdyX4Rq6Ori}y*UqB`Dzuh!(u6Bv#5Rde`5L!vd9U7!MQ@;8US=bb zd5{qGDdD_E&(#maVci_K2k>FBa#7iv-~Qb=ciU3#G|@_aFd;vhk}jI>98>P|$Tf^Z z+AjYGiSqZiJ^vv`4kN;NAV=Q*ztj@}iozC!I>PD0IT<}9u@9`t6y=kvN~Ot!(%yZ< z`QWQ%ivHOUzM4YF=+J02=Z{sNG82&uy=|Xh6Fr!v+%j{(_PPIT8}8BxrLdCPsA<=F zhoqk`1&S5l)Cs72@HzlosW;*~VZ@4IJI#C7)%!+?_ihZ>IRlcos)Hnq_YRP9S9(pf$pnp=f95JpQ!532n~@4H96Ir)QfJA#VwMWIW}}9|hb_J&W!Q4JbJ1Vy zGg~BIeT(L%>XLsK!LjbwrTDi#OjzPe zFb$l#x-|{WDD3@ax&%9AmA^bR=5G;-M**ig*ZT6hN9pvO3my-|k_*IGdY|5xMQ_uLd8&87?m$ZDpybz6whV#4jRItj&nchc#x92tEdZOsqA7at2T= zHk_ZZW+1Av9-#AJO`mri{wKmU>DY2oCq+9vp`Quq*n0?Mn^l;_&GW^JU@?$x+}3hA z$Zm|j^^e_9b-L$lu{6>W*#E=~n{wiH(QQXtFXDzSgz|TV^1;-ziBz3!j}dQ#=Vn4t z{IY5C2;-d7qy2>7vxKSjanZ9{OMu8noNr(F*vCBE3496*)NQT5;8_FgKd_nD|6OJ1 z8+XIyn>;An8mbzy$+P6QNjul{d*?S&qjrw4q>t6T!`CUU z^@&WP%tiv|)w1YsL#(8cM|5fe0|$?oT}P;7At+=cZWUXq7d&zC=$(69t7oS5+k30K zXqB@c0lg&wW~2D4DCGuHashhJTbVMX)Dm(7E-xEZdo@Rq_+{3I7)n7vHZui zUQRGJ?G=2c2${ocH|Kn~%rNzg*zbX!U;1$O*iGa%14Xo<%B^fCPVS_LyKu+M!{rVX z6j{84?d~l)TmKjQWr9-bMVEdtLwap4Wf>Y+XP7g*$~yb32Bdbr7YTHPaDw zZ;Q1#U0P!PNV~QAK!0Wz8Q^K_x%OJJv$A%$r605WygZk={E*JS^rSmwI)1k;mBtUv z5#fc&5BFi89^le(v4ex!oWi@%1PZtW>QOyac{k_px)3w1-MSzzUjPsE`%7i9Hk%Z< zeHf522`&`#;2r?6hdMqwwPD93Se91}BHe20k0{bOc~vcY9Q>bMyP4Ru@{y+8qKe3zO@Xx7%aUka8d z1rC?{4etx7zWF9a*rWqBOzl3NUw2idEuP+SV#6C16WatueP{jN0&gpPWzBz-liO=2lSTEmiE7y_ecjWGxP^(Hb2MZTARM(ZJ^v=#GGzbODE%}j%k z8Nz2+^s%bf=~my5PFK71%IA($AlyNS$Umbc==D#jem^tTeG2NJ;>rMgeg zfU!w$_{3*1?+RBJ#r*+=(%1Oc|7rPxtM2W>!G_vhj?6>eGUt3>dcw*&>|uA~n@M9$ zBrJSq79WaHcg9ZR=5=+M-t6G?8f4PQte(@m&Q028Ex7)uvgudIr^t+XjnF_*FT5XE z7b#M^p07)`u-rFbM!h0qeuKgi&FkVD>}fGPPN5^4ACobE*x&iV(`Iu*U7S8? z99o*oY_aC6I^Aw=W0lzYa3UccQN{vZ#UG-59%(Hua&Sk@eb`4d?A#nqq*C9Tv)?a0 z1{`vIup$WKsF@n6Gm+Cj&!p)ev&D<;0f^T6Je2$hVx#Wf;;N7C(jVE9X4E&shd0`< zEBMp9oQ0<)+Es!qj~w?N&nvpSU0#DDWsOQ_$+blEWP%KPm<5el`?G|XaAktf{PKo) zaC|+3QdC#GQBoqJ_}_MKi0SjBymwBRqMs8pMmQ_BeyWwfBUq$+-K_u7eA>mch7^4w zasOHcGAw%z9@Y2XER2rciW?CeFmL;XNG|)W?7eXO(-+U5f{d8G9=f~M^tDuwEUz<8D}T%P8=bdPv5?E$3n&X{^GWF9Wcs9Oe`dMGO(*NU#nK5*Z; zAq8^l<5zp6VW1z@j@F$xgkhf(luHd3Y4RW1NNm9ATmj!+F9R;?@pgya(aL%e_3f1JVroED z!I2vOLsT{FbemVZ=TiwBAL#jWIcrtEg05c6Lxz&|z~srIRo~MYmoDP64sXu-EI%2d zd2_mT1b@)oyhHxa`Xg(?b;wB@=D!$x6!PE4reKQjtdlqH>3$0wlLMG2ckzQsDcFK$_60Lm%5 zHI6)c#2kIiy4>TSP^rg!TNbZ`J)lef`~)Y8d9JjZfBy&--Qt8$ z2Vr5(sV_q8@%{($DBYY8b74ue@ll`Dd?H;(3sL4#EuToF!JLIsdRP0vQ64#VMDmUU zbh;|4`JmWP3#&b3-+#tV{6Rn%kpEgw#%R8QSh{zGnr7<#=I4IeZ*}gc=(o$-M6y|D z0VBb?VK^XPS*CBsd?L24^I%PMYZPjsn0rz)ct`vmhW446w@vF?%v}G4aNg~T3hoCr zmZREln&;US4x|}TD-5d)=Wb{Z-}wII{cB!*k!PTDg^tD4R&mAK6$*hFc`kvIZ_HIsL9ByIqGOPYy(fa|}Xl5yjuSOyU-cQ9Cv#ZvD1 zzCO0>!FeNKt{0Ke7ebHE8t*^d!l(iLVMFlFOP}MOuFe06rDmEI_^L_6uMV?$fPJqw z^AA_jUe=_JR2lRMm3r3h1F%lORl(v36$%M}0R)w#ew2V7eAyQ zCXLdb3WvNudpk2DN}tV)S^=oL=08QqGXIUiU;5wGuW_-C{|?fNf0k8OSKnd!HHBzc zClHQLFJaKPzQ38_*P0VW^#+?6J6Dzy6(NiKU2k7fy0QaT?$6HmG9M<>D$7(X1f$W)$fozs-HFl!Rf{I3e zD8>%vhzjPtoIsAQ9`(Cje$C}TA7Hu`W}Kya#wax5e*#UdHa5#Egr7FrV?N|-LGW)B`6~sT5J7$fJArBu*~v=Wduj( zH_o@a9*qw)L_u5@RaZ`_;arJ3I+A8A=}uVeg4YCR2&iqrZQtl_%ubru;(Vg}2#may z2}&b)tML{5RhlT;kHEHW|7Y~}Q>rQ8P20CVI_1{7TdW(y(KpNpnU89+wh%)WfWj0QW z1Iuswp8NjMc!zCz5Zp1(gLPyv{JU}edOxdH*>Cj3n})i}@AR&}3pdJ4Io5{U;G%hS zE%IIqD+A9z6Z(3xNf~97(Y3JQ%-ClLUJnGaypwX}=dLBlgu@w|m#q^<+7_wPGa{6Q zrG%gI7_to#PASWCqF%;u-7oCY(6CJ#`i5bZS&754xMjLYRe)~PNCi#MZdGxw5c;S8 zJILl1;<0*`-#qBbXJX#}S=*8$TJhn)+p_(*W|em;2d|oo+TFM&1HLQ9(iXs%u2vSO zc3RW^e^hhs|4i=>9IsQ3IN=+mlB^3U8pqw*u`Vk2YdXXjF+^_7%x#l!Dzuera=+)c z$z?9XkVs?7ZE5b(vW>;EnYny-zK`$sx9|54`2PI<{Ph0i{dv5eujk8hj0D9%o>|PV zHzR#2r4hCj<*_3h`n&~0jn252A{7O{q{Z&k5G*NXk^3yN6n(*?n(h za#bAo^dp&|k?3CzUyqlhfmn^kjGnz)_?{ zz?(__44ZkNPPhZDhprVO&taooruo?T1?_Qux+nuhbo@0t5PP}ce$kdzskaz0cO^%q zc>IJWS!@V*OoL|3}yI?P`sqT^b89tJuwf*V-m}zyT#}p!tfU1y z$Fhz`$6R1GI`Qm+J6d3K^q=`UTx1H8M-%G zbWFLs@z?)grC}e2`$(w|<9SiuI+n!#$m$Kh!Tya1eh!{TOug$D3dams= zbz^O0fJDh~f%~Ry#jTB8$eh(1Bo64(6@scyWH_Kx;ozt66=M5?UE-Kl7Ls;cxSWPF zVCvyUvi@YXid4XMgouGAXiC@J4U(!Gm)VI=I9$Pd9Cy*bN@v@~rRj73ly|;Osa*Ba zh^kYmHjvz0y(DM80AHiLe+7w1*84obf-gFz>v^w*`d_QS_W=#YId>i~^Pv!@GK(6C z5mgsY4G9+w<%vEo#iWpAwVC>b2On;4Q#-_{bQRC){$668RjJ$naxCP8@GfmRS3HW; zwO|?v%~JM>>Of?AC_o`y&5&=6snPCaIjY_4=I4k7!^y8?>A(m43D?UcM1~rOVN+8@ zXmK8zH*}R$@<}OST4MeX35c+8MLe&DV_{KR}>EW-+Da-?3{o5w=Y^VM<=65F|QwPmZQhXGzTN%;l4GzTncF6_a zu|0=OGCpDP`^2RFr=AEk#g*zoh&zwd=-=Jxf^w8U&?+-=wzizW{G-@Am` z`rSH@e9(B{sC7pgwl_GZXRZ^*J$?(Qx{|+IPMy7|(c>;u8dW?=n?TJ2rOK%}Vj7AE z1u8YjUB%o;`h7i+7>Svb`$}8}*qy*21)DeV4C(C$s5Om7moqgHg`1ef6Jfd$# z-?@-F=fH@V2x|AqSCDQ1SPz@)9rOI4kveiu2}N{Je@VjVGcNA)q0b8g@?22lp{D#F zJUT|x^+{2oAAJd1b=X(~oP?UUvSI{RTe+3KEA3^SmuM0qIpDR{Fz4!=DARS~XcVKn z-ZzPiDp`pEKjmghX<<-_X@ohi$pz~$qo}gbC%ZYh;OW2WkIEP7V!BdbtUNO`G>$?E z&f2mD9U{Nn%uwY<9%pbTmo#!@+Njiy1>)%D44}Eh0YV#`L6!#>ZT}&9_?tH)BMIqH zGrq#Oy%NnGTW7P_55~Wht4VkA6}7{^o)C+%I-ZzVRcoJF@ilCa?{pK{Bv>$bl z)@~Kv5<30TOH)3Uop^JgKk~V)c-`)l$FE@(?3999GYrI?L(2&~SbfO@HA7;)F&4)i zwI~4Vx)IF30e?$muAwLnl_`rlj@jY)#?4KOoWm_?(^eAOl!}?$v_03ay@-ePGFHX; zC@+HAyLfetp8gn}eGj2bL5N_5o(h{^jXH6=_7uP&)3wk1!Ovp+x zcWsGEk{b`xcG|h#deHG0V<5)DSSEMZ z_{)sI4EFYd>!YNv!(qbaTMt&AJ|m;phsUMzWsWP-1PFlut-Ems8a@{c4QP`e;1A6v zjbTg4c~fKc{t*)UhC>|+4DLQRe`W|Op9Z8=%G;6#O#7XU>P3L{#?cJ(+OlEKwchYk zNd=)VIhuOzmZtz^Qh=q3pZXr;>82@JOUuDI-xv`(MGUxIs-`5e_cWRjmooJF*Rtwe zAUZEREd27<=RgwhZj6@elceZRX2@f zPJ=W7x>>)Ls=ZDv=<#2bOm=|q#apbWBU-v?-DN-7&DQP94b2l&Z=G7Jorf=9J71ki zhbHNnohOvpHhvur+1z+Ec`omaz{__ zulfW-W97ZTwgX4TiWk7%W}8UAUAuG>qbRAE_YZXuK;O(OXRMK3M;!~xz(djjBG2@7 zPv~|)s%U_~$ycAYUb14S=WE`G@2yo?eRjcq1N`XDa=YP#ta3+V%3cS z-rF8`8y@Kux6gwVmTY{X=y z>kFKT`eH$#5XV}X)J~10TRW}?Cu5JEn?5rVz>GATT1YiA)^}|w+WE0I_2v1~P{N#L zPSW=(<6Tj)U6522+KaHo5gm(vI8rw~jcDspZ6A}0m(|sjuD_+g`bI6*50*A+eKcPJ zNDvgi7#^s1aBNk8$3$got+@ihfMx!Y5OP}}d$Pl{-A@-I^{2{7IH8Ay#nl;@Y>BrN zZ-76s14rZ)JqXQb$E^BIN`xj8*~Q=GSYampKE0Q_A@`M|=k;YxCP+1TPamyk3-NjF zOtC^$<@ZV#^^{WAaO_Wf8%h}VINg>4UYyarIbnldkUQUE<0xCSi>*U}&i-*o(ddFX zx|n!73A-ALhj=~vgy+5H#oO^Bf4=tH`#p?>t2`^T<4yBqX`G#q{>LPxLPhy{DQRq_ z^my)HL1Ztw>X3}d3$XpfB*8Fd`vOiKx7CN1SEXzA{OANBZXT$*d~wuw;k2RLjKQ|T zn{s&m*m>rzq#}`!--4g326uzDzVw=)e1fSdZ*cvPzhv6|G1g@D*Ktm0MbZk@7jSaf#0Z*SZ4T@YC7e?t$F=rg*;X7Ruz6 z|MFVE*>Ed+3k>wk4`*#k8!Zu1$g5jnDX&JWUId7sb@4>p;!}dhZU<@c9{%wU!qEr7 z6s1i0<@3UBE5EdMa}T&>e~OMII@-mqIbN6Bl98BIO`&*!Ig z9k44)PKn+)mz;8&8y=Xdnx}KFZ0nq8A7s(|?I~TQhT70nYIY^CNB$S9x`9q6en@Ja zw*GU;(Q`v^Kc8Uww0mXQ{%m6`7Xbgfr8D~@N0j&Jy7JHuMG;g%W20y!D9dy#V1*+q z^8xQqu5Fg-MI{)Wf}u;lOA$60>q8n*Ou1_!9o{uD?Fl3KJmJ{$b917RlBLOzzLQS7 z@k)gm37i;V6mKX9jY!x|6{QIUqWPEo`|LlYNt%)tDkZ4T_5L0;(f#n6dKP|4Q}1S zhv43y|3!@ZFQ1tK#l7J98>lPasv2S0#(f}kQPNhrb?aLK*~JSY+-FjsXXgI5Zr$m= z`NQk=E^)kdOR-2pRmtd;&E6tqz`dCe(Sz!&$ce=BXMnyv-g8glj)C0@EX~hLo3;0zR|MF|5f}~4Z&+W z4->V=VlrxUVf6+Y2jGI?wx#Trx+53$R>7Ctfl;X5O$&cic8k1xoqZTIX#csAhDHot z?#W3YO!a0v+n2jcipFiq@A25FsHpV&tlx!u6W-=YUJXh!S&`5}brq9^>88=(_Wjah zIB`E!2)S0fKzLU@s|lh}@JzK*LMbl1%i(n1V3KAo@4!+(PI?o5hg~3@tkrPsKa%N2 zbYn`tlQM_{lacS#m!ZnASHtoVdx{EijO97s!_K~bgvR3fclA+_bRJ4agJf5}zas=PXkOJ^9G(}b{AdrzOZ^Wp8L zKh6;1_QpfS7Xux8U0o9$za(!?kwD_H3Y4>4Y@?&P(*?Vw+je|Gw|pgFbq%MHxt?+N zk^Skq@jdE_%H3-UW?O7|fL6DCM2{8dK*iAesAH(II)G9|R&r7P3{ko#p{xmB66LR- z>R+sCF1L^%zfodVV(10LepWQcaxPud?O=9*S8ac>M)le^w)Je!Si#AVk``m)F#Nh| zQ|^;SGOCb3iuV`Qyq+OQWWr8_9p|+xMb7CwdBDZQ*V(=m>jw`WFuh%29EWZ5Kzc$8 zmu$MO0cT`Za`_V-UR@pNkxo<@6j`(yB#&bQ;t1b2jo#APO|sJ^a-j_;^mm3Yp*mv~!<3bu!0!!p z`a5UK&(_7Yq3_sbB2F5P(mlNd_lRML6}oIBd_8P2TK!t%WX1guLAR}p8)H5mLrysA zu=>E#f5mibuIA45iI#-J*`=t%_xYbOq%3M>R6~>?pR@A^iv%u7PdtC!%R-ccwuD4` zbR5?BTq*~t?Y776ViEhD>-tHKf=(QCIwW$4RAEySJE{1*pLaG+_EmZdzojSt)u^*N zT)b!cEb#2W-^4qwwvtF)M7wL#wCEM=d59aK+Sb#X;k>>X&Krr-Fy|k9PqQZ$La<){8kL0I|V?TPqa^u(KH8)ZE^cyr`65J zbqPRgV(RWzlUvf@Le`7I;z)Dc-I&V`WJ1m1EjD6&K$=83W~E0jOJbN1NJ2qsKs*`y zIk9sq_^@E_=nzCZFv6c9O-|rQ^=I3fN75Fb4`-zkOb{ zEZwo&lY$^80MPc$s#Jw35U?(VO}0sSFHI~dYc+voPTozv&XgUJBQk_8X<5NZ%t6Ok zb+Ku{qlJXL?ZXu|h>dsC#`KZvpJTE1XbkkSn%+^Q{aY;H=2VldyRQl;3|H9gehfGL zHtYbCUjMNXtb%yh9;D`0z-v8zG#MNtN`VUO%v*QGZ-P}PMHpr7IF`(6u9YZv_dKnQ z^5kJH-+Otr7Ux?x(Tw72In9B!#3by}rY17C2`w4(_9hIuT4!_IJcSRKq;^+0aj&;! zi6J*(gu_(KZL*|*V{w1q-R=R=O&5|8fPZ%Nh9}^TdqEIgEP&;y<@aX?+Oju`gBG8*}*+(qE_ulPE-G+j4MGO_mi z5$kc#a36F0K-%VxuSaJ(=)}tOvG-`A9V?^})M93%J#L-KKbKxHkF3_7WWse)RP(duindo-Mg^3c7+n)ald#Wi=RO2(S zeSiy<#atZv{P$z--17F(2K#K($DF-NjHh?gvsCq!R_I8nZY7;Jw|GTJF`f~Gafo^@TZBgeidx&Pf8Qz z$VPn?4w{DyVa|0P!lklKU|0+HXW=Vg;qFAy$GoU{(IepQrF2>)uyRIkopIOQ;I`aI z*^ojI!rvj=vK66_JKfSW3f}Se++2h!a>7BFu3+I}p(IB(TUn72acv#M5mIOR%*Pvb z=8>MuKJy2dOKH8d;WiUeRe5Ou-@!HdI=6S(e=E!uF{(cndaj`U3A0-+e}+)EgS%n# zMr*Fqx6m}b(!=6fb5b-kG=`}(yq=DoZ0A_2Nr_1KH)&rA+cyo$-;ZYB(D`piwCo$j zJ_28Bj>T;j44oLiTm@Z({+6o*$b3m_Ll!oDYhz@6>VH7gy7>g{S}*M)7irU!|Mqdxf&YSEXlhChiiR% zkVjwXtHdwYxR88$!F8#?9}*I|4(OQQzq-`JQg@ew6erju3acAqqHAOEZ0WKO3Bzqu z!Vg5b%<7MKo`_*hR>P56y%+d(9T&vf?Lv!qs>_K!ZaExkXAxQEc^y{X{AyoZ_+~rL zxu0&hHLA_rwMo;DV}w4IE?q`^y0W@fj!?DyAWO>UK0}q!Yi3DQv8nM}-b(u>z<~=@K=bD&90oq~|>zVMvGpj2XJ8Iu2uXw^%j%0%E5DYHx|T z`%RUq`Y0xE%K1~6U1gh)Dp5h9xo@Xba1pYIWFOLNpr+ zXTz>e>zwRN+OU)WH6W6pF!CPRuNaA{<@HxC2@{-C zlpE}{T5Q@GdMkha@Gn{#f7s|?En-u^))JaNaiY8=u8Rx@%RAIAgy*vCcg2=&gbQCS4LWF?~SaO|x(b@s*fH?TfoVZ#S>C9uI}9 zv~v{q6uK@@2!+nuh)#&=0zHjsMuH>TvXJE!?xk5AORaL2b+g?rOOLUk&r|G%Grqxd zGhN~E5~E0)nM4n%5wz0<%)>BJlxO}K)jeLWQ6uY)0z-Tb)Y-h*)myfmDdgGy#0;-w zTWjG2Fvr+$1UO7-@yi`k%ZO$OYi0*PVn#pT-uZCs&NVts!Ij%#YCW?#*UwZ747s8y zwYcJYFE>Mwsva=f;GP|7gDpW|n+0CZD5}T}i*r6;(jfwwRH+9AHQ79PAPTfhb!z5% zy(k$rv1gU%MR^<`ZUZD~be>~j35mwQIUm&eK1+)}Ov||VO7E$pGN-CKBZor?$sI!) z35G~=o ze|%I*pu*#0dpyDI=fsX{%+H985JIERXq;d;QR-GD!rLps*R55x*>s}oFcf@`_6B_D z{(XIIUNgg`?G~ZHPl3y8$4=1*fd0&#CgQd?bEi~S_-Q~=YwexjHX;Ug^PP}Le%x`v zYmm;MlN8Woho8yjo!@<=_a6qH610DGouI7M4NZrY33f|>noZI5bCjD+Glpjty39@` zW5D+SBM)9oqAyXA=A4i@Q&LG2`?0sTX{0`%FQ8_rN_RN4=Hfkdo{vVzZw;a=lAX~2 zKsaK8#+9Ic#Yla@=$Q#r*lPIQN=`a|d~Wio za~RDOSUd06h-qN0&&BhU5Wm^paj(x5#05{8Nde-UY!pk#{QB=?jcXO-M?o;l6pyyn z=`N^e2EzuV#mM%eH9i+UZCrZeb@2t2(Y9GQX|WkmLHV3DCx#Q3ylkQK7NK_Ra(c1- zIZ??cd3zj}3*$Fgg8%!erI9nu1}@(%B1{n2Lss#72#b$fFU$FXil_j|JAH5_jO^4K zvkx0igK3BPX;F%Lz_cKIWAQ5l?t81$oT|%o(pQ>Za}#+ngi`J)nmj%C|e zJFaym9J%La@J@b?MraZZq`npC;k(mV9zVF^Q*Rg_LPe+ONs_Uj^9=W_9Q0p?kJ9eS zCP^Q{pIu1%Gt7Xb6}$P9^B(EqGi({9u4V&rzD!q$MFrt< z=(=h&TLA0Shs=Z)(CJOAx9h=&Ro=N%SNJD$y>q`r@Gk4nm^h9B*&jR$_ufz2;C!IS zNj5Eq`Ca}Y-|v&L;^T_XwQj__^uvOv{h7KKusWcjV3Oyal)`r#h%rgPj)~}~R_BTJ z;zkfRLqOHcV659$z_*0YBjXL8LSf2{e7zv>D@nmRb8H`xp-+As*b|V0d#tP&4t_}%;SF}IvX58xG%q696mc^xwvs4<3kv#u-=hAb zviZ-Tg^O^w5ce<;$^;+q=b*D5&>xfF$myl(W z8`r_W^AXBzP}P#*D~i9Vu8y@u$-nEjNkvFK)8D5nzWo0w`Tl=(-G4cI+xC*VcdL=F zaWTaDiRp~ykTOkb-t*1=y;*Q)6*z$B1ylTr(vKC8-Cl0#8?B>xfR12Ke(g+ZoNE{IDlu)kF-4cvtOcbYV2t=^OS=06o2N$K(UeYGdoWHk`Wz2+&AR7FL%DD^DzJPd+yvn zx_rK%+rVtc;CU#KrxU@c62Yl)br{Womrd2{`5H}~s9~+TSt*qT@%waZATdv@Mnraz zABo_Hn+3bW;pekqVYL`IA`R{+yLE|9*v$V2ALE3}AWA|)q z+9f;NtCPrqGkyR>kBi0lGv91_t*;5puS@E^*Y~7$Avp4h^D0M_A=G}Hi4q1vT9%N`BTHJbtvt=tZ|Ed|BIh& zpY-S?xfBS?kC8()y0w||#lN=7L6)c&lgbJHoWh1G22i*&&IM?+Tkb7-hIxUJzHfPbh&R|5e>(BZev3z3Y*s1 z!L&m}6m$Dsq(%-+5Kr6Wyo1D+igC_EqHTt_-n9=%+B&ali04A$Ur%@jP5T65f2@L9 zE1QLopf}JaV78|C+%$~6kWU;Q*Y95O-Nh+eg@Lmxo%R-bXYbDEmiy(@Sf_?Rxz?WQ z>i{@v+t;i(KoBARrVT*78~1VMgwhi}4ihc3vT0=~9tHs~_NP6~d%+bg9*i$G5UH52 zj^mATwn3{i&?}W-VO>6KbOpyZT`k2ZKjSB9mElDu5hVt}x>`VmhUm7<<}5OKJHzg} zrpzwKgFl!u$u}dbF?RYC6sDP4ROUL~4Q;5Q6A5@|crf*J=q{rLKp;2sdFhu0?!zP0 zA6*lr+hjgp34wv(GwkJIJg+Z3fL1Yl%zlc?nHZ;`Ud!350ds2~T6DdANGW<0+mjtN zW@!}rS-{YcBdo45|J%a;j9HwgfR9BUct^_A!B?Lgj&8Kc6s!JWJrlkzZ{L2u%A0vG z^Oyc365E=uy~AYUUtx@cKxv!R2!j9*--y8ibV@tIl<8MkFg>arsf+#NQE0=#Em$J& zNK9pt@KL(CPqiHKaaTO8>RDfaetVIk!-kQrc{!nBpza)-xdGmnMR=hNe10T9;>$Pc z-C2>o#=sEwfvZNlkeE83?!W%zPkem%WJw3j;Mc^k}Q8|&jK?77ffj18(swsG*S-eD~hbN?QpQT=d3SC8jplfT`^$Sm(rKSC$5tLR}yU; zn{Z!;2MiZM7ukft@d9&!O>g6Lk!`slp1GQZuh?yqN44(?`mnsYW@VA-SDD7Z} zRrVq9Zl1G1Pru?zK`VHmF?ut%c}ix?=B=ebWyhQ0TizWLn_|KEVqXWQ8gGjC>FG_Z z=GQA-ubyFP>;(SfX2a@4yw;|n9VacetLN+agsi5=4{NlQ739bGQ$-(5O*l~kr1}pT z>UuUz^IM?5+g*zppsy;bdNgQ#E8>#7_BllXvwU!peGc z1zz3lJYDT$z8+mH`S0Xn?(n*%5C(Q$qS(}@<3+bwt`QCFY@+2y_g7wydw4%!ie9*L zx-py@hTu%U&dbOyAAiVeD`{Gt%xNV0nN3QYt953V0Q1B#(agS2^5X-o?E6A-8JB?x zc~h3Jmhr5=06qRRSl`t+zICT(8FYHFGt4pmE8X6SL>pZ@*Hw^Rfe-?QWJ^?(ePYUC zVKW^{?BAb)kaOqQNOpJ{Z0_S3orl_Pm)gj>n+3gnJ1u~^^N3`o5%OMfnoLER2;4L{ z+8!BZjIvQ3DZ34QNGnb7o=rD%TFe`|WLDTkep`3obAZhR(?%Snujr;-DRKwDDib*& z?fXR3T&2D&Xl%a=+?jIy+NO8!<=Jy|U+x`lId6T5;OilBIYYvD>aEf*Xv51k)$r(u z^}x=cJW}LzrGFvo;ix-{H$ZUE^3G0*Unc=}Oy4M;X>^S=%?KSQEHiKTp7u>kN6uWR zxU-i{v~O#s70iEHGE}0hjYhJTn;8JPGqqX(+S9Q#pJ23_#?!nmc`@mC_FiMkayCZy z*kGjweNc*A({x%|z?+h?9b0!s-zro+@l_bc!Q zIj2=AFpVPx6fP&I+h?5S+BFB$f;$;qH>^k?kGm`L-@jOl{0vEwsv^b+nFyNG5HF~_ zEhE`^d*NRl391C1XACVDH`ej6HrsYz8MH;14lVbvwP!_`^t%jvE|gREbNd}_G2+2z zLGcZ`l#spK&x82fZ9=(hVk&C6gGnJpBSZ(kiF{n{W4dajX!n!_L_ZDR30+bgzSFaB zwDjjw8{Vgk;WCj#zQYC4(U2u5{J^yXj1hAC{>&&e6&YBGJb37-KAab#Z8I|$2Bfen zqS4F3UYpZAtq9p#x;zB|W!BnLAJTyT)DXU;+_I6Q4fhNr@<3pZN zo&!=Qecphj4wyIe4P4GfA0xRjcf8J3@;0O8)K!yd&-~aGc#1A`r$bJ-qBRAQ!had3 zcJQM^PSb01Ct(5;i=z)IX;9t0Ka$Zu*c9?#NIV@)2i8T_ih@B>M`<9U3p(ub%QT7ad*uJa*()1ilEcq-Y>eLKr@$OTp2~Qu7GA)!H-Q4 zdI#d!^l6SzuVJ40)R-~aXDlt%cnB{LQQQTYU14~Q{SgCBhAPA@%GNa zZzN-(6*O?l(XQLDgc!M}Gu793^o{~rrkI!Kyr;ls2|rKZM;*KkAt^_W(ec7WW)(S6 zRotwZIVKe|UD?GV+h(O-5btCT^mzAcF@p`2)UOt>z@b4g*7CLDYYnbr6}`L*)4*JZT$X{zDhK<9dL^564Igi}ePp zt`eq!%48EdFc>pgv&sV7-3SfwhSQJj-?pDTF?3uEtkAAlU6h`3aO|+Pd>(HIBUF8l z4QYYjnb-04&U`=L&QSbEs)r}O9FzWP$yBcu;jjPSA?DRM>rp z0{07*Hco}k?O_v2F%1_e!C>1({>8J}q5dxR*mi4sTymkk{t2Y8RYAbtta9PU|??Pqhg z#N9jpp}xNGnpO1J2YF`{?^!$&6@1!Dx40kPe4=H8d?GKl??3%yAY(w5Z&&th?z2ZF zle-CcPk*MrbgFxD>Ew->g~d^>dtZH&bI}Jp2(0d6%j#u-Ok0U0Nm>?;>`TsaYSH_= zNrs=%#01g?!OJ$k8XfMly>~S1CCL69P{1|EQ@!W$iU_rw-}c)j0P(xc+ZzV5rC$q~ zhnHVAF4gS_XK-IHC2n!xU!}3UF__~aNEx*c>)gCv42#*J6=LTBP)A03DJO^d^}=A@efHU(*~p-ICt9=cgeL-YH{5GVWkdTyoJTjU#ci4;wP!DJ8r znO-GHj*cjn=|V9aQ-=DQT@qy7(exsWaPUxQ3yc<}Ti(d@*3k?*Pqukc(t^(`QSxEy z#au=y1FvnW;G~d+d`qM^tzH!Zf814F6S9xQWlU_rA$8k`7m@05xlqdV*0}&_a?cmXHw8h5(5_> zb42g#kF=$|+9mNLGX1mI$+#Yes>Vf?z?Zv_yJYwZ*V5M-FdHRb8!i2rNplt7q+z== z;!&(0`vkwU9!T~NH!AH4QfN=49C(nAe;c#;AgK`xvfV~!s8s1-CxF4u#7E`~EI^7q zja#HhBcah7j5BQ&=@{o~`+ z7Rxe8+Zg%x1?=<=&IPjhC{*}5C<3~c^9%?`#sIL@al0y!07$6}jrXo2X50*$ZLzc| z2$&*sL_1o*vi9$5Fg}NGn}xZWc{XY;X9kZ+H;;Z_HczrMniuFgb!g8Mr5uS;1wB0k z^ZBytyWY@bR4JHY^|c>VR&l}5UU{%pclKvy2&FB-2!wpdtVUzA?gtA(_~(1G_kmzJ zUn^0mo&^A;J){iBQne$xx?C@uWozVjZmSYR#!tDI<@COQ_2x3|2&IWmti8Ce&a3cC z>s=0lZ|Xx4sC<`$2S^osC@w!mbPqGv)w`koH8cTuTiA36bUWEPK(??xpytN+Ibe<^9yvGg-t}?nxQp;9fhp$!<<_0OnTx zNNbvamSly(*l5J3eg9PcuqQdl&2EG8jKn1sl<>#sL(6~UD(HS!6PD7>1=-6$c(xyg@0*7a@&ut}lm;mK7-`S)L`uBssRf+mX zrW8H9yS~4IlmuUxZ0}9RcCF>4O(_z*-`6uWBR*M8SRu3X^Q^)R zc1;sNoTYVl(HlkQZeIlfX9Dpv0N3r5tlYxE0PUhY#$O1=pDQ}8^9I9{tncqV>Xvfl z5uq{co8S~9Kf6p)1iwLkPCtCKj^jZCgm2VXkhsz?A2CS2I(M zXo^@!b@DQ1O`RLJcWw5Yvf1rpjHBSN!n3|+e?;vA2 zm#R5-vMyo;>t10VqqLvm{6y7MQlGQbZdNSrL$uQ^@Sx%9eT!`^>V-FRgLc z3=+098i*Ta{z57i068kt4?6l-&a{Rz>^NM0dXVk^();`A_>^2y{Em}hLRqcVBrJGm zW$%NSS{l^zr`PVU!5yWYa-TON!AKm=JG*<;Brf$W{_-uMaWUI%)MhJZD6wvUUQnLx zmH1urax&bh@pRqvU4#`>S5ne+Ir@YM+@!T_5!P5d09Erj zA8y+DY}bAYEhZ^?DBC~5bSC^Uc^u(O15^;*?INuo811bg)c%yuS1<6e0JJq3XrdYV zDtL(e&;wSoKeLu#Pr5b^GLKL`6GyY%NKL9|oV^6?bz5zJsrGCd2h2oyQol8JXexj) z2r5|?DdjTN3jd4(S*G0C&hXfdMZPoQ8WT)qFUIEq-o;50UV~?B?Qc*ys*YW0;-;J8 zsKIo0*%(gK6{dEa-ow|{fbSll(7)lZ^^iQ^r@^QT?Duv;9VCK`A?{)9Sa3DjX@iXc zETkU**$()f|2D2aNm{5F%9XAqjc;}Po`xO6g!zqBz#i<&-X0UA{w?q|VE+}h{B%p? zt0-gPj8(LmhwdzTble!vHbqrUqb>+05nz1FMZ3l)GuHlbBz3m`=nrEWxvcxu#*M2){a@Xfva>T~3Dm6YAcM+JPj5W|g)dw3i; zDPp~az=x$ZhpC%K zgYo}Xa>gALtt`^(J@}9+PuyL)b|Aj-=BY9cREK*TaPOywQhT@inb6}d6P3PPFzvzcL|3#7c$IJX*hP41ramoKD%*%h44` zr!>n_lQd^jj*J>Y-F&l6f9*ZuPSc__A%*DVwx(ti z7|VLsFEWTGvG3 zCM~AN^B`Yu0H;s>Uep)rzEfe@G@_~aIOZkB#G$HclsC{06F)*(Y=a}fRZX(xa<$?Y zDSzaUm>?mwGCJFZ_W=g%jtzu~m8*pzqR6TRw z2>kX#PBBgHDG``jhIc?We{x2C$K&XM#W4EKoAwcfc${Bgy%<;g_Nd)e3^UpMG3VcX zW&DU(T`%%>cAc@E+xWq*L~Rb>5tdwS$H2XBMnqTfICBUVGS*&DYtU%i-6HT*zeGzo ziMv^^yUi(`ty#zD(20QqX$C|f~E@<60WaISX+}0{foTK&I$O zPy_BxZkcV3JB#i=pIZNxB<5~r?vR=ZX4yMbD1H@bXZnK5=A&FWg`KC`44zFF=Y~|2 z<5_;ayJz({n>$gZz0_Uo=Mi!uQZ5H-l+nW1qsxPx&$c^-D}Dy?riAMuHg)Nmsv}yD zOG%`8oSstub!Wpu4Hvb-TEZxnUi08?3xZ}-9Q40IOgI&`n{mH19K{J++usvRxr_RQ zENj)GHVdJpA6h3aQRx33ivEEv#P1MQ8Xx_Ye?%d}Q7tL?!FGk6ClWOJ%qI}B&|j!+GT z&ro%IahOc94zM5T_%iJ^=wf?Vdeu2h04(ON(lOEi^48MPp6qk9*)rsQJvWi$$>V>$D}l^$t~1wDMoZp$|P8CuNM$1M1I zggyW6=t{)}3#V=6JLD){s+ggTzA~O+=3bnEF@WEX)u>ohj2Z}_vyc6Q=no*?u=$i zGgIUL&T?n#_0hj{>rnkb_&AB{o-x3?IFe%-`#Bh}>}k%(#+F58_JNv|aRk}sRGW-r zCV%?HN~N*prmOsL`>kHHi}U+1Z`Jr7+Zu^sMmO%3J8XeZS*T=@2sUW@&-En6v|FPg z-W~G#aY?Qt_IAA*%(%?Vf0LPK%{vHqi$(qSyMu5d1;DZzd=aTdp2ju#nfr@Q+M38J zJzp}UDcNO%8^8iqEXqidpR5H~&SdN%$)^z2GY!~)$+wj5`H_Hva)Y8IsVv4u0S3XJ zEdFzfmeMJHLgNx1^!->xENS(O9XhUlvyV&vo3kcWBzzj&&LS=$Ig$FL{7vExyyqG(A0aeOp=-*qOSsif{@(M z#!`4~fW2s=#r6I?sc9Oz4Bf3$#`OlL*0u7*1pYBYcuP zIY@jKC;j8#sc9~u<1gvgJ01$edu(=RuU<-LCb;8v4H*6#v!48q%bWap?#g4XI9&4L zTN3+k)&YGB&R^5j#o)ieOaF&(Z?BZliVV$Pn$0;CTIOPE5iPYWuS`U7>5L*S3&$wp z><+cR{-OSOU-teyGqaR5of-FOj{SK`<-E$8&5KKo7oS$~maHJbN`$;&P#PCtf7i^C zGUVK&w54&jyDZR;vbw0;5EfKMKWgj!FZXlId3D~jg;MB` zQ7=p1rcoPQ{K)_Ei9`kJn^pG}u>MttKPKeZA zA;$R4$UoQ|MD6A`65)+;rwiq2_RJT0sWGn`tvRsGB#JZevgO0KjABsmts9)m?AIQJ zT25t^kqt4oAMe=>;!co}Qydq3i!i#Uc|Sm7Gvb&hq6qSk?yFv;C^RylgYUHfZt9(E z*~quqRFiUQz8Fl**{lBEq{dOqOZ=o;27<@O8^&w;v-Kq2T#+C594UEm%Lnuu*OWRp zAC^-8BJuu#6_rbp`ChGrK%&!WUwK-QL48QS9#F*o;!a#QcU7-ohlSoaI%{QykUkOm zz{)T3_bxxbt#xW1rm3L5Sy#o!AnBI;C5`5W;~t+X_8P3k(cYUn_PtOZmdTcthao)y zSz9t+{7s`WNXwlk=5@M0H^0!{sd-bXWza4o-v7M}zOo|=R{LJ@jruOMn$&0pAIkgu zarI0XsjX6saq@C~Zo6lSXp)`5+#A>_K``Y$dP-;!yWYUMkHHl~s&gNY@N7l;-u=Cd z!8PyD9p`Sm0e^A-^7Z^Dj=BjIH_STQ{}O$z4;4^gsoZ$On(t_n1bj&)OEA50*9@4- zj&=-ZA zTHs>%J3L?e=BuNYk=`6^EmTd~<3u-uNgg+*JRNB_$bIw{nI7%?Q3jz1G1=VAKkqt= z?h9L;{dt2qlRrNGT>pXsJ3S>#5LyxmeBJj-?QaLr=e{@Lq7i45RgzI5Q<4yE5}y25 zkM5#s!IyuJB!van_HQezh}KJHtM2w`F_di2KghTLEF87D=c`Ir@uV=PK>W|XyqNHn zLg>}U6x?I_Ab+yzD&+KEj;K|irG!y`_V!cDS-lQJWhLDH2Lq}jxB}p&k4Uwgp}%Y5 z{MY}kk^ik@{Ocn4j;j%CYHA)+{~9xIa7(e->8P}9+PSGu9m!80c7`WJzPWuW<+)Vh z|Jf4u8}DY-N-{M;JNYc0Eg0N-mgLF@L4lXLmmr%R+g2Oxn5M9VjGvlKwzvg-$!a5n5L?g=a2MW0X?d+le|oX* zk1e}Leh~37haJk*$76-# zr?&8MgMCy5>ckWl=QCW+D?_$dC!E6daJYL{l2j zx~^9tOGvfuY&@V!7VbL74qx|*aWOo^2?awBNfTqMPDLEzT68Kolu|ifCn21ZIJ$Ci zZ$>Q9CyiHJN@?XIOQ}JCu$CZ2BZF#I=?wRP&?E6VltUz8@M~md^&-v=kY>VEcUST@ z0kVP%FS9~IHm_qgtNV4|KX#g>tIkzWe9B^|g$9e%$H;;yz{ z{saLEpuU?N$8@v~MFW#Y%XIZPdrAAen`Gl2&K5)jE%x%4q@({?1Mrav#Q9j8kxVrZ zb@F#jCQl-&>ZMYpzkYSS({4wJ^0bL&+#5ElYW>4RpPcV7s9jT@G;MkgvSsA|X$G5Q z=k$^GN^}TR+k6d>dCj2qb!f`4kru@@{fe1=Krn8y<@qbPUu>t)*)?&1h54V3v7BQC zk!R)r(C|7yCPDnPqNR*HzrLqa>Xlyc9nOcDW=m7|!HX(`e^d+O#nm87c| z69FU3?`;NRrNuN0=@Yc{jN_kzmKM6Zaz6&Pbq^(QoK4T;ga#V}>|Bf+=`&$iPUmr8 z@U=H`+4I0t@aKp+Z=vC)<05ka&U?v6L=2hB2lY=D+zzS*4=ebbgCl;{EOvN0meRZ} z)UR9Gr>X~$Q9jNStdAFNZzOvV!`9hV-s?qbW+dlGY<5X{&I6uiT|ts)1>$u~Yi*mq zPHyn7WY{J<7tws;ifYPUP%?EZYw}Gc40NOOD-}Y0d*9I2Pzl;UR%ZHqLWs+5;>&}P zBqv|Kmas@_&`8$*cca1IZm*$|L!HSjQSkUPXg^EtvnLzH0}+uX)#)&+^(yAZWSl{T zG^dg1^*ck)jJvx`Ml+4uHB;F!=(m;QK(|J3!IKjza-O5n zF?3TUhym=xO{W*o@<5jRymz}b62V{lQ$hea|ZqrPYDbPxOlPX15 zB0ptk`cA}Wu70nHPcewqYhWIjjSIi$Hal)qfnf|9esXCMW)nulPUl$A2!j{9nS5|D%KT2(A?IrEY%%DbN0e RTgHD&L', msg_size) + frame_data) + except ConnectionResetError: + self.__connections.remove(client_conn) + print(f"Connection to {address[0]}:{address[1]} lost!") + client_conn.close() + if cv2.waitKey(1) == ord(self.__quit_key): connection.close() self.__used_slots -= 1 break - class StreamingClient: """ Abstract class for the generic streaming client. @@ -221,7 +230,7 @@ class StreamingClient: start_stream : starts the client stream in a new thread """ - def __init__(self, host, port): + def __init__(self, host, port, quit_key='q'): """ Creates a new instance of StreamingClient. @@ -237,7 +246,9 @@ def __init__(self, host, port): self.__port = port self._configure() self.__running = False + self.__quit_key = quit_key self.__client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + def _configure(self): """ @@ -262,6 +273,47 @@ def _cleanup(self): """ cv2.destroyAllWindows() + + def __receive_frames(self): + """ + Receives and displays the video frames. + """ + self.__client_socket.connect((self.__host, self.__port)) + while self.__running: + payload_size = struct.calcsize(">L") + data = b"" + + while self.__running: + while len(data) < payload_size: + received = self.__client_socket.recv(4096) + if received == b"": + break + data += received + + if len(data) < payload_size: + break + + packed_msg_size = data[:payload_size] + data = data[payload_size:] + + msg_size = struct.unpack(">L", packed_msg_size)[0] + + while len(data) < msg_size: + data += self.__client_socket.recv(4096) + + frame_data = data[:msg_size] + data = data[msg_size:] + + # Decode and display the frame + frame = pickle.loads(frame_data, fix_imports=True, encoding="bytes") + frame = cv2.imdecode(frame, cv2.IMREAD_COLOR) + + cv2.imshow("Video Stream", frame) + if cv2.waitKey(1) == ord(self.__quit_key): + break + + self.stop_stream() + def __client_streaming(self): """ Main method for streaming the client data. @@ -284,18 +336,30 @@ def __client_streaming(self): self._cleanup() - def start_stream(self): + + def start_stream(self, mode): """ Starts client stream if it is not already running. + Parameters + ---------- + mode : str + The mode of operation: 'send' or 'receive'. """ if self.__running: print("Client is already streaming!") else: self.__running = True - client_thread = threading.Thread(target=self.__client_streaming) + if mode.lower() == 'send': + client_thread = threading.Thread(target=self.__client_streaming) + elif mode == 'receive': + client_thread = threading.Thread(target=self.__receive_frames) + else: + raise ValueError("Invalid mode. Must be 'send' or 'receive'.") + client_thread.start() + def stop_stream(self): """ Stops client stream if running