From 86883e9e32b63d227c312127b66308fbd1d4ed57 Mon Sep 17 00:00:00 2001 From: SEMU Admin <28569967+semuadmin@users.noreply.github.com> Date: Sat, 16 May 2026 10:44:39 +0100 Subject: [PATCH] update rinex dialog --- README.md | 23 +-- RELEASE_NOTES.md | 4 + images/rinex_dialog.png | Bin 273657 -> 632110 bytes pyproject.toml | 2 +- src/pygpsclient/_version.py | 2 +- src/pygpsclient/rinex_dialog.py | 243 +++++++++++++++++++++----------- src/pygpsclient/strings.py | 6 +- 7 files changed, 185 insertions(+), 95 deletions(-) diff --git a/README.md b/README.md index a210c2e2..95259263 100644 --- a/README.md +++ b/README.md @@ -161,17 +161,18 @@ For more comprehensive installation instructions, please refer to [INSTALLATION. 24. [Server Config](#socketserver) facility with the ability to act as an NTRIP caster (mountpoint = `pygnssutils`) or generic socket server. To display the Server Configuration Dialog, click , or go to Menu..Options..Server Configuration Dialog. 25. [GPX Track Viewer](#gpxviewer) facility with the ability to map GPX files containing track, route or waypoint data and show elevation and speed profiles and other metadata. To display the GPX Track viewer, go to Menu..Options..GPX Track Viewer. -26. [Import Custom Map](#custommap) facility which allows the user to import geo-referenced images for use as background maps. To display the Import Custom Map dialog, go to Menu..Options..Import Custom Map. -27. [Configuration Command Recorder](#recorder) facility which allows the user to record, save, load, import (*as a preset*) and replay UBX, NMEA or TTY configuration commands sent to a receiver. To display the Command Record Facility dialog, go to Menu..Options..Configuration Command Recorder. -28. [SPARTN Client](#spartnconfig) facility with the ability to configure an IP or L-Band SPARTN Correction source and SPARTN-compatible GNSS receiver (e.g. ZED-F9P) and pass the incoming correction data to the GNSS receiver (*requires an Internet connection and access to a SPARTN location service*). To display the SPARTN Client Configuration Dialog, go to Menu..Options..SPARTN Configuration Dialog. +26. [RINEX Conversion](#rinex) facility which supports conversion of previously-saved binary datalogs to RINEX observation and navigation format. To display the RINEX Conversion dialog, go to Menu..Options..RINEX Conversion. +27. [Import Custom Map](#custommap) facility which allows the user to import geo-referenced images for use as background maps. To display the Import Custom Map dialog, go to Menu..Options..Import Custom Map. +28. [Configuration Command Recorder](#recorder) facility which allows the user to record, save, load, import (*as a preset*) and replay UBX, NMEA or TTY configuration commands sent to a receiver. To display the Command Record Facility dialog, go to Menu..Options..Configuration Command Recorder. +29. [SPARTN Client](#spartnconfig) facility with the ability to configure an IP or L-Band SPARTN Correction source and SPARTN-compatible GNSS receiver (e.g. ZED-F9P) and pass the incoming correction data to the GNSS receiver (*requires an Internet connection and access to a SPARTN location service*). To display the SPARTN Client Configuration Dialog, go to Menu..Options..SPARTN Configuration Dialog. #### GUI refresh rate setting -29. PyGPSClient processes all incoming GNSS data in 'real time' but, by default, the GUI is only refreshed every 0.5 seconds. The refresh rate can be manually configured via the `guiupdateinterval_f` setting in the json configuration file. **NB:** PyGPSClient may become unresponsive on slower platforms (e.g. Raspberry Pi) at high message rates if the GUI update interval is less than 0.1 seconds, though lower intervals (<= 0.1 secs) can be accommodated on more powerful platforms. +30. PyGPSClient processes all incoming GNSS data in 'real time' but, by default, the GUI is only refreshed every 0.5 seconds. The refresh rate can be manually configured via the `guiupdateinterval_f` setting in the json configuration file. **NB:** PyGPSClient may become unresponsive on slower platforms (e.g. Raspberry Pi) at high message rates if the GUI update interval is less than 0.1 seconds, though lower intervals (<= 0.1 secs) can be accommodated on more powerful platforms. #### Toplevel ('pop-up') dialog setting -30. The behaviour of Toplevel ('pop-up') dialogs will depend on the screen resolution and 'transient' setting. If the width or height of a Toplevel dialog exceeds the screen resolution, the dialog will be displayed in a scrollable, resizeable window. Otherwise, the dialog is displayed as a fixed, non-resizeable panel. +31. The behaviour of Toplevel ('pop-up') dialogs will depend on the screen resolution and 'transient' setting. If the width or height of a Toplevel dialog exceeds the screen resolution, the dialog will be displayed in a scrollable, resizeable window. Otherwise, the dialog is displayed as a fixed, non-resizeable panel. - A boolean configuration setting `transient_dialog_b` governs whether Toplevel dialogs are 'transient' (i.e. always on top of main application dialog) or not. Changing this setting to `0` allows Toplevel dialogs to be minimised independently of the main application window, but be mindful that some dialogs may end up hidden behind others e.g. "Open file/folder" dialogs. **If a file open button appears unresponsive, check that the "Open file/folder" panel isn't already open but obscured**. - If you're accessing the desktop via a VNC session (e.g. to a headless Raspberry Pi) it is recommended to keep the setting at the default `1`, as VNC may not recognise keystrokes on overlaid non-transient windows. @@ -421,7 +422,7 @@ Click . See [pygnssutils release notes](https://github.com/semuconsulting/pygnssutils/releases/tag/v1.2.0) for details of current functionality and limitations**. The intention is to enhance functionality in future releases. +**NB: RINEX conversion is currently an experimental facility based on the [pygnssutils pyrinexconv CLI utility](https://github.com/semuconsulting/pygnssutils#rinexconvert). See [pygnssutils release notes](https://github.com/semuconsulting/pygnssutils/releases/tag/v1.2.1) for details of current functionality and limitations**. The intention is to enhance functionality in future releases.  @@ -429,18 +430,18 @@ The RINEX Conversion Dialog supports the conversion of raw observation, navigati **Pre-Requisites:** -1. A previously-saved binary datalog containing raw observation, navigation and/or meteorology data e.g. UBX RXM-RAWX and RXM-SFRBX¹ messages or RTCM3 ephemerides (1019, 1020, 1042-1046) messages. A suitable datalog can be recorded using PyGPSClient's [binary datalogging](#datalog) facility. **NB**: The file should contain at least 15-30 minutes of continuous data. +1. A previously-saved binary datalog containing raw observation, navigation and/or meteorology data e.g. UBX RXM-RAWX and RXM-SFRBX¹ messages or RTCM3 ephemerides (1019, 1020, 1041-1046) messages. A suitable datalog can be recorded using PyGPSClient's [binary datalogging](#datalog) facility. **NB**: The file should contain at least 15-30 minutes of continuous data. - ¹ Only GPS LNAV data is supported in this experimental release, though the underlying pygnssutils classes are readily extensible. + ¹ Only GPS LNAV & CNAV data is supported in this experimental release, though the underlying pygnssutils classes are readily extensible. **Instructions:** 1. Click the  to select the required binary datalog file. -2. Select the required RINEX protocol version (*only 3.05 supported in this experimental release*). +2. Select the required RINEX protocol version (3.05 or 4.02). 3. Select the required RINEX output file types - O observation, N navigation or M meteorology. -4. Select the datasource for each RINEX output type e.g. R Receiver, N RTCM3 (NTRIP), etc. +4. Select the datasource for each RINEX output type e.g. UBX (u-blox), RTCM3, NMEA 0183. 5. (Optional) Select the GNSS to be included e.g. GPS, GAL, BDS, etc. -6. (Optional) Select the RINEX observation (frequency / signal) codes to be included e.g. 1C, 2L, etc. +6. (Optional) Select the RINEX observation (frequency / signal) codes to be included e.g. 1C, 2L, 5I, etc. 7. (Optional) Expand the advanced panel  to enter details of the marker, antenna, receiver, observer and any user-defined comments. 8. Click  to process the file. A progress bar will be displayed and, when complete, the output file names (*.rnx) and record counts will be displayed at the foot of the dialog. 9. Processing can be cancelled by clicking . diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 69934f10..73e9cd9f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,9 @@ # PyGPSClient Release Notes +### RELEASE 1.6.8 + +1. Updates to experimental RINEX conversion dialog for pygnssutils >=1.2.1. Provisional support for RINEX 4.02 and GPS CNAV added. + ### RELEASE 1.6.7 ENHANCEMENTS: diff --git a/images/rinex_dialog.png b/images/rinex_dialog.png index 4f7df7fd4ed601c69bce23e3ed27dab69a5c6cad..4b668433466a4675a6fc8d2c0e0d2f6a57420d30 100644 GIT binary patch literal 632110 zcmb4q1z1#H*DoE?pddL22udT}N+YRAmvjy_be94mAR=7~5=w&%-Q6)Tz|bHJHFOU! zcYMF^jql#)eZT*m=Q(rs*&XZbz1DC2PK>suGRZx
gbLu?V&~I{{VJ=JuM-vd{F@7R`*|YYS4UEQbtNCqpX}QHY=z6_F5QO0zzw817K(O zjln835r2q#t#lh}WbjEM}=qT4r&gSaVO<#N}Kv?7lUKeA+)E ziEN&b(TvCQ&hWvt`OR$~{ji&XJL`>GP?14>M_ Kz@z5906%KCu`fqoJ~|Fj?f9hzUajVLGB`L6%l zW}|=FqW^#wc`r+SR|G-6cQI1PcJFUP@ZYuLAG` p`2FVu5m?9H(Z9r6ymy@ElkuMtMEZL&cd)epTU7Y-u2=UxiHpj(1GvmH z9o3{1GNzS{6m5ld3Lb~xcX_l+-FJW@?7?Q}Rm3Wibogs~baDQWF#7l;916Q?B#!-z zpq3xpB0AO}KD@?)L2SS)7lc9RrHeQh0eq|1ERMqmAS9~&0Cby|68$GHWRzh|n{nwj z(`ZoF-xHS|9uIz2oXcDUBW{8h!Kdy_G`y%EvJZ2mf0oL$9e{8bE(i~nI9>-Y3u2>F z-1AJKr6J?{xxQbu-ncu5lk~mlIzMrKMqD5Jbct;CNn1K8B -&D ZB2>PmTPs@f z!;u_qE-2Z9C#P(~uuOT&JnN%G4M-M|3nbfL gFip(@NFLwxvcxE z)wue%t@iXl9T5lYzv(Ptcz7A_HI*PjYD;C!HT|qY(~-Sp)s~t8H14nnkPSaP^3FkU zT$_w>{5;Y*+WF-1GBn_oJJ2E~>`xvK$wZP3g@FdTF2>a;VBE-E$!=A4juVg_Gh}IN zGn%2@fwH}z-bKb|C^-{MER!J`!DHPt8oOEfr09F+kaM(b4jKzov5TfbXQDkGxuD?4 zkxMYz=T0{aX7M^dtK%M1su~^YJ=OTPWGzOGT+P1Z6IHz8Ze Fnibw>q9?a5azdu0zE6 z#!-0jmGP@?P7c7vg}`l Jw98Fu+XBftx z%gH-7jh|`lWRRXVdvrIsn5C2mj_Ig&o3U$g`6bfP`dc9L_7f_xMD366!2(4^VwBA1 z;Bbs<=pJ5uoD3~XuzWR+tJ5eZSu$2|7YgoTimu6OKTjz7VsZHD&A-=xrXkpc)bq_q zka&K=qw8buYLukb(xSs7xrTP;CS5I3Ml5xXJqIqvSD+q(=dk-ks2k_rS1;76m!Il| z3JKZ-NA?Fxt{~wqoB5YKrDZRePzv4{in|a!6W5kb<1ev^-Ua`y88S#(0vhx`sqFpD zh!^I(d|qr~JJY|v8CWWW2H_|;a2cREX7F=v3J)S|hSuooA0E`IsTQlO-<|H4jQIVG z$clNM4YdpTn~L`L#-p9okoiwu9mkOcp&oq+z4zTM=iXbn n(}#Y)SYfm~u=1cAv(Qn&0<=?^=-WRk4MmsW zCTATuXcT-AjYKuP3_^3v=J8#Zm}2p79zU(ByBrn4t+DHmvMw;V?)Z7mw;2KRDtKm% zE`6N#fuwCrYc5a-#p#y`DM6dABL^<0hiMB)KW3Tr^FKdwL5 w2LWs*G^W|b$_(`wxm@QP?-zhGbsOkw;4@&znN3fYnuH8_JBs2Es zcUtqhpIq4|3}XWKAC*jrsareb;J>Pik) 8k(Ge-)1EB?7^J-SH}Mz4o`G>u&NtH zI~?e`;Z8KV2)FibaedX3Rjs1N$Jf7~YL)xu4bQx!j<=(Zdae?hURpJhB{iAOwjGWC zuZ;g1o_`mL4r7CDPvl4Xi#33pq@V^ySc)H&u9bL_ts!;N+<0&Ob;-X!OO-aZrD;)< z^A|J2#S20 v>^k#Ulh>LHKaGkxSG*Mdhv()|J8l=&$uL=E_C8 Ni6>zaQeano zAe{!{WHp+`xM5cOYyGeCZWu61d|Hy*6X!UE5E_x&cG)|GceI ngU9f6>-USD#x@m8+^Lg!VU5LPg7~H4PZNc!C%BCK zabX=yjr|A|?GxM{MBF0vexumdyd|0^&$Zmxrfc~#VFo>e&gXGKUgowP!L2Z}o|B@>TCV-aU{7+n)17=sbDjb%%A5Guv6@Fa4c-;o$c-EZrvOM zN`pia<0(>z+)>F!TxOi5(vajnA{$~VSiZHHtX!A`q0ui|A+fCv(XZ9`XY)u2BvSuv z+Xnyj8KMZIb-fAQQ8k1l5}H?lU2h_GRJ~drm?$@*dd>v5@an-c1xd$eq!&8TKT-^e zv`)T-c<=?G;|s)@+gWG=?jG}+k!7aH%Ob?4e`l1wr|6Q&KaXZJTP0E9sxumDDSqrD z`C7(q#D`IUdwD`*e)4xl$-grFA29?3Dduu @PCdD(0mQ$63MC}cde7H{^p@zE~{>wTCleA 8T zR`csVlS&qPxjY&rrM^%EZV0iQ@akwkZ!l|O6}k#7TPp9n__Xl2)#7QR3(^(oin4XA zT{Fjg6FXpWYczF3ae>4N#sfI@6uFT|J%j{AE{-Y&yfNs?B*)tF?!aVG;2K8Xel&8a z+8S_tZT(!?sw{)+M3{8tRnGx*+_%I}mFlZ-N=hOw4B~>+KFhHwOO8>91;>Ji!Iq?s zq0uLm!}U=saMhKi0a5Amayb!YdL^MOd$RBS&M^wKWa7LPe*||P8gQ=7v}Wu?z?O)- zqNT9xwW)Nmys}U4Uqk7M^4gDjkHQc1>s3Q&nJCp`9sZseQim&i4!-@xf<@UvNTr{B zaY5a^SN?%Chit}ooOFtNO$Z$nw6VyW8YA#k=})u}x98yz5Wq0}ivZ>RgXiB)^4Ww? z58e~u4@02P%Qy&H30`)bF4I!~Y!gFr^oRJ?LwgFhUGy#*c^w6T%nCDPQhuQ7PAF%` z*l8P1%3cC&q9HaesCDH06f#2ykx0NyTXHNaJvG@uKoLE0Z)?}hUTM9ofl!uV4_|D# zwtU`awd2p68%wCP`YSm9({rOX z8?G!v7E|%3U-eF3>I2YE^;3B6@;nOlh|SkfnQw}jBSAmn8c2Od5h*1iukjQpEaw;j ziA-5n`VR%Wz_J6!EK8wz@xuvP{k8@T>IN&&Jj+XxLn)vkuh{=;2-lJ7SarZdpWG+; z?##( 5d^p)pok_?^<$)Y z_8(IIQb6Pbrmm!HY^>=2@G=^}#6<&X$3Dtu>$uD0kxXM%^6NKQj4+$#& Rl!w!MBK9t^M7ar6qY~* no(UNB vtJb&jr5Y=E;lPtYAJcc40vF` 4uivR<{nrFPOp~IJFu-p9*VTp?QGEwcB xUnPkKT*x9Wb`LhzW%(h*8v^q zwAa-r&*XIGFO;%Z>XmI4A>%kWKHQGN&V8ej(vYs1TUW5kXq*+93>C6Xq P9Vyxy&T|IB3aAO; zWPm}Silp>acmEHu<}m(} ?$0NUa-WIL8sA+7hbmg`f`XBK;^Y0taG5K9;v z#ca^$l`W_ys-_J!zFWj#X?eW>KK`Hlr@Vtf!Z~|Q&k55DvlD?lR$&CRb^ 7 zyp^9c2#{(!sDN)g+^6)cxAtb5`3^_!c;FJXo;L^burr8^qgpOdLjj2P@bL;xIiZiQ z Mc=E z{>EOMidlER^7RuqH1+(?9+r}@B(>zghB%dAoCLC{4De3HneS!6&4vIp?fj(`O_8^J zp%$;pESvgueJ&T#0sw_deS_C+K%^v9iP`AK{Qa3eD-kH22bQZm_L5;zE)=n~p2>C4 zr_7z=INZk&`>m5h)O-{gU2{Qu$N$mf-1UR}h7gsPFN?>cuwUs!YLMU=J!OBTdH=NG zH;0Cn%!7N_k&!Ki$>b$_<5E21KN9J))RJDlx;Y1rr1=hK&i=VjYBbFX-L)MVOcNLV zu{iASWpy?>aP-4H(w) aC>Dn;gDd~h$3A^VVWQs6rq4b^eGB^K(RN;oW7p{F_f2{Y82 zmr9B_cXEU;zzz+|x#_yU2D4#u*{)$tq8qws{MJp-5S8ib&BZJ{yWFW&A)CvRTEfAH z--er6s58L>pv6XAm&$_z^B+I=c~v)5KTlF*+2M4K^cIIyG#@KY0^X{nsV08vCDG+C zZT3DdVN^eP-m*yv>6DsY@Ie}(-V;oQi9=zj`c{2*xKs_8AgRYFUZ=qI <#7PURRP- z!6T%-f#G~Q%H70fJ_C;4F0Cl`0v+Yrp$QL6vI2)2I+q1w(J2Pb39gGZW}Q2D)t(6J z6W(E?x1nVH2-SNe+>6IZGGlg0SOVmz>0#Nt==@?0`itat6QaRgbA=~M@;caKs?20_ zNY%r6;ilmf=5}LCF>sZJ&7O+Vseqjdl6r&oDA7yTaT)Ct=@!>zq`f`IJgu1ufsZ0T z_x6araRi{VlQX>LWbJu5xSZc!p8YupC=^+0!;qe|D=UrSq0 t`=bNB`+MuuL`4-)n&{Ojbfpz#1JC77t `AGKj7r%^EOJLkme%d zh-vEXX@t0x_RJnadTG6Fa+f>98Y5-N4DNE*K82y=vl$kbNFlv6?zQm JmQb zBJTZPHI^ox>+7jHpm_Lh?d5X@a_VxJq~~;t_fC{KPwTt;Gy)WC9A>Y@@Yuqo_5wrj z=)}JJX(wuWqVd|FjgQG&^E+3dC%!F3^QJ5Hlnef$U!A&m(Nlhe5KM91$r5o2RO>0X z$-V&%#%&Xse?)=JoFd`y850B92H)f_xtePVDUT|4E C@h0fz3;c9bJ3^k4iHIBR+&yO!Unio^5>L;C}#XCTS@@% zj9}Hk_kI!NJg tir2j+Ry0NdO$9@5tut4$v!iPJ+;f*LJ68f?9lERV!OPkg26fDnesDT #{8brP$# zfkTz0=OF{A@{Mj#==QQas9Z(-Y{G8PJgyJ#tG4CTc&D2xj&rUA*varLHd&{FRUwV5 z;nQ<0kOmiz^QHLJPm}z?hT1_<%br=L@qNjo-aDcW<{d{S0SU|qxsdydf~`l&N9sDi z3P*~ZTGvy6FnkpytSu-%ev6;++kI@PuQdef+rqXdpdj@1cChGyAy;D;Np7A4DAPx$ zhr08gO0GkERd3IHJXn=e@^O3+blcRo^RaY*Mp;7zGh+WogUInmrjmjbJ-NG(n*o!O zu`lvEs>nTOKZyo_*{ejU@_SyobGC2I$-vw_+8Ojn5UOUoEtsH8!fRB%6olFg*I=&K zh$^TqirRx_t%6t-=Kri`#!^ !WPT_;Ix58oh z)9H?&>-|!gk!wB{r9hWI5LS(%q5^do4&HW{a%}L2_B{Ap1JH4ZJbu`k#N6)vJ5^n# zeyOYRs!%LwacW|B!fSJ54Vk*C%4>lv smj_b>3pPwZu1`>^N-#*mch~D^(1Jb@Nu*Tm_fcDo8>X* zf>SfEjObrQ47MQ0nI3&ld^t->V-{K>23uEui!Cy-DE=f`!dI%YH{%}e81E*Q!T&`+ z+vnZ?fJ4i2tT!YpWj7ik1kx{@5EDf?!}h$|btb fFAv2gnA=-(&*_l*5q794MQVugf_#Pe$imOpqd2#@qF`0iYhZ zKItOKze{y~8!yqb^K4p&uz$uM*lRT$hsEH%>1|Xs-VH?rp9HDVB9DT siXoj2>ncu zPH?h~b~k$zBqlR1?x^RP?%z7~W(BmOc4e~7w)ToDS0=c7K1MLirch1b=ZrbW4Nq6@ zDQrUZXTo!-2+XJkYG=H$zn8i)`6#^wDTc-~S%#3{lRFD8Q08Sx&C;94?LkY>eWrCO z?V2;uxtWi8s5GZF3suS+X3TJDbO3#%o=7r=cBPkTD10vtL|u{>^~U&TlTA|?c_eJ} zI?3IJLi*jW%W`vbhDq&^<3;u4K^+1O1eYmla;%^In$2q-w$=VRQ>cng#KX7F#DCAT zo%I@&eZiz-)kytAZu=Tq?@t!9RZRG9@ivhv4%lV91z;>8_tEcWF799W8=%Vg_(MdvmU z%eBg^^IaMl8hp8>T9+M1cRHpkAFRuwzW7v=s+egv?oyZ~=pDdq_VDqGtmnxI8(qT7 zyhPB~6h@R48D&}T*fw9^KwW!Y#jHoLWftjj*u5^w(?Q2gW!Cm@Y>Y~LU>s8D 3Jc7#gTFl%azY33*g7QVL37k=71a`>!z z9mz*hfaWC`k{DN7>?-~%VH(tF&Z~^G8qM%z{A;V`*XQGzpAdXvczdwJn}d}o?uvDm zj;pOgC;>X#Pi|9FJ@)izRo}^#W>|!7Qp5;v7#o4sj<2YtK $Q` zR^hs&flloYD9QlDDvZR|k_UiY$6Oox? <>YW?htR*k0 zm5;w()f+fZhWEBhV@{j*#(HkvPqLKU-dkwMTKTN@F8N_H|CFvYmWz)KY$cLIqy1-j z+ *NMga1)pJTR`YXje+?n{=?_< z -FK)y>h|a zuL{S>o{Q+Vn=^pCP?ONe$)+Vv&B6bm#k&On=uKQKf=J!>kwB2M$un{TCq0n=ZdDd) z?@q{aj#6tcgT}FHG$%}d1lET1YjtW~mMckST=oaR*;B_{@BAXVDJlg40>Y~z)xeUV z%k@-z!3VunXK(5_y-RLPi&;`Xc{ytjyjJgQ+xhOgnqR?`UlFszlA>Fk(h#+y+SpWU zS-!#2ElXis *~e}!xeE78=v)CuZ!S503&(@C`n|^-)CH~{uLPW`}nC6dyRZSR$!g#;aG}(2K!5r z0JxDCK`-%pYv52ySIRk-_U;IYJ{N?Q6N+r+_+65{DFUdse_bi{(&~VZH<`$>$X}Y> z+}#rW-imds+H6MhtR$=B44iV8<-^4MPd0-U8zya~f!#;lVCiIaxsNaS c-fcoomGX4t48w^LQwk63J hIv9tydfI)Z?zLl#%;Zl7i z&$akbRgmv2=4dQM obz8b~< k>X7m;$}w74_s#JmZ)SS$t2ULhmglU!Vc(tE zc_n|ZpU{zb8~QtxOL-LD9NC*ByElZ!!s@_^deIrrn@^yMY+d}*uQJ!X 6eTo|5jkg1|0p$*gFnz40b$Es-xX+8R(`< z%jtq@gb+({(-7n@& rpcg|WcI2`N z( !*U5`*3-hKUdgEx?@5)$Ef=I>4HU= zh1cdW>jEejPEDJT(hz|;_F!H;?t-B6H0uY`xU=dC7=8)0;>>z;!6eN2QznqWGtc?G zhW0uqwrrog?O~x4JV$1vYLI#LHo1| ?%5LD7~Ygvjt>vcUMGq%D$Y W};)W_Il;Tov0)y5; z m$$#No-pu4KZ=g>PL^p4yTT;R^cZXt=Ic(t5Y?nh*TphJ*tM*oXJ&0 z)z)|IZHo_tBEx>oyW<0=h}_ls8-jUz183L`!ATqiden FRftbawALC6R>O- z->$PoXjuw9tyN${1F&3qzA1ggD x!dQ)-7p}fYg_;`A@T`R zd-(Zp?$zyN9fF&64wD-kbw&9tyw;Kw77;%2-j7ef7l!WB(mIrOy_M!&LJKmvBM_Ap z?%qgOnnTLMVIFhWO-vpEp)R8yg(%MIZ|A%{H;*EIIEw^jv<) CG 6HGzPXh~4a(`uo0g9L0UOM1+oMwm-8oSRl8$(-qpIh?1Bn4R$;atj@X zke0L4< L40-bD+1S`FBrg-?W75Mh3#oCrKlfB-6h%tyZk5XsXXBnr|2q2N^Bk6>36{HFE(ox7KC z0Me%_S0%BdBr^K==GoWBQ3!w@KJPS19Lv+RN%~u6p2l|+tKme|yV)SxnxZZO- zzLkZ#DSbaqAL;Q67}PCdI4 H%zGVh%_Snx3y=Vq>$Z53o~VQ|Lc zDZGjc+BL5WXwV3hI8K${shh%a{$l3haiT0(^KtIx2un8ovc%b~XEmJbn+kFAv3Q?f zm2ARNFc%G)ifLq`9_lh4@p3B+L^~Q5%EAzEb2eSNU-yu7TQy)st-FHlX3jZ4+IQZu zLEDoD-S-)JLQh>j$!gU^chuk| Q}5dTz9dJWzX-Y^JmFzdD6Alohd-wy&pfwbXd2r%*3`O_S*H zi6wyz+*WGr;B!6|0@^)VbWi-`Pwux}n{6up{OJVslWo~*BHf9do55H}G*eT`=4-6I z?;hXJY!iRu)_fG%jqG$ p5yZ+c|QNc01G7vDafh9u`r`7Pdq(Evhsm0mME&Z(uvaKRRBE`h9}Kx|wr7gb)iv z+b+Ovt|#H)mR1X=wnv({W}SHAWee{GK&NBD+d# +FWU!CL>i%O{MBRlh#-G#z$4 zC;u+F(^1GHaTKAtDO_9ivJ8C!MSqxzn_+519G6yFptv?WY!Y+{)&gBUK?mSRDS=EV zk*QA-rymF1J~^Ln;VCwUd<>#2*{$S}{h<2HpRt|d<{h1<)+@8V2CkiHlZ)6=L^!(STQCn}`QUi7sZ)t!K*2&82>hz6z<-Js%Gi5Px#P zbRSU&c7mc-+3QuJZWA9@p+e4Juj;-M_g-}CMT_ddZ+GX i6^*wOt` zjS}ajKIz&aGg2-RaIS+%;6dQ?Hn;gLCixP4!t+zGa_ifRHB!~N`MeO-3<0iT(^BTQ zREcg$yuqr-+@L60T$xBo{@sh;Spnv0TAN<3N~Ys5a`)VKnLJ}u98U2&&fg_RhPF#9 z-;#44yf<&h69*YL=VGJ786@otAmtAwwy=yAmpT(atM z+Vld4CMN~Ro%iKBJLAL*A* &K*Y2x;1t-;i-0b zw53sgMT+4%bFT;@v#Km=VluHbb4?cu%9rAq(4_B{oJ6y; ){v7Cb^V(DcfPtFd1p*7H! #ltnW-Ht$vsd 0^7|CoAA5F#Fr^8wB zlWXupnZ@Oxvl>~^gy+(G8%>kIenAyp>Yg e;x(G}Y|No1 Tb_gqP!(_IawY&wBV?t#yA% znu~`7(@<;G?}TNH2?lIfb~jprhds& rZp7L;kDQ z%&+?hu^@ 6 z1s^-A?m~(%MOD+pu_f+I=d{{yOJ=_K**~582vNjPGjHNDy-1qD#p#mDh{MI{+?Lr; zBk@)pzlW?C>IGLvOE5hk)pJg!36NyLZyb*j{NaQoj2<$ZFnlXaLb?g+>h^AHuN@D% zxpMLaD8*l)X#6GM?*fX&^qSi%YC`O#ZxDbn5P05yfiKBU?uJUnYulWF%z3~IKo|pa zr(QumbUdw?o+S+iFO6ThtEkDtcZhK3A#Wh^_py^*`ipBJs_-@n6N_$S@yRIC!#Cny z-zn#SS$SnwTkHCPbX?++@rg@QiB(+9N!*)!C_Lo!yoEfC%Eci3?s5cmMYU*$$ aJoPjC za40<^ACtA=cF?x`#*?;Gfn~OBzpB`I%lp=Q)n(Vv_=d{dIO}p1`5`>X*Vn85L&fA; znp+y216fd{7p04P+|EE&Zu(~TvEzy Iae##PVgqpowB=TnZT7%k4hiY)8 z6$2jQoydbk#2c}G^YV7|;NI=AM3CDH|F<40^N%Hw69BV20aUiQdiGT6wD}$Ht_xOo zj7u$J8q!#b>zyOHbFdjWFb}Dd6@->{8ldxdS~lxE)Uq@!VhTZ)22i9}tIXKKLS{%x zyA19T4#-+RMr${#cqK8)8BQ3R_Im=V^-%whYQ D$+%0q~VueBr2i*xuu#6QbtLmtvGG z0Rssto|$cuPb78T(1QZy8E{qf8EQjC#Iw+v!~15wTaRc{`KBU^=sm&|?&nr_oVcUZ z46S6K{7;<4NkdEf`?U&Hu`Qb@yt)QUi*w4{3;} ZgLWn(Lh^k|Co}b zPpi-z@xmba*B_eCXGFL$-2yjgBqWGi3mSyEbE0Ifgwq&yl =P?XYNQ@}MN$Q`W$oH`W8_Xsu^N8390(QGyl0gF zoKX%;S4-5yU8xF100L>+30^!^z`}Tn8*L6o@~X5zCrGQSKr)@nxCNlZod0g?lx7Ea zu6TRMCoioPJpuDcn}Hk~LJk&cAJV?M`PSBRlDU3G>SYoBaCB}%^ZiN2O2A^h<6}aL zXyrF&fUoJ`3@iyb3jJVjQviw6U!&ffqavXOqFXj08hV-Q{mi1g+jx>fVTdCl(tzfn zk>ZuEC$KdcTG(|ErTKRXQfslJj`}Nms*0W9w`+)=2-}x3Auf9}ProqI<-WNUBtbP` znZ>jz* ^K+(F73i!n%i?Ykt|t@SLHf6xVvJMwZo! zP#mEl0S!o}J^!oj^H3Lc75F`-wDBK7kr$Nj2YT; e8OrHeV6L^7bw+>n<1U&nrG^Ug4j-L61-p$sTi##D z7=-)P`zUg-`C|2>xLh8*Z$Com>I(*7LDNG0ep2sT+evKxbj~_q9-IjKp0c@6X9(K+ zoY0U?fV`N~9WJn=gUm_A0BE~`@z0Nlb6Cp|xrP|~8AamfCxvl#S$<*L(Ok#8$M)um zD2~_3 <>6e`y(p6O|Z9f8JQABntB%Oz{gC_XlcoppIazm{zKQ J7lFFWOQ#b$i8LUty#(FQUOe-M zcIW5jZu5NcC%?=+?GWBnML`6CgB~v^kI>7q^a+>DDF7$UKf?_6d-Cf(o#*Edd61{Q zKD7et9RpDkvL|VSS!L#S_k;8&mftIU2`hR|WEac5S{~%mcEzHLxwwJFtmq%H56S4q zAFK2hz4pS+y^Z%_>5u)h(Yc-TYI{_~G~a`dG+=%3 >&&VQlF*H)v^Bf+V1n#g$wF5RD?VQ@o!lpjzFp)65B;k5sFiXYFDs zPtE>35e2)EH`sfR(-ptfnngXpMu`c?woaw4N}uIAtWGycwoa|x3;29YxE~6M17NIN z-dET5XYOGbL1?})`HAP-Vh+m=<&~$~^9X=DwrzhO0K@J}$WX!GSYEI^b-Q?fjO2Uy z_4G2xE&8Rf#SH>S;Ek!$(j;qidCE8M-ohW~(+4!^4!8Bo&dr(@?Hrvkznd+i$1SdI zC?u-~&?rzqE=Qv!HmE;d@u^VrRvLBLdEs4i?rkERE=gML%!wV4AitY<`(Sc;Tl8xG z?K%O%9E=yulL?H-4<8Q+zca6sN;sgT)5T*#B=0H3JXsNV{d=J=ZVs3P*Ij9X=B%E1 zIu= YP9 f^R4G1 zk+gIW+$amCgUPhkUypU5bWrajYIrCpyV&ikgZv7)nT_St`78v$$# HC2t>?IkT*{EP*w}c{%heGS9MZUvQ!UUACp(}qE&7JVQeUuw~Q83 zr2Re++p=k61{V%%yZOdTtttqPHQf*!J5W*KL8tSDdhnm+39-}J<$f>nfxrG}rP-`( z$T23F#O2tp<*aGZCFD XmB!_51UJ(VT&m-!>$=GOJvFydxuhXE(Oa}kNaE~< za|69hT2kZEH=`SA^>Qu|dL_Ds-A&MS%M2Tp!(stm*N1oKKeF<|jd?VWj}r@2@4w*4 zi-eQg=Q1Nga`co|IwebU>{ory8P|Bb5Fu%s0{oWP=3gV4*ZD>gLRGyg+Xwm;L(~&s zyi-@D>JX#*_&(p}>_4#%eYWbpx2=D(P;1?o=h7>}e~v$^ `9Y+!8x5=w_l196Tt8%ty)11>%ci@q|AbfCIC+QG!9%CeDiH@ zq;EPHug2vAarpcr47(3K509wLhctvB%~%w3>saG(RL{OLMui{O&25Ulya5Q4E1;@n zYHrn|()2Oig|OTG^9A&P>r=+GpThGTj1Q}??T;W7)-1qPLsG@2lNig-qy}82)>NMY zXPRW+ *tVJ`QX60Iot&s zpo?g7QvPL5yHsTk?tAx^fqt%W3c4tZMVkw~Tx5+mzSCr$Y+m4%9qQLgf^7${tzt}g z_F@@rjzP(lldD4SdH|7b`o@%?yXM(SU!v=GKnT82ULO6J6ODd}{$zOKvAM?i{wdgV z%w;ccCcVoudm~Zo@L5z_Ap8zUhj!q0nJ1e5dLQHQ@ip5fo(lZ<-G{fAP^uH>BRO(I z+2rWh!RF!Oa$KnOqc5a=qWeQ6pEmBp)=tsKhHbRocq-Wr2U`Z0OU5JtQy5&{u99u$ zcoFU20ZPw1HI}U9^T}E@^$da`pSsh_G(=<~0lSyqL(8do^=)~-E8rT$8LPR2wfWE< z$wU;q@Z@DISA(mBnq7qZ=>VvPi~d2~i&Lrqy-Zd4DX=RFvI~XkfS927o}}$KwkesG zT*ME#l+bO$09yJ8mb`BEAh2|+N7w16lD&CZ9?w$ny$bTfT1R@>b+3BA8@8>Hd*04! z^;FzpY#mhyb>e?&R&Vb5D|xOV=PF%!GBbUod5mFHY%GCc5fEMbpHjteqmb%Z{J^`~ zrv1c_1 8#CE~>Dmlo>{HfX;fv_>2UTbX|7 zGAUr>9rgY9Vnd^Rc*3X%k-635gbzh(f#>&5obSHLO$%nFGvm)X2zTQmU5Xaqbj(m5 zHX(|^bG>o$_aJ|iX4id*x=7xVUIW#CZ~4SjU$lma6P#$s8Q$U~YX5bd=zGB5=d#n~ za@;x*E`nQow{X4aQ|{HM{Ta=ZaUiDjQ99+ S zW|6TrBA;|uE`}=8hm-s_=9dUG!?4xqw_TPqkDqA8z6^n+!Nj(f3a>8YLNIsM@ZI$h zhM3mJU1>4P=GJTDM1;qe^(YB>%7(E?7idE*FZUGHtbLrgcH+70)mtW!(X_tf&4O*- z&YS$F67L2&`Krw9KY1|)cYHR1xz(_SS9Km5eUkG7C_C#ODx^S)Ro6c+_C;=ghf5^n zUXbTt7kNrOjwe%!g~S?h<}jnlvv|Hds>bUjkpEMvf~hZQ+%QDu_I-(c-N$*SHuSwb zqulf~hRdPSCk<_1yK7~1JS=r!Q8=ae{*3zoqL^&Sl07~dt0bnjw@Z?(IJge7gVX0x z*e^b(B?(eI!zva;yo#+yhY)PZB&+XROVn1(S#A~bG~R(NgY9THK)KMm8qqu|$TfDZ z6{W?rVJs#*dF`8^h2nU49ifWAJyCH?@F9@PI3)u?os9675^&nPs#vE6%0AkYy1id7 zAm5F+KXLKr9u* K`b4z$3 zs{OD-Wis|L%xK`)HDD%=6_ph_2*2_N1%*~)DXN4I*X3(L9;eKlUrwNM=)hemD5PVx z($J*jr{CcVgJ2fKnz? *YQL}`9(!$ikop8ucx}MU-Z1AJ3&;m7uXxOd+Nh#G$MGAI4e`>tJVf6bUrTA) z8C9AB3`ghB2Q_s#dju+;Cl( J7{PhWL(XfCB)uu zHUJsOJ$)7)BMN`&qo7p|v?E**&MdlUqoo~&L>PZfKEdz5Dm1U?2f}oI(6fWAI)*up zDvk}w-WV|GLZ{dQFLK(Ch`n4rV=5*?(apd1D2 <}0oh6fWel+()mA%| zP)m;dd2Htr`L;dAZ}Udq &C>43=Lx(k=cN?7aeSzphRgc zqJoHh1&;~eOonX{S)Ky!QWBv_x1=G;HN-$1j*91o%;n0P7A%$e!8JX!bH{Q23DM1z z-|xoxs`pQf43a&gz5}M!qXgzxlag~kybg6(#l%%l{jpd-d2XmC=KjXo`t10K3a^6K z#h{86)00edf)YMX-25g&kcDogdC*lG9JckQ{g4G^o97qJ-18(}>3Kh9U4bs`^s${6 zgW;&laUOmJE(}k~wEeKD9B+prnK?L318`6KXpDe|j}hIc)By%Lc0YV*_A8+|bh&it za4`B<9cvcfWq%xu2`~cNMFzd ?zHg658aTcXaY|= zvW%o-0jX1To`G2g11o%PO78oah&-D}i;5!%pwg9-Q-tG>Cx8NpoF|z@8Q=7uQJvoh zQ?9O<+DysW4&|8cN!U BI zA~!!Cd_>?&zFWftE;|=nb96Ke+UqO?ge0EBe7?ok<;&+vPIO)Wpx*aDE;&{ga2j#t ztDG0{4+C4=Oro= ~ggJtw*`v<-ti=$J?hO=BmzVL;aQ01S|-RZR?Y1mYm{s3hPf2wp2sh z%?nyv@JeYW#GCp}Czi|w9xj(C(UZHHucBEpdwKgIE95Es A+c(T7q>_ z1T4g-W*5I}Ahjp$@7-r0)g=NQ%wIPS5*vBe?V<{|#o-qgzD=E9Y4Rr={X&=hs8$la zU%@GeDC|sBo^EZ;8@<}jt$v%0>AXm#3V5?D$penAh5k8Dwm#|4ijCyokQR{t89@~d z4=vK{#8BTi$oDY3p`*8b5u)ypjBU!wEA0SDMK`C#eLsG|suw8zL$Sh))ml+((UUGF z)3YqVoACSsxhfVcX;&5-leD&9J}( oPN!o=Xo>OD z_-}(ZcjoJ~=PltJ5OnA2^ rIrAi5D$)H3wSzDam|X(7=`RJ8G+FsH~LrG%;m0 z2Z~pY(G5siV4RFm12l8w9LPC$$8_sXx>@?nV$RWyf{3#iN8b^Xdr>fj(}vgI9XeX0 z2n9~piO6tre#4-FsB~yp5mjXg-edlxd%wN`J}84uXj{-)@U@p772U#d( VPYWG*%(xe82`O6q4xedg8dJ_|W}Ri#f(oY=;Z0UJqvbzI>0E>$( 1{CAy=nd2BESXT>9bE}TPv=zkPICFK}?(#fBG(mQ<#*%4hqy$ zX_-feog3EWMN8 MksNW6y%Gtl-E?^WH3CTNh?O?fi>vE4Qy_~8MkOCNeqA3DAHZ08AHOUDEnDOPtd zAO<^rNo%p@td?mWC^RE>*bgB$1YACdFkKtfR7R^4Uf6I(dr iYBOk2A2Q_vAL7qbN8;lge Cy$qEPNMFi!dM1ti(GzBs$nB2km@Y z$Pr$#f4pHGOz`Lqood}t&kgNHBGY1D0bl4*I8x4V>kemNod0^Cl+beu&&;scxA3o> zL~af7+NL#~J5GuZH+%`|ui%xxS#y2rf;NU&_lk4;lu2XgyG8ub{7qj4%@zXS;xOS& z>HtP{YW4_#I9j3h*D0hz&0c)tIR&R`7&lqhS`Y4-? cY)=;TDg`+Gy ~C+DO-Szf&`$`ngAFBVv5X)4cQ4_krQey@c0s-E5GfwET|s{4vVClZ z_TQ1t;Q!U+Xj{>^ DX|Elx?^MbFp*E!pLG`xWZG!{Lj%fakY8^?%fvCJ5-k|l^vg_cWP+mPQ zXPK3C5R`uB*Nt^HJ~c$Mr|W)Vg2WYYsVY%uWo-XXS6a5c ?TlV9otJWBm`-bZr!3RWfC(wE&MH{sJ` zFB(&*U?ahqr@7AMcXl{m1AryeCC)t?m&%SR^bBohn?TM!C*Z)P27_Ni4zsg*l}xX7 zhNelJ)Phpk#Ha^y^GVCGUL(B8ZMT0SfONP;hccRh7)~x;p1@^ap6v7tM7jv5yz_FY ze914%xeSPV6eZ8DKLxiBfNl3u_goS&m5 eZb&3IQ?p`T|h{ z&$?^0i&d*~d^Uz0GPcqxZLrP73G~=onm=Q@F*Bv#%ZhV@z8Jmkd-PLh^uvw(;rYB- zb +=m2Uj10Ep10m0@WT_lNJjMmkd;Dt>&F5# zD=fbBi`pl%N uzT}E z#xs~K``(*mcHq)e1;aUS-im=Ie4Kjji