From afb6ab36693e5dbf1dc4fd4174c5ea080b6fb2b8 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 18 Nov 2020 10:11:24 +0000 Subject: [PATCH] Add Tilt Hydrometer app --- apps.json | 12 +++++ apps/tilthydro/ChangeLog | 1 + apps/tilthydro/app-icon.js | 1 + apps/tilthydro/app.js | 87 +++++++++++++++++++++++++++++++++++++ apps/tilthydro/app.png | Bin 0 -> 14919 bytes 5 files changed, 101 insertions(+) create mode 100644 apps/tilthydro/ChangeLog create mode 100644 apps/tilthydro/app-icon.js create mode 100644 apps/tilthydro/app.js create mode 100644 apps/tilthydro/app.png diff --git a/apps.json b/apps.json index 116f1488d..3207f8ab0 100644 --- a/apps.json +++ b/apps.json @@ -2395,5 +2395,17 @@ "storage": [ {"name":"gpstimeserver.wid.js","url":"widget.js"} ] +}, +{ "id": "tilthydro", + "name": "Tilt Hydrometer Display", + "shortName":"Tilt Hydro", + "icon": "app.png", + "version":"0.01", + "description": "A display for the [Tilt Hydrometer](https://tilthydrometer.com/) - [more info here](http://www.espruino.com/Tilt+Hydrometer+Display)", + "tags": "tools,bluetooth", + "storage": [ + {"name":"tilthydro.app.js","url":"app.js"}, + {"name":"tilthydro.img","url":"app-icon.js","evaluate":true} + ] } ] diff --git a/apps/tilthydro/ChangeLog b/apps/tilthydro/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/tilthydro/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/tilthydro/app-icon.js b/apps/tilthydro/app-icon.js new file mode 100644 index 000000000..86fd7d388 --- /dev/null +++ b/apps/tilthydro/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwggNKgtQESUF5gAEDR8M5nFAwdVAwoWJBxFcDBZEBBZNc4ALJCxQMCMZAiLHgRJHBBBsHGAwHHABAnGFxwoHhhdMLAgRErj8RT4hGQJApGTJAaNQrnMIIJDCLx0F5gACCgZeNhgWDCQMMBIJeNC4ZcEVYpCFrgLBC4wVBRxQTBBYMFqAFBLIQXCRw/MCIp4DAoQXBFhIRFEAIFD4oXECIIfBIgQXHIQQXEZIIXDIgIREBoRyCC4TJE4pEDCIgXIZIpEDJYafBAoYXDIoQ/DAgRLCFgQXGBoNVHIgREHQhkDa4ghEVArtEC4bZBCQZfCSAvFcwoVCC4QnBfQaQDFgokCDwL7DaAjVFC4xvCcQ7UEAAwUCeApAHAAxvDSA4AKRgYbEIRR2GMAoAOCQhIDABpGEJAhGSGoRdOFA8FGBxYIGBsFe5AJJEp0MJJVcKpYMJrg7MBwQ9EKIK0PCIIAEZaAZCqtVS5QA==")) diff --git a/apps/tilthydro/app.js b/apps/tilthydro/app.js new file mode 100644 index 000000000..b64fa4573 --- /dev/null +++ b/apps/tilthydro/app.js @@ -0,0 +1,87 @@ + +function displayInfo(reading) { + g.reset(1).setColor(1,0,0); + g.clearRect(0,24,g.getWidth(),g.getHeight()-48); + g.drawImage(require("heatshrink").decompress(atob("o1GgQIFgOr///0oZLg4PBAAP+oAQJjf/yolBtf/yAQIj/5AocGCJMf+hKF3+AGQ4QFCIRHGg/4DI0B/wHFgRDEBIn9A4u+QJI9Fl6DJhfQApIAFDgkCMwwAE3oEILA4dDj7IKIAPAAYMDIhQABnwDC3AQLgI0CPBQ0FGZsAlwzOGgZnMgO8heAgXgCBUG//QnsAAIIAJr///wgBg+AGJO////+EfgDPJgIPBEQIPBCQIAIn4QB/tAheBKxFAgQQCAwN8loPGgr7Bj4RBDwMD4atGD4PggP+t//BAMtngQFqEvKIMFLAJkBgPnPIu/BgPwAoMP/4NBj94CAgOBBgLIC3/8AYP7aAcUBwW//AHBg//4AmB2gQCt/QDYIMDRoJ6CEQS3B/wOB6AMDNoQiDBoJDBBwIMDRoQiDQAIABBwQMDPQYiBl4QCBwYMCgh6D/dCCARJBBwIMCjfQv56BEQLHEBwW//uv/0DNoX3wAiCSwZdCLwMvyAbBvELyI/CPQYRCoKHC+6gCJgU//xrBAAIZBAAMenrHEcIRNCGIKgC6XQGAaWCoH//1Qdoc9jzHC/z1C/EL/L+Eg/B+DHCAYMLOYNkCAkAvEPLYIwCgCWCAAoPB3AwCMAMD/oUBAAkB+EHPQIwBPQMZEI0AlwBCGBIACgfQEgIEBPQQAIIYMLGAMvOgoAEj5NBvpKB8gQJgXgAQI0BABYfBPgI0BABSaCCgYzMAYL7DABG9AYULTwJnMAAN+CBUHSon4CBMBBYkHPZQuFj6+Jl6GFAwwbK35dDAAcLZI0B/wRGg5hHgQRGhf9Hg8G/+QAwcbCBAjB//lHQVv/KUK3//1Wv/4QKAANr/4ABygKFA==")),24,24); + g.setColor(-1).setFont("6x8",2); + + if (reading=="startup") { + g.setFontAlign(0,0); + g.drawString("Scanning...", g.getWidth()/2, g.getHeight()*2/3); + } else if (!reading) { + g.setFontAlign(0,0); + g.drawString("No Tilt found", g.getWidth()/2, g.getHeight()*2/3); + } else { + g.drawString("Temperature",0,100); + g.drawString("Gravity",0,160); + g.setFontAlign(0,0); + g.drawString(reading.color, g.getWidth()*3/4, 24+40); + g.setFontVector(34); + g.setFontAlign(0,-1); + g.drawString(reading.F.toFixed(1),g.getWidth()/2,120); + g.drawString(reading.gravity,g.getWidth()/2,180); + } + g.flip(); +} + +function arrayBufferToHex (arrayBuffer){ + return (new Uint8Array(arrayBuffer)).slice().map(x=>(256+x).toString(16).substr(-2)).join(""); +} + +var TILT_DEVICES = { + 'a495bb30c5b14b44b5121370f02d74de': 'Black', + 'a495bb60c5b14b44b5121370f02d74de': 'Blue', + 'a495bb20c5b14b44b5121370f02d74de': 'Green', + 'a495bb50c5b14b44b5121370f02d74de': 'Orange', + 'a495bb80c5b14b44b5121370f02d74de': 'Pink', + 'a495bb40c5b14b44b5121370f02d74de': 'Purple', + 'a495bb10c5b14b44b5121370f02d74de': 'Red', + 'a495bb70c5b14b44b5121370f02d74de': 'Yellow', +}; + +var failures = 0; + +function takeReading() { + // scan for 5 seconds max + NRF.setScan(function(device) { + d = new DataView(device.manufacturerData); + if (d.getUint8(4) == 0xbb) { + var hexData = arrayBufferToHex(device.manufacturerData); + var tempF = d.getUint16(18); + var tempC = ( tempF - 32) * 5 / 9; + var gravity = d.getUint16(20) / 1000.0; + var color = TILT_DEVICES[hexData.substr(4,32)]; + readings= { + C:tempC, + F:tempF, + gravity:gravity, + d:device.manufacturerData, + color: color, + }; + failures=0; + NRF.setScan(); + if (notFoundTimeout) clearTimeout(notFoundTimeout); + notFoundTimeout = undefined; + displayInfo(readings); + } + }, { filters: [{ manufacturerData: { 0x004C: {} } }]}); + // stop scanning after 5 seconds + var notFoundTimeout = setTimeout(function() { + NRF.setScan(); + notFoundTimeout = undefined; + failures++; + if (failures>5) displayInfo(); + }, 5000); +} + +Bangle.loadWidgets(); +Bangle.drawWidgets(); + + +// Scan every minute +setInterval(function() { + takeReading(); +}, 60*1000); +// Scan once at boot/upload +displayInfo("startup"); +takeReading(); diff --git a/apps/tilthydro/app.png b/apps/tilthydro/app.png new file mode 100644 index 0000000000000000000000000000000000000000..c4a4e3243dd42bd17451f4893c4a4bb8fdac90b7 GIT binary patch literal 14919 zcmWk#V{}{%6nwGmCXH>UF&f)!tTwitw2f`sYSP#?8as`x#{S;7IlFt#{>VPuojZ4C zZkV#76bj-8L;wI#WTeGa!FQwopYV|2tL@WYd+-g`L{3T^c>n(|x1%Hh`~<;4TE`gx zkg)!LLICNR_~3_dE;0%daJxvD2*gaP(JiC9tarE@Y0S?E3Dhralu*&| z9tBd~5Mz2JP{T_nRAY-u3_#`w8GXivffiL337=7cfWe5PCMEw!78qgxN%mdDi`O-U zYm_{?+fKre4l1P0)IjW2%xAqsQNScXwC4Oce%bH@K+MYqFXzhk3Vz zeOB5yMHBvkzMW#|$L1#&&*{Cum@;+^KvOa95_aJtTXEGQ@_a$;_7?%f^QWvdq^W(W$PPBgs*EpUkBuGj+?eEv-cBWbNh0C}%#Q9)yz0>#kc)lV6m(k~_C?(r-pI~q_$89k> z>z!?k^tH|YvJXvI;Pqx!vjPVr$IHv*BD*7*S!boq{bH$kNx#iazr#rb9)pNzSGY?e z0ypy4*=p0pa=p~{mqpisl75Yvg?tI5ci!jwi;INO5?kSqP`?faW@bO%nccAz z7Af6~t`#<8nTnPc7W)YW*-O8ChbC@r5)%^%W=mp7 zggYH~2L1Zp-6wjwY{PM|v3>rH&`?N4+pIOSnU0^i`CmOAoGjMh1;xk56Z<_F@BDsv z7(~1G`NYWB{;j_F*RNmEf5C^5lyoS1@6OfNa#-M^^FEt#Onmp&tAjXZ?5tX|D*av3 z)6+A(m_XRT^U=J1xso<~z(l9sO+i{Z)KO7aS65v9-&$cc#z?yjq+lO(0k$VeZ{<2fPU zXY@Y<5qOK0I`y`z+!896hFwhL3srje%LjuuhkyF)no5d_d^xS}-d>+~2#4%nx8SHThY zIr_Ihk)fC+kd&2Gr2+lPE_LDG7K!TyD9Sblmr2DXIG31%d*jY0-OF*dPINXwv@h3SP0#eD3Ejll&JUKYkpyZZx`P^!AEDI)r?J zMaG}5F%+(t_c~i?h`?is{>Z;zQUCfAnlfamb?>=p!%J@VcWP=XiMtINDk`oRB^8x# z<6%9;Pc%X;>K!ilRDcsYm|R=L^<#yMK)4!Zt+W}2d>ycZ<5hULE1s;Ri~6-mxvT1z zi|Rjk9Pua!GV)(-+mb-Q@MS35R1^WX&qG-P&4CZ+!Ay~yyD7mSpUd$l)4@pa8~t~% z85kMI$HybX!x7=(hsVaA?=tMQYIMzMrPW<-o={E-3JQeNc>D*#agsC!?G-4=AYBBr zYu!bRD3-DF9U_#m_pxXnT`ouJB3$Nc#i2ESKtNmQvyr7ExQgTP>;Y%ji63!wiGxxc zAuU22-|$2Nz~5VgVReN;$CKQS0iWAVDS8mwophId7Te%adA4|H-3ZAm}D3Whynp3>__Cp9%wpt;i{DAPT5Ef zI*YT|n+kIgv3T$k3i5d3p(3=>(nJbk&@zlfI-iVP2Qew-P((NoSh^+VqRWp}G4S5@au0|s-0IJ_`|3k^{%Y#OT z0wnW`^9AhDY?+lI&w?m@&*)o_)d#7h)E@%KJ`)YD!}ZuC8?O&PR1KQ~Uhl0hTn zAwdMxMFxDWU$L62{L^B3P>jGdnn_im<>PqVg!Sd;CylcYM#mEhWb{+XTl_K3Khc>7 zLw}8)*C=N38T#F7n5h?TeieFOyM6|b=LF?swbAz39dUTiDa!M1SqYC31gx8j8xH}o zP_zwy|Lfw3A4`A;kRUDo)g+hlo(E1gH=Ar_=Q^8oLYJ!CJx55RT$723PEJu#C?S5^ ztp&IUb1gL)Ba!?N^K;n5)O1DoQY34o0Y^j7?Ns~UuY$Prg{%y(^j&naNrYSLd3Vef zR7}lqQ3?tQJio?LjS5Ym)@>pkZQ~sPHs1dRgQf8{!Cku8CrDtrY4gO*T1(V+<<(IW z>F>GO>FXZFhJmH}aVw1oeNH4L!rV1%?7pIU#O*nhM)K}_(R~nZ7HnBPpJ>SY7N3(g z?JZ8`s=RNH=Y_-SnQ*UnM-s3;(D<>Qy~^RSNO~k`okG|ma3*SbW@UUYmL{TSmIH7r z%=>vZ=86eujPn(%+G6D|F&c|B{Ije>x*+~T{K#$oBwAu!UYJszHa-1@@< zEwh{I+vFNA7LDRdM?grmTznyt@h%Yt21XXYtJQ4dS-D09$5hUR$f=H;2yK`eGG3dU z-3J!KJh`~II0j8dxc)c_VipDl(@59TxvQ$C&1$uh$ydWef9hP23RR=IIr3!%u)ZfK zJ>8z%PbSh4^4Q$8Ig#&A-%3$&i`RL4Z&k$d7PX!$zAgAn@@)S8w%+DHqn_o6y5|S0 z+hk|kw0eKKY#P!P2mzs(GRBg-XyAV#`9Pxs3g5V}SZXc)ZbLoYA2sO3R? zTl(#2s%*R!k=*STpym2Y{3^>>j1(XxBMn%$d-v*lYHx49+A(lyTL-#%!DcI2zdxbZ zWH#*aWY~ zIlz9}#o|6OHsybR)};86zj1%8rdIPTW{v8^$DAv+%es+!E-d6y#{J_}KLQqbV6SV= zQ;)W8+S*HUEFGLif4luDv;5)R;mJbKK{D#{?+E2&kwnPj|9%K*F`1c`n8}xOwc&v} z#<4mxZaw7Y;7~^DgrOZWpw9>fX4w`3;yVmX*VF|98!y$~z(J1pW0IENM$`S6ejD}; zGKY+sZDWhjBAo)j+IMN#=H)umzbKR~%)-yVdUlIUEYNH^6#a%g`5^W-Av{Y;{&c%& znB)7D=4QJh^w^ID($@voEVjFGj;XnF4eR4X_t7)dK+0kIn-VH(|8CCeE-lq~Je&rP ztGXz{uH|;mdWbo#N#B*9y_K(3@&F`%P~OLXe76U8%b5rH1$EVSQp z5cCnXX%%F0Hr&?1PbeVQE+br~HpRf$dXw6VWE-^G+iic`&#+w;oHm`#wdZBJ_o^UO zj1RVc;AEUK0D!ym^)~B+$z^9D-DU^lgUPJdZDkEtkUN8y{(k1~Y_Y=gt7Vx^y+zGN zhqu65fkl-rkKGzA6Vu5;$11;CiK5q8!|X^2iajIxct5Q3U9(wh@6z+6iM`oe23Rw^ z)(f}4IX@dR;$Am9?!+e~L`6blz@ZR%@bR`-M126csI6|3Tg#WI9m2LR)gQR5IqlZ) zAyyi#Pn=q;)NAtSWz%MLn3yNet~kF=|GnJmL;cxzavk-7tGseNEh7U72xT?y?XOs@ zCitGPGZe#Pz0fW(wxAd9&w!;%V<*e0lb{|`FAynC&gZl%4dQXRdX+9OayF~6n2E_Y z$v%lcDXD)Ly?{VFc!m^GQC7=!<{0ABl5D7}~ ze4|3f%uM`TBDUE$Ep2geaiiUAxr)i`L|KWg*hRlQ20MR&$9g28Qc?MF)v4Yq95O36 z2Rl1;C*Rgh8V44&{G}z5|Ng*ajxY%h&aHQW#+NT^Mc2VaMMZ-dNJbhin?7>Nv{&we z<|DYC8|^VAN;w9~%Gx82h-5C}+*|Wu!gib4DJgnQit96VGlN%A8BJe%2=r82{dJNjsMU5tLSzyQ^t$|fWn_-hW=n!UM&H~Ja_e@VXYtZZdg9v@hyM1Qx3F^~gQ~Vr|8O6ssoCwtqTGDBl+J>}@w*^hHID zsXkK!_y9!^I1{*^t;`>}xSp?p*w>~F1%=D>b_yamI88L>my5xR{}@J(BXcrqS9K^X zFQ47x^Lu%S?fDE2FnWzP%V1xa%;I-u2CMDg^;8N*99h<=pTqoU64SQBY@r zJA=_lRNwk9F`{G96=tKbpy7czfek_LyH2jNjt;(494{z^8)Iq&Z2$BoyEDG}pM#qB@GRMZe%F@*T{EKV<-$k zp$m`(KMT&VaB$Rv!>VG+$w7`k_x^_0B8aU2^w^_8n zO&)+GB{E86sts9^Rr=P4JApHhl9XlsvQ^Xd_H^CpJC@Ak{3!^^rm;%TUs^_{N~eB* zFp5wqM<{CeCG7m&ue7|?s0XrUQBVC#yYo=A(<@ax^!%Nt0fa6ACU?(=+U@$Hf^2+8 ziS0IDD-CAYVNFSBoPCRf=qxfaGJTR`D;tA$hpX57%^ZPmGk0gJugXs(;xldTXPpVo zgn-G8iRsR^LB>P6iVZ0sITt4vn0^HJMW$2?H5dun>R*WPGSI3F|&V$n~k>4|;pxm#-ywtLzNTLAP*?pe{>p;kV zb!7m)Mg;yUBwCn9hNX~16?S^4eHWunp!-BST&gjV$~${t1kNn3y+B+KfS?3}k>*G||Z9=$qi8^~FZV{a0ma>ETp1 zQ&?0YZEfw;g#RB{MA*nc8C@A{w>&)24Jsy9H@Bz$tsW(+XhrkLKdgq!sfE6qBfpn*e5$R!>a;Gi`Qt^9*=p3V%}YPAV-6N$+XPfALOtlZEVPQNbq=^v}#(g|5SJTE|YIV!;>8HqqG zlD^}rM8_b&eC1Q2VHz2WQ7eHYY&}yqZ;t(#%VQE>xJiYc#qX`Sc$+fR)$TT-OMX1l z5YZ)|!kqi^^721QEgJeW(b2WU2x`Ugkm61EQU)TIxN_05(^GH+hoa|6Mx}#1lJJv} z$SSujNaEd2m#+Sev5*LQ-3YO3NLuWJnlMOQLTM=|cE-~pV0p{?a+XV zw`az0f$5Wcn}yqOKB%>3$G$x$jWSHz%(dU&W}iE>Jv=;Ohy^1{o4~PHtyn%RI{NO> z$Ik!_LR!q)(v6mqnWI521+K=R!-~|njLuR`Z3=cdn4FxPS}_$Ln`j)r&2MM$;#P%1 zMO8OGD~ZeIp*B8VtZg3li==4~xpeoS9>ppmlPX*S`WF?AZplb}tRP1*BLF^xCyjO& zyI79Lc1EcPrlg%*C4MMlT%JaZ92&L~C#C6GfH`ba3$=E|1~H)~wsb6)uUCguY%pNW z?!Kko@c)#~WM@mLUo9S~jD%$VOW=GTWEPlUEb}0Bg#vi|2=B~dB zd0hU@IN}-mY%C5i(lK@Ty*|Osmax2UM`RowWebNdqd0$ZTWii7*E2{_b>QDj_N<_W z?}3Mhj@81^fJv1h4Kf0PFsbaQ|Mu1(q{98PgfyI%HKc9t!04x1c9FhHhM*y(Kq2q; zVE(Q-(-z(aj#FXPx_g<$5Jt}RGVJ3-06-+{moJk*y_dU^-I3(WP%++BrQ1**Cl4~4 zjgg6tpK#y5LQZMScm@>6y8MPndNLLiM@B(;16ea(bdpQeV)1QfU zn3w5?)+hK7t4O;qe2)<}~9e6Pj6q<>chR;l>jK zi;A+GZ6sv;f}Dec{nX7{-9?>O$?kd|gF+IYE2z!RV9~X&OfDW9A3xRYOm|P|FYu%P zpNuQ?&%)wj_0IcN*Ap=@qO+AoLT(#v72~+gGpAkdc|ARLi99#u+zbxY2BUR6SW@WE z;%4|TOQ~{05b)C!zp&K_^AG@(?O>fne#bEg5Y1&(TZrV4r@pSh+r@K28o{n<64Hj! zqLn%&#%5#?5)z(#W)$H{q-3a#5AS16k<*y(c)s)OFvyuo$;!&g&VIX|5{83@mQMQB z4~|nnz=#c~*fviUd?y7==&p>Uh6l#97-+V|wYAmjOz)%5_#3e>A*FK{@5B8>AtuI+ zRS=KZcRfZY0S~I9R78Z(I`n>w0Ji)$>Q#GLg7~z6toeRYMO+9;wg{w3mf*e;9GRJ% zLSj7WU0{wr<_-hCH*6kTS%g&i!BXbiw=zN2SdKDn<;t*S`Y+ctCc;{TA9)Hd3cjvR0)wXyLtB-ujd~z(NPX2ljTXKv^uzm{m{7 zW3KL^qyXfO+8Ix|cDL%H0IP_W!4(88s^b=Q> zStzhd%%?#}5H8G;G{*MsekrsTQ(E|*!2yjPdEt^IgpW>3XqbT>pgUGPZ;*o|Bh?<5 zIF^_0m-0(Tf9IA!4i>f$%4sK{FhYck+}tnAOtdofN-lSZ3`!l{OgvE|F5n+VUR)P+ zKq&I}X@b$pc3cCyALwyx-0qWW_Fa##03-Ja=y3fnGFr-eXH4kocw_%y-@yz}x`O%s zBON+~PDsW9U~U$fbNM0f@NW4BBYH`GbMHVOf-%lK5EBv#TC5rJ6t|C$@9|Xy#q2iK z2bPm^WTc-<*(A^zfar!d%hjyolA$2~*gP4cx>7pkOpRGb2V6 zz0}+cDp;U901e_kTud^2PYb-Hf%cb`-N1(g6H9+JQoQ~Ej9egkJDXep!hr57Gf}=j zRRk6uHcJaVal}JM!sWTkJi-WGe%KbE%ugl?0yB893(XlgDo z?|BhpD)AaA){Th|J`&g8kf*FWSL+)1j`*;|ca1Ak^TaC<-6ZiISt*HsgZ&|!w}JC7buuB zLkE(}sI)f<$tC{;0D|HFvj9K@tB8Ym0CkWrhUP#qZx!ERE?Zz|x>0wSd+m~Di;rRe zrb$`rzDRS}Dg4jA$-32mNyKw%0CeQ`adu@QzdN17Y(ex4|Gf>Kut+d(sm+}Z7<^G+ z+l%8gJ$*dLc{h1<>M8?mZl9%&fq6)M_~?0j=j6nNGQ%m;y4Ol&*#O(Hec}rypB|06 z?jx69-rLV#sZC;E!qh$8#H9f`F?V)h!R<=-OLGB(1 zd^mAZ(%m4oX;W-NUlTxnXF;Q!Tk}@&uDR=`r6zrsJwcs7wN$@Cb2N>^ttSY<9;=mC zRpKaLcAnm#W^q{1+1dG(c1f^IG9sDDVm#A$JdVRsHNPOA0qKxC4$VV{pinTqoT7p>1N~Und2qa3leb0^=uwt9 zvW#hC=lC9cXu>`wCM9m-0WmyL)TXY;>R{W0zX)OP*tz=QvUO3gxYDR~yDhRi;9Dt= zZQR3MB2Th!CugVe=ZpbJk$m!23~@5DJOTn9LQK*EGYu?guYogA-oPUu@Z4Sc^O)m@ ziA7lN|NiFtd`F-Xb@M!$iJ=YJD7Z{|L_+GQW7f#=>QyN+N;mfg|tyjqQp^l0eGUx(ttz6e0*#w0BBY;fQJrhLG3<|PO`GHs;a7>4swAp z{ii?*2@w%NWcD{Wdw@FL2S_m>&_nz7c6(Yp9@X3&rAntjOesLa#dK}|pTzni@mPUE z;9vC02AgF%?2o*flSCNT_+#SXl%m~0AjDEgayR3m3>+!XU$TLZG-(~;O3`yZSJc>`Gg3HhVr6A>}W&CC`^y*vFCQB{pc7mF{X*C=qV~s z3ZZZ);Kc*`1GcxfdwYB7??b4msh?C9+aT$gn6fypxFD_mO&kM&;&`f};Ip zH9VOD?SR?0{?tnPyq@Uk>Dv7Ke5a3)kd!ryIXKhVGB_IKoF~(Yy&Xb%5M3-us?9El z;vCcj06j%4R~5lbO!_o0!tSc8J@q#&96>Cqno9(k;x=R2b*wl@^gsP!SRj?z^txsW zMzF@FuCK3;O8fVM#8Rn!<>@-p_x-Md+2_lhA*cjx$FE$tA*~$ zZI0W8-}VTNy2fgkzrUtt^5$1@Ny!iii9*9pPWd{rD@p~7%tyA9;K0_tY;uqzW8DA3RL2mSW4L3LT-w`9GjwQ`+|DWkQB@^ z)L7=^sIAc=^txCFcdm$OyePJ@U?6Yqrs+j2bOB?aR!H{n4f|h9^G6!3KQJZR>=|LB zs{}w;Ec{Z=U`2(X#72_7puTQsib?jjPIt1CTZ?h5+coGcL+}-IA z#}YMol=a4V=y@6^n%0^%2CZggjtM|UmCDWo=;(o7MWnOA`M?Km8;=|pvOnkh><4r=LmwiA3rNKP{QMc~58Zl6>U#N|b)^*_fNFcPByo z1v)ne35xFQ8RJ22p1z7QcZSuT*ZX8-(e~VartRh(UapJPde5Md)nv0gBfb9K%)Ec= z1-5h0r&zAmZv!XxXDZFe8L|nyyz;YD-lK;r6^fkNRHnUt#GM8L;nH#g=t3vHkBDB~ zW~k(v(FF-4eCB+nQUsg90$F*h{VF-u0$%Nm$P*;w@$fHuJu zvm4+?m;-Ln^EgdBcvdQiupo}cMRJ#YrQT(s^y-Thtmn(k*)u>96wmi=8468+)nl5p zys%0$qsVlP9?2Cr+7Qy95el8&SKXaJ!BCkt!*{Y||zmMv;piF2rHZ4?RUMsK@6-1ucWR60D|V7>6A)kj8S9yIPi zFX`kvo&jry!VgGP0s)V{Cln0g3wSjLHfh7>FG4c^+9K@M+t>zC-@IxC@XGX`r)WLu z71VxP;NaIOTQl0<|$h0IH}f= zG!HA!LF?EBs#c@xsZK_FZnaozRb%6&000@H5oM}TKSG#j(@)}mUL7=wnTMdxeZ9|Q zw(N3nXRCkcFQMwkuK=)VRJdJi_=0IK@T#l+YCN+wg zv5AS9Sw2rF5rRZZkU1xehrk-VO>j_9vF~N4s5Quaqp&bnet+`?MY)iWkWuZSoL~IN zjfepB@>x8k;Pq*J9piJ%zT6DCdsxJ;68S)tqDkI*VZV#@d#dO`9D@8Aw{i%u|3z^r#CVPKbC{mqck5Ufxs%o{Cj53xni5d?~*gUoU`|GmP zQC*ScRCX2Pp|G{YC#Q$u8aPw|ZkI#QLR>k!3kV2UT52}DyTB6z5X4ky^U(7@ChRB_ zo0?M{)Y~ig*!GsG(SUKtO+;AeCCMnFmba5zgB%tvF0Nv$`4!jW)6Fi!?X^7@6k_&f z(B%cau)I97aHTTZ_E^RYNSnsi+hb6_EORbV1hp)y^|`4ea=#y8oF3u}j|j{dH6E#X`M@ zel-~u<-?j*%fnAd-4-YFpQs;;JNf7R!_ph9sHw6>$HzIs0=m<;*9!{eR2H2bKd42!f)5Hh)mV90meMxu@BAC zvt#3rl3;_?-so@ZZz_LOG$Z!1$p?hb@Z=N}&eq$sV!WA>mu=p@PG*Wi!S3(vk+DKL zI6kOeiR(bMvdbXBr@9}O&ca2cFlVuD&A$YRi7)*=(n}dL|4jh&G}^9aGN;V$iT8t8 z22!#Bicd>NPM}S^2PThr>^E*6eZCJ!TwPra#Soz&|Hi|`p`xLA_Sx8u#}st|Eqs8U zo;kc)m5Sy77swX$)|};}prp!|BJpNqBXit1ZDCr!DHaS-&bhcUNTkO`Mvqg-7HH8t z(+!42W@KQ13IJ2p=S#l|K*<1f(4OWF|Li&6t4PjS*#WBw(pEeK4>4Tsw85DrwN zyWQCwXYsd0{wminWj1W}d7jKVJfv+Ja^8A*?Cm9w7$6Vv+r2aCJ2bh$PmGzwfkQT$=X%4+PRxfmH;^S*hQ`!*XM5zfxReiV_~pU%f(e{orb?JuUBqFAj{ujSdg9e$n}#Q054!T|w@ph2-HtaIaeCF!A{uUhdzX ztdJ>lED_i1UYIL0wF*OUL}O73qnlsqgfG&EB1ahaKGAVVYj{3BD?UxZRCCOVEXnOUtkI>*JaxiM` z*}l;Z;sLf;^Sa&V9Zvl&$5$_7l{n@|O=Q-Q;*b!qeHt>;(d*QChz?irV@=$hcV9TX zl_~KCv<_knfAzHJ>4|31WVD|xj$#~hJ(*u`vd`JR7JPfy@k1QioaVW>_1a8h-+N}- zgc30_`kP#}DJ3Z`aDBreBO{~U6H7{M^TBOl`IB4#)ZfT7e*;~I0qVuF)vu>Zj*l%Z zUXwn5a)@FZ zLUNm&6IGb@K>TOuc(W&)k^FPP*5{hvAn#eEmd||L`U$3Po>!rv0WkLO>wORIHGsJH z^!Brg%W966j?Q!EmIw6qg7?gvA-c`;xTlXC>pQr9vKx8(Y#4Gm&W`K3*=**SN~O&D zZuNej9ieOSbVp~Xr3_ZoA%ph!@V#FSZKec++Dg*$rD|Y0WVL0r(e7%kbv<6qaCsrI z&<9(O^WIH?E>2!ra)cx_ux~3>&{DC<4oxGux%wmmmwCp;7K|$Rmjr;T8M%Q_v(-ga z&&Oljwkr=h&k58DD;>@$Irj_!KsWvG>JKEgXr=j~?90CmUG4w1)|peoKsQ{h?R~c# zq%C)Uj#>Sm!sX_6f3>70SNT;N1aZhZ2#zDcuqgk}aCyGZeLvBvzcdJ34=V7d>e6it z5gEI3ZAx#AN*-u)zs1q5 zyqm7In*TpKKu!UgW)xA|H6xTzxz*p&i(3SGR1uxd*+=?UvrOQt#f5L_UWY1H)LLarF$; z=-*vnV*Eu#?3$jFvKmyRw78+lKm(?hQfzjCBkMBG0(x7 zmoe0bbVj0*>zreaUXJdE7m{T~); z3h|U#=RlVDEuP`B1Z0YgmFvt40TNKh>b!7nLusM6l z;fk^QH+q>S1HV*dM^xr zgb5TG9Ls2q#eg~SA~La!Zh$D@4PoPjHzR~X2nY+GSB+&5F)vJpkE7^UDCEp{kr;#7 z+Cz@TV23txNI50^+JyFz&t^Q;l7gJVRo@?6umL+Mq=?VX0}K-08=1_hJ+893Dd$Na z+Wpx&9?`Z#+xp|Nrh15`nd-&0oE#bN8)UWy^}qm84A%AX6Z?hYDctX2)R({y;i z4#zA>LA)@o9Nn3N9(K!QybtDJL0B{z+&=-a#&YtBm6^Gk{isQA@h7$fxbre$Xc&8P zfuU??SDjA_uA|g3TBj!`CEY$1j?mH30n=Un?~ggjT3Ddo_^?%$<_a3jp8|B8P8iCUr7G}#jj*9R& z)_fRDEF3EH-0*x>O;#O-rgI=*z{++yR}{2*V9|&%v58zR7lW-AD`gZEs#NOtS6r=M zt%Im(s5<`rWAMH^d+npbdE0*QPL`_%o$j1YUmn|yxlUj2_sRd4wB8&vFNA!-RNiWl z9A48ZI0F1~wO)L6+Ya$_m(c2CQF}yt5k&M($qxusQBjEzx;yL^4K7zNBbS+3xM-Tp z;wS;(r`ZU^iWn46m!aw`$=hO`>-{V~_ovrzo_81&_Vh6@8_(tYT6pFgQpUEx^OGxaIKh zzS~8Y3+}^#hED-w3_OE~PLHQFK7q@jZ)1XF6V?H{IuUflhW*8q5 z3hHF8%=zi&C}w~BiUk!N3yb41YVo4F@1MVv$XmXxpI>LS^=jig{zv^uC!f<_Lk7OL z^QKbKKR$`k&&EZQ@MmXa=q+!{`&7BC$?d#k(D?IvzO8w7X^;nS(9ta~FZ;EMh?(RM zSRKu^%nEy@zP~;^zcYw|0qqFWp{F9#(=;#*bRh6M9yUwRn_HOWLTJ->XHamgxkaD3 zQoENMT+Og*NK8&<*8M%~FD53|8-jpEb+q{~#q#zh_fF=Z)8TcCXW-MbZTTIu>Pu&@ zMLo(#?n-cX%Pz)pO3B-ArGsDab>DZ{P}}1H98^fYZf;oACnYBn3;B4wy*$3{`CwsU zf(sB^n|z1DT!@H>U`L7ET&&jjE|puXFSC4=;!@Ci8~7Lfk*~b`coQs#DUb|qxMzWq zF&OtE>~htAcNf0%R}>N7^?&T}zTar~yzVRz3k4N0Fi$hlWqGwd;P3IVZ~4^{_D$=} zH+kxSL(2;D5{*Kfz1Brx)^4-&)jmh`-R8wVyIhLX-77U8T=@iKBoxJ~#f*af1K}(U AB>(^b literal 0 HcmV?d00001