From 298b9b4e7bd358396b36f4fca65b192eda8b362b Mon Sep 17 00:00:00 2001 From: Victor Lange Date: Wed, 12 Nov 2025 13:30:27 +0100 Subject: [PATCH] Reboot & Auto Feature Changed: - Defaults to close the app instead of reboot - Green Background on success is back! Added: - /reboot switch to reboot instead of close - /auto switch to automatically reboot/close the app on success --- dist/ap.exe | Bin 608768 -> 611840 bytes source/AutopilotManager.Client/Program.cs | 16 +- .../QrCodeForm.Designer.cs | 18 ++ source/AutopilotManager.Client/QrCodeForm.cs | 267 ++++++++++++++++-- 4 files changed, 283 insertions(+), 18 deletions(-) diff --git a/dist/ap.exe b/dist/ap.exe index 75ba5dd503c35633d0a0a50bcac2ad9115f0bd32..2fc3944f52a0b61b5967b9241eeeac3771ae3617 100644 GIT binary patch delta 29829 zcmcJ237k~L)o3E| z&J2DCDjIBc0-8j`M2Ra=f_u=2pBfZ-u0$EdsF5g%Mw5UGy#J|tdmAO+_ulWl);@K% zI(6z))v3Bm4_&uZcHLk3lMR8AG0wfr{CvU6m{T0c*m;|OzSVY1yTXR`HjPuxOsp1y zj;T`=#v;%>FR@jq6Q(6z5XJ_teqCmvEsP1^*D@x(xQeld=g5g>p~+ID#vhp}ek{6X zLQoldim~O|jKp}`nX19a6NmwsR?3(|?35U@iXDdROfE~@Yr8<0nK)?+2s07^X-K&t zED$p*_OXtI)PULuE848YQfX|(g?oS>bFe@5?-Sn#uU3jWeE<8|r3f)&yP|I}V}O8z|O>qTyJ+ zlyX-3e;>hzdtz|3WOZLXg9*g*e!i3%MbQ+94?*$vzjEPjDA;E?IX$0^nO6DK`| z`psNkoRW`Il5JhhC83lgo|4Rk#OTwL#6xRl=Sv(}WEiB{hJny7CvXKoYyk22bmi4_ zieIc>y$iF=^pif4EiHCtwRwLwS?|h{?#d=dx%DjZyY4JO8SwzQpw0yt=91ojfV2BfxJ68eu*Ms*<`4 z96o`hT7$jDm-tC;vEENwmt#opM&O zr>>$-VIewVXZjP5ddphIKtt;UL(x_PhMk+BCsYPvb0N5^GPpK^Chn>%h*|Q8E|l)7 zEQ(cfyx5e5VlA95fvhyPgX3XEzN<3qh&_~-INdk2b{Cjlt9CkC$mk%Mt`Bf4st!?u zV{IhS>pM%>k~rjBSsm!2brR^}Yl2c!7t*|yC#kM*3X3F``cDf`ARJP#s)|X$p-!=5 z9n|CHiO2lWigJi#?OHIzPQpVS8-QyYQ;gW*yu|nZ=yb9ndTnv!9;;}?)F!HSgzeB@ zumr_U68LT68Y)lZWAuu}{7Q#02sZU580`27fVvr=GPWTT)zs4RQ+uJ)Md9JWX|M;Jhiu#h>VVR59mEJ# zD8IyXT8dXfU^*>{s!UGr$4nDDN#K{nHB_F+KO2Lac3M(Bm`UPxEBVr#ffKv zL-g~4YutLLCjG7)PeY&^?wwI$}WV*TJJUd$SpA4tXsetnhy;( zj4_1gCWQw197w(Yw)85P=_rap-iNw?QDazPG6)8LEv#GXF#)Ng^-_?h^g~};5Ea_a zN4$$LL`250U=S&F2l^d*lx+MOm`fhsOD76B7AXSjKCmbyJKTzq^4FS9laOzbe9GMc zQb}hjIkvAT@teY$*{qoISXz*BIfGAD4h@EPeIBeEMXr}*W3}}8s*J`ihc<7l&m7mj z;>3`mvO1a|S_`VLbpdP0GqeLCQ~S`f=p+|u7bUujg7eoVCBvqWgnRx>lDC!)H1)Pa z|3M;}mTR2=I)NA~fyp)+GqVi`F}UNCQ*Rj$QATG!HHOB+sJJ_!AyF@H{FfxeQ2BUEDl z4voaVD@inlq9Q9zOb_LGBcXti6aGDMQgl~3R@fzv5FpRd>}7v z@g^!e9)W6nFlR~eLANo6NDbV33%naY5P>IA^r z5u$n;Q5N-4a`XvnxOi|x?8GQo>kCX-=S)zskr9M(7nFjvqQ$EImekRq;(-!-5bd)Z zp7Mto6+5X^r@(R}_8B6y-KfAh4oQ0qxTHM}*zp8_)2=>=!X-0#foi%+86EG@1P@gjs{`ia9;>vezVJ1P-mF$ zgpX$DY&3BHK#?_rhe5|)MmFlhMrm}+m(ejD8z^ZQ9TcUEwhWv?MRNcbll+sK10s*E zhEO@;XON#AdkCcgFoq#Q*KgXh+;`4BAz_%Mj_1J9eot(5DB_Qul%(48;24dGY<#jY zV?0YtmAxrj+6#o{nXOUtMlMBvY0Sk=V(~$*CFkQQdo+CmP3MT6G{fqnqHfHQDVQT- zCkb!3k{17e!Msu3Fc|yAzfs_(%$8$+OU|}hv!*j@PQPR%kz)8qqy{nngR_lA#hVWd z9Gcl#M2Jc1i|{7$HI}XV5|03H&@QSNIH^`tUj`Eesn!+`v|=V;;PHQ~98JeY0;qq0 zN>yLIBQ^z;#81JobtKU1Ac^e;8VCSDcTE{B)zf28DV(SM0>< zw8maX7|itJB{voRg$n!{ye z2|97h#l_*t;mO(?V1o)zCc1@_eJ-!H-i}KY#0}?K9z?qtKZ0%(z@g{`oTL5A( z*zq73zBlYedys3=Ni<9QpE%Im>Wi%CAcs24pPjSaF&k z?9Vqsl06AUm6m045o2aCKW2xIsfWNWjAOj`jiC#9nIE6U%QY7y9*z|07(ppkg9iDS z4F3Zv$3}z1?4iLm9GwS-2K$Z%)eh5{L>ACYG3NbB5i zwZW@28eB>aEragAvuM<;Z#NydlAPRyI;M5*fR$fw$2O8ZKIs~g%cPNd_o~kIY2j$3 zFLpKqjcrewGCN>c;l^u=_$sA+@MWq{q<(;+_V1#47-hlW3NaF~;8aR!BV(cj)DKC! zSp5@eiv^Kf?fgnEMZ{D~uFZXM?~ zM|?C|6FWX7bW9qh;Sf8H5O*v`|3c_Ej`C{QvXa%#N~06f=)^R7b{d_QMkgT#NfYO! zQJx$Pe|SbTP@V=2bZT0cCcNq8^fZ@pq1X|@0*h1hP1M*Yskho^=!@7nmfAOQ>X`O9 zXH&;aF4;6t)u=+XgW6H9N4WY|pnQ55#}$66$T(6IYJW@V7HD6jaP3Q=1v*mZ*<(BY zPBy**s4|Qg!c)k;<~C@c0s-wGoZwwD_%v#Pf*#SSo>$n2{T=5|4MOU-_n9UmZFQa<0)MG2Jv?kpr6Z|JH7>~eFuEkBg?%MaT3)V>k&fOdl86xRanWD3t5Yq8Ui;))lw2#=MNv*qyri{=gi zOifHlR149#({5^pCxvtQR%XVA*B+pwx)~f|1OkEL4%~BcXi}3m&Ccu7WC)s_G4S-n<@r`eUya_7IN6)=&A|?tyfC^$qRj3P9iAIG zS3sJ56Aqa@B6gqzGk|wMNjVVPl5tpjICTZdqn)8IRb>o{wv)hqEkH@ON7Jh z5)sMqAzX9tMrp-sPL5`9Y4K-pBM%GMD)c)5Gdn>QVsk1|qe66KDU`yqGDm>e1*X50 zI7&^A2#;)LP`^0SDzO8BaCug2h^fb}OSi=r=TSgHMS+ zm4q_*vRdSB8yx{OXq`rbCldHGM5C+m*m1EJh?>>o=h@UN-{d8u9;;> zmYHRUE=0&OG7PW&VLGrxhgXD4GnWeSlDU!V|DE)W+(^?k=@#L|nr>`eL}dAuc8f%r zZV_D=K0VVdUi+K0TSWJFi+ITd$Ms7q$t`35q2-eFi|}N)2tS2eB+7J)=tAVEjA-%N zBd8f;_a(Z&TRJh5iHuj6#{J^k46W9rTZAXwB0T9RBf2o$k?9z( zKbJdZ^q(00J>&Jv>BKAaWIHCFkjCJ6XWUxJT+Ja2yh-a=;qx~4GO05x|S9 zTzPdo9869?t}{67&hSO&_eqM)K=BG=(!TI)Zu&xaGERh_!Y>kK`b9MS%380y`ZVsB zG5?4W!P$XjrxId^OxJjw4A=OEV!B3n(lx?Q;TnlDT_akDZ&{0$*I%2C8PPxD8nH`E z*Lal-*Z7uZx<+`?HNyM5rklx^WSPDZ4cD@kEwBIcv};8Fh-<_yHC^LXGF;=ks_7cx z#kzUzKtzAvOxH-1=^D}D_zzYkx3Dkm9nnAH9k1;)-J44HB4Zi;@!j3@kMLyZ2tS2; zB+7J;Xt?)Kzjetie4TcWXt;;@m%TQ5b;b0LSITgYF1RwLXz`_hH4dCDbj zq2}W`kmHg2FvT;I#dO~P((2R-CADyCctXYs?Id1ufs*xPqlBw|$_RKP3>P^>$IgK* z92$O*yts146%oVw|0^vc~ z(cxyEO9zKn{$X&4og8~!C1dOjnGqbq5rq+{-tu{1JPQFIS5;ZjG1YOMXR>*4FtzuL z0hrd@fxtV|5JfDgmQWE0j}5QPm`NEog3NnB{q8=fc-2nFt!m?<6{i++;RdxZ*;6Bc z#tj7H#-tc~57AKhVJ@gfNhkLA)J!mMYoaT74rKVOmXQvBh!)VwQ@B>aQFP53&`myF zRBDx+Pv`igI^m`|rGX@yaDyFCxm}e^*3uIaD~s3|%cCbGowJ~Z_UYcYQyP8;#$5`Y zf!ieX`ou+G+B=6J|5@vO_D-I?t5kE<*5#U<5lN1{a}YH7UGL!@3oHcVv%wHM2{v3- z4%_%tj8P*rELHG^KRtK(MC0N4Xfc3?=j4zm$1kR0%>{tIaiXZY=;66$h0#uuxWqM7 zWIQ{kYB1CT({}!V*3KWs*gKmb(3U20h6VK>noe4_{Ld^KU7=VECaWrqMSyqGp1$oL zn~#8)k1dKb`TFvdVED&~1meRZ90;!r59X7yZ0nZ7(JG=S8QyF2fyQo2RjVIj?>rqX zH`LpW2Ziv276E@!!gFa|naLTMeBMXn#C1mMNtVF~gy)3S^jfg<&B1tZWJSjeTC3sc zX=tS0&hPBkHJ-w^fa#mZ-gzdeOLlb#?+NXY^w>go#OOhZ5t@40-Z>P4hAT2dL=Rf} z$tP#Z)AdL6et+_0rYK!?#F}gopOGV$e6LdlK5(_XQ{iJulE{v`1)ITlVlJfs+5(i2rbe zQ{$OEoZ+hirJ18in@%=QxASKv=8)2!dy3JpQr+0+U>VafW^yWO@UD}=nlE-zAZQMAwv@U_7J9YX-RNY0h?+M=~{ zK-89sUA(+p#l;k!_@X8kXs1Dc1-32$DxH^-Y8jqka|DdJNd`y2n3rU51dRDf21meX zNiqo0$?Ae6ha+GtOfonE#-b#HBVe>985}_r=*@Us(C|;}EqEW=B*5v)fT&{D8Sg3K z1zAyrqj>Wbue~5yOLtAEEEH9AoL-a_Rm2cTv8ZA)NO!5j(RKb#L=DVh^T5`$80|VF zr`@6!V-Bpq7Ep}5zc}Hw`4f?m9$|4}z{q?+gO*G3d95YcwR}dcC5iaRV!Nr4_yy`M zN$eU~uU`&rF(%dFCB!yDJI;h3l`%}c<>6`CNKRY?BJw19Xwuj8qaW-?@9Rgi`t14@ zX_{`WRmLt(GdTTVKU!+YHgIk~`kH?9^Zn>=`q9H0llF9@hpSQygMOkP{aru0Xh70{ zp+6&wj$ejI;-G<(hJ|fM8Nk3;Ez>RPD0FY-U3{u&qk(Js7~*UL2hX{ifk%)$S)akG_?4StN!c!(=)+F2;Hlx?S7n*fI0 zXyHY8bV6|T<=E?`#G%onX9nS3c;KcT+>1cC_zqE>NcGPK2y6{^c1!}|EGP(jJI(=C z8F|c!mL?Nw*YJSFQ7LItP*kBjk4kN7LL1ZOn+Du(^;wlw?do*k9WxSt88b*PKy!Ha zK*OAlcOg>ro0M)|=Ev!%h4<7Awu?w$NTSysk5Oqv7O$~*>EKJh zI}$rd;J1rws63I6X=J=)&xgXUwvbIp#A~ORDptJ2MTNEi+;|5u40<7GZ4rT1$~}I? zr>Kj8zz2FA+VDY%ub>)+4~nQFht?hXrAR)Iz^{mFs63I68I$3IqAnqmve-!tdQoy0 zE(6m<+tTRe!X&JSE2x4kGv<}C@jnu9uT5=-Du4Mk^LK4V9}`!PAFD5g+&DWdhXLa? zppd|H0&{z{4Ey^S22>d49eLu{t8b@HtahLS+)Y5FVmHWz1vSgujJ?cw1zon zaNKhYdkD&2o0fL*x|EBh*{$46f|MI|{W?Gw5NT;f3w6_QxXbM7V_9}GHLJ4~_nk@+ zFQZU&`>OrU?D6>&HM~yaRm2$-Oq%I^XS3vwA!t$3ahEU72FU2g5JV(j7Uq+TPp+(& zg-v!spK#Go$|R{*eJPieBbS7DE}?XW`9#^yiB!^R_KmK^%&d~vL|KK>;19A2=klq9 z^I$T?P@>F8G5-OQNyBmer%T~`QHY(y`$3|~W}1nHR+X7)((?Z{(cl+@u{m(t>`X?Y zA?N;GqA|js9wEHAS{b|TM@-?odp`yvbM=se3i!+6v*G@gpcf@~!AMaYHBuBu zFGutL#~DiRALLXY{Z6klLWhq=LVf~g8&9iSoE|wExII5IaQ#+V-Qdgx?00!xW@a&F ziC!59m;FrZpfRL8;&t(4XLfW2*bVXQHc$LWn;AoM!`;~A`c0i|0|N(TOkCV7G`Gl9 zIQvybHXu##k{Xv zlg=sW)s(4*yS}s!F)!MFFE5 zL3D{`oRunL@1lYcM7>`}%nG8tldcT3|A5c&Yk=W+6di`O$3$@r(P}42{u7wkv4+rf zhSDstlQ3}&iPShGCb|}=#xpL))8VHB)fOPSd7`4RrfjpGSMCDz;Y5{BxdI0dq;(R| ziHgdMdx`uMZs+$Bjh3}8G*sWOzri82&5%nsU}|NKvraoAt<%i#Og^PLX`3PH8(Q^$ zQ;YQ#;|Em%)7fr{h>78CHN6J+1b$G(ijB)Elao&z zv6IHz)fYi($AaWx&Etb3@{5z?PZ^6%snd!zZj4x0V*hz722tqEpEQmY8zlZS>snE} z22Rj5jfE}3+(j6?>VJZTOTqPtl~b!D*Mg`oLwef)L|uWEDW=gv_1eT!Q$uXBS>gEi0HH%V4;c#xcZjhrMklLF4)I9?~vq`NOa z`)z-_dP`#I^g6r%i9dmGEzN;|TShjz70PQj(4cC!0o8f|>g7DY^$^w}<3Bl&)t`d- zo}tjO1-L^}k+X3>r(U$zuHA^*Yp(;4R3v+F8z%A={I&r8eu51@s7p6e%UcO*TVVwb zO87Z~%`h)%w}Tg9Sk3b&^minhXAIZL(~h4(&_zCW{G2dq&%mfr-hAvA82Z>lH2%MU z3irm~9Zm75TCDCg=uHMN^f+$|@pfeM{!BdEQ2Hr9H^>#I4+V1zKn5@8bnxl`GI%SA z_seXaWf*wV0k|F}FkdVx$_k8#em$HEs&~To;9#NFTswIud=mCosbd@X+Fby(1BN7? zzIOY%hV!p&IA6e5#Mgqa6<-^^62A7`4d=@P=8Sw1mdkN;8d8Y^H(D&8xgyrKYzeOD z@I(yL+CM*|M_el)IwH7Z1` z4Nfu?vXkIVKXDEh9t~8nXy~?rB351ajU=%?=mgmD5?d(1wurXSRd_~5f4if`LH#XO zY#|T3r-=D|%wM!1>SN;r3!)yj-^u(Qw#$Ex=wqwh#Q$xC_*JFMuY1@@{}5q!InV(=~cE#a4LR4vNhz;A!E4pY&LZXv5RBwe zEBfyOonj;VQ{|iRYcI#|h_3fHvYWtZWam1F|EZsvY%L=AiTWVs%7+*~43L-bH>w{* z@IS?%tP@saIDA+P6y#?s7DS8KSpR@h4|~c%kxL+oMQlsx;d~!^EuVDe=)Cwlhar_% zn-N|g8|)-_Yx#nx#O8*M28!6fDj&ulmw5)0&c~Dj;@@jo?~~Y*5#o4xUAc^E^`LnV zn}|suvEO4LeC%`&@tKR7Ki5aikE|xnrv*9{U+~6q`P4Y0kT{=kj>2&j)qL!sFu~h> zWct2J8tGCOejLIk6jF~rRfvCM1@-cJUh6LI%3~!|>vNf49=CG_rlgO(!u4-0V>&84 zh6)nv_ESjjXD&z6utxCdXGnB$-kg z?=FnD#M}{DFBf8FNX(f_YhfdY?;t7zEOT)rk=T$N()lZg`#D^mOPo3m$8)GJ=7LDh zPhjFU55eDXPIu0um@$lv5D5yjzX`eQPbh4_MSOGFBl4w!?E4GA*JEHHB%O;id|R>vvag9TN^8hAx( zFjTowXkY`ltPHMI3bXj_=v?+iX=m8RE@6|n=C2}EaOP5W9;cRYYA&13sn!CL&12_- z(sS9U%CE|7Y%xxN)co&xgIBO+oWkP*G_jH`=M-%xm3SE|#=4++ckyP?#;#>J72>lM zd!miqz}BK0QTrgkRra$07uhEPPO(n`9BL;Au9a#9fz|jcM1kF}%T#og&%+{epd@hGY`NSEQN3hvJ z@G`FdsD-kl_E~aDnSHL1Gg<^DqU!ES`c_tWL05fC9T1uvl1V zOG}%uCGCw2l}I`Q@OkzbdbUBJE|F%GUFUdG!mmU*q%K8ym!iCrQR^!{3xsgzQdu@I!~P0)rToLvum^XnJ_Ivi)?d2PH7{mUdXBS z@@8cbsCgzeuBr{x5|i3kwhWYJQn$K0KwV{0R_E2AbWpgGTwkD+c7wd13twR2=t1PP z@ll4)3#?4}2sv$^NxkVi2I^5~oV^07_=`CygLucZ*C^*xASmMhkHy zxM`fajV%nwqJzyLN@usR&vU~dugOq#@^nH?xE&t~PIi|elZzeIqLbZcQV%E}3NH4D zNj<4li!Sz*L9w+(y976T-lQt>b_pJ~&!kHIyM!F}9;fv6Y@56b*$gjC;By;0Lz#y3 z;HXJb7vj*Ua%#OixBMf#vo+A9wDJXF9vj1{=h+2S%f)>55vRJ@bN)O_fFQsph1f7twnyr*ma=P1>ha)% z)(G2UQkPUVvPf3ABWz$3x5?*BguP=>@;Gs#Ey9j*>ad_Ms*bZLduIr#9u^L|YLSXQ zH7Synv4Ll%Wo2v(r)bW6E|s&lIrTjI)W_@%>=TpPquT9_tY9S7>t>VG?f9#UUzk*b z8fSypm{EqTQ7TX)ORLzJ(?fHHjFk@7v*W#Rz5YUN2}s&2%9#BWb4_3;w$zc ztYWO8xdEC(*)1kDrAV_6WBW|%kW?;@U?xCa8PqxK9Zo&ZUUXNB=d$z9GMYbH zi90z{*oN6e9u_FvQ`l>B4T^?hiaDa|5bikk@;)w0$nH?PavpQcBh7?7$sGgbHK|$d zt3ef-RHuBcGL;SC)Oz_j$1ygQooQ09I(7;A)T~J}jh&UDI*m=qP@R^gIh|c#$~IX} zD%06qle)!XbxdbVOlo=YF*bu~Ce>ZMOPIl~HmP&{$Jk7rb(!R)Sd}x`Mw8kZI)?Mf zW|Mj@v`aXjZ8fRQ`N#0*Ywj|s+w*tf40NAK%|n8^fIVVT?Y>>Y1?(x4+EZ|hUC5p{ zsXr9#5-w!=Yn*(6QD(a+tA`iyr~8zID9>HQ=Fg{aua_y$&1OF}sb1+7$HnY5llnEN zOPJikHTj^;VQUs}id__NIOnkQ7ZPBq z1#CAGmdo!rY-V$d-uJYz@g{Xcz?*Xgdoe}T)dzE8>|We|N^WB-*e$DQ|3NSY;)0X(1a_-Jj}RtS(Hlsc%5Zmu zZE@4VQg)K`XWmShn=7zg7S3^H@(JHx{o`;S*C!~ldxO}2l18VZNrCw*NN{60;d>)# zcmlT(MRqB!2yh-e1#ajc;jS3)dI#0I63~KU2z6#kC3Pl-t7M7&4Sc)K_M=G|{m9K# z@QgJ#*TIHcsTrfOB0rgULL|;TCAqmGJAf@F+ljHfnKszT=AX*ZOun8;{J+Bg$>U_i zAbZHj#Vn4VHKIQdpF$cB;B>*x4dmup*jAZpy@Rpcwd-m{oAa)l5Ym zpLEw@gao#VkKfB-3j5DEz7L}%;BZEqcK|KyTFy74)f@i39MVgNG8ez@aq;UO7r*Xt z@#`KJzwS{OrSK?+dF;-L`*D&8M|a^Gknj-4D>z=k@p_Keb9@NLhj2U(C$c{16RhB{ z9#HSYZb&SJC$c8Cty~tGd1KSrGp>n9SZ6pd6s9wWZ=$e>t#aNjv~cMbHn#LGVH*>x z?-km>c@XfM@;JK^_%2}w;1hra70(H)*&j>(OXz0as(r#n_HN*S(8Qd1Zvk#Ce^-ZK zQT2zyPV8`T_BboFe*(eLn$G~olpJGCtTSq;{#AIEn{H#h{;y$lQ`JY1_W8aMUShO8 z9bf|@x#B@InJ+f6k86s=!|Xm+J>Wu5y?6w5{Xn43l z$FOFhtn?~zlJKn(7o);a|3@q;Tw3uFt3icpz|l%>5L@SB8@aJP^fdRBPXeaP~xaG>f>fMWg^mIL6QupAbC zQqyd0Vy{$92P`VP(E6o7yHpeV7rJy@sHmA^Juc|31y(`Sn_S13BHmtc8C0ElO98i* zue7$acip!FlIeCP=HHD9`Pc;&adbqs9Tpxfasz5=#D*u(!A8KZ1IJj6Nd2o3Hx!*_ zYZC9ttrnZaajsoLljtfZ_<41;SR)>&`cN1yURYiv4i{(W7@L=bFGJ0?X7NZxoXzGY zuEb-8F57BRj;^=0iN_*0*k+4g)g){iA>9i6Ds`J}3-DdSY_ZOAuWbeUGW4`<4f9DK z3hnG$+kW6jDi*PA(D}r+Lwv~cx$SZBr_Htn<;8ztD(sYq_#CAqI=yZ{wAl?yNARQ6k^j#)h z!(F+7yYj3+uH3*~S%e9=Ub=?2?`p zsL5xAuMm}I`T5!lDKY_vUJIR^qe4$L>C?Hn#zHHo#zND!#zNE9i`fvhPZG8`ssXn< z2HIx}uZw2@|AX@^)Scs)X4jjzxhBih`~~7_;OnI(%O!aW>`j&fI4L(-_TXgQ%}tYw zZT8KU%JN3G#qwa$Wmd1{IcgFky2if4aY$8e?_qtg5iRo{6k)C zZS*Y=hYPu`Z{^{_^(ED4c)OP>izN%}8?DzwMP;M)B}GxZmXW+46Rp+a7VF509T==% z73P9Ju88y}VXa4n3wT`DAg(V7)oO$Cl7&`8l+UfGaIzYgF;PCnqL$08Bb6=e@8Pk^ z4(t8C35p`#sa$4#$wI5(B@3;Bmn^i{4hoMuXDJ7TzpHbV#}S)FfNz!S$^qaBwnpa+_5wr|R318+G5knj<_DTJy-QN*Zr)u7=49! zmvBEkt&kqKc`7aLN7)+|BvE#eOj&(fdC)4p%pL?q+*(7oo@ZmJjyqu$Goi zQ0~A9;0zBEQq@$?ao+FG*#qh#_Bq?5=eDuqwhJu_AvkLLP&m%Rb=*d|>?3|Mc-Bf= zlvkP=yxZfImWF@rX~KDCr$-Q%6+PkEDK7Nv2i$IX8+;MRisM3W;9F0jq?C#|l>g&w zr?{oimGd>*?2Y8?HvSRlqIgPB`{Wrim_g1Bm4R+_}p3%t8a1Y9D zWaBuT>>dVuCIpS_688+ig`9r{haK)Va5~)yz;*6Bd$m{O(fT9GR%MJZj@`t@39kcA z5{NUO<6RuC<8Zt1q_RudF8p4(iEZbcmxR}WA2H#(O2DCr#8Jd|m4S{Lj@JM`$1zUi zmN{nq18VOOuRUoO!<;KX4LnTu2f4kH{!Ic(;zg~KimyE(j*!)+Yy z;qX}wKj82%hx6UVmb;u?fTHV8z$vZ|+|-SThv0m{(|hiIIWo>?pJTtuezW~`dqjE2 z@n=V&^Csutoa0;%yAp1{=O)ifo+F;qbH?Ya&3P=xf~ycOu0a@{pbSdE&w6+4m!tZv zidSH`ZpN>Taot=DxCQ?(2Cgifm4IPK6YBj=A=pt~imP95XcI1a+T7a#b$JKiVCTP5 z@J@>t*Oa}*#A)#pd?!S3Pd>rrK7#uT{-wy6lp>yBxq2tPCOZok;R-hwHz2HFTIix3 zHyk8zmh>)tO+G_E2M@kQHksw4Bj*B&xZ4#3#N8@zrUHs=I$qcjaLcF|`1yEYP{5s@ z65toGFz^cjMck%|0-p^ivWrjUm*9{~5W4}s?)V~qs-q*ps2SL<&({=@l=%j2$d4{^_S&v&nN zPxM^kDag4s$J#{~hV))V@^fDiUF4@f0(+0fD~sn~^!M=l^XTtkX7liHB?^{~Cg_Qy z@$oZTh_LKNj^YY6n-^mDP-Q+6RMN-6_QJhvJqNoDSH0Ohfi>acILV_MH24VYOM=286JKcA9Ao77srEf>zMFwN*VhMICcM4csmHUe+gd&ym`EVH`wqes9R{VFm^uh zCoZ&cyaV`*YYhBRyu!uiydZJGix8ZA$jx*RS0vWUE} zva!Wv-O8GZG3ikj7eg1Nt+;pn>#|z^w9sdtDxRhcXU{thvs;|MXJ6xcwresj&?XB@ z@cjtiFWn`=6`tNtUzeY;Oj@?0cl#T1LYdOiwrtd*dGiMK4t`UP_rCb1Jkl|YEoogb zZ`Sz}hV?%9rW_Cl4e!l)OYRo0Xzji3E%|fH`Ip6dV{gk>mCb8exk4MKtz5QZk#^Ox zvzE0iXm4G_=EYhUXxa)+?*8O$d7e}_KGt&8q@^uOTG_mXD`TV9P&(i>I@TK7ee0)kt>~E2+R=eF$7)yae&R3kjbio8725KC7TC-c zEwL5Z%-#t{Tl;B)#@;pV2glV1uO!*4SxZ(6;IwHfXi45TYyW~ zR%o!1Gf*yorUtDDB#TiRnm=Z#U+tDbY#<)82&e6yXH!Po>$)~Iz(hR^HQ>J%(g*_XLw=A20(|p ztta~(fi3zk+n>zp|9xy!?#WV^ZG%6puyz%&75HQ76pj}1PPq*93cL@&yd2y8pi4RF z)^n=Z1YW5Pow$s#=~dXnGKYl>Mp!3;9fwAQsrYvv+EHU6y8@KP2lgyB6I>c>4R9eE zTn5+*Jv5B_(^Ny_0gLdq()L>aFANrEyGRZ$!TFN@W5IM|8T?+MSgF@fOU~4#aFFKZ zLO4rt?f}&SjAr3tU~T3M9RZpR#?xO;x0oI1UxTbI!|Z8+Ry$iwUKCRZGp(Kl>$Vt0 ztM|Sl<)YmU#Y(5N`?07}pPT#E1A`X+?59spzIp7kCBM75Wc%)~o0P#;VQ{ZHRM{&G z+x^#}%1453m3-Yh2s~hsd?7#nw2-fBBmFDNC6TMvz$oO(**Dhij_HMNf9z1xoO}A5f z2J2~Ta2`*{4s#)2_W>(Jt=QUp-T5Amn_0cxn>-$G_d##>pDg zyN?)zSsay_g*s$(!rT21==i#ilgHj3!3AB}*Zn;)du(#Vg05{gReKc9b#s*-FSpv0 zPZdeW7U?Y-q2%g4g@&MnDtlbso+z(XNnGd|!WtI>%!S^b2AjcaLSKA6!?|A1a9(Mo zA!+7C*8zi?WE9h_lDGR~40yfEZj*iW-tMS(im$cz;SoydTug?ZO9`~_AwBBtX(fYQ z-;=iY6xW`;HjG<| z%@wiJG{(o<^AengEw`Ms>SRI^-5ngM*o6F7C`1PoDc{@O1S1C!(w@z|O{0_oeKSJw zCcX#3PKrGo@j%Dd>T9Lg_`0X?ULC@_;`zRw!!Yu(oJ7*RBT3#7JF{YWghI}UknijE zQllOS4Gf+dez+W7F^PN6<}DoUJvd6K*5BmB!JK@bY=a+3C#_8Iga+9?GA(#dKcVl; zAMe93Un`#g|KKy#*YgjLCn6?&f#stvN7{>X@tcNxuMYn_-g7Bz-^&QwIst>v5gU*~ zy8;KGW{jeDiW~9AyyWcwwPQf0pmZWwRF!6o-85qGY$+bu!+`s`K1S&fX?9N&rQQ>x z73nO@I1!EddVqK^N8oEqo?Y^-Q%W$k=_}*w>lUbc>l8kHz+;$rNIu3YZt0ygMj1S2 zo!i$v-Pb)Eg9+$SXfb!s_OA0%qH*v^JlkV8o05?}{VdlnxGAH}CT{OjW0a9N3RBQQ z3C&7$Fu8~62vrP=5Wqh z-Y=S!LBi19^0CUSAWQyhpLFD3hwnc88=w2m>%DQTQZ!=fRE5o$IezAi<16bL8H^I@L*?B_Yp zIp;Zdo6z-OP1g-I*If}f^`_PbnfdvQRWc_Z%Gkv1Ke@%WajD8i^|qd&j!kWrf{v;d zm9Z!^C#G(Z8l=go7o>^7QGZm}*y|aSz^`XazG4GoKVPJzTBK%6nYQt_M`hOmU^ z8t!N9=THOMV0ek2o?0tUtey=T3j+FvO?6PAis zjnB*Vkowd<5)o7@LrjC|R?(Lw${dq%k4-Rsr8G6n$+ZMtlQ;sQ*Bc1MPeQ|qVmTXv zUu{7D#;YM|#$yZBb1idgkOLp%$y#wNPF9O!r@_`ZV+}qgC~Y}>)ieK48{2DP3`67H zG6XCK*FZLmz8;V}1FlhLrkw7mP5gj6_N;@|1?(gS%i?QAQqA z(v~ktsqLPU+Q)=KFr%Pn6m|$n0FqJHq+a%v>Kg^4G^2Vbqk4{zlw~A-HQmYtNQ{^# z5f9#EgS;o7{3%FnH8LFk9)Sx168*#z^H7-SqU!_f{+91%fbF$k~?dH zTTuC|ch;07miUM+mG7)6OLPl7WXi&crv+UOSw+I;C%uTO05}p(f9hJ_N%dYZz1H~2 z$XqrN!n`pc4w_C$b!@3f{lhm!x;iz|zbPcDMOT=5O?9KIJcCuF_V`Bzs9O#>SX;~F z;7Ly2ei@XKu~fJyRvm*#iT?l$-a&Y{{R-gmD>ID5IDcwcQA{Tv+-pl#($UC}jcazK zXy1oeJiLPhejD$k+{FxFF>rC(&I$sTa-vx%6fM{4_3 z5F=k*#pSI=FXUtu1ZFQ}t|`=umoa~M2MPQ#@1*0gVoWnB+Y4Fi5uP9tqtJ*kPkmY( z8nXgXi`f`(?q9aQL=Ft`8`*4h8pn7O4Bz5KNeXCx%x^cQ;MStlq(H1f1SL}HRkT~7 zxxa`$E|z7G!K=cX!4My&c7tdbgJ zTc~^^S&3g}IM}hQjS-`r7r+%YnJ0V!(`3{UjIbe&f@hR$+Iq(PhXyi`97KMp;rQ~@ zGbO>3Pu%N1Ec6rhI^`-Y(buF~Xjm?qjAJL0nOrF%)Yf35b?o~vbzf zc^?U~`_^HQYPNzX39U30C>z8Vm8M$C0=^qcsmx?&$i6|T)n#G-3t$T;`_0sjDNEg4 zR;kk%#TU>>x_~tm8G$FtOznOB9AiPE_!&?Vb-yvRg*Mu>?i*>{QIkkl%+#__I%L}T z8*Tg6lZb|FixWU6kXQtzs`ygMx7qCZX|sJT8CSQ2Qj0<{>AcjIP{}+o(q1`FeXOt#)MOsgv;#>iBe9lBZ3L#q#K0GpX2OP%i_;!PL1-{@3{z*o$uxL9C$F%XblQKSBdlXD= zNn(;)xi#5H2U`+l&&oa4q&`?6wj?r#>w?Fin`{;=If>*!$DSNU$3SwpAeH1uI(7)V zV=|cO!U2qH;{fYX2W56Y!Y!aWXfZ6U$q~Zv6aguk_~VS}*xe=y4n-8733G>!9Sh)m zQliv5;(Zi;$E2)ID|Afm}#3BAGfc*}& zQC5u|M|%p4O2!7U3GL{#!)2(`hN^@@k(rU1@u$HC6`4tN{OQykRsPc{d3MShQbOa= zcrp(J+MfZf{hFA;VEeN~>>>g?rSZ}Jhsc2T8{_aC9kl1Kuhw+rM|^k(g0RLxIud)( z8{t4v_Mx~ zXNY5Q5{=ow=$xH;wz^Empvj3+a!C0e{RbE)hJZvzY2=L1&Hy70|BfbK4%?_|VS^)l zm?I<%;mJ{-qiraVlg2Sww(gJ($8`p;#%Sj{vT=8O_#dQwQzY;34ZJ3SC>Y`o=4>~kX&9cX5(Fs{}dKRT( zV74sEml1@hQU)qYlYxqQWT4ZsW;8dR5cQ;8Mp-E_|A(W>}DMF#d+nBV2nEs2ECetb>7&<@j3}h0^%G3|&A=^lnfLYT@99gmrwl;1i#Ct zBm|Gcr;G%0{e4$bQGt&Izf3pdAR=9C2sew(*#3XD3Z8 zsU5`E>3Qb!4hmj)3-& z;Bf+?O(jzmbM$G42_7dP+HQim0Yy_ZITo0MZOlLNlejfIutWzUrTCY-xQQD!i=k*a zUGQ$tuUr2YnVwrI|1XBewF_1As(kqkj^d3QYy2@Dd zs|<;9s|?Yl$XHH=5!Qdo=9TEk#z;kWsi6K5GhNJu!9gLMo)C){73=KLfv6*XoBf7;};eWXXB@;mJW#UbYclVVQ?hO z4UXv2=p!s|6V{E(>sPYTks5Mal3gRlC3u+`n`ra1Y;2;kn&-EKr{fv0T1k`}4bhQg zM9*8V!ah)ynSerRc*LC>3-Ll`EJA-M=^M*c6mv5c!qa&o{P=O{;toe{V5Ez{@)oSH zpOB4<=%_bEg@eFvtK?A2AT$fQ2d8iFdN$k(v=+-qIA-su>;;iJb6efDW5yc!Z~G2;uR=R0H)6 zy6`p6a*16UmqZN|c=Q3x@!Z))+=Qn(vp|WCtc*;}U7*BEFHmxxZj^A1!+G2yS|B>1 zkAbsF+_1{u7Pts2n zBH=r)Zw4n)5E+)+H{vF?W&1{S^d?mFNLB6#5IcS9AWZJg_KxU4TuDbH_P>$G=_)dS z3kP#s#Jde<2EfMkqRB=D1lzb9_1(k}Kb;tHDV3WTVT8np`a{HbG9wa0lIT6?U|w>B zaUe1*KRLq7quJyL+wUev7@O;5Cf$EYYT2%$t_*74@Yf&1P;#9%dAl;R>awT~t9Xe+N`Z(8I^pxyo3tV)Nz{NZ1kn@m? ztbANN3Ac;KGxm-qun9&zX2BxSr z9;Cqth+f)rZr#s8M$%6ea`{U${KjQS4rNz20*{}KkP}<8@-lk|DulHOEzv9&4=O~h zq_hjp4cW9)^^BJw7Q6AF#3pW+=eA4_6U;Ye6nh8CthMPvA=k~P4fHf(fWpklZCB&Lm{v~Y zIt-%dzS-~}KpUNHGW*l$3~Cjm`l1kJW+L5Tr$mp5U`l^C+4@?j(|G=WXPK(FndO{> zqxe{(xU^xBDFLIde32hO)5*rVNbJv!F4`lz#K$#ydNn0XR&{Nfv(yN@snL{lL6Xw} zdfw|uya1;0OrJK=22(eB3j&J1L{SaP4N5dRxXx^W5{O!ympMGxwbBz@u~fu*!~=Sy z&U~<&WouC|QB7D&7yus+eNk1y_?804SHiLwnG2$+BC!Y&yyC{{)+%)f z;#C0c)c{?jAhhbswxD=h>nnJdIDSuSp%wBASPDVB2I?D8v~x4T8dZTUD5k z*X!xI_aL}M-NNfPi_xw_cG|IeFby`Meuhvq7pJ^7e`@JOkF+=ypI8iN&`P;aSS`u7 z0+Xzkq@JD_vYQ&Izrk)v>g$P(`f_OVgskD!mt};uHzJOjga$@rPP|DF3qVAFg&vyp zbRPL?6)hX>GjAfM;p^a1qc1L)@l(ElDlk7`K!(~TZp zlwlb3lLP3Z1L(5Gv;#x`%se`|6q%$|6vA-cg`*z>W3{wew87}!rX6Cc#D@Tn>qCii zGdOsB+YCGk6*kyy67bH3`>b+&7(|IRXeB-zSnGa=+$hV&gLvy4;kG7v1)7PEfVjpM zABjUeW8gxceH1=~?0$H(DNi{q(ujE_$}GG(=I0&u_8XH_p+ zqqP8UpO~tjI!rG{b9kg4$DB@Hf=tmP_08f~oV-{ZI}Nsm>O(Iw6Qyl{I=#ru87>`J z!0@q@d|(?9KHv~XOLDz9T9dEXCI#Ie&*(+UlrM43KALmjLWMY9Axc?W6Zbc~!iQ|C+z>ljJiK|aL` zBipE6h&|EG+b1DYHN1lw60aA=Cxek(1rq0QlkPz0c?VJPDd5Ma5|{=skePTCZM07( z@r(iD)97L$@haqsu?NqDf?bpwyLhplUgAi|O|&yneTdU0z74ZWGQtX8joYZGc99`J zj^k03L)B&hig)z!erW~9gvpK5aKibUOt5NvHmRHe;J5qix;6(`QwtB^1dfu!z4qky z=xAir&NVNcEov6(EeZT~-bu$}#mK1f`X|}>>{=`NlsR6?T1^gk2OZ*g`^b^JkQfF% z7j%3cf%yQsU-hZlS-=njokSWjsL3^CVZ@+v4dt?7-#v8F+d%@q$~)Bjh^wLHgCunkfF_iOV;*FGyY}8Q5wFrxcK6r$o%!SQJ}kUWu}rf=v41*Czm-dil1@y;;%ve&&|A4g zq~EI(lT1vmy!Yx%cIwwN7o0>DB=Z&=)sQOGkWx`YsElDgQI&JzUF(%*-{@*3wRl=k zFB(iWg^J&IYKq{BiG=gObb+Drm{VX9AelTG+do|@-iHJ4Al`S%Og=MHW^n)As54pl zX$bAVmKprGB(Vr#n_bB%GZfr^D>KHAfpW(O^YEtQxWb9Bey;oF*uSJk%18d?q6WzZrJy=7^;h~ty%pJ-borc1xm!=Fbb5) zJE%b~jv@r3Knc_+Py!VN>i=G!u%%>IMNS|6POmfiJJf-}gj|PU2ajwxKX>G663-rI z;0CO-hT*x(*YEPW%({}EC3>Xt$MN%M45^BEU82;PajXElDVg8qvE#Iv6ZWBUAt$8I#&&A@D}K)+b}Uh0|qcx4fCMH439fMYQA1B;gquQ?u!h0;25-W^NTNQV&!z#lcPxcn{CkKw*$E7%N3l`p6yv;; zXzfChB!ThvHH3B;O7nRKVZ4(>+FD3VbRE!moIp3G4xLenJ7T(dMnz*y^=6AOrqgF1 z&ZuzS-LMZWp<x{r_Xd_J{C`n1C7V2D+Lw@dVJfjBFh%rZCM+w}U_C3f$4!AAqIT z;2sNvpv;|TH|bbA6KFwTsAF2Q%HnY z{D1^Euz!GYiFZ&-r^0&s2Zw`tOmXpr^Kp$>;ACPC@V&uQoZxt zQfKO(`6Ki$NE_|q*L8Az5pH5wsZR{U>*euo2wycq%!#X3ykl=+z0iw5&nkZJ81I3y z!z%jPILJ7PWQlu@O~D*af?jNv#Z9vL=rCPP$}XkJTIAk8L(y;+Bs=#zve8-$4Z5&t zEW+MT3ON79>Gfr3(!IZUzY7vO;t;jiu3esb=&S}kiqN*u&gu%d6;z||LwQRV4QhNV z(D)Ak8kHiybsyFt6R*cB+7)2FWhk^?2^_yf#8m_C<1})6{T3)%w_t@?WxAvVw`rPa z!EX!T$F??~oYP3XXeAiG3SJPPi~wzhdpZ6?@S+T>c?qR{TdMo)(Kd&rsc*L3b=lgsAFOSY@a6bg@U`M=!&k=F-oLg@8M0{HDC{Iv zTNt|=$5CjhYVO9w>U9@j&t~kcnT)+M61@3y*@Ng@A$V2O=Fgan<5Qr!diVAzbv1tk zi5nB_`}l6e7uTyy#`ku~_(Ag$;IZDCUnryX$MJlKJ~G=@IXfV;Ydu5CWp<65;J5;U zm#~9eW|#U%`dS&m3QsTis~O?ncN3JXgM1Eldvs{EgY9q;e4>uvGbKZ-$FpCfLO9rp zO5zME9a=53&cN(|gFPA@s)MyGM64lBa&%B8!TEmT3@@D>sAZEw?+44+=8|V+nRP=a zz>b8qP=KYl7P^?7hrQ%t_79c%dqB}b9`;J!L{RCYCrUHbYQbX=`hR9%aE#Y=y{GO1m;-qt~ zfB|TF*gD`c`=*RCw6W-?5t)4|vh}iScA%bBJC!mSb%ru}4dqg2^Xs${^wmZ1s%px? zEc9Dua~Qd3Vn2SH^x;?ZsalxF$jkyo)sY*uo$gydg&JE+;wt zhnL(PtReoG5`ro4ee5w8!K(%5O2Jtu@IMH=w}Pan`l!Xl)zsoHr+%X^#csx(93OjF zB|%FSjbC?YcEHE>3FGr(WcJH2!ABK>{leX?q6aBqbykdKh69sMWmm$8a*Vl#aMC`%;mW>TETeXrEqbwbdZ;^8EzW0E5sf|@F@ZP@StNX zmDzzxR#W|cX(j7+5L9D_qLu7rftL$>1S8H{g#@1$@I&Yi!=H8-hxswp=c|PjoH7=w zz9Y7T@573hnTBr2>}Oc(Wy}|tf@SOC?A9zuc9H=+1C{`^DjlhW%h6Z&FaQN zf*r_;(=ru%x6JmIT*Ev8T+pH`ux1k{?>xS^kVsF%jp9dBQ*$pP;6|yaYQgJOqc8g12uDTk3 z%mUp7H6rkGl?|0H#w_sSM1wU_1V7#)imGglRE-5qb}ONIrPRQN=tB5sNNc27>{Q|A z_44y7Y-}!@AXGO;jznzuUE>r%ogt{R*mObl2T67|n<=Qzs~(Tp*kZO&_s55PwT@uCn&29NUnbxcMZ|g4Ptfil7!vxoS*m$!*H8WAXl#&RwSYF) zNBDL3hwdeqc159CHi=oK`G9VA4j_IyYs*TTv7g)=(NB^|JO=Rh>?8E1N1}d^YK+Zs z{7R0olLVxG#6&-0qGvJDj~M%%?^)<{BP>aTD2WgyMj=Y<&DitsJhAxqfMMUufVTt* zJ{Nrzuu$Er<4`BWS6fK%c8H){Ot7zvVAM)*Z6U#<0{%q6hXuS;z^Ip`@5TteTtu#a zQ$+ZoqWyr+*X>7N(^pKcdDcC+(rUba5)HvSNW)qM!!<#x)4 z0cYE6KP^l6+^(URZgabS$Ul5(o0KN6l@wMjZcuDxKjDn4Y&xC7 zvaKb$TAoD3nj^@Y*mK1Scd$h!b!}k;6dtk)Rnl~_TMSD1vwBc+vO7)cfLh0$>;aQ% zhs?zuGpTOKTVm~eIlich%lj_s`eUgXaIW0B89`W@_1?(-8xO%T*`Os!eZi`hGZ>SlBOMHZYp(uq8J zua@gcJQ%xMklWckfqz;`7+t2)9}XH5`BW-pFAX-RqqYufS%w-fcUZ&hZBw>Y?y**| z#vz8LGx)GI%2t__r+P4pX3|YLjI!5<3Qd|bI>?R9f>g%wX|^c4K~M)IwKmCOY$I-} zF?K-ebk(EGTy9b%t7Olel9g4mR|Q3VIw)7Md1FbomEFgu*c+He8w=}Z|MbtbH?hl2 z>Y~!Qc6|tY$|UcSAFwyGBjXKKd(m9`aE3id7?y$>$qG#B6i_F#(@pAi%Ut_tw%DXj z3eUBl!Y(nX3Q*(N^(HmnJJ&v*J!n#ELAB`Y1wlT?E_B!NN$h=7czbn{O=jWw3?CyG zli77`21U7;Y^L-w^f!sU@h3u-Qig^kbqf2vNqy|HgW6+Khh1(^drhiE39D0?{*@rN zDytob*;IDaq&7MFq^WtMHjUZNq2>+EY0Pa>q&Y25b23+Znb2YE_pK)Na;Q(5$<8sUFNzN1 zb&%yIb+o8YI-Ol;QXD>Ki9bC?ohX3MS*-IMT&NT2D>=+&v&&7@@{&GjHoHzxFEA=C zXXN$p4EDaMNrmPN7F}p~p+Ylii6cAZJB2X!XI#FR zS+bD5V^XwY7P0B8v$92O0VuR@7@o@};2u+Ysh!Ja3u-&t;4AkmW=lKV^@>^_q^SiHxxlD%S5zbilLIiFpJJ4I;!CRSZH zsbDo*g*!p%jpRZ$54U6}7rT6e#c7$u7OHf6{omE}PR?vpeJdO5rW3VC9CTJY!J7*U z3ng~DMQ~iXe8MN;^ezk0|1{Ar3<#nb+&xG;@oX+=eg4oV_s_>^@%zh}sAPmlln>kVQ|Ba9H z|NkEQiHv_JdTjJ2Klv2m|C*zpP<4MXHfr`zabcl_Emg?r4vacZQ;{t$@|2I~rq{rW zFh3BANc$V`z}Z`{l~}3ZJX%4V8bjP9#`{IVdKS>a>V=Zo``*pFm9SoZ5_5?w0++ZV zaEU7dm$)Kui7Nt?Q8A7QSj6U5J%~;Di%1`?jtCD6yjtMZ0&f&}qrgW9e1yP@aB{OB z`UI;5Yy{Nzvk`(&MM-LA^C}goMKspRmbs=$ZS0`qY^jw!JX^42c@0Zs*>yp_BZ)m2prl+Bn}^D&1`nmQ2kWeC0ws&n*S>}olx@*q}{%M zOS>8EGkaJtQpoqB$ztA&*A&b60XEy!2q=3R`3JB~vJco-%1EwCYWXC-so-@^%6v-Gwr$x4NzUD6i!KFcoYqME-0t}pt`vIqQQ zmIG2>U5mAuC2Cp$-;ADZ{am8`rkP!VE*+6()Ge|ekt$uwtrFK?bslCapIx;Is<-;r z0?w-3WL<;5rgS49xn9H87u^km3xcFs7g1~nq`#KB0q?Ah+M3y(z+k}nfx~PNr~VD% zJ4;8}n)zvkb-bCs>+F-7`Aac^OKa=+AbwHJL1{EEs4U~7`PaI;k?)p{g<5Pa{MM=@ zYZERu@M^8gwwb>f*=k$O{}9<`YvYAl%628Bw*dcH?H#rq!26^&UT(S1wvinRJ#Fh` zuiFkvYuGN^%fN4~TEXss&bzkz`7M@@ZBOu-)nD6o@$(8P6Pt^^we8_!=(+wL{-u-P zGS?<+8y{{_r1lDmf2NQQJu>3#z6_wHW<-sXG( zp*+uDLbz9juZK@MD{U6t7_Ey#i`gg9Kk0>%|{W*&VO4R$9bV==Utkn78Vx`&g{XkgRj6_vKdU8#@(k9(hOF^td4-UYX>cJRa zvohM!8yF=t$3ydlKr^5govs`~5VMsTmOIq>faH0G<*m{>PCgeYUMtOpnDjf{vKj^r zMXQw-%ifapO3YfTTnx_R;UwV4{?*E8>9@+|O0#v3cR3#|J?6X$oSVaSXnv}fYzxA$ zwVoZ_4tTA4v*NY9Ejr`2*6~*BXO%Gw!QqnIz+Y2J`k&U2?SDj$hg9KGZMSq??NiDI z3(eISMwHUtPS;76zn2mmYJE}J!QQCYqb#$Y;rok1Q}qo+<>#xbtQ#yeNjF$%l5Vij zTG%Tsb$+Pqm4bC&DjU$tBY;;{7O7VP*VG+=lhr!_lURiFDsR)(`vtL6z*|L?zLh;^ z+3487x45@Dc3b-@>-YxV=Dymo%NkQtjy=|IqB|UWv5^#m|5J?U20kAbwR@~IJyqMj zx<5F)w%(dQIX-~Ty^feoEk6MG7&K$Hhblh>K1BH%aJ%IGkK=Re>~h6< zH-f+_hgp)f+LE!0U9GmEu`R9*whL-5cRk3iC`+<#Nc*G*5ooo%!M3aFX4m8F*A`4M zR-sVQomcrFtj@AL?s`hpgXcs&curJ;HXC)L&Gt(5-(1^uo6~a0^`cOERVck`Dt!~R zyW4Da?!&Cj_LRfzehXoBvmLh0l~us$?#B&cJC0cnVB5XJ*1#9K??+h6+^x2CmhZW# zB)3}IY~yj?;BMyk9+W<}&aeF+_ucHg!WHQ7!ph&dms$0S^1mpzVuyak{SJ2McicNg zzdvSg*REh6Lv=OVX`5j=4E|%Ni91EMcG{>0ydyU5%~sk$cH15gjP~rd&94~mX~yZs zRFA}aOV9A^aF_(v7v3P^vx z=ct%TUzw2RQycrhF}L6d8r~}Jw(anqQy|H>Rk56_I3$@D@UDUwV4pNdz-9qQ3)mvy z3;|mOYy+(0%LKk!zzqW8><`cLJ=hy0{+4E67W9@{+q7%fd5_aKN9du*D-MZfq1h6GOUwXZ70=bfUSrrsq@QmxLqOBX9Z*`;ZXsX3fLv!?E*e4;M)Q+htL#of`Cf}>=N*H0q+p-Spjzm__lxt zhKd7ok_$<|n1C$;E){T@fL#K1_jde6DX%>shzYKcSXL0ZNzbdEbE%;>vXA@a5Ix-26(!3nH-@ zfE+ha%7LE_$Z=C70(>?g$9;|%@Hv2-wX!PUX999OjHv-W50K+gOdasE068AL3)P%5)b+K??|#eunfoD6eSx)$F4SxoiuC8zQgM--CL#SJjTc=wXFd)#6c^D0c{hs3 zU%7e`8ySU~E}Fm?ijSYsk9+cskrrGS=JUer(x|}`?GuU{$nPV(d_C}RwVBV8*sHj# zO!IK>fj$yDER1orn)%eQae_w-3a|jzq{DIZlkkIhcjzPF)citpYuGpg9}B!?vVngI zeC{%uEO_e>X?*f*o4`i{Kl5?}zZ7o=u|+S)LU0WP-#%g&_!8h3;Li_}G5y)xU(Pr1 z$9s$4P-2xuWfX;#tt=x2E1Oq_Nsr^HWzfY@E9+hGhN6wRQ99q=#Gg|}vo^;8HpuxK zb|t?1oHM0Axn@d7@!jm6DQ$I^OUwhqv9p$~UU%w>B};}i_dfWB@=WjgHV4xI<%0gH$CNTl?>b4{-Mfmb z^WAe+pSN*SV&%m6C2aD_UZ+J})_fpk{&>hbx+h5spM$h^e z*Z$)2x_kTY8>bGpO3l4*wW!ZaC-vVsQGG|6WRZPgZ&Z0Q^D6=?D5z^g?-(9 zR=ecIkL{SZ`w6Q9=y-{Z>D}3)mh?VzL~-=)oT3KwX3R=i=#QetyxmvZqA=KH5a!`| zg;~5^520~`{StJ1-Fv7VZ}(mon2N9aFM_#GiCPfg_O$8&!98TCd|;S=LWZPci}p^P zsut?qpBsX&$=Kuab{`Q|-w+piLf9j@qBcY5?XlT}s7EzKZgkSuQ*7{x$+oA|kd%u< z*B*naF%C^u87aXKG`j3I#n;&T$Ej+~3MAR%30q}f&u9YUM4~_O_Oy_{u5T!2500WK zT9Z)0OGFY55QRNB60_?{n*z~jqoo;mCP^y}w+V?muD^Af$|dRC-g(p2A^N%8qmWxa z^GmAT;_F$4e;iJI-J>zuFjx)f?O7}E4fd#odkQ@sc^dYJc`R(Vm)m?jo19K>&*oxp zPg2S`l9Qe*J#v(l`+BYx`R=(|aUs3lo*TVAJG?zVmPb%_d+xAd^vZ3nsGTMkKHeUh zcJSp^(q5fRN~8TJ&A?JAzMoR`kSZ5@yPM(UA!M{?ZSS1Z)DnFyQn3@?KCshbk3c-o z@vZc&q}=$rXNg`tf%ou=eLYXZ$u1?0WO>i0dC%LK6~hw_JEKyuuiHzFdLT3~L~6w0 za(H>h#08leV(L2kH z{Cm4&q8*@i49F}Tok$j$(u}d2P7L0G43GR_zmIp#Kf6?}c&lIY(dF@L~gn0X#=w<>Ztu6Nbx>hK9YANaakecf#sO+b%I zYr4D5+w%!kB!`&AZ63SPrbmf#1X$?Db5zu*HsbcadAd4IK|shlsOT&;Hk`u4e1s~- zMGB)iZ_g1GCSBizeLY{>>=^b#GUH02QD1yL-}G*rrB0XJy-&|lTcr`b1+&#*(#YP4 zv(@>T|8|E~;Klepi2rQo!HK;O&sNI@S4~pcnR6%49Wu4;lE2@7|CFugx4!+*6@6=I zpPV#i5p7 [options...]"); _logger.WriteInfo(""); @@ -343,6 +353,8 @@ private static string ParseCommandlineArgs(string[] args) _logger.WriteInfo($" deletion requests are only processed with enabled approval mode"); _logger.WriteInfo($"-g skip client version check on startup"); _logger.WriteInfo($"-u skip hardware hash harvesting and upload"); + _logger.WriteInfo($"-a, --auto, /a, /auto enable auto-countdown timer (15 seconds)"); + _logger.WriteInfo($"-r, --reboot, /r, /reboot enable reboot after countdown (combine with -a)"); Environment.Exit(0); break; default: diff --git a/source/AutopilotManager.Client/QrCodeForm.Designer.cs b/source/AutopilotManager.Client/QrCodeForm.Designer.cs index df2eb0c..e5366c8 100644 --- a/source/AutopilotManager.Client/QrCodeForm.Designer.cs +++ b/source/AutopilotManager.Client/QrCodeForm.Designer.cs @@ -17,6 +17,24 @@ protected override void Dispose(bool disposing) { components.Dispose(); } + + if (disposing) + { + // Stop Timer + if (_rebootCountdownTimer != null) + { + _rebootCountdownTimer.Stop(); + _rebootCountdownTimer.Dispose(); + _rebootCountdownTimer = null; + } + + if (_currentOverlayImage != null && _currentOverlayImage != AutopilotManager.Client.Properties.Resources.Win11Background) + { + _currentOverlayImage.Dispose(); + _currentOverlayImage = null; + } + } + base.Dispose(disposing); } diff --git a/source/AutopilotManager.Client/QrCodeForm.cs b/source/AutopilotManager.Client/QrCodeForm.cs index a6eae5f..2975a52 100644 --- a/source/AutopilotManager.Client/QrCodeForm.cs +++ b/source/AutopilotManager.Client/QrCodeForm.cs @@ -24,6 +24,12 @@ public partial class QrCodeForm : Form private bool _quietMode; private bool _noWait; private bool _skipHardwareHashUpload; + private Image _currentOverlayImage; // To track the current overlay image for memory cleanup + private System.Windows.Forms.Timer _rebootCountdownTimer; + private int _rebootCountdownSeconds = 15; + private string _originalRebootButtonText; + private bool _autoCountdownEnabled; + private bool _rebootEnabled; public QrCodeForm(Bitmap idQrCodeImage, Bitmap qrCodeNoSelfServiceImage, @@ -32,7 +38,9 @@ public QrCodeForm(Bitmap idQrCodeImage, string backendUrl, string preCheckErrorMessage, bool endpointsValidationResult, - bool skipHardwareHashUpload) + bool skipHardwareHashUpload, + bool autoCountdownEnabled = false, + bool rebootEnabled = false) { _idQrCodeImage = idQrCodeImage; _qrCodeNoSelfServiceImage = qrCodeNoSelfServiceImage; @@ -44,12 +52,213 @@ public QrCodeForm(Bitmap idQrCodeImage, _endpointsValidationResult = endpointsValidationResult; _quietMode = false; _skipHardwareHashUpload = skipHardwareHashUpload; + _autoCountdownEnabled = autoCountdownEnabled; + _rebootEnabled = rebootEnabled; _backendClient.ResultReceived += backendClient_ResultReceived; InitializeComponent(); } + /// + /// Handles the FormClosing event to stop the countdown + /// + protected override void OnFormClosing(FormClosingEventArgs e) + { + StopRebootCountdown(); + base.OnFormClosing(e); + } + + /// + /// Handles keyboard input - ESC stops the reboot countdown + /// + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (keyData == Keys.Escape && _rebootCountdownTimer != null) + { + StopRebootCountdown(); + buttonCancel.Text = "&Finish"; + return true; // Key was handled + } + return base.ProcessCmdKey(ref msg, keyData); + } + + /// + /// Sets a colored overlay over the background image + /// + /// The color of the overlay + /// The transparency of the overlay (0.0 - 1.0) + private void SetBackgroundColorOverlay(Color overlayColor, float opacity = 0.7f) + { + // Freigabe des vorherigen Overlay-Bildes + if (_currentOverlayImage != null && _currentOverlayImage != AutopilotManager.Client.Properties.Resources.Win11Background) + { + _currentOverlayImage.Dispose(); + } + + // Create a new bitmap based on the original background image + var originalImage = AutopilotManager.Client.Properties.Resources.Win11Background; + var overlayImage = new Bitmap(originalImage.Width, originalImage.Height); + + using (var graphics = Graphics.FromImage(overlayImage)) + { + // Draw the original background image + graphics.DrawImage(originalImage, 0, 0, originalImage.Width, originalImage.Height); + + // Create a colored overlay with transparency + using (var overlayBrush = new SolidBrush(Color.FromArgb((int)(255 * opacity), overlayColor))) + { + graphics.FillRectangle(overlayBrush, 0, 0, originalImage.Width, originalImage.Height); + } + } + + // Set the new image as background and track it for memory cleanup + _currentOverlayImage = overlayImage; + this.BackgroundImage = overlayImage; + tableLayoutPanel.BackgroundImage = overlayImage; + } + + /// + /// Removes the colored overlay and restores the original background image + /// + private void ClearBackgroundColorOverlay() + { + // Freigabe des aktuellen Overlay-Bildes + if (_currentOverlayImage != null && _currentOverlayImage != AutopilotManager.Client.Properties.Resources.Win11Background) + { + _currentOverlayImage.Dispose(); + _currentOverlayImage = null; + } + + var originalImage = AutopilotManager.Client.Properties.Resources.Win11Background; + this.BackgroundImage = originalImage; + tableLayoutPanel.BackgroundImage = originalImage; + } + + /// + /// Starts the automatic countdown for 15 seconds + /// + private void StartRebootCountdown() + { + _rebootCountdownSeconds = 15; + _originalRebootButtonText = buttonCancel.Text; + + // Create timer for countdown + _rebootCountdownTimer = new System.Windows.Forms.Timer(); + _rebootCountdownTimer.Interval = 1000; // 1 Sekunde + _rebootCountdownTimer.Tick += RebootCountdownTimer_Tick; + + // Button-Text initial setzen + UpdateRebootButtonText(); + + // Timer starten + _rebootCountdownTimer.Start(); + } + + /// + /// Stops the reboot countdown + /// + private void StopRebootCountdown() + { + if (_rebootCountdownTimer != null) + { + _rebootCountdownTimer.Stop(); + _rebootCountdownTimer.Dispose(); + _rebootCountdownTimer = null; + } + + // Restore original button text + if (!string.IsNullOrEmpty(_originalRebootButtonText)) + { + buttonCancel.Text = _originalRebootButtonText; + } + } + + /// + /// Aktualisiert den Button-Text mit dem Countdown + /// + private void UpdateRebootButtonText() + { + if (_rebootCountdownSeconds > 0) + { + if (_rebootEnabled) + { + buttonCancel.Text = $"&Reboot in {_rebootCountdownSeconds}s (Click or ESC to cancel)"; + } + else + { + buttonCancel.Text = $"&Close in {_rebootCountdownSeconds}s (Click or ESC to cancel)"; + } + } + else + { + if (_rebootEnabled) + { + buttonCancel.Text = "&Rebooting..."; + } + else + { + buttonCancel.Text = "&Closing..."; + } + } + } + + /// + /// Timer event for the countdown + /// + private void RebootCountdownTimer_Tick(object sender, EventArgs e) + { + _rebootCountdownSeconds--; + + if (_rebootCountdownSeconds <= 0) + { + // Countdown expired + _rebootCountdownTimer.Stop(); + UpdateRebootButtonText(); + + // Wait briefly so user can see the message + Application.DoEvents(); + System.Threading.Thread.Sleep(500); + + if (_rebootEnabled) + { + // Perform reboot when /reboot parameter is set + ExecuteReboot(); + } + else + { + // Only close application (default behavior) + this.Close(); + } + } + else + { + // Countdown aktualisieren + UpdateRebootButtonText(); + } + } + + /// + /// Executes the system restart + /// + private void ExecuteReboot() + { + try + { + Process.Start("shutdown.exe", "-r -t 0"); + } + catch (Exception ex) + { + // Fallback if shutdown.exe doesn't work + MessageBox.Show($"Automatic restart failed: {ex.Message}\nPlease restart manually.", + "Restart Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + finally + { + Application.Exit(); + } + } + public void DisplayData(bool quietMode, bool noWait) { _quietMode = quietMode; @@ -101,13 +310,20 @@ public void DisplayData(bool quietMode, bool noWait) private void buttonDone_Click(object sender, EventArgs e) { + // Stop countdown if running + StopRebootCountdown(); + if (buttonCancel.Text.StartsWith("&Reboot", StringComparison.OrdinalIgnoreCase) || - buttonCancel.Text.StartsWith("Reboot", StringComparison.OrdinalIgnoreCase)) + buttonCancel.Text.StartsWith("Reboot", StringComparison.OrdinalIgnoreCase) || + buttonCancel.Text.Contains("Reboot")) { - Process.Start("shutdown.exe", "-r -t 0"); + ExecuteReboot(); + } + else + { + Close(); + Dispose(); } - Close(); - Dispose(); } private async void QrCodeForm_Shown(object sender, EventArgs e) @@ -148,25 +364,44 @@ private async void QrCodeForm_Shown(object sender, EventArgs e) // SUCCESS - change colors success = true; - //BackColor = Color.FromArgb(0, 117, 51); + // Set green overlay for success + SetBackgroundColorOverlay(Color.FromArgb(0, 117, 51), 0.6f); if (_systemInformation.Action.StartsWith("import", StringComparison.OrdinalIgnoreCase) && !_skipHardwareHashUpload) { - buttonCancel.Text = "&Reboot"; + if (_rebootEnabled) + { + buttonCancel.Text = "&Reboot"; + } + else + { + buttonCancel.Text = "&Finish"; + } } else // Deletion request or Corporate Identifier upload processed { buttonCancel.Text = "&Finish"; } - //buttonCancel.BackColor = Color.FromArgb(0, 92, 40); - //labelCancel.ForeColor = Color.White; + buttonCancel.BackColor = Color.FromArgb(0, 92, 40); + + labelCancel.ForeColor = Color.White; labelCancel.Show(); if (_quietMode) { Application.Exit(); } + else + { + // Automatic countdown only for import operations and when enabled + if (_systemInformation.Action.StartsWith("import", StringComparison.OrdinalIgnoreCase) && + !_skipHardwareHashUpload && + _autoCountdownEnabled) + { + StartRebootCountdown(); + } + } } if ((labelRegisteredValue.Text.StartsWith("Queued", StringComparison.OrdinalIgnoreCase) && _noWait) || @@ -194,8 +429,8 @@ private async void QrCodeForm_Shown(object sender, EventArgs e) { // FAILURE - change colors - // pre-check went wrong like model/manufacturer or import failed - //BackColor = Color.FromArgb(91, 0, 7); + // Set red overlay for error + SetBackgroundColorOverlay(Color.FromArgb(91, 0, 7), 0.6f); if (_systemInformation.Action.StartsWith("import", StringComparison.OrdinalIgnoreCase)) { @@ -205,16 +440,16 @@ private async void QrCodeForm_Shown(object sender, EventArgs e) { buttonCancel.Text = "&Finish"; } - //buttonCancel.BackColor = Color.FromArgb(119, 0, 8); + + buttonCancel.BackColor = Color.FromArgb(119, 0, 8); - //buttonRetry.BackColor = Color.FromArgb(119, 0, 8); + buttonRetry.BackColor = Color.FromArgb(119, 0, 8); buttonRetry.Show(); - //labelCancel.ForeColor = Color.White; + labelCancel.ForeColor = Color.White; labelCancel.Show(); - //labelProvisioningInformation.ForeColor = Color.FromArgb(254, 197, 114); - labelProvisioningInformation.ForeColor = Color.FromArgb(255, 69, 0); + labelProvisioningInformation.ForeColor = Color.FromArgb(254, 197, 114); if (!string.IsNullOrEmpty(_preCheckErrorMessage)) {