From 4a4daf9fe726a525c10efd6c6389adbfa1256eff Mon Sep 17 00:00:00 2001 From: Emilien Bevierre Date: Wed, 1 Oct 2025 17:46:01 +0100 Subject: [PATCH 1/6] Add README and change package name to Couchbase.AnalyticsClient --- README.md | 119 +++++++++++++++++++++++++++++++++++- assets/couchbase-filled.png | Bin 0 -> 75020 bytes docs/getting-started.md | 2 +- 3 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 assets/couchbase-filled.png diff --git a/README.md b/README.md index e1d8013..2f47f57 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,117 @@ -# analytics-dotnet-client -The .NET client for Couchbase Enterprise Analytics server +

+ Couchbase +

+ +

Couchbase Analytics .NET SDK

+ +The official .NET SDK for Couchbase Analytics. + +## Install + +Requires .NET 8.0. + +```bash +dotnet add package Couchbase.AnalyticsClient +``` + +## Documentation + +- **Getting Started**: see [`docs/getting-started.md`](docs/getting-started.md) +- **API Reference**: see Official API Reference [here](https://docs.couchbase.com/sdk-api/analytics-dotnet-client-1.0.0/) + +## Quick start + +### Connect + +Create a `Cluster` with a connection string and `Credential`. The connection string supports `http` or `https`, multiple hosts, and query/timeout/TLS parameters. + +```csharp +using Couchbase.AnalyticsClient; +using Couchbase.AnalyticsClient.HTTP; +using Couchbase.AnalyticsClient.Options; + +var credential = Credential.Create("username", "password"); + +var cluster = Cluster.Create( + connectionString: "https://analytics.my-couchbase.example.com:18095?max_retries=5", + credential: credential, + configureOptions: options => options + .WithTimeoutOptions(timeoutOpts => timeoutOpts + .WithQueryTimeout(TimeSpan.FromSeconds(15))) + .WithSecurityOptions(securityOpts => securityOpts + .WithTrustOnlyCapella()) +); +``` + +Notes: +- Use `http://host:8095` for non-TLS clusters, `https://host:18095` for TLS (or your own custom ports for a load balancer or proxy) +- If multiple IP addresses are resolved for a host, a connection will be attempted for a random IP address. If a connection attempt fails, another IP will be picked to attempt a connection, until all are exhausted. +- Connection string parameters include: + - `timeout.connect_timeout`, `timeout.dispatch_timeout`, `timeout.query_timeout` (in milliseconds) + - `security.trust_only_pem_file`, `security.disable_server_certificate_verification`, `security.cipher_suites` + - `max_retries` + +### Query + +Run an Analytics statement and stream rows: + +Note: Results are streamed by default. Use `QueryOptions.WithAsStreaming(false)` to get a blocking result. + +```csharp +using Couchbase.AnalyticsClient.Options; + +var result = await cluster.ExecuteQueryAsync( + "SELECT 1 AS one;", + new QueryOptions() + .WithReadOnly(true) + .WithScanConsistency(QueryScanConsistency.RequestPlus) +); + +await foreach (var row in result.Rows) +{ + Console.WriteLine(row.ContentAs()); +} +``` + +### Query with parameters + +```csharp +var statement = "SELECT * FROM `travel-sample`.inventory.airline WHERE country = $country LIMIT $limit"; + +var paramResult = await cluster.ExecuteQueryAsync( + statement, + new QueryOptions() + .WithNamedParameter("country", "United States") + .WithNamedParameter("limit", 10) +); +``` + +### Database and scope context + +Target a specific database and scope using `Database(...).Scope(...).ExecuteQueryAsync(...)`: + +```csharp +var db = cluster.Database("travel-sample"); +var scope = db.Scope("inventory"); + +var scoped = await scope.ExecuteQueryAsync( + "SELECT META().id FROM airline LIMIT 5" +); + +await foreach (var row in scoped.Rows) +{ + Console.WriteLine(row.Json.ToString()); +} +``` + +### Cleanup + +`Cluster` implements `IDisposable`. Dispose when done to release resources: + +```csharp +cluster.Dispose(); +``` + +## License + +Apache 2.0 — see [`LICENSE`](LICENSE). \ No newline at end of file diff --git a/assets/couchbase-filled.png b/assets/couchbase-filled.png new file mode 100644 index 0000000000000000000000000000000000000000..8a5fc816f7477d815c3eaab8f9bbf8ec3b02b8c5 GIT binary patch literal 75020 zcmagG30zG3|37}p5;uzL(zR5UQ=zno_Qk!SPAj2?7Lzt9l~&U_xMZt1qfMJFN!t)5 zMMKDtvb1V-jZ#_|+Ec&RdzO4Z-{t?G$93-o93=~!>xDtH-w(qFkhAi!5gMI|^mSUFf-*~iaaMNL~+%2(xBp`~dh$P(`|kG%@bTa8<2xn5e{3=J_igecIqc;7zb&?~`2Svh z@Zf)l;UBOi2oxbu>VNPg+`xY)&DT}M+ST7D(9hX*OOUH~z$%_5kY04Qc^r22qHOj! z=<4kc+SOmVUUh@ke|x<9|9ouZJApl~D z%2Y6cAEv^Qt2e|TKL|F8QrHNFi5&3&v-}TpVA$&Of#=&4k8S_6!m#Oi|5p2ZzPC19 zo44c4QdhI9@pa~ly$kCjZu~qP+O}?8(Tm>GziUP~e3kOewpZM8jq`rvq4E&@{48QH zCGC4y)lf=jS4t;+;|1%tA+J=gscWzM{9S9&<1;b$-Iweyw=@i&zr|Kznuy`9-k%a@ z7W>S6wWqfFr>BLYnuCbhgRlQwIiUT)!)bDlAl5H_HLTT?)^zF+{KM5`|i#*&0ASuDiXcxcbu)Z{D9-l3jEoYShmS_)v?K<{E)Dk zU3slNN8T%xAMQPJf8FYZb3cB3t!ipa4gKegxtw7r=InDtO7Wte?Kwkx!->6P>*~1$Iw~1FKrzj^~wBrK^x;rojBtDW9F%S z*C1=m_BGks=(V#=Qwwj3ii|F!dQN>2-|A+M9#|8sAh>B?z~?awd&D@Cie z=Jb{BjXhiK9Ct3*k+n9%)FR`C#6Q+P*(XdJufNaozH?ydzHSZA)mv8I%zBv6YwGFs zm^iuFh0++=Y*xSLyo*Kk_mrWpBg-nna|VJuC=Cuwif#c zA@RP?zkT8O1UJH9IXi;TP-qPPlAm1P)rl9olvF?c^5gp!LfOP`A}GCoFS|Nns4P{} z{G(jS=;REbqgr6q5C6d$R_E3nV=Rm3e9bNMo@|_`mSFezPQH-f4mGup@ABWC7pCRw zNcPKXyMO6yYWf)wWw`YEx6L5zfSU|0*{s#7WA_mysVz@VVhkSN#Gwv>@9r`7|DKcod zz-dWYlj85Nl23j|ZcR8jr*Xt-LNYRPQ@S-pO3I~TJImF0TGM3n36Ih{I}~88*>gmj z?oel{znUFb7?D@f(jQCsy{eQLh&8$GlfRX+TuNcY&CQuUY0izq_qL9Xyp@bJH2*l# z@|y?3wLEkCfZs=_8XS+^6`Ydr7qvD9o`!1Ky}R37lapQI8Cnc+S?5 zH^(NHx()tg$V$^vOjta_>*s)Y`G&N2>YygNgFCFmRNePv8M{>+``Ifwmfxy2mtxWO zBIYW6a&*qS!$H-E;~*Eb?)9TOqlsh=S8_DJPHiqVI3@Yz;+gnJ=^=Q=dZvz+P>geH zJmrf$$mD}VUo6OFZwkbz)56r*W!^*DtJq}{?}pPIvSD3(B9F%<`!gIBb!E710beTO zeqy?#Hp=S1nfN_Zjo#b82k^$6&NF6^k>bE-`-ufVqlS7!DWYvvpW6QXTAQ~E2#G&I z+qV1Nv5sYbGJF%czgn5TFu;{zwDfDPtIj2x*Qb3J zOAKx^u&clC-32gX&hFX1D2E2uQ1ZtqxIWx zvud#>LFv391{9|!A1C}YL zBW=EkjZzk9T{fOG*d*@3aQ=hz6~tp>GbopxDc11u-lUw zL|)y-->|{TV#2bz@Gn-y2@kyzAMiBhX`VoV^`_d$~?U5yT#h{lcJut{EC@heb z8Rb#R)T^ z9p36Ro`!YzXUJS=TrnvrIUc!|E#hz$qvOTP*%bu`=Y5R@YqTM2Bq|^jF#p|?73C5X zjn?|4x|D%@th{@x*$QZ_B&=;hYd^CQ6E^0G1KmVl;z6;ABJMal#>sqz_? zDL3*}HM*@kc{+x9;V1-9{Ot07l=+kCW_}5H(aA`0jJ5XO26iV|YRC>{q;$lA3Yg7d zT@YZ*uE*V9!_Fng!`z}KimYx&0wSm~_KBRUL@T3ld3*W^kLI_C4T>3$<>`B}>R%R4 zoBYU_6MhDx&v;FSEw>XBDc>+*+$jSpQ$b2#i2}Syj{EK2*OOb(GP$qEy-K9pkCktT zDDszt&6AORsUml*hb;V>zzAgr$#76B_Oj<+JpDOet)=&PP*6wvs%GxV(tH8?rW1Z9 zZ7VVA@o-JHSV3=~$llM*AhNv#k~?uhZcRC3+^bM}bZ@@Te2lelG`7-v=J1E*?I~6I z7`6%RdMVqc+k$NN|I#^lDAy2U9tOXAgZGvPY``6jYlT+ z$>vLl+{Lkdg)t&ziiY{eEvca(fGYwBOUEjca2I5c|&OR>7Y6bIrPgYHfqB)z)rrem*L;_*y(jhTnXRHM^-ktAk3Z?4;5d@!NR9y!p~l{bL}%7& zlBF99)L3KS%r|&T7ow#mZ&7@7P}lu2c^r=#SSN~66{^@h8%2D~xoME@cuHzP=waU8 zlO?85914IOGV!Z@xCO&{F89mP+}$*%jkl;qcLpL}m60teYjSIh)I%Rn8YJm|i=={7 zSY5*qqf{66Z-V@0i7?rqiV&pqz^3~g=buW6pZ%oEBqHi{PMlGy0xRvJJiK`3bl`1& z0U&Pfw-2@tw!H0wXzG+`u|1NaMOxRJe~jd5YNI=lWW5DnPvt};NsqP}u&*PUm09Z` zh=BT|h3e0ljig_+M{(dQK4ihYga@BBii8AN9go6NJy3nvfLuujLKfyXDUs{sI+MjV>q~ zndbBLxRA}{n0wIY$g$zEH5hiL>n$#8!M%_B{CWKrG9h)#$kBxueJ<2#TI|`N#K|x+ zd<-DOx(Ib$sCvob_8LfqU%)F^zo{WPT6l7F;$`swIEg;+A8hHrrMQnNH-WH(dhsoC zawTn~ojMD}f%^mmq05A6+Y(^sfGM{dkKAbfF+ryYFm{axAE^1JkUoX|qtq?&SpiDZ%tW+p!#eOqM)N9mIoYhweu(Tr&9YD7q#}rE zn}2+Yz(`q+P}@V=biYy$eLHDOE^E{VnAkjOBpj0)6-BE)OM_m z>=yKNGGAW%4%+i|n>OLdXw1dZd5hj7rBPPq*8F7fY~Rn@F>x>W<89nW=K8nCXvdtn zyd7Vg>T9q;8A|N)$Rp@8{DR0GWa+-dXOaEQq8Q7O$Nsk5npZ^M`NoZt!4`ZVF(*K z>5Gvzv|pP(FmkIOPe144kAOyZ2qefNoc2aFS{50T*^PG8@yO^);3SaaHl$r}6+o}S zE>l5Uo4pj0#|^*_Yc0}Q0~J6<>aAs8W!PsU_E~$z_K*p3v=Kl?4vc#G?-DklAR8a9YD*@@QkE#$J!@_ zvxbmKahc>P_Dr`JfRRHh-w^Y_8Qwz07)xe%3Jj_nDD97~^c!=*%IA z&y)=aJ0%c!>v1a!uKEKz_%Xg&Ons?nX=d;&jCBQdT@9yD$1-Hb)g@xSAkLWw3{pA8 zM5`7wm3wSKI5@gemjw^ zv7i7OlEEkqNPO1+16bnMuy%L_p0XLf@K?$rEkfS!R z-!YmEB_`ml_*e0`&vUO?U-J>`8YCjL9*V`6J*Oteo;@;zH*PnPoM<8qV*g^^nxkmV zk3CsM&mm45d>fJlAn)?`D4Z)Yk%8bD!kwXoG4B93X`ID`<=HYQx3HZ1W{gtpf)y-7 zo;@TV&Jx4oEuor2mB-)X;Q%_iw8KSCP2~wJo#zYjVJjpsrD&V(Lug6_&`RhPJzNie`5)H zobfdVZPFtxiZK$|-y#ajtw&4n>SZV~tpLoFBmKkdB>hFt&B>BL zOAwyAalF6Md;0L<{(0cSPOzX7s-sv1nx*{!)EAp%eXO`*z+oOjRvbVX>#$KAm`S9? zaYP7>z$!%I?m>d9NmwqqeyAG^=u1O<6aycC5fU;-1kcRWP$@auF47%(RUR0cP~`2{ zifW;T$bi-^r#&H!(ZZpK17I4Gmyd9weZpW=mxEJuKAhaXB<&Y)WDW^?KeD)oM z%4}3nLzQtqk~EedIffha_@X~JWJ4O7a$i76iI9~e4{ks$hhdf+&6jkS*Dmx#Q6(og z(u#W)&jP{upSgh2}651dSrN8a+!FwsoyJJOktj!P-hdo znuUY_#rhY8VN|l@5ozh14qi;5&JI&%Gon1gtNDS`9I+3uT@v8?dpFy-T+fe!*Hh z;z&ZQcm&}drR7RZuoNm~h6rvuUQPI!^I`zSbuYmkBOG`+szaoqgp`FKy((5s&NlV64qF0jG(NkoKu;xkRO+bBe4`obF12fIl_E5ES*MX-SS zDttNnBTNqJ5yPkgqA!I0XaifFp{D^AAru-IJuu)9nSj$e1cef>0-}hZDW%>9b~>(o z8)b8hd8Epe8_EmbJpBxyOlOuC7m|!zY6s7#bZ>+BMo$rgMr1P{!`C3)n{X=#nMISY zkW}P4!jj;Ig3lK~RALS;n~AYV9)3O}{7`tNpiYG80)8B!{YBY?eitFu45mJvm3d=j zTlkXo{q%RspE0}*!RH_tp7lGgNg5$!Ui08X(SnH10ieDIW*R`x7?TCF7zLU&X=vi- z%iriwY62&gECox5qe3S18Emv@r{X{#;dp_wl`m7qx8u0gpVzNL5{S0z0-rQ0g{AQb*?N7rs>|HvY@B;R-UkpKi5_*Smv5wD!tp#uArx8?K=lzTc^XGGda?$o2Fct3 zh2R0m9+M4tGS6wSo=Ul-2lu~rfu-`nQdC%k+Od5ITjo3q&|7}Q;jti54Y0#2$Sz&A z=?)}IarT1{-ab7UMQ#vK{J=z%U0{IMe<=p~lWnHlDCi@3AgAVrseq*?!l06bSj)Nz zE=8YPXZpZ`w8gdaczR*!j0BKvU;qXvm>P#nJri7t2u?nlIg7TXzyL#Qyrm|lhWNIwzb!_RrFmByJz($6FBAz(_nYjx!q_1pvbxh++E}n{E|(+HTTwfEV|uVtcK) zH=LHV)u9#9u)+)G8JkHd1==P)jl7yRoCd@2T(D%NIEdH)Id>9QA^f6wz61?#f%;OB z(#z=iGi+PyxIRv(nge7h%00h&{C6(8J8+lS{lnlN#` z3nYH*1L;k9!$=M;*~`lntoI>-WCe6T-hhIJ{eXg;6zF8h@oK#O3ok3P?hg;)lF->3 zAw;f1n?OZrOK^>e2wg#aj^*U9BOK3hz!4`dfg^fNN6h}MIG{k5%CpxAc)4tlz_A6u zbt0g&0#GOi(40Drr2-zw5?j9;WbEJSyJXBkw#DqJk`-87n74D}ku(g-%^HrjNTBin`e0tK@Sn8lN2CW7>bRo*R< zqdifLb{~=uq2EPXf!Wmr%(y1&Kl5e&TT8cKKC1~)*aI1h`T+|2cn$|ItK)@j`tbl$ zQUL}EJgqGSttr9rh%{q-7b!@3)XS+!99tN=MIm7`k+3GH#U9^ID#$hRT5KqCm~!mz z483rEU}yC~=A(Xq4(UASE)h}6!!u^qRX{`lRwKK>#3khm7?{!pn{H<^Y^B5`%B~bc z!}FXUxoulSSdWpc;t>A^@JxKP6weG*b2_#~=__CUg z`nly#=jEt->p_&tT+}xy$kFzc7Q&Ah{UMCjQ}AjCN~loc6}O3Ixiw$#kuP{KUtw6& zh%YGyLEsaJ>$^Mc`gCgF9qazoDVvNJJCoIStgVn+CVT?2sP3iXk@1}Eyaa|(rAn39 zJ^;kO0Ei}_FEqYRmV>EBGQW(Vw|rG0WK>bxVuZ02q1w%h8@+*NR(yc22Kvj+4#LtW z!{9c6;vS6fyx}xKVdM-x#FrBDY>y^nz@xR{ZHfgj5CAT3MApj{d-I)iOOL5+;=c@F36ndZ{|S*(_pnJjKuL% zI=z;e6%6Gv*d!lMk1mH%C-_AL6l;ySZP6mE`~G0DFE``v?@+0&!0KC75Li~ zP^FRzEI`vc9isIdCrF?wi7+MhPrw$+S@8^8@JQu7S-}?EF0FAf*nlp3-+_!gkTDU) zd%hGv0;4@}wDTMfwGBWJqrWVWV;3;=JYg6E@t7h5`p8ML>7Gwa=&-B#;fp@wYZ@*I zMo&f>lRzt=p|(<>8IjI>hh~Y6n37{q`o*FZVR>#dsrh%U(-S#&1bnmvnv?JLWLbTd z7G?d5L=DYB2W~sa=1e}gm5yl2(;84Zln~*S*G!na7^XEEnt0dnwHg0Bk@HZ{e4VKP zt2emqS`P7;e;43jZcP+ELRmI}gktT`ald*Y~Mx5 zz+wCh#O)lA2aOZwt}o$E#tZa%JWQv+R@5AxCq_EL4^=?pYTs_6jWd-iact1!|uk_sakfDGt>=p)X+ zaV(@#HTI;b-%dUT+l^D=I1wQ3J;301*B$-fCuWKRYDBAS)Fg-q!X*%A{-pwZ+xo9?>|IIQU98x1Szm1Q(TIi3%}?-Ia^ zz7Wn89Y{@uVjBU4*l>OJ1ArF=;4|7-ql?ia_GC#~`Rx(t`AUfm`K~acQ;c=m52lR2 z9Y6yvh>g5{9KhzUV!{0fI?iq|JF4a>YPmI6$x=18w19;#9pywHv@ngJ=>{#Zgd&v9 zUvMAjas({2gv+r{fgX@IFLg$G(13Vht8VvGhY#^uUvpBj$Xd1;R2ltYCT|$pqRAE~ z^&aw}_4*Z?NYjJ*2U#0c`DTE<&19K{py|Lal}O^nllvW_lEdc1iC#QZ zikE?y@!-g4ev0lQ=qs_?-v|8P__Z0nRLJ`KJpQ_>g8irDYa96`b~5sHYqFuGpBj{5g2Oq;-`DaHyTzKR1{=+&a2!S zn30RJ;=ca|Jq5&O74}PpUJhSTESpT6Rs#n;kmlNr0rr(Jx2#nU?VhaS3xX+s?C0Sg zB|@q(+62yIKEhF_Upe0zm~Fc_(FZ3E4S=bG8Uqp-HQA>78!@3KQ1wXARa~}dG*uq+ zhr*I-dBW zz?8s|tUwP-#tex*=t+?-b1qsun1K74 z28o;{0zK8eIZsSHj0=fHJUjt8kKM73T*b~JBm{AeDI#IYt+VM~1=Uf`Z-9uouT8^) zpcQHqWI*b)gO=PEHr)ki!O`##F_?kabU!2}R*Sx03+;9+~_;B#VOcgiAP3SA}5?U zApnFp)dU6G+35Lk^n8DYfjoODV_5?q*wiD-5;+#RHO63Z%FMAJ5*Wn=O(b9@mdTrm zfj{{|Kp29<-#fvxSXUqzHW)z}NT!e+TY*WHPSx{rAVMx>GvG25I>Ngs81koP5V<g)w z?($%wnZQW7$YBYT&0*o0h1Rm*d{js94b)9Jqd@dfz~HdTm>lh(;=mhV5%pVWB%hwf zks}5L6&@?L;R2_u$T}VREo!S)vnX^^_pM+ONZZH96cz+Ms2)sA%@CK+PtoCI?-k(~ z$GOapmRN&+WD;jSoPU6aUV;f6^%KoLx zC82-@WHy*UHDm+n^Im1zxU2wm%oPulIGz0NpB~)~r#*7ecrZ9Wg#=7vOt?pEx^qEQ zsGFm9-L;O?VULl^TKU+g&ka6I4jufN_a`+A^k4>hsKEQ-K8irs_qD;^MG@|En0MyD zkRIlp2J8}Y@?~pk*_V)nftJZ07lq_aCQlUS99jNB^xH0Bi zZh6V2w;2zH?$_(|e;61QZ>?zc%$4o?URv!Flh5lLu}jUlj8fWIfiwNC3mhVug?qIn z!cmC#ZhkIgy}h@K)EvB}e?@0HRg(gBx20?o49`7@m~1`)YS*#^PW@Pe%r1z&`xiky z@U~*GmvBtrYzpK#B4+kw6InlSE8H${7Hj2hAhA`p=_A8Fjg#1oCY{jCw%#HlGGcoV z)qZ~jp#^aIG)9iw z%Qg+!Mq$g=z!s+6&SPcdxXYYL)K6lRlyD;AW^8XGY+(Et4psa{8`2Uu8MV^rDV!A~ z4BXN$(h+U<1^H}DWt(F0k#F5-(hcIaijOr!+(QqwQs?HJH7JB3Nz_eU-ou8~h8mUc zzGtt(B#xtPKRb`T`IA?2`?blbnYsxmFzXCZLc7%I%%E8?RyIn;*5-jCWFVbg8N0)T%3RVXb8mlCO!U9IA z9Q&J)4Y7$}(s<7IA7ik>4Xro@E8u1n`;>4+RGy{ZH&rX!ol)4AYCzqW(T2WcPA}oT zgP&org>ZNaIGAYbo=1HE&gUVTFV^MwPI28FU&F_=xd|4LTOk6Zfcc5M@Ulm~Srf%!{y zL@5qn{#EcI2hTrSCdacJb5^|^?FE2%C#X!`NVokYfZUU;m)E{8Fn-bBuz73-d%I4hbxR_9=xeg4@`EtFVL4mWFdw{nnh;EOF)_BgaP%F-n$(+YdX{|e8 z6A7@(3P6}G*+#4v7>+gbGa+M8`A!z?@d)-X8Evq%;8x+mN|rp~=@wimqDs1>>n7NK zM0%GrTmdmC)P-TN8m}9~=nsN2ai5ln9GP}`u$;HGY}0IF!j3EvBJ{-lP_nIgqEe>) z60j&%TM^_%)+-eI2*S44J*X`lWSi8$vfSGc8g3XAh7*oSoW}wgmJ@#4Nn7v86Oz8u zK#j*}he!p8R=m&N54w!f8=zpz!ejKMpPfUul99G8e5)<1Q9nT&Wp~e_7DMQI__u76 zGifg)^*8TDYEt+bIQOE3IDqQ(fUn6*vAuACi|{)m*tXp*+<>hKeiH+NYXb!m5BCBP z8k0=|-C3A7TW!O(HZU4~5>V6O^tG@|u9$1|Is;-D$kQE|z{K#O1Vl#oknVl0#?8b7vaLDxy z4y{?0P)rSn&{GcS z4}IuyewO6qHel@pur@8+YtoAB&*8@x%;xQav4*t0V6SE*l{M=(R&5c&Fs|A7Wsz^T4+vlo!f~?_MF_cfZ*Z zGJ2Ko(t$=)KQP|@b>LQu4m&bhU=Svy$cp={clUJWKG4i*(2Nc{o6(#p2vZa@I4AG! zO`6X98yOqx@fQ?eHU%};8n%j!fbFn2g}L8^s+3qe4|;+xhGjwSj{ zSo}Z0ma<_Ir&-|GbR%DHGQrju+uJdlSJOcC*(oUTFo}0V0N{S8@xZbF7;UH`xOPNL zF27vCw9NOK_&rj!>c1&*#KK(!I}J8o!(K@AZ4z1VFP$YEHEVpOj+I(aNQu6Zpys`l}8RRbqb6j z2`kpKm+ljoFsFz?mPUkXi1y3}p^F^Pb0%u%^O(Xy+eL^8qrmB2zrzz_V1vPt6+#bg zaYF_CsC!n!A7eMCQ5Qg{SjkRy?&3RDgWg_q?sG_*d!$9bREc6ew;|yv(Dss-1&F`& zJd@P(P0Wn7iDKz|Kj_l1CETk5ABhuG)L3%wH9Wzm+LG=7C0kIv8AI=yP*tyJu01K^0OzZl$Kd6hYWPVU+cgx(LnT_jIP$MT06H zjW&44aqbFHb5E_vlKZ|l={M#kc>P<10ei7f6=pq-gmQKaJEJt$;oSvg&w}A;^4{m6g zDZS%cuctwFvkl<73tFw1ZL&?$a7musD@cD>-4g|d9u!M6IB-6DGbpDPHr6#rPr zZUeRRnWn(5(`V-rW8}L+Ct-HvSt2|dK%JZYcmd{n5?t5pm+Ll&E69)3_AZ|5I}2XF z97-d{ApG$@UgyT-MuLIxT0Idg3aX87gyRmO6)p=+AG8Q-cLO6_wG_-tFshY(64GIKp3d~aqp&kRsUs*nv1HBZ!YDd`>X5+cJu{Qn<)j)E zhRV}?e$}hY3vltF5*!w~tTP;-3msA-J}E50v1QGNhzMF};dD=E3cqw1lX^@+sHSHG zyOFY>q%GX(nCI2l-X6RxVQLhF**unFq(F1l58-De=zrahTPr<3*a_zdaO`My1`Mnp{=xtu9FBo4yG{|@HR(5gkilu93b1o z$X?ZMLKCIOLDkafl{#T4%xLtx@MY2=hxQo7*ZHJHtX8JJDg zVArJ2O+l!n9@Kxk1It+n2(adLKF5fM*M-909qht~U@Wl!=-mK%wf2hyff);GJ9v9z z^3gcNBouxB;BEFoCZ7$*^FdoMC8aCoQ5`u>e!LYf#9z9XL7}Bvhx@9V@pl zYv?e55&I~Lz3lrWbj(Ywy-)!j&G;mWnPtcJ+A&Hm3#MLJUZ)-8yMgXm_taoN({QgM zc3sybL+F|9AqHt2M+jb#wJW~X>WQ#!j}{53Qb(HA>3Gal=1|3sh}~#d>6=Q zSHAPHF=h?yhHv3O4mbzVD^u8bu`Gu7lc5kale*^(hXR}$OK~Bbl*)7!Ml@^Z`-TJA z4M5hCTPKuXYmOAWRMdo#}|t!`r8fuAk}V zSvTX8J$4D^mF0|5{RkO;e4tp=%V|d@X3oN#tb}&~+HxhF3Krk9hTdWmIi#R1^Z_iW z9i28;zLUCX)L@^6U3&jrn6y~ky6fx;R91u5U18+#vaV=Sa!OWFdq%Dzwj*#>GJ6KL z)?o@dbrnavUa>AgS!@a=n;d)O>0&_~-VgPXezDHcR}ftWfn$QmGZ)S{;9~IbPV!w8 zt-E%G*CHwG##d5UsWBf~zNj;wGk8H9>wyX1cgA>-&<}f#djTciNzGJ1MlL{w(lu?_%rg7!0F*a_QuBhqN=;1 zn2zA`n!j9LD{)%m#jHnv1F&I?k(R<47s8X`hh)prIXdv~Y;4i>*xo1j4zfuwI)bKe z*oB0_buBO=CWTS1$qIW?Y}w5wxe=+_`8ksC`;!p%QGqU;-eSzZ^DO)(AxcuDA9wqU z(6@}Rg?eUvc%PoTdub1}d_g&}y>IbOVTxj%zK_Z>plJX?uL8d|^>Zb62n$a5rtb#0 z4?r9B3Y?Yw65j5P5`r1i4eZ1xOLdOcc8FreKvjmAfG;ji*?eXm;n&Zr8Xq438>J4P zn&RflvgdVkBw|j^z+y~fn=}=QuL;9UUFFr$hKcQg)3ezNuw{h?h11YcvG)|w6BBTc z_5|(zb)A1|A&(pXD<-VDv64^T#6*AhESp$yY#D^qd^7H4yeLNyN9h{}g9%HhCn4D9 zNJwE?_9|0q?J2Z#^VATFs+@sI?3QhUFMQevf-|<1a|Mn9vO!3y2;Jx{Dna46ZM&d- zgvZB-KEuj)cWYND8Cqe!H`0WqIM(1fWXhcedYvhS-GeicBCGXs+QQU>X}qq5?@V@d z<=-@-cq?PRs~wjK(RRacU!hx&FT);dmmj#5n#xK2R>1E$vA8@lzba^F^CX;Ti@W`{ zp|Xl*MT!XvFKi^8H`Pc0s+MV3`}MG3VQi!BPD$ddshzK+0_<#u)=eRaOtBZrF@6k= z`75A3hnO~U4`V&jQxL{krk7<^osy(CYX;^GNU>}j9h_Vz4Eyw@!zK7ZsFooh6vKPb zBj2WseEYsDDVrTbMf7Z8N=YRZ|8?gbu)vv0V<1trtfMO&^afZSKJd#JN+scq7keKW zGBK7R^j-14po&Ftj>3UNUJR8sd|i_u(dZB^$Jq#lSautt(~zoFy-n1%>KQOx-!X-a z?2bELuSP)xcqyNN8pTK$(tH~X;y8UUC3BGedz}@QpjN83%0O&J$vf60888@O!L}+xoykAs2&3G)OCBIYs?bN@9L;B+@9-kNSXT3mCX2yTI3Tg>4|!!#<94$0_aM zHtEOz0^bkQmI!s!t_Y24X!a@|y~_rL@RcOuSM-LVDuZ|iVb4zb@jiGlEp6e{i_cn= z?bNr_ofXGCA?SNDDhW$rc*5fAY9Wn$)dYu#5y!rC(uCC$G`FXSG&|`>h}u@DIWKTl z5#Cb~Na;bf95SYCzJ!ySJw{P6oC+lEua_m{E?(vNcm{prn~I=VJo17|q););^^h#8 z`Qf<=C>um<5PCf8Ln9=MRh}$(59ZjDcz^UHR6Xd^{?#FYBLby*na)3{pf~;T!@>YV zUsa%Dr*3SMa{1foFV4Cu?EWd>EB2QH@V84pI`1z+9cX;Quc@#_ACA|G^qieRUkF|4 zA<{paKLmwSZeMTNrY*JemuZV**}cX$1wjLDPR}fUtc2y<=zXVjTEJbRVa z`bC&c!mFixMyZ;KTk_xpL2-ZR$Bt5A;-#+BFOBUz+C57meFnYOjDt%Q?@G)}N^cu9}`{uQvEuX8jR9JQOdTOjC8)olCu zK!6U#8F|=N@Y@@Htq}Te#I#=rb1m_z5zvmSRI;Uu!*`BidsA=?5B_iI2Rfl=$OA#E zX3#$k9qkq@rYAZm>q}wrFflJDOACZqm)cYgL+9YY>6&PHhcx8=CkV3cVbIDIc0 zR=YS0SG%d)kZ3;vh+Pj|z6rNgXd`;^H#)ok6OFwPL%B3>VE|yQP;IhbuMF274GK%- z;QIGfVHU!?pGh&mSv$Jt6@r%SBUGoLd_YUbPTevds!}r;^+*s9GA{`ZXR-EeaM+av zJ8P=HWUulSK@G$a+*YpG=+JL`MX=6~ZYE14z6V$YK9~0wxzx&-%1$|j42E8o z&c1iW*fy9{LIkt)8xlq$y7cHrJQLcPjP7$5pF}t1RtQgzF^c4n3HNjNNeefTOLd0X z68w$e?=Db({r4j5^p9KcWtz$dpu@b8;o)YPO?i+n|RQ|ndixLaWYP~_yR$Z10*5W6$V z>vyBi4~9~Pg9TgEHEnOa7=1emVm%x|DJYD*n>x&eQ}xD;ge8>SD%nOF$9=B!=ekej z--bD2w>PeGjRlj!DEpy2SfMyj7{6FDBj#j2R8ZZZ7O+$6NUN~&fXws{Zj~F;@P{(i zbHt$VCjmzyYlI~v7TV)X^y%&Q9t$r{UxW=lD-gyV?6;((J`r)O z1hPvHE-7p%u+=}#85Bm@80YB1vub&Pg6NH1c}=#`%qj@gDK3_`%Y?YO)Nq%#Z^ccc zx;S{_i`Z29Jm>YwGV+qnzEtpRGv0*zD%?X5)-_BVZX#R&pUBg3k%kqaX;UGd{-wmC z&@HP+R0_U!genSI(_h^hi!5HxUJRv;t@LegP`-5R*$;*SFh*5&?%|A#!{>3h#ea-;|(8Ey5N-eVT&1?-CqZVL6uyAmG|a z-;z+mlukqo>L&Us_m2A*Al?QJ;2lUv-oFBg4NTzALPVeiK3@y2-I+Gkh0{~Dbl5|n zF&$7f?9+h5fmYL$lP(;phi~@sy2osYfvGevVP1qZS4hb0kiPXo3BEq~ZVFU&Cl~if z92RY#1&2GjY%yU@!0IX=Ky;-BK3VH0(*9ikuCQF9&P{qMvqB1s*#v`Q^jC(>o|lk}G}&L2wJ{)g={ zm5-uxZ2w&LCTeEF{qri+=<`wKn^%*{XjZHw!bWe$SPVyMyapnF5mMH5~=)TQ0eu8rf?8o^6*kXadae%lurqJi^FAR@ARusHn zaKTS3;8@7r!Zj=V&Ym>wUh% zR1v+g_uDOel!2F7lv)#{3Lw-tw7-7c=L+X=d-cc9uFtM86)I>hTfZ%W zI+I!jA@{^;;e|dNk8I z_kT|gw$cdhy|`|$KmF{LeyKh19W@)%HE$alj=a4dJ@B?JH`GiaJ>bTjh@XFNShD8g ztJRC7b|@)dr+96CqcvC`z4i3dtvZ8485FN;`wppXDWLu6UwS5s;&ox)p<92v>UdM; ztrUOd(2w+m(OcIniMBp8{G7T>d;QMJS96~=H~ao^e8E8xy770${BK8^=NAwBR52eo za8PGu(3U5@;6K!)7oWB+ku^LguONB7E6XS&sjD3RI%NY3E0t^CzHMD1een95^DF1Z z{-LJxyN3(@_N(ucufC>6Mj0FQcAkFp$a=}2N)@b4ax>R{+NmtLxp@7&IPRtkrqj;9 z-F9um1?weePd;ki%T@D#`tQHfo_;8oTo^hev%0S=GGbzytn#Y|-yNDxhlE@7X~7pB zLa&`V_4Ak^w^Bu7;`NRWvoG~?GrGFoY*@cOb>>XBRr@vsx2cJ5*h#m6Pbn1pvrmt2RWocmIWmI&qa-1_=HKV%uV{^yoivKNsui|+VN~q3e_vm= zKJ=BE)$slGrd#gS+x)B3KJ4pneY3A^;?2IviBlB&A2W5Z&&pA&_Py(=k`DEc;<$)h z+7n9KJU#>w@^!HF=|5!*E`X}wk3?oyml3EcZ-csedR@-$)wxL?*SfM+T38uhylCnX zR!TmrQ1m!_Saq)C+@~zo{+(;DX6;-Od-8nqUdyO87sm!$?tkr(w|TgAm|RS|XysW~nc(KO z#N(Cu)eZX69)9aH*lg=1via9;y*cuyjEw0qqw?)*Vz(CS#amxIdD6O1B~$i~GiQQT zA|}N5riPBSoqaVK*>9-Q(W(0heL472>Wfd$Sa)sPbjBB`gxv6BKh3=M=+O>;g@IFU z+y4*)DgP8d6Lor|c$J!F@HMT&`!8z+_}*$L$=}`6Vz)u|{nDpt`WgQ|5>tG2HS_m5 z8bf*;?0drZ-)SiE$MdF{(=SpDd;P&c8&Xn6@hZRWFEi*6Su8gaCfb*}@{HVMDYIlvDUXo*7v$w%czETITer@9_qyE|hNGK7GSiG( zU%kijY&I+zk{Ky5Y&$d@9T~P|!;(+U`fy!m>9w76COKvXYFx!h53?nIYW+XX-ZLz! z>x&mYfJh7~nZF7u0tTXpG!+D-8z}|_l#WzUdapyDF+`bwfCd5Shyv08u?74(J$bVr?ChdPG_zrSKhh0%tKV>Cb zSkhZ*scSRjhfVS78GPGhRPjEh!b4r0%hNPu9L~r1aH&8F>&u5#5F%A0^A8B?VP&wp z|DDF!_Rh|s_6G-iRAR+vh3yAjUKW}+{%*aLYGFP0UMnV^<9dfCkF}c{H>in*ibz@b z$IPdRyPMB;7nv$1cQze`To1#Z&*hg-%;u-nNuNI3;vA(zLK7mS0xN@(KeID4`vkoW zTthWeh;u+>c%Z6+Oy_`mkLePzLOEvbdyEya8e9Ik!18oZa_%G(;#MU7i8!#(2+W=C z=NehD$^IYe&^E!L&HI6l9J{2|msf4vSL%$jZkz}h&o-D;F%T11VHZzr-*k@uu7pIcj)k(P%9+=oFrd9Gte;j~zzEmP}`_kqA%t~2(77j*l|&7T!o zYd-1D<&U!H-k_PRX@BL zxz%V;vbr)@QaEVXX4N_N;c?ZwdkjpmKAbW9#0p$~zOC+ws?d>~FB5}n4=-Y86KrJX zYh#|qvNv$-mv8Zz0GqS>REj&$-x%>!SCHm`yiLZ`)bv@Qdn0ktI!#6|C*CX1cOsg3 zTvMG73`2mmi;HN;!|R+<9=HqGvnN^xe0HWE1k`M2WLBXc-Ilj}$n@Xf;St`7ZhX7X z*{wAB%)z?R(EzZ-TVOL-j$n0f;eP)6ZXWd*8|fM zqJf}lNIZ3IZMn^`3j0AgNpDjQTQ|ipHKxUTn{0d%S&g){Y>rTut2$#pB>kkjS?xtz zn|r#UF`M6}NW@TQ=~!sktl#@E!^6rG4_whLkGx5S4%aJ5_TmQ&T^6*$4*yHEHm0ool%(B3z5-GU9MU)r-f{#8uJ~G=#E;&qbc*?FLhG0CW2% zm0@e*@NP;~kDR-`^IX*onW``WRn^&e@8R8T8|%UHV3!j4y-V-jydj$H-eZbg8^q>q zgh;WmV+U>;SFQw)g&5S7=9k&_DDe)^Ef+;KfkIf8@$_YzupthFpZfC<(p|gnrsn;< z!&!z-I|+-7lP$WY>8)ze`zJ^F^k(_UK8|Rb+sHvfnRMh{jj6v z{L0YUVQZ)P&H=&JX9vOB`xSW2`LT$349M1aE;TU(C+@y+8@pyQbnAQnWQG!c2>TY` z)AKdds-)Tgl@_mJop>@!jR!tKH(ekyGi^{?cDHhiKg{dXvxZgsl=eRicsss+P1O?e zVG|K(c@|K!B31H<)HDoHA?!k2FTTfXvbM1x=e3m1mog1Rgala>7=ItesY5(7Ywx>J z{CwlAtZf$XVl43(EwN!BqP&#(5Da!HyraPOE1BvnR7iSFw(3f(U2TY6P`^ zoqW@q!KHZ04CkNtRgA##Cn%5&SqzBXXhU@32JRQ z8&??&q*fq`tYzHdJ^`4D>#D?XMwfFIl1 zhV_PhlsH=rzusjWStHd7QX0&2%=(u<}&M{zOi{Raa(7)tlhA zWyY;p#2jkIo}h_9YZ#dLHC5d5+s7)WdIm0AK%i%`#E$iMCpr#cT<5kcmVy|V-n)v^ z%@c|t)ma!Hz|6Mm20Vdut&gz20>n%IsgZuksi~`E|L!OC*=*_6#3$6~s|}p* z5;J``u^aCtJe>s4G+{a7-o5+N>i*x0+rNJGD$~Tzp_YGZq6}NL_2KdE3(3We9r8(Z zBbkRv?m_UY(Vml14ktXnE9#CDkZ#y#P>gke55^KhE!PoRnfxdI8In=LUYjBmpZKl(C;WZ++JvuqLJ8mM}zyYrS ztFj<$F-h3&FVW>OJA-A;<7N(#BCdD7?%5t%9<7(lm%;9r=ki_xT*xI#C39?=p=;9S z9wid;jF=u>wqBYTd|tEFZ*r`3HD*Z@oVE|X>*nEi34uaBz6G8m_j<{Y2!9aB(&GC? z#784#^e5-3Uz>-d)@=P&(k z)kC%iTGY}Ooa>`6&q-BIzN+UEfC%57_zN7=!NN(8bQyZw(IJZaVxsTsrT-M zyG$ap1x_9H4xe`q30Fy?WzFS(@`rJ=2d=b`Zq`^{NwgmFnM+%%`F^A$#K1v@2g@wa z(#M6F0R&6@BlRL;^ETZ`8D?P@tkIM?Lyw`~(&yck2P)QPZysD&PUG>(DYY>HcaUR9 z4_nvIiFr6pFegS|?!&5y5?T9o7C%AlV#f-X z&G#(L4|g{bhadx68$U=t^{b4W6mj|xLN2s?4}}Cu5UKht+XS~;hud{5(H5#42_l@C zB+^N~8MvZrTvbx$Q-bccH)U*JU%xlqg7f}0MKrvEacaNf&F|4ZU{WtF_YKzwOiVUO zAvzYa++t|#c7ymxXL{uj;x7v2F`bsFsb~4(RSOTM!v-aE%I5#%{p*X|y#19sj=ojo zvF|JGF4@XLo!mF=N&Bbyu$qyKXaia7@VxqNXFYccH};S`8~elOB3~1_W_S_bGu$~J z0V2!~{J(qc+Ad>plZD`Cu)_0KCsqx2{_=b0x0cXg47=}6T1I0y_Lw3#YvxfEAHH+7uh zO3U__OiS6dbdGV?mNFjD_9(u0ZTc?i-^S@Sm|Y-5&J?{^gk3Zl^66OT+K#%Wk^a?a zw{{-y#}^R#*i3 z=fh;??hU|Or&jw132OtnlMYC^!Evr(u@&`Qr}ob?JGJm$i+7^8jNul1u7#WjZzHab z+dLF_w!g%yM=sASqTZxT3=4L}E%r56rT=eOhSo!S1O311lj$+xi+5|6DZ7J68mc!x z@qtLvI6Iy-beBouJm0$yxmDkI4&fFo`!&ld&tng^va1|A)Q?J;?3gcty@4P-K3s}n zio@F1cdL_WSWen$FkCjVf-xz;$jz>JK-1fS?xgqf%e{DQaR~{z4Hn#58+hMzUIm3y zFrcPN0LZN$tu@M*94(#rCY<_22|RVxsR$L@(?gq)OG+k72I5L8Wv+;1SJ>BsdiGFZ z+`M7kk?NBsw~^n^KN-KZJ|HOXczpA*Ww|X_IJMT+rGx@;SY|=PTj9-x%+tFYT<|f` zGahu6H(Ht^eQeNG+J_LX!Ax$i?qzb~8aqR{uBZIHPnnrsP*ZlL)4dE{mL?f!HOp8^ z!$|#SEfd|xKk>@#6tzbRR=AWPZciJ*97GOaGSkyokLNoq@Z4P9uG`4v?+1Ue;Ltd=aTCMp|8! zMUgD1;cR@Y!SyIB8Smhvf92i_HnvJQqOpL;2G0A?-FvK7;ZWpK+ulfY;39?S4o}te z)9v77F5V$V&k>=LbOnmRRVAJ9O4ZuNX09`EXSNygRj)Dw{LZV%taIp>D=ZZ3VxTHfJ@9Mhv#9EHIezb%89KfE zLJxbt&F5T0U@^bm=*#n0C&GKnDL0tR5lVW;w7?wh)7;%0QdfZLMFr!@0*w>#7uWtW zKK^vAvu!`ZuiaPawYID*TPTj^ykHj9Qv?lG#~nZg)pYyvUXKbqQr&nclJj)4c1w;u zAYcjV+81V`^HHV4+Q*E1>?Q_Qyvp6>uD}tSHMUvMm9B(wRRe)lJsDo`Uy&BOXwiYqB5i#(Brzd8IZz^fW*#nCp@WO zI9bv#mRspQ8b9~>iAqX>MDpG#f9tmoa(0alA;_)lN-xdF6?7v8;8Rwo!-kx2w@Qfj z&@~zA=60WURnF29-hTGIgWK#Jc8|OogPbR6^7QUEoR+4F(Qd%LDUOuhUWy%=Zr@zt z!!p!jRe0W7stvEdW&r+sK%!$+@LEFBhiFp;rReWqkuDuD^y?BlTmAA;0BZZNMAXW-yHa4lOUw`vL z&3ZvNkC_Ce8r~|^UR%qj$>lkm1GT$2Fcl#QE_Qndi^{!0EdFP>mB1VTvH&GteTHP> zG-4VkRpjM__PV-Dnsd872G0#0z!g}9!@CR>A|YaGl@XsK_b0q?hS<3}eQkH9UOnR|$NDkkl>G42w_|QSLMWEL5Ik)FOU3NRV`4X3Yy1Qu9e6Co2oOT1 z{34i}ac@4e8)L6P7cnmzsH-<{;$rT#n!pOE25y2O$@SPsoDGrNNml=OGKt4i3e)kv}8QaYV zCay+EE_;$z~7B7g%^W6`lzII zP<3ZeD)>pe6_Nb%2JgtHsv0l1(_P{#ie-{#b{_|dSkbU48sn@3%ZR+jcY2uA+>-L; zS%+&HIy~Z=`S(=){7a74sZ&RH#XidV;@#79*O!&B#-SW%9nC6e0Muxiwc)}IkBqP zE_(T@Td_d|Ug%|&B6>a_x9GU*eTMr1Sar0WP=``$tY$qlga9RZ`L)212Plu_|}&tFP)=9qjj(EDpo8bkiB*v6 zb{6=wKIy-j+TPb&PnDvc{T?=vvu+3BEY_YwibtttLzg!gQ=!CLJH;hpVE zFdEu!{i=O7mKWj%b(H#3M&}EN>*N%M71IOb>Dh-n;`(RN@(ENHpk-fh8b6}`5)$)V z^fqG;XRHynFw_Jg5N5a`kK9vhbKG~eKvr9}%9|zyR({p(@kF+pLgFrPrc&z-1!+EP z-GbX&dU@S}6vXMx`}YS!NjtVB6V2o)tO7;FJXWV1cPCJDpmVvtB}a;EB2y^Fr%QBa zQ*P4@>H+KrS!Voxi{?^AL_E5DE6y21nx%jk#%!8yu5#o;JFVK~uXi5!@v&Igf=7v3#Y;N?@ zQFEOwdePmOs?ll}SEXvo_`w@rFw)NLe&C|)n;U8X=&M(*yGr~CA938T$+5>(oIJhT ztHt|lvSO;&zr!2*y!|}RZpDK)C7tP#c*0ab$PkxRy_)?_!-U(bC+$RpV`|updkU+NRvD2z&1Q@mPbnA3r`-+Uub#h&sm=jPqp_PU%{# zOo=<41+JD9Dgs0$Jo{=_)IEMiT0?}gbZw!&=bILK3#jHI{KRi8ugmWJCCm@rB(PKA z=@#6kTVo@OuJQ%EY$hI!hhW!P`8PzM>x1xiU_KfsK^uHg={|ERCEH*QQq{cu92duk zg^c(a$lbCO#`D?yQvSm@ABxi%g`96RdZa>eAwB1(bK?Jm868vAj^6P&`1yK1-2;KMBOx4Rl zqGx(c(xQ9t4`zhJU6j67<3P>2Vu@1S4XXGYE-ojtJpu6uT&e$5E=8^>9Z;x4-K~z< zlvm5KW;7fHXW7(XP-6Vc^XGx6EZQ#CTMYHO*MX}x#9+oiy(0Oc&Mj#F*$Ehq_Qwl} zOD})79E<}H|NWk4ba4QKi7!A}&nt5y0`;xI#-6qcZgm!HXkU48cK^08Hb__^pYd1> zfhW{?J-?JFPQxVIlZ>=@t}9nufvCur(4!Ys9@sKs7zfKMLjxvw>CHyN0wZ5a{_8Z- zBU?z=T^I6uu{zM7dz2|zL=uTKpSmwxdg{b33p#P0%>$Fg(G3vZH7&sRMCjCCuYHtH z+=pF;SL7zvacCcWm)4NS>ZP0M0;u~*{$4PrriYY@VUb#w6nMEjE*L9JwI8k5G*mhQ z)T^5>LMAvpN3OP{5+p<{8ERGbSB-3xDEtLsFxqr_=hds0O^JK)rz8s?kNb4&(bgV( zridJusp5l#t+;_(&QaI&Iyl?xlG7<7<-Z#PW zK2f{0kpnK_+7tJ^2|jeS`w;n_vx&}|;u`6NVwAml^0~(=cRpe#9AFtc(rAdA9YU}# zOJK><2#{NT;s`g;Hf0{rLz3qKsQ=GCSJ$?nj5A>gh~s|qPEfw*xMw@dI(oh?_$C92k|}h* zOT^ggGBw20_q`=U*5?sTe<#pRbY6M6mxeAM@1o2-`>rk8Gm>fY(QGpVzU#)NwYU{D zD~7gt`Id;Q4ul$HmYJVUu%$cMAJ2sFN1!jO^YbBOMZ4ksA88!VmY#Ui4|%r0&B$oa zelqkt6%0Fxlk{1U4H3EnoH^&o(z1$$*Be+9bYgEiu$Z=MS6uh!QSl`BVd>5_Hs!BkB!E-GeGIZ-XVjq{N zR;VMT0^EE1x1pQn*^3<`Bi#d(PtN=-@(R6{h!7lJ6FrQHDqgxbYm8WJaWEm7>2B@a zMzbVCYyViTqMkp;cVzHg1mp7ObL#*z%r>BL|V5^)`WNYaHhD@{HVtm#Rv6>m&i)7!p zB_$P09Y;9ip9X4KYvX}=?~ z6lvSD53yAI>yAD?Crag%E}3-XE>zeKqN?=ZBIc%TeL!CkGBUU;zs4WMjyeC26d8$0 zCMo&(Z&ARe3yLgx2qK2vsgp?I_2V2ePiR0$`M3{`*(tGU{4@YRc(qSuYz)jF+Act$ z%9Z@AI9VmE6ykcm!PB>5;tDA}9^H(IfzyTDGM7S|nhi2I$lMzjlV(avY5!XHnCg;9 z@B&f@Wpb*Dg5kioz`{FpBkf|+3`yhdonL*as_L&36LSkyWqQHH_>wzxNrKp8=u`=i zCZP?T$_5?eUSvx%L|SntV^hdCyi(HBEdZrQrT_=9A;Lw$&IW#^q3@jqB`-9#HcLi< zKp#8P)%QoXuY9IDGEc-MS-$w&nL5O=l!biYJ%3mGG4D(^M96+&hRi*rRhX64g$>El zx@I}0MxG78$A5SUPE5+_0jz+7zegy2shvx<<%oQu{?isC_;QzxBQ~W(fgf;wj{AYZ z`X=Sk<;P~X&tvIpRYDZ%7_+?>bcB$?Wg^rY(YE<%+pqzU@$)UQYmShBUYir5+(@c9 z?21lk-1dw2$LqOsABN)rv)!^dM z*sqF$o@BEDYmJAK-Abe_icIp34F9Gp1FuEV7IdExfG9j2#E9@xt{{1v6O)Z)hagMK zXz4b{N1Sdm8&fuS5UGZsA22x@%iX-_wtO!XQh{ZC}a_iJatKJFu8m0Y{of;%W0w+LqHJQ_Md=Uw;vp;rD9` z3M@gzy5b1w6O^uMR|~%U4CC5Ki3OWPMgRj;6dq=eEKx`rsS`z?yDiPFW=!PGy-R1R zh^3eXr1tN#tn7+lqr~)A1^iFJS3~7K)Y;Ya?z92iYV=kGhA7q_%xSeEsHopt+TY7L zX3lL#pp(@cjizx~aMT&pB3n){! z5oJpF2^3JE&6a;Gmm2l|d)e?lSeKoGuf1SJC~eA@nVAnuFCTk}23^jtAdTI^aX8$% zah)n7y<*s^Ex)V3Xy*_429$+u6|M`d{7M-jk9!HVr2ZoAc1pN6k>2#R`q#ESDfjg9 z&6;7YQ8w2$MpA$)`E_ATCP;2cfn+OWAgGT>_#LD1$7N|L0vus<+tXU$NC+=T5x?&!u>OmDwO~lxC2O56*M3lBrHDENu&3lE&!YDMHpJ5DKxkI}GmR_K zifyQIrc;v}Vv2*$`1mq^q3TED7@XWrAcTjl(S?;$JY>FCmkX83X|M+hc9+E7;uPwo z=u9;gv~+SQn1UR#*NqXWZR;hySKh*p2_kWYH1nOeAGoj{sT}`>%aLvb{oMo#Y1b|? zgI7GU@>0Z?<{evmW5CoS%GpzU;CM1h``TqE1}f_I6POTkYpn{h=m1lqTt+1tF9Z@8 zF)*ZxL7vSPgf#MWoLsMXP0*|Pc8T(2-r**t$5M1jSL`Ij8gY7I9`v<;U>@t#(AJQ2 z1{QcCg4=9{hm=?k!2`MBE8(hdnsVGY?Ml+~BO$4b2;R}4o4)p=;7^o^@hQ#_ZeqRb z^s9fUxE*S^@s6NylxEZbgb#l_LjBV%T}cE>C(rBr<9bDQ|x1h2s&K{Lz$G3^Oyc#xy`+tpJq{~6M*lBfT>@#mkT zv=kbSX!9?4+%LU+HRZ5Mf2PLq(lg7+@>+dbdrpkjvGW!ObpF=qES5%Q|ql z=d2z-QjNVAK)F`C{q5}99z<1S>H2OGQX9xBL50vK!LC0TklJ{QglVqBh^Obj51c)K zAlPWHRGd08@-3w?o3LK{rk=`3FL-)jHlV_C3;VPSnZHM{687h$%=Gk%(IlKdV%>*1 zU%C}sK#z!EsgjXr)sA-wLt5q6;$~ZZMm`PDM0n{%AE?YR;-&r`${2`zfi|#K;9Wt!4i6=$%*^{15kaQJ0%A*_;S5|OM2 zS_S}7LNpyd@B)p~ftfSt)V(|UKNb>`EnuKrvu|VoctmdaBR8#K+`s-EHz#<22NC`J z38}pzGDHQj{wb6r1-NcnB#5`jL{5e%+I=^x<_N}lrG1=bfc3Y_fq&I< zqdE+=0fCj2!UeLJo(;6W3BZ)lBP<+?N)%c?oQ^mS=ZVhW_=_gKn4BDRcw*>YgrZ*v z5|f^TN=%KqZv2rOHZatm)ISmaT2PqhP!jPxGj@`4(JARJ$mAwxP%E{Qe1|qVk10(= z{7D(`&x2THWTfK4K`LWV4vm}{KH|)eIN{!3raU@gs@>HrLofe!kPE$j{@*EHfRi}G z#^V55*GRJ1xLppydm}RPp?Z^Uzn~_^L!T7V9k5FBY_tL(ybBnBxv9Y z92pP{Km*1YC}P?iqJYUk4kd95qML$F{+?y3O%@t}2Zb8YVN8i0pEE1d7{4BZpCo`r)>Q83Ah?`yJon2~9&vG))G@i}K zQ0sUV`YP*rT(|YD)Te4QqVcIm!|qJF|Ib?T@1tQns;QX%{&x=eXIK0Cv#WYUqrWpA z?K{s|GUq+pY-Kc6=hhdT@y*HzR(FE~GmEYk0b2tmH}j0fciF%Fb+di+-F&2Sv0N|K zeB9e=ZoF%@t@3e7@Hp7Hl|E%6F=D;!fQfg&R2koNlgys-xYafUU@1&4So+Po&BlF| zrQINVbtrsFECrlU4SW6?O`!Ya1o(7_e$(sn`PVUM`?vG|29BRJpovZtP=+JbP@sTQj z{pE6P=VvBLj%y&U%wT5HSs}xh!4-*0b1TWEt?F%qGV*io&!<*`;?p{O6oDhvOLx7~ zw7+vC%~i8*MG&*Ac-t$s)KiAN2t%QSA)>G;X_nF2%wy*Fn)KKA&pJ37eYQ2YYJJ?@ zXtqSC)BTvX_FRe36Z0b-7g7ebG3VonS%6ftN%!L@WYxIshi|bt8}$ESH#OYjco?=@;ggNg%bDVCIL`N&JCP32sr#XCt5 zGH1k=-%)xa(&#lK()=sLEgOcNsH_^hZMuN3*q-t=@A09IDW4+ZyZeJ_ZCfPCO_8i40AUy~E{#Y1(I$Z7g>A|OJ zj`!KVl}Bs|AH;V(K~3q?Fw{k4y-X%pl{E4sC<#CB$qe$Z>BG&=alBZYNgh_Os2NUo zAMTB)UJ~_oRLb^A>nNYJURFyxGV3ALS5ZWqRg=0^BJ+3kTDfa&9`?~t5MhTXjNr$< zDJZ0!2?{O%5m=deJ`3&dQ9RLGo>w7ccB}hlr2CVKZ03$>HNtJ_(D!FNp5hdy?vcA{+XY_%$p%wtkTSz=5hkr1bhH*Y$}U7P64HvFM)FFwR1bG&)epd z+h!G)eH7g!-vM|)5*6{>eeoXoTUy?Q20l#F@xbbe1f?)3+d+8BLi2JCy)mlOI8*cx7ie*8`GlB)HEs^{*{NDN$F5^G!sO&PVym=Hb8 z+D6`C`1SWQo1|-1iR%m3$|j*+Cz8je5E5{U?f7vx^?>D%Bh0mNLdCyRBRr%D4c2^# zv?w{LjLiBLzwA6}5P+ZfAqx~?qA?KA_<|EBw^ma$qg=vAYp9ed12OSB z3WcufR4>j1fycQ-@{ehv-C`OcMDc>)jogx6XMwnNY1tosLIoZ559(d~-VXFv|2+OX z2Lr@jpVFSw0wVa;hacg@Q-~IpfMiO8^MV`{6?oSUQ~o>`3-exb|3SWC^Df;4aDdvf z=x8GzS4G*$#*x!ROK3`hCX$&;V^7jY;KZji8%2fa{}4-C zR?=%SMGzZP+rLvPY0`l>Gmc=)iL`O?ntT_j{aOwGfFGxdqm6_7hds~JQChl!2p4D~ zL2A>V{NPT`3(z7pTBZU&H})fLe62xV#s7~d+qC{KYgGBcR$UE17cbduqvV?&0BDh0 z>)o@!R;?oLcnJqJqU}9;?0sExQ zsdo{8IVv}ZnyIb3)`FkA*oCGtBG$mFC>pMjyuCDjCXrX9Ow(W_>t2(Ng55X`rxyR8 zVIyfXG)4T5!kRV^2CYx7mB~udO^qxKs71brVR(Y|DKnYKCE>>w-h-ZOVA2Vla<#uiQ+H z3}BNw2a**z<5OeZw8>4mAQ}L+f#QiIl0j}HD7`U=-w!-X7u_+X6SDcmSQ9kkZj{(HiTa$WoZ1cPxDqP-H3c)Ax3 zi63x&kHaD(*{A*^=4W&WjV+=CV8a!f{(|)=eLikN9Tz{50q{C8+PW7H2{)zbG14qe z9``>m{{QpQcK9W#qqJE-6AvCl_A9+*$K+RaI#Y%kF$H5`!Oo)e7VAhZ{a~=OKL|NK znNUCigxRVun=pu6BDV2Hn6o^~?EuMlTXb!kmMFXq{?|(p{1{Kna+}{cksZyMHav18M zr{6W}?_6ivi?a0?#!CT|1OX*TkaW;TdkEHL2<*Ac{XeE)x} zm)5^PzZgd}mzIC^rwIemJ3y1T-c3G;1(Nprcbw+r^lm~=2W-Y( zyf}}Ui$?*i2k*HMg7`t7x6kOnG(F`W?YF!{ExUYDg?J~S2iD;CnLQL(N?6}2h^E0+ z;+bx!_giT?d{nb3)mTf&0%v?er7IG7k@?YMw5lGM<;Rw5G;xSVfzruX{tvcV&`4MW zRU^0BpEEDQQE-xrUr0O*NI;tt5BHFCI91yqhA)>qdSLj{H`OIkL;>Cjk=w~YaHc0G zqzl+6e?#np7JJCe^j!)W7fz`_rrLR$ZaTUAV45?TY5ST*k@+`#dueP{BYvlc>F1%U zsA_EIp4l~P9!)QGgOPue4dJQ_fe$k`OHVb3_Ec7Tn-9ee?5K|hi5s( zjUt=&2N*~i8?x@*VnCdT@qUQux#QJGFmv%%)OsQ^QYyyu{L9Qz^@ap$A%!`XNR$OS zxj?DjDTia`;ZEtlrUo&+6zZ-dOl5++t2Kf&i~rwd{96kO^C#2p??n>iCbp-0vrZ#cChBrA;tyc?&Da(Z)Lc`In{Q& zvcYny;B#n`OBnEG?1o7gAtQC-R49~nrhky3ul*-}{kAV{N~HA!?Ge2zC<0A;BZrZ5 zfGrNpT*C4XNl4i#)baC@COZCuchkpU2I%qT-u~x~CzNg~(56OWzGzv_ryW4zJlCk# zPVmLAU)IBGyJd)Y!qiI{B=n0SDDJq)#xgdu!KKDW#l=Ab6gI_)Pfs*;Bv{gA{R4yo z`nv%AF}CoPTw#7&vkW=%to7o7JyksHn1!Ye!x4d<*S?$kbLd(A&9Q~f1+hM`ThUqp836|jxL6nB@xvqF>%_m@1o28+Y(giYa!dEV1TbJf?pb$n79uw5YQGU z6>C6(e+#^hjw=H<{fW?BIJ0w_r`d^HkQ0t{1q+X-Kv(m_m)OJ7L>O}lb&A!yZbjGs^yzEqN-IjKl+Y_ z8MZEF;ejZS4Wp0yx#RwmSwbG&>3qP}BApPWxkeglZiX1IMhoN-o0lJgyho0H)2&{4 z{bLN-aK>gx!tsXf6?3vjA#s`{uS5^am(t`m_5gmQcMxz3{_n-duh|24$Tzd9rk9(p z@{5eQ~nq=r-KIwhVou zl2^{3xFMDJj(&zXT~M6_=sT~p$%b-DVtqwfqKNhW8vPR@nC> zZCN&(_v?N4GG|rXFZ?D91He&o%;jS89^)doH4^6Lcmi4DO%G^Sz!+HtUDjySCC)v% zp=ijSgn2*a-`B@E&PnMs_#%7u=EHgtnet$;9pAWxDnF3;Ai}ZD_Wp8T+?C2O2jA77 z;~1Ewu7S6fc($;+*`Y?&^6rop<9n{Arx*}jR!@8U_tUu5Xk~708W|xk23w5jx_jR= zx3e8XJjJ+&3`SPyUa9ot$~_SiOK6cHJDA$?tL*G8X)`@s4Khr%^!AE%J*@5v_ZiVZ zj02-C@NE-OJ?FRG&|hXrmW>`;hp;SBMAvjs1|XgmT)xiDPL6fE2i9@h9|L}L8)*|8r|65a#06z$tJ6YIh`O zQ^kjT#i%mQ%<(6MSi;4L1P0UBIwfRRcLXCWyvT`^sqV~Kme8>EEmhW*v3s}#%vA}i zSAZfQSD^F_a5UP`}*|d6jPBGg~o}*^>Zskb7mktZ`kL z-Yn{=mI6s!gRz!U&=luOBW7XZ0+I1i$7A~4GWlXv4bg$Jqp6dmlIBTf2)_#*FGvox|bmbZ0X zi!#7CU*zUA?3ST>WmS?Hn6TB~6RbA5_6H2_uW6RcmZ_Cy*x)_`8r|&atB`fMt}g`(Ne( z#HDW=ySt;TsnX-pLg@^dR6cJ_nfq~P79>r}DD zSS;4;jz)j(D;GxD{i-wYYq0syci15U@iQleMPR8KxpX+-bx~mT_Pbz=^Z7LaGLH`A zyOR>PJF?wo`?g$J==1hKO~C2gaR=d<2iNRTV`Hx1YaP9|=ff$Zs?D8g-ReyRs;0%5 zZPw`~IIXk9@t7D-e8JT%>Vk5VjY2FNTeIF6#hpwQnmmJ+IBp?I?jN6@@TWGnUpYSI zLGqU6ev=nk8OAMbWkf0IQWyNlV5R+)8IBr_E zlTrto9BMMz?7EDK?Bzp(u+UcOH5SyPJ1ck|XO$3d;7#;?;lDM@>q_C|qidwqe)ULo z*_Eq6edJUoSjUN1jxo>aPQE#gjKuY>_w26zPBnrqz3caJVT?FQ96{DK6t0U5vY!kNN!;29Q>dev zrARB+u}S|OCKndy>aO7XYkf!oSsN@Ad{5O^(Yd6X;7C`-y2M6XF@*_|u!ozYDs5;om3fo<$MA>PuB#?Fokbsc3y zmPe{8`3oP_-Km(*JHwv1tyTX;&Ph!sYGz)Jd+ujE;b9jOYN>q3nHnb(a01jtSZ4bY zH|iUBs}}=+5g)#`#fihQw;whGnLbQc0Z$wGQf8@t8-S)H`8SodpZ$lFD*cA`oNnkLzXdeV0H?%dKNYXpos7nQzlLnXs zzqvI3i90Ci-(Aa?tbRvEcE>qEB?|KwYTxt9xeI0~kXfmt*|+{REhi-;1TaDWNPo3p z?(`mnGlcL5@mItpW@qKOob<+kiJvT$`ud9-jV*run>}GWXbf{9GnwuHqDZ8JxWu@8 zTNks?f=W`mM9Oa}Q&$O2ssnX{DhPzLUN2(BYy3$dv&T=>D#|SBK74O572Q@K{uRZs$cDl7bM=CzT!-sA%P*J%FL%SN)Q}_$?if<0-6Dgt z-dfuoX{5=aVHHPmG|5TW-An;Nh$`?jSH`}gPdb8eRIb}{ZJ~c;bhBpSUh>=VTFR#2T6!k|BubJ^kIfh_o~AAw{qUEWPR5MIt3BGRLAPxD#yKump+_- zZK48a5UG2Y47fN=vl)9BC}^dVohkmYjv(nxqr=RgOXKU#UlG5Fok{@*b&iF+>SKtV z6Z{CeuC)oNnk}n(OkFmzoE$tJHOh3v)z|mw*32=cOTmFNCh^W|{jh;JM+uqYZOrv< ziil@-ESGgBJNI+mlHx;dq{U3!cta-#;+K)zT)JhCI2kFpX(}Vj@#UfKxJdc@8PAm+ zug8QxaImBLb+NzeQVe^!g^pQCahDJ0d}FXa*sYh2TJd;ZLV3~I@o>f znhEvE{WacR8^KG$r0RgSnTwhw$Z~qiS951k_d1@HF2wYTi3|^2QetOtu!!sM4##8< zuli6V<=dO1#w#DgOPZ>tGL~lEy^BWqmzA5d8#dKKCqGOI+taH4ZDV85Rk-}ysLky! z-EbdT?R+{bt3$j`n>Jg|(ozLFUs?6m#H#-ZWZ)MJb2<;Qsb5tpA+na7DU?1jAsb7b zi?eHBz;e>qt?N|v64%JSY=ydd4Q1b=YIfwSd0Pl!Mgxm1SEZy(m$4bG6xyt=H>Hyk z6Z~u4Ce9i!qN1*hU}R(}Ot&8&HesG0DLI5XHj03q?m9ZD6FHUN^t;-gi>IoQ z4aiOviGXVLF82@ok`30djW8OswU96|6zW9Gm*t_K6T<98_x9` z*^HQ;TP9Y_g`;wqR7?{A7MtRwpG3W5Oy}XeRx^bB(v}vy4`1Ci{jjO#tB>%U@8W|n zDy5qylMmGW+;&b4`;@)K;X78pz8{c*@bae| z!Jj18Sv7Pecy~*kbIyM>eE1R2D&K{1zG=+Ll6uffz)uRQs83~_=6NvA=HCwDFGs}t z5ZeZE*rqEXMimM16p3EVyrs83u)Vh3xHQ9~yqe}fchppT!hB)769dG{(VyfV&DCT= z_P^Tv@R;N(Tsay&*fQYaMdsVq?r6oL zVq*V>GS11r+e&W()vek`nVH|FKH_#Y{|{By0oT;k_AjDnD?(FSL=jL3pcMs0f^1tE zMg;0$i9iGal_hA{Bi5?17|t3<6lBWYDC2 zz2`jV8UJUUdm~ELnco|}ZcWQpQG*J7KdXl1LuGNnw|5q&JgOQ*7MTv2~PeY7~u%S=}r7 z_Trh@44)LH z5RW3l2w`#wPLy7C9qtGjds(QpiNJ(z^#W>yH<31Q(t@G9`6-e$MVd zLoj>o9#fb=CJv2!U79Q#_vYZ%r+to|cp060MS`SXo^`RWRQK&+e~le>$y_+Bm-ZMu z6JqEl^VXX~v5_gNhmeb%SHQ z=Oa5+CayP2U$FJ>wg#|)i}CbZhgERknC{}cYmJgVI&vTfYLSdmXn0cCfnNnxcna7F zAL9T8e0o89G`j5h#8jrWYm86l1aFS4R1xXrNoM?9h;xxz$KoxJy6h0VgBl;He@}yT zQuu=`RzM+wLcQgTgSG`O_n0nC?rwbfGCer}BZMSwwtjuVp5+G9u6;hQ@74Ltir)UT zcI_9?#_vLi;DqZM%9*CZ>7u@O+N0MZV;5gXhNRe@D$?faf$&xT^WUcF<+J0aHP|>g zqjW?aCZmyVt@u0st((=j8+~I3+Dt z*L7+vXNG+LW|c}l1JA(KZ$T~yc)GM)KL26dV{zJXD%-&iMx;LKvK+_I23(TEPiqmj zgC@T%bn^-n89`a=pm2b|fL60$?sUy?6jvplprX&B!5e6hX!L|$fa*Oy~vSErvk zQI1W-PvrQz4NyPsr3z9);p{k=Nz8-Fk9$g;=Ob-BO$Yz+2r`LqEasXk!#j1*zigpS zy4>+wW2WB`a#gG;u|trtGvJi1m``HZ0ZBnMo}|B0ecj>5UQAxGSmR-EmZ|ROV!QNt zf>PP6onFP+0X#-j%OAT+7e*F_+KM|nte1LywA8>u9bYSO@sxXAb&plDtV#1j5hNHs zX?mwfkfQR;q3Ugg=yGbE@#1Xx;QsijcOGwYTur%i9k3?b#PD*#A4VSREgs8oepe z1Or3L2{WJK8$}SER1H{n78PIWFx&&@eD4?iKr!|-vlWvjN_rLvk&)Z_6-&6!x7U%P z&RRW-n=!WgG&af(zfqa7I31e9lr%Mp<^p zMYkdb z=;INLOw!{tvxy1)(MttV9_*zXK9@mTlN+y!#zkuUNZCC#U7{E)L$0_l&Jtkw=vCx_ z@wON^IK(!6sayCkJ5w^*(ozuAZrQujG}x=@g3VnGteZ{we9Wg<^yJK^0FS=;aB`dU z{P(gEnwqw@Mr?M24dR+A{jR!4Fj=;?Vw))P05|rh-jGqps)HJ>etnXg*|n)7TLQir znOoNd)yBCtXCygUe(wDZpJ$m%RYn7^ZqylftT}i* z6ql{56q?tt-PxYB7P6zn+9u)%~(oVzh}`%@2Vim!!l4UQBGVuJiM5dd@;^ zT1PrIIa}qckvX=~4r}yIEiMK%+W73gtUJ+KG?8ptH|ah%q~G}YRiA-PQmx>_@{(Oj zq0+{Zo{2(1$oEp**bC5k;p>WZ;RSIMN+T}t)r|G&9{%nfS{F(3?U!oxtrE^OV(lK~ z)!-x!2icEY>4fRMJ(iC)Ej1+hkUi#xUQZ3Bc?b)1pM=w)VxyoP*xbruI76A97(g-M z4A+^FIgnqm$IzO(c$c7$mr}oej3>l?nOg%9$C&{F#-TFvjzP&3XJ_f5pl@MMMrz{E zU)GuWcF8}!c&f)gIM@g75^D3(i;0eWeSF}yit2ko3dg;4N#S(kK&3y^hd=q{__eBa zwihk>DV(ZXNOT|ETo?6rymTRVY%Em9UXd&f>o9H)HVjV-P7RGEbSMRT76yE*Ngqkl zDJ@u-YmeJ%Wb`q)7ZE=)T2tL~o^-Cf#o@zUIb}A5RTc zn-IVXQ~bJ7Nm|gtOhwpD1xG8wJq_qqAf%rl@7S8^GGk#F9@F1Jp1Cl(zCf)ge(6(f z=Ws#1b%zgo%`r1t0}Z)#HzYFhbv(d_#4BZ_1&1?~wRZ;RN>vPXWiKbBJ4*#VouftW zezs@fy8FcW$S}vgSRa%8OMP=z5q_Omkxu#eK#`7Zyw=>GL9^dakA`V#c36A3OzDIS zW{eEKo|~#qSV+h?p#Wcw(bJTf?sLq(t-*2?UWCuIVU7)|73>F)z{DNScWM4(qWhz$ zYWbMN*Hd+6uIY1=Noo?CY!1+e+sL*}u5s~2SiI1E6k@}xQ!iiM8MtyNwDeIw*<)!@ zZ*-y{_T#Ry%V$cnvUUNdWBzg(&zZf_fOB@S6hd^j;zmt61Q2J(s)`E}j4Ov~JQlCF zHaSM7?^n|Pi59wNYu)tFeP&|fcv`ELn#}0{EJt!JNEw+5YpAZyow~U(v{CRzTd8Js zf2aT8Sy=2#X-B*>y`)s#^p3!A<{mG%v|p~#2~j!mP5gKZHfkZBJ>~)=Al= ziAY|U87a~n?C|UJ9j*0BELw;wZ9F6zD^VKP<$;i*$g({pC5mB5BI?$M_VVy62sh>d zKJDOfnnB}%nNJSb+LjX^j5bA^YGySB4#<&vAFZ#-4Vt@5&@NST$*T>eW;Z0m+Kh<7 zhK`Z>&&%1ZPk^z*ogF@orAi%p>vxSlNFFJ3wj;CNls)}TO=OkwfDU90K1pFM!s!hH z(ftF;pl}UlW(ofN|6WSHA*E5UaMM(0Iv^*lc6wB|E$}TpTvc?drK`^HhsH`dQ}~q( z-Sdj=1s*|o_&Bny-YpLoO<4b;MjJWl5@+v{>P08DzaLC08XQUUsfyL~cU1pa+}9a| zsnVm2_+N0QMw(`kZc@)5 zU(otSOs^~p`q=ueR=ag})(`i2E*RF#nlm5tUbtB5JFZ6_YB^43FLl`ZStR&WNouBy zXV{bmjC9yxaqWNxSpgBg`Wt);zPjh|!0j64{XFx}yh$B31;vuxUM-{97qgM3pgVVN zf+4rQCdsDgLkSB_8DoW7)0P&Ja%@!kTyL#TJPxnBAP1$bGTMh}mf2>Oq_!6KhB0mZnnwmY7i!ZtZSv8#u|tcX zE}HXi;j*s%tUK~Xw&!2*vNM8+aGq;lEuE%d7x>tZDR&9%=(OAE%f|{lU(Asm*vn24 zeZ9c(WLGaQ`BUkoRuMIiN1&2Jx(whX-Z3)f@93Cqt5tZqt~Nh4!7u=vr(>g_=(Ciy zBEx`L&FYP%GqKk3TIah(kgHF^sG$%oZ6m*N+MEJkbgzJ9S2~P33I!Cz_0HIsw``s1 z{yhgmGCW_bF$&)z924NK0y)d)7mSQ^dDG%pTlo9oB(H~d+Oyr4r@9aIoy^S*c+??f z+93>v8V*su{s6UR|E;c_A!Mj-F}`0Ys7hTct(EEj{l$cgdvMQ8czA)t!nC9Zd~rFj z_pkL4TTF}2<#~R-CWKXA4%zn}Wb2jYEv^#P5v?fO>~ ziMeJpp7UIjT;a5(h_~@(!-`NaazwWK&ebdHm9$!)_rJ`mytc_(Vw3HkYSW`?Sbff* zQ&wbh)8K2mk;tR~MaT1mtym=3tm~^;$c&~^w*X5h>CNup7B@smu4 z%F=~3ce84<@KIMSl*E?XOps>k~=`-d`PDJ1@HR!BY{*wmGU`kj01~ zved7gESUc?s}s3+Oz)Ef*3lF$qP;kn?^DM#h|4^?Fy2_Xyc7#&*r8ZAXi%nBJstD$ zjgwPlPV%>#u3lAVZ-tv0=Bm>jTQkHzgml5)qRVsVFWhm@|w|7pQw$2Gj-C&cnbmPa%Kr!Kk%6QI>(oPA<4TRdLL(#=#`9de%G^P7ZDqTxodaf^ zAi}9}b#l^*j(hN?QXvs-i$20X3t%7U>b!qTagJj2ktI1`cX)cn;FqTsCoeTL;66=kRExm}D6wFB3#*?_ytc;469A3I{#b%C5~Q!JKK8XzVSFtbN( zdf1vdJ?a8tAKgD*0`W$DOL5Yj;kJ&q-X`Hy4Gm$g_V&M>N{_Wl$kvq6DuArBtjycS zY@&WRF3rLs(!tR&Pp7aUW7F5-#<7iN+5uWAt*r)tN|r&c-X$8|t~naPfhjt{_KCKZ zEx&e*oYWH^UWLTm*EN>RGP~~mMI92UII8cC#Yz?A;1*4J^W2U;#r@MG>i56Qc{y~I zHG;s0UF|wuhPv!jr$=Z*F&#DVzjRvFrXlLs*tc_eP5?=gQt*A5gK)NjtS#L!!lb!O zS`5+^nqlki+G<^?PT~4w*ZgDB(Qf8dVKfM8Oq!~~P0g!Jhtm4KdKVi=Biru(CKDGE z`C2gfQ2xvJB9N;(iEa%H(OV=zB7~Tnh|oW3yjvBVeBJbj)dkkvk$fdP7XXRkY^700 zKU=lwk(!)Kwdb8wR2*6-8}#xWy!KU|(oAUmbkDK%vhZB_;40)|(?C&1#gR z(xRLkPg-!2j^`tb*aOF!b91eLLMuu2eYVoku}__x6$V>-HB$=00j^MQ4>_^DV{B zO*uBj?Vyhxpt2p6BORr#GZ`Aut-k`mDn{QwfA-_Y8ZaWup_aW7G@5ZmOH0@}Leiu9 zsC^Jv9KHZY=u#pQnytf3obyI5H`$Z(PGqKe56~3?pulQY>YJ0XY15-PyEiF?g-*cm zl)gUesh5kss^tfcDZMjo3ROsgdz0+l-1ZIlJL?S{U3x8mWTju9o@Z0Hvp2j0%Tkc- zIXoNb3s&3omG+~2LTk)^SowO(*R4%TdyY1(4-MB!GhHIXs}HknI8R$!u}dJSx9{0b zy@2GS@Et}YKyt*c_w%tA@7^6JWeYS5AYeiYp|xK$@1BQ-aC#P>(3oMYn3l6BVS7pMGiQml5H~e&C>PZ{|lPKYzru^}q$Q%yhGSLK{dZo|qHX2o1 zm6m*ZY8vO-R9#(TdCDCM^$u`Ls;#Y5riFQ>gP-FgTdVs|o6QyM)3tGA?a6ZN(=67m zdu3{Cs_j+DZ_KycWM9OJuOS8%A%`)k#auB+_~+)$M%b}xdv=243A&3!!c`O4HPhR~ zCzqLQn}4Zj(}@#i1Z^8f&7@RUuitW#liwuD%gQU{x_TMPMn|2isL)f9kZ^fD>$~ez zdUl#>(?3oQG7luwq|Ua6(LVn!I~6Iy=uIJr^fZS|`p5R0xsVG!(%cI+4tp1jTrSGa zZ%S=$O7VBh`{&-hB3s*={(kBM_r5$e-J?42sK)<%a-rus-TX0!rES4v za*3@~E6&A5^HIto_EjOFkL?pVvo{-X)^5LWBCUH^q=g7SO1V(+_U*~ioPBxerW@V! zidw@YQ?nhGDz5_Rnu&?+t&^4CN&ZFA#-=kl-;!zVB8e$caT&SalHbTH$VSJ!v$vP2 zuB^-vm#EIkHWy3JHh6Z5me%O1m)lA;Pu*POBvdK(q80^B8Z_R%8Y*}*5$Vj5=*YXc(kr7RzJ&_Sr z_I~Gq6Otf&d3!SXk*!S!4&G>#NhDw)veq38=p_w$gt+-`HT5|j>mV^USLaX-5;i%c zn>1}1teo}LtgI|*ZLw6VtnzQI&{L?a^lzQ@RjRBCXsxKItQz~RvMSXzu;i`x&{O-s zl3ICrsb$NmS>Ln0y@S#Ul@7fV)a-0U3F+!bQ&ilm7E9R&cB=O0_CFYuz3!y)fMzHn zUZ!Q=BCdSvnxTgB1C8upx4@ZWH~K`SAI_w>pDdkvHIXu)J@CDxIsMVZy;l?c-UCG) zR=S5h3S`@cpEeV8^4nYI`&_J^wOf_uH&MMcQ!Okc$i*F0@8V;bc@m&KY3;*K&)Ns2 zo7>WhKDz4{e@xSaS5h_7&lOY+x+nb_J7Rg#Ol80=mINx{n*WN^iYRT^ZtZr`9WpOp zC;=*xq29#UoH|Ig&D>mSn;VvwSrViC?U|z$2%2V|nyYhK+>ZTR$G+dGx3@z)9{%A_ zN~`}vNnYOHD%DJ1HuT*7!E=OxbNgiiX2Ww0^m30G=2|(^;9smV!{r{3_e>k8rGa4W65#zR9_vTbHBwfHtKR z+&huhN`14X_0?#{tZFX&%Y2n$jzRu%l_-1b*!Mp8yA>OEM?ZgLSEly3c72Plot{ne zF~hv&>^f%4{?}g<6y`IMu8cTzg@uZYqUJrOliqcUXsboHWyO zU7VxU4cdFGO zadQxE>c?>lUBLtyXc%!?s1Omm9sBC&d47O8{Nb=1f)nJ$FeT^n*obGW0cjR{D>uhergg*qmM9&Z)h~Oni*&yrF$fK08ZZlKm z^D#+e(NRzFNf`HTg!C~_wnsZz_P97x0D3P*@Nx$h|8Oos$J&XU192KM*Y0dZTzy>z zcz;I-9dF{+gpVWLvbbZ3|IM^DjOudS@bSJJti3xx^|k(QrkZ$Yi5g4ZdHY5LAuM`A z+gg@4S<5dTM9JG94vQj?w5Z8s7-RkcyBJo*+m%AwVZ!|%u#J@R&+d!=EE_WIg8VdA zMvXF(>$lr(I|B7ZA>w`Qo@YUPC7Dj`aWAMQzI)JGS&0sO{sR zxBe3@9?Q$QOP?=R07@k5MTL>Fmz*9k_V=rOZdij&cK(V0!(x%hX?$}ZxcHW{U25}Hm;~uAkAH`L>s2xhxiKnS-sP*SirJI z&h=eYCo1yw=LX!;8>D;ik|U>9j)hKsMgx>!N96m|68tF3Jq@0wQ$ea> z>0C=L6c#Gw>eqWD#|$7Y3#2JaW3l(2(bu}v8{KrV+~ zJNF{3R!`N|2Rr|LA0#zN@D1w~QOWj%`dMkIkSiWu6l8qMR^(|`i;l-pN#(=Bh)G?% ze#L3N)G4^EpK&2E8uqtg_3I^y5wbm!|EMl9FYG?g%h8 zzo~vCiSr=x%|Q9@&N!@kP5u2Wa`9{DR-D-iz1w@|*(&hY>#));ndLov(K3E2)KLnp zO9~S|DTFvzjq~_Unpg}5E;%6=y)$l77moAAEqn#~@nl#4M#RQ*`maGm%)JP&tS55L z!8~VSp3xdyHpYW+GUg6;jp{?6m#?hS@Zv&Vvg~!507JgIx~G%sYsW`aiq7=EC5mOYH6X@8 zTsIi;-qNFF*4-ZvgR=Z8KdZ$PdVw1JeIAr9(w12!kSmn;AuSr2Mtl%@eUG!QQ$+rYmHmJ~j z%(wZ&{ZJ@}QwtSYDoBe|1o!wV!q{=isb~Y-UZsi~d$J;&A3kluK{sdbk1zt%k@XhC zSIqH;#kvy3qGVYEfbMBOYrU-|l01vdqQOBV8jM^MU=Wy)ugChUN z{SWCWu57bK$OSj12_rY*vA5Osdt^HA^0`BjDA865g?7xXp9LwyGn%;i|5m$}LY<{G z;1VhkQZ%@Q9WtHJE#&xj=(_>>o2&m z$Q9+uXWW>`dA^riv11={xUcy*A7EVtod3Of7M^K^T)Ekx!e@n}E%;p z$O+_e;W{%jNkrUH2>IcQ}U| zSN0Mcr-YE89T3RK_H?Z5Na|G=1Zjt0od|)0Y%i>pi(T)-ZSQGNs+^GbNr0=nWjg76 z-RQ=F_X{Z$^|xW?1CvWQI2Aut{-@@l(ySR}ygIpx5+417w)I>Lo8GZV|~mD#`e^7ZF#6xa}8Q z$VxCSegPAxEIa_OR$OKBsbQFV$*WU<`agmCFlzaVgA;y&#mY87O}qf3I|tt6j;WGA?|NJMZyHt@3{t+QDz}^a}v$=evVjNtE2A)M|{FUo~C~pnkDFbm5 zmn_PalZF-5Ck!u63nSM-5RQ6_XZU7H+ExmEa_i&V!73%g3NOB|COy0ir3cUJ6amI< zkkt$7Z0UcC%_Wp5jvSVJ@l_cS-%~DyyY$~;;IlGKULq>MTz@e05e{XHQ-$LK>vI4D;1g)JYV-d zQpB*r<%D6@9PACm1aIk$@)em3e8qiXV3DP^-w8Lr^(}I=ffbD^2j7Uq|LwFMR13| zIwlLY_``t)_?0$WlrQ_kUolT)1Zzb|AO=_YaSG`fCP?c#gtQvcw`2?{dDCsXDGK-w zx|JU%!07kY*PC34dfIDgpJgF}(8Dr5s;?pc5t23L0Frh@}cQ~@Vw_sInB z)w(i+9kz-=(ggTQ0Z>z80zsxqA`+-><~ z6ueSzvh3k1gu)iXDXfUt*>Sf_@Luxj^P7=d&r1|ROETfK4fm>jI|?ke7+CjV9~=(o zDUiiN3+@nOv$_~AlPLMSzYwBlE4B+aX15X_JG0Cnw@C`y25%usO~Wb6oqR34c&bbs z2Lbx;A<8hJ%y`aI*&gSW=aRnkVTXUh9_orC-yI>qa?o2eY6$fDk_W?@Pv#mHK zQ_0`idy#GzkeZ@QupD1%-=l)T&<`cc_Uj5Ef!gH~IG+{UlllV24Z+2v0&EPj0*Fv1 zRPah&rc+M1_vw`CWScc0F%=GjsXt=R_cvJ~aR=iP@DAy9BLaB@lKj>cchPVjLdUq`*IM1E)`dqGDgcsqIZQXN83fD-_K4EB6} zi66@ZY`-|LZa!WBNg8m&jWPMMQ?}R2i9P|d?POLz3Zur~r2fV|whHx=+w7=FeKqpx zt1sZ#7oaQTT)X*OB;~2eg~EZ4o(=GN#0n{oM{ZHOj!3@f22niw;#eO_Wv{q{>kT0g`0WN_KxtLL zDh>Z9XC%EjO^m!lA7Ya~n#^Yr$vJqqvUUpdM9dU%09hzm5Vp<6%HnsaD6^pA1eLfDI-zpb+ zx#jB>J-M}}`>FQmHuTxy;E9;&dhtA}DLT{Uw&JzrHNV}s#3G+?(8*+t(+_U2dBKGEt z+oS|gVl0HbGnQD2!Dl9~(BT;9O$@zJq(J4IlP1@vU zH5G=*!Y*W{yup>KR%U1kDBxAbwN-NfBSElJ_>D%<1dkNmR$2;%*Iu)ROY+>pTraMYi$ zCi?Sd|8!+NT`NgrRoOiOWIfDfgC0U%)7`njCZ*jI=#6f~eNPugEDyL%s?baF`Lb|- zHRd)cdeV?lpn{N&Y3nkd^7Yo^(lON8%#e}37a?uWtIsqUzl(3@bD`T>E04D9(}=t1 z0&`lrO@2hTTJz1Tz}HA(sV+sfJ0I+%KaS3N$qy2mI-BWR!JG;J{jN0`u$|CDd}&w) zn0h2&4^6{E-`o17505AE0j{Y@v%P;bEsUaR4_}+`HAh2Jd4A7QGg5A@abR5w4p?`M zF#m-ZcZx>_qfI@B7EC0s9$F`eL>NdcvG5+LJbfX##WWa%xWL#B7^}e%71OxZ8dXqD z-)bukizbSshEZ(Jz$>{h1cteg%2;GM->4_r^vD z^U*0Vwi(G9io3)5i_gS}&gPy;U87o{ki){O^c7K)k|lxYG>ui>Hv|x)Oxp4td}bP- z#PdtXB$k32aaqM6vR{=Bdj<1JH0qlm2A68ABK#$Q?E04$9E4s)KmE!5abft8_vh-& zjcxrF7B?6M$_UBvSv^~xxqd}%TMYB+>oUS9G>}b-pFXOR!k3M2AKnkx;QDxXqd-=@ z6a8Dbg1QoO#+;YzX5G#(_KGLWJEt5X$rd7vw_u)onYk%E^R%?Ao0zTpZ6Ex&TV8!v z6pO{@npo`(bP;HO2Z)q9w3E0eou{&-GpFNNM7K$|#_h_YLP%N~VP39PhhJRA&ovU} zEr8j!u>JFHlXP@3gb#9e1FR*M(i?Hg5a^^`b(WvA=d;GK>;daM40ymm31R*oQN&~g zLF4tP#V$J-*tF=7O!T(m&KWU zIrZnXU{CV8lOSWayn0=f<;Z7`Ym^0uz)n)Y3|Qx*Wb9?YXHW5P48ATijB*4V>BBbH zeWd~D1R7|^kG+anDR_1=ZFz3sr>Cq{h)X6d_zZf8FX0wP(}`IS)NTCvgmML@G=Cde zA5G3B#Q!NN5XwN1SuwXsQ^y7D;1qU=wNJG5vr{!ziQN=H0;37@(sF(leBdtl7DNmKE!KBH zkb;q@mS&QlDZ=Law$w}Y0}izAG5aF1~;#(%8)K9kQ8*Lhe}2B_NLHd%gT9OY}l za%VMwHsI)^eF&v}CI>H_!Bf|5&T@WdU@JM8dGv#Mh=O?#Q+cRudBOr;Xd$um*T7Gf zXZIis$#V%Is!TfH?3!9mXf3~zR6!_`?+tX-nS1%Na_Mg&%xeN}YzAV(0!+|cK2|op z@gv3^lN6}72LMx~x1RN%!LxTUJNTGx{^?iZv};00na1jfYwM9L(3ef}>N}WCJoZw4 zovD^$pXq~nO)ey`{ZRHX9@J*N3T3T6>r@zH{8w{T08~fANNmGlCQYHkqS+ zd_75{Y|5`U1!#42f-#W$Wz>g1rkH&K-D(Ew*1`e3N;-X#r$H3C%fF)v&*}@zZZL9y zdmG*xl<#9Ypr@^QaF?Z*VLA@+;+MwlSx^-wU42$xXX@q4(-X$eeohdj!A^e#jVCp} zlmDoOSAWa{ZPJUdSAlh9!>MF6;cwCUrSN%OkUZaHhYp~6?r{S}jd3CTjjwO*c#zeDj!($4tLHTIoMBOM>3|`lg$9QFhNcq-W+VU4*0p|`5 zMaPKlPk9tYU5!SyYI}8Ebp(+ep!Ax|kNicyb~m^6hd^L4_(lPF_}+D2kPZ5ZZz_a0 zo^F#0z@s8B0pxFI z-CvLVnFhfGx>^?uWq$Fshyj2%d%Ew6>` zgnKMtf7|B*>IKI%7=aRC#YE8Y$!I1+OYxg1)Io0T+ zAv>5==;B5G9s9~6Sk92$WrzrP$C(0M5VYMrTMjt|&spyJT!aswoE5FEh97IQlvw(N zUn|#Y&QlA;JU60#_AR*L1(eBu+GnxhaXuDwk-xB0p!(L0r@A_A`%XS`(=Aq zP@VE*;wxc(V~Q-Lqi+>_=rT!u?jlbVStpl&V`hSoBwoSC@wWqjEYKIpXaGN$TJM3M zyHA*Rgl$!Va+n{MSdt)0-C>RMfR^;H%^emFM3D#F{0AbfJpg*2__n9`7(|iJ5e3Ns zMDgQ=g!l-Ed$`Fh;}4BTwB=2}Za98R`4zP15Ng2(+Vx-h!IPRBA`@p2Bz0JwXu|hz zVlM;ei;$uy>tdpqdtjW%R%Cu7j_{H8?%Y|F{mGy_MPqf8v><#62{vUXKX>lGO+}9w z5vMs(_o{c1Ac-yDdmo(b!bkFV9X$Y>92k?vlGC)Cg!w+YmJCysubqj{_b`LqChN>^ zAknYjOWwc}2clFY>noop8Q{6IXv_5jKanPYEf3Bo#G|b5Jewh9gt;b^L!i|HRh6vk zZT(g9bEABYoGvMW$P1Kn0=V_yLPEJR)001T-TxBWXJLq_f*F=dK41y*;D&L1_D@uy z0CPQvDkl9r@cB0Aq9eNSOA^Q4km3g#mE@|1z3^+Tpqty6R>a^Eo{6`dw>y#p zK|#;JPY)wZ;Ve=@h&J;O{T-z)K?razh7$ZubL>zTo{OPKdfA|M;NBB8 zR$B@SA&f4Ug!p?9$XN4lXwOq+_O|ys1G_?jU9*Oqgya#=w>`J1JC{%nU|^{T5BtEs z?_qja@F1jMz^AQ06Kqfn${!c4gH@Q(yr_c`!ZPI~zLrNZEqD#)#wMaO3Vwg`%&?VIS**q^*ED^M7r*nBY1m1Djj=JO(c#y>3)EGA?m zsfQ?E&cZiUa|rX+=vIDowX5g8+av}GUmRg9f-vtwFUjIbCE`>VSb>dk9dlPiuM6k`&omjU z<}J~+P&P;r5io}usq!WcWCh}x<(WL5uNhCq2NcwoACp{_2IrDU?pO#cH zU*l&yIKg3BqBf{cBe~j+Bo)JQ;hFfKLoP(Ao-yets9uvY0J9J0n4(rZ&HANKi>Xtv z=p>@71{8jREY)=Uwkvx**CnRWcjYXNu@_;BQy}!{N3>vf)b8+j4UY#ccwi*QX>Mou z!#O_!ROfn$QV&=uyc?o&Q|Vd|6nKMFbwH}djRv~An6J>&CwQLVl9w@hqoBSH6t@XD zko65q4_lR(c|78?USt@JzriYDhbU8!cHD(1E8;90-^}wf46Jmu4AmLHi$NxW?D%NF zp1_Bjcpc(xa41oNt_6HV5Sf&MV*0Bf$lE-K9lc0s zG~X-~I$~H*{+T&>0|6=hUMe8WLsb`X2N1$aNJ_-<93GfAH5s+{vvW08b%z0|MzGVr@Ji|2aE&y)7*3dn zQZeFP0Y*fL-5Y(>?l!BO2X0wn;Ie0;_h;>gC7-B7AB~S*2}IJK_2tzsiEU8)74&as zjr>Pvc|S9r@$LEsF=_Bsp@=Y`<{9YrN3=wKSy2!}dXj^ykr$M*^BT7!#V->!XEnh1 z33Tz;q93PW%@}EoU}X{Jv$65FS2t%(!nl%x-yu|+2YQxAtm#_;N5B9{KCq=-Q0vvv zVMe2Y7Ch}R`tlWT3LfkUb_Zz3E{HXxZnJ8LBPY4?WgLILlX=B$(g(!vx*9g{1kl4! z&d(YRInKM|kK*l20RW%WLkIzyQCVIW7#hnxGyh->SwW@_0CuGlTc@l~_uF{T%_bX@le`o>fm=e$EAK zO04&3w5oI5T8VKAwtpC^gz8K>T2gd?6R1-pXWrs(d>WTfVzjj%hrOQzL5I>yo^oxH z(mwSUVZItH1S_2|(xZ$M4dvA}mSZ?+g5`c|I@mMB!iD;6 zL@x&plBA0WSn7d>7l1D6>|@5u&&6@~Pf_)8L#v+EcUefT%6bYfER8TAi6fzO^wSgW z4oJo}cg{lKz8PEP9hlHska4`p_%c47cSFr-l(ng?KOXSb5{~jAnvj_;pG8IG=RWfn z8T*29kqwnK#y-IGmLEWhQbe7*tS(*zmR3}U$MobL@X;~bkc=?)olgKTSSHr)GU4Q5 zmX7gz-YGu)atzd;5hy_~KU|kFllr{f`H$QM3 zC#Ghb-I7HROQ&4sWg|3F!Ow&%YX+*BLR*G%JyMNrQxLW(OE39tPbxlMxx(=7!2izgB#$BO)_qiq4c5H ziWv@t6tjz7XgmZir+|SOpv^x*Aar#64Ze!Ey`k$}MmZr8OAoN+^PgxSlwpv;XQFK^ z%Y-+*W`8B#)Fq)D)<;HcTgukduKhu*+?}w2NLrc#_Lcbykf+O z-_sspj+OIfS%8(194a6Yh`DS;NE; zoLVhflyX-|f!WSi;6v`RYI#e%ER<)` z+xtU6sTh^}U?0Z-IqLAED>W;|%jeseA&|rZh%zcCe&FQlY&}$)9%IGjh2q~I(V=f( zw`34T8Uz^4bS-5lymO82Ntj8FsYH-DJiR!(8uD5Y=MDL}C43i;m97s4(X9Y2pp%q2 zOy^{QlYMB(E@pWK7wNx_yu>d+%$qDCK)Qs@u?1Y}er6m|hgTnY*SMKD4YiXj=)xdP zkYl8R7xW7BP()e*09 zXby6>;Qdwt)nfGOA~)B=k6uTE6h7e%Uqb*4msl%}7*}t=z6w$jgBBaog@s*srZxJB z=Y?iP>^SA)`=D)#(7i$28#!H(0)@F&uC{fL#@=Be3T%Prs z)B^AKuqp&`4~6wV{R`lI5LLq$8gaEK?cZJK)=wOCr@VH8!x19)p^$oq6-!(W;@xrQ z5|$O{fHGSKLV=bc0wN$V>+o}QE&-Msp^~8v<}$Qn6L_fez~W?Ln8~;{SI@Hk${>0{ zC=m`EvfKmKFoZ%(=bRt%b9WV2SxMI>U3KR|g2C*os{j^SS-{@0zmKGM5qZEL2&BH$-Wd5AahBg1s}zxsDabU8zAPEj$)+~m(94lP`m>j z?F_CMtLv~ue!`l}i%EEAuC_AJSrQr$u(+0#08TFJ46spdZVuX=94S)P18Y54_s=}EMWXJznsdDDp)3@rg?Yy~J= zBZL~z21B&KX~7KBC&ZE*a-RhnZ-Fse6q8mWC*IIi0B6|LwgtNVSlMu#Ij&p(!XU7F+fwJNQYq90LU*{3yS|MEn*$iT`xuzU_bd-+C#*NFBp}!~S zi;%Q^gf+T>v5J2a=GBQKv8=y&H2j`v5J9eq@n5KHKNFcgpkMJKi$K@loX+TyMQiM;gh(c%knni zGD1-hqjC#yA{<|ShxG&!q!xI#V57Ah;{c1dEQigOQO3)?|ulA+G{vG#pBdYcbHx z1wy^=aqb|@uca^Q5|^KGB3sInsY<*qL|YU`s0wrPxaDSirqQ?(*BmW>jKupvlb8ic z+OiG|HtjAbg>36Gk+PNxDp~JMFw8RoCF5EPmd8cl4e@isc=j`n*eS2Q98u?I_2H=? z6f93;yv2mFhZ#-(RLmvg+C>9YA-^80qEY->z!4)~A+NiS*NtX565aRIV&U<_+6~0G zXqEt2gr(yiuuCym$(Fc$fT_(5Dq2qVDL`|3Sq*eY*@JTjltttUEl^(BBWq{A{9G(P zz#lZ+<~h*O1^_2&I({9`F5=Qr2wrX@*BNs%ElS=;tezHfczlGbe}qq-#NfA}8H3PK zM4F&2t$l!*O6Qxscl8ru9Hh<=AR{Rlc1#0}9rO|%<{=)9a-${~0;0gsr;{OV#UIaA zzkT_xS5#kM)%6z}cKj$}{pr?^J;;{d57t+n-z=BDclcAf_m-RA&ei{7tyG#=(AL&Ep+)W#MT|((88B0gM{e+0Gf$^+}GI#KtPH5y^ z4&rtH9vjPIrMN770LK0X-ijnRU*u>D=hx(^AYw-Z2UsRT@i$G>?C=( zl_+w=%l(@ec1Q4M=wW%!iXswUVSyHEnY+o+@lC|(-#Ed8@)Kx`CZ@QsO)(N2-N7Dc zPm88M2^R>&*l>s>y-gzmL5JY`pp42wPzS;xJ2fTd_wd?MBMu2ip&(zLSv0-t2`J)e z?C3n<)zHKjk+!0v|TnjeTd=-I9hoS=JSPdvROd!TLC zksAo(fEQS)>%S>3a3J9@TCT{Y@~gRmx+?PweBYB)jnVM+cRRH@;&?qid^aaRP-%a9R}jdK^`dp9{si{Md&Pa_g!Y(S+#r90-Y$#t89iYObl@EVVu> zgu^Ndj%b>G3_p~Qj~s=7-4s5JjZDnrZBH3f1O{Ofg4-9&?&JJcse?gCAtuihrfJ z)Im`XHT}f|vo}jc6{1cI>mYpHI_m&NMrc}Qw8K6vF%tXbPWVq`{TFLuCrr_ZP4NI@ zxtLXBo}IDRIdleJm~;*cYZ#03erVT`@ypmOv)C+arpO=9KHt#IBh>oaUwDu7qUr0{ zZs8CaoLrwIPqg8aZ^d3hOA>gyv95x36K}`s)isbCZpwkB}$pf{+_B-)P z7Uc35=;R#KaQ!UMU$0$)XDIcTU7(7xb>zD=A|EONxBM|h&h@}D-A0ZUG7d)($93t8 zwvBnZyCemXce+4J)Wx8Vt&yx(L=mp-|1vQp+`MFG1BhvPKnj#-W5z(6l7jkvW{8Pb zz~`;75Xp15(fB;R?lNdQ9n*GYeZU`IRM%wu!K^mifXKI|;6vhA9cIn*f53KskX{sI z{4y~3b@OJO)dxyAdZavBb{7M&%w1p-ig4}~i8>Bnaw3iw;gj&K#jY?dm}~G|mQPBC zcERO!$e-7Nn4^Vd?%pQjn#9hyvq>*8Bw>8Djyu!M{+!}sft6q1LUxOw_@EB0-x&btL{ZhtOf=fg_M8ld-- z4M49P(Zo21iv!)8%I>oYQZtrL0Va|r6?a0z^cG;G(osO90(no`HdyE`8QP@^eh)yQ zy02gs*zy$UH5y;oT#0D@g6SOP{P+Zx>6xZxl%@hL%5B(M#(+7!`vUvFdvMT`@was> zD}mT)Lmtlguoq$YVjmwMSOdBph0={-1f~*{A1P#&_7Kh(9YgExGTy6^yW6}E?!BAqrZOjl0Iq|5nz*Y^AU{L`n?vYxfR>$}!^p0%H|Rrnq@ zquKeUvHk+rD;3_Iqd9|o_lcCcT0<9Vhe8Oz2UdXRaH-VT_Ke7h;ahz9mzf0}4V1Gw zoO_v(u*KR1lfV9ARx6fl3E~akMm2j=Mk>h;pV=a78t88bmK_6a((%-Wad-B!v9rMKy$HA5P?70Xqa9o# zo%oWBg6N>XO&R%oGpu;4J*q8-#n$>;e%#>K_&`(db4vG^osd-!y@aF+NXq=II@M9q z8Nt0!1%4+giZ!q>I&QZ;u!8=7wL-nUz);`hX4JV^KCJuv{Y z&*D#;Fo{{k;U>!g!l!bfd7R2cM)NV=vg#z5UNsE4BiFS@ZC=ScIP0^-RChi%SXq?W z@T`^UQY>EG&1k9+i+S9Ole%9&N$goJCd5>#C}D$0N7MVL&1?2f)KrMUQY{;05f@RJ z=bZ!RRT{vL2I8NNuKouWPG5=PpQ~k<7t74H>2g4=8Rj&6m z;2^+!mXVgnfWwTm6p5wYs^~bICcHglXmkR@t?>N=M&1BC0)a={;Pd1T2AlEoZ`kyf z_|ZZ$D99d}>QwWY_M>Zei>8F-RdT%&VTz}=*8@aQd_lQ=L92b>PY+UVvehHYKr?w; zjZ&8&rc=Tclwo%sA8HWe@oAVttxeHQ3<`zrs{PeUJVQaE=*@W+>x}CJWVklZ;YW{;WqTq_Oiri9$-@L|k9Q zrtVE+@IF?}=?}ARmei`G8;X;3N0cYLqnaB~c$l;Ip-ld7v=LS)<-5cA^P&f;Eq<PI9L_s6oqj-e)_*_UaM!?S#f{}oDjRezN3iGm#-pa~{oTf2R$nJaUS+*+AuBRUvE4z~TOPQ9iq znuc*q)3>67E2k|-yPSo@xk$=>Au{5q$=`V6xBU0wZZGk`Ts(>Re-xZYlU;qW z^ZbLg2);6+cE4Ca&c)9_n5{1qM7vNFxge;@S@yAD-pm`rYX9PrMGSn_$5?c(rp++)TmZwQpCsN4_`9+GG;%H> zCGd_YG*tJ5o#3K>jqngr6+1+!hQ@R!eLZWKBAAP`sd=5IL^1M3G4drTni7heto-Hr zOtbL5v8yOV@~yIDT+m4Ik`<-{)lWMusRZ3V7k8F-dtl0;x~&)OL{hRrKJ73CK{VHY-o4bkn%QUl9cpFCS+UQgw-J%1W7? z$Cds#8OTYU5%6b$e(2OWgqw49kj99NcA z(4nV{JO<>LMf@-7)H{>oHuGAGrvfdVum809ND<2y)!gB$UgZ`-<#j~*)R|E@FIFt z5Fs@ZaP2O*hUbyzXjSK3h(VI>6{tqVS5YCZ8vJ)-@Ez8=T-wie?)LM>@O4WBe{dGU zz+;m(qQ!`jC;pQ&60Tv_6QC>#?`T)?(*RO^aZ24og9p}JL)zYnYkHw|r?PN%G4IFa z20WdFjr`zJB_IyKvNBOnT(+p8F<8r%B-edz{jW_)OJN>YmR->Cj2MuEF9smGULvEy5mzyUlD2HK}FTD0{8^>dl+~F0@Af&a`vV$Bp;vhmsj939n8Z8)lcY;B3-4!J zME<@CkqFwEV?U;?j%wCl$4MavZ}k9-*cZ$up&7UFn|%%nK$@-yPatL60!W)`6lrt* z1=><{LD)*;y(+~F^C;YtR|ng^H-uH@mENm|f!%ErEfM92ju}SQr5o)uE4bui2xZZ0=veKzIWr4}vn+h%#2xBA9f*ICQz5 zA97@%?Lwi060_=?81||ya^xJ9P{fWoK($4Iqem03TSD$k6b_4$`~Tvm6LYLl-rdL{ z%Q8qZPr$=6v!#r+oBldmvNC@Fqwu}VcCOhQ@i75M+ijwy%c#gG`d4TlEavU45uRII zv^6l7Ms4SH-M~D7dNpAw%_S_wW<6W54vAfpGS zja;?^P8>A1@Xhx|8Zn6%M{vc*>NJKwkqks!CIGjQK225%QIkNUfn0|bt*_5^i`)dH ztZ~4IA*W2YQIw?R9}9eW-F_eyyMnh!2K=T2XK}?xq4W%DB2{!of{hBG#gTrz@~UIs zv8jRk2>pZg9jxEojc*b-Y-Wa|PAGl|rqvIkIGt45+uUeote54+padx5KI|IOzZWjW zRpxydNun31&N6$DVJ`gnz?NvmjaM;S7#A;rhL{<*jSr@(Tam5 zArvO2Vw>q zE`WFog@xdVV&KEz7L6ejR9Z^_RXK}TQqTKxbATd%xBqSZFh*+fk@dS*lh>;q1&^70 z+BY)Jn698_Ct~4OO8YrN{*tp8_n~QwINp_Pm_z3qmp+J~QWU-dE8Qa3AdZ{3Q|=&# z4;#wI+iZTRFF{co5u^m!_E6nrJkmvk7IbZm=6C)1vL7QI=w*S&l7DfyGu?{x$P4=d z39O303wu4X)u{{ku}N3I*8I#R4?on0nS1LV>m6d-RAMiTfLANXdrOf^K91a_tC3a9pR(|3G!_W-ZPuY&BMkJ_x5 zJqdh%!?VgInUEPorJV6`qrGyR^Im_=*P%W3mO@$IM@)K!p4C1m&c4&nz6%yVT%zkffX$QHqWa#l9c%6i<2Sa$TUJ;UNFw5}5(7XeTixPd z5*yDuTEwm7&;8Y)xb7wCOyIVk=t@u;_EGPej=im-a~&y`_7$u5=V%ID+3l;kdTzXW z`GfRuFkf>_x0ltH_ZInI`(T4r(tRdE{NVNecKE?^ARP+X)3>&@#SX1rR>RV@<+*i> zd%AkNmDutnl>#XFO40Nj0mp*%bL~xHSMD8S+~JfP!f#kU=entHk}jDo4fY#juLC04 z>-IozBCcBEUwviMt9}_sr}4#4LKnBjSb7W^{AbJkac``bN4D)MGI(qCkdvlS`(rF| zo{+WG{%c3xONZawC6Agr!v2vOwo{iJcWx4*rXeZCf6-7)xM;WB>aFT_LpZd$3}%9^CWTdUOVFJC6R*xpnZMBiF>2Zk*gD3Txt&_10DGCi3vz`m+$oc80@*+PD3 zPffJZ3+s~)@U*kNDYV(4{B@V-(|>;Nk&Wq!K(%=B*f0tPXlf1rlKk2dSDUX!3NZ|~ M#PvVf-^h3V4}jGh(f|Me literal 0 HcmV?d00001 diff --git a/docs/getting-started.md b/docs/getting-started.md index dbfda0d..6211304 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -7,7 +7,7 @@ This guide shows how to install the package, connect to a Couchbase cluster, and Add the package to your project: ```bash -dotnet add package Couchbase.Analytics +dotnet add package Couchbase.AnalyticsClient ``` Requires .NET 8.0. From 2949b0c8815e6df79ec5d5448dc71e54e24457a8 Mon Sep 17 00:00:00 2001 From: Emilien Bevierre Date: Wed, 1 Oct 2025 17:48:14 +0100 Subject: [PATCH 2/6] Add nicer note formatting --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2f47f57..88327e8 100644 --- a/README.md +++ b/README.md @@ -43,19 +43,20 @@ var cluster = Cluster.Create( ); ``` -Notes: -- Use `http://host:8095` for non-TLS clusters, `https://host:18095` for TLS (or your own custom ports for a load balancer or proxy) -- If multiple IP addresses are resolved for a host, a connection will be attempted for a random IP address. If a connection attempt fails, another IP will be picked to attempt a connection, until all are exhausted. -- Connection string parameters include: - - `timeout.connect_timeout`, `timeout.dispatch_timeout`, `timeout.query_timeout` (in milliseconds) - - `security.trust_only_pem_file`, `security.disable_server_certificate_verification`, `security.cipher_suites` - - `max_retries` +> [!NOTE] +> Use `http://host:8095` for non-TLS clusters, `https://host:18095` for TLS (or your own custom ports for a load balancer or proxy) +> If multiple IP addresses are resolved for a host, a connection will be attempted for a random IP address. If a connection attempt fails, another IP will be picked to attempt a connection, until all are exhausted. +> Connection string parameters include: +> - `timeout.connect_timeout`, `timeout.dispatch_timeout`, `timeout.query_timeout` (in milliseconds) +> - `security.trust_only_pem_file`, `security.disable_server_certificate_verification`, `security.cipher_suites` +> - `max_retries` ### Query Run an Analytics statement and stream rows: -Note: Results are streamed by default. Use `QueryOptions.WithAsStreaming(false)` to get a blocking result. +> [!NOTE] +> Results are streamed by default. Use `QueryOptions.WithAsStreaming(false)` to get a blocking result. ```csharp using Couchbase.AnalyticsClient.Options; From c7af760db0219650f7efa079349e45c4e26d80bf Mon Sep 17 00:00:00 2001 From: Emilien Bevierre Date: Wed, 1 Oct 2025 17:57:39 +0100 Subject: [PATCH 3/6] minor edits --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 88327e8..69c1d44 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- Couchbase + Couchbase

Couchbase Analytics .NET SDK

@@ -44,8 +44,10 @@ var cluster = Cluster.Create( ``` > [!NOTE] -> Use `http://host:8095` for non-TLS clusters, `https://host:18095` for TLS (or your own custom ports for a load balancer or proxy) -> If multiple IP addresses are resolved for a host, a connection will be attempted for a random IP address. If a connection attempt fails, another IP will be picked to attempt a connection, until all are exhausted. +> Use `http://host:8095` for non-TLS connections, `https://host:18095` for TLS (or your own custom ports for a load balancer or proxy) +> +> If multiple IP addresses are resolved for a host, a connection will be attempted for a random one. If that connection attempt fails, another IP will be picked to attempt a connection, until all are exhausted. +> > Connection string parameters include: > - `timeout.connect_timeout`, `timeout.dispatch_timeout`, `timeout.query_timeout` (in milliseconds) > - `security.trust_only_pem_file`, `security.disable_server_certificate_verification`, `security.cipher_suites` From 69bab89868ca7445c616e00a90abe5136044320d Mon Sep 17 00:00:00 2001 From: Emilien Bevierre Date: Thu, 2 Oct 2025 11:17:22 +0100 Subject: [PATCH 4/6] Edits to getting started and README --- README.md | 61 ++++++++++++++++++++++++++--- docs/getting-started.md | 86 +++++++++++++++++++++++++++++++++-------- 2 files changed, 124 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 69c1d44..ef8ea78 100644 --- a/README.md +++ b/README.md @@ -81,12 +81,22 @@ await foreach (var row in result.Rows) ```csharp var statement = "SELECT * FROM `travel-sample`.inventory.airline WHERE country = $country LIMIT $limit"; -var paramResult = await cluster.ExecuteQueryAsync( +var paramResult = await _analytics2Fixture.Cluster.ExecuteQueryAsync( statement, new QueryOptions() .WithNamedParameter("country", "United States") .WithNamedParameter("limit", 10) -); +).ConfigureAwait(false); + +await foreach (var row in paramResult.Rows) +{ + Console.WriteLine(row.ContentAs()); +} + +/** Output: +{"airline":{"id":"airline_19433","type":"airline","name":"XAIR USA","iata":"XA","icao":"XAU","callsign":"XAIR","country":"United States"}} +... +*/ ``` ### Database and scope context @@ -98,12 +108,51 @@ var db = cluster.Database("travel-sample"); var scope = db.Scope("inventory"); var scoped = await scope.ExecuteQueryAsync( - "SELECT META().id FROM airline LIMIT 5" -); + "SELECT id FROM airline LIMIT 5" +).ConfigureAwait(false); await foreach (var row in scoped.Rows) { - Console.WriteLine(row.Json.ToString()); + Console.WriteLine(row.ContentAs()); +} + +/** Output: +{"id":"airline_19433"} +{"id":"airline_137"} +{"id":"airline_18239"} +{"id":"airline_10123"} +{"id":"airline_19290"} +*/ +``` + +### Options + +> [!WARNING] +> Option classes are imutable records. Each mutation returns a new instance of the options. + +Initialize, or modify options using: + +`With` methods return a new instance of the options, to allow chaining: + +```csharp +var options = new QueryOptions() + .WithReadOnly(true) + .WithScanConsistency(QueryScanConsistency.RequestPlus); +``` + +Or use the initializer syntax: +```csharp +var options = new QueryOptions() +{ + ReadOnly = true, + ScanConsistency = QueryScanConsistency.RequestPlus +} + +// or + +options = options with { + ReadOnly = true, + ScanConsistency = QueryScanConsistency.RequestPlus } ``` @@ -117,4 +166,4 @@ cluster.Dispose(); ## License -Apache 2.0 — see [`LICENSE`](LICENSE). \ No newline at end of file +Apache 2.0, see [`LICENSE`](LICENSE). \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md index 6211304..cbfc1b5 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -12,7 +12,7 @@ dotnet add package Couchbase.AnalyticsClient Requires .NET 8.0. -## Connect +### Connect Create a `Cluster` with a connection string and `Credential`. The connection string supports `http` or `https`, multiple hosts, and query/timeout/TLS parameters. @@ -34,19 +34,22 @@ var cluster = Cluster.Create( ); ``` -Notes: -- Use `http://host:8095` for non-TLS clusters, `https://host:18095` for TLS (or your own custom ports for a load balancer or proxy) -- If multiple IP addresses are resolved for a host, a connection will be attempted for a random IP address. If a connection attempt fails, another IP will be picked to attempt a connection, until all are exhausted. -- Connection string parameters include: - - `timeout.connect_timeout`, `timeout.dispatch_timeout`, `timeout.query_timeout` (in milliseconds) - - `security.trust_only_pem_file`, `security.disable_server_certificate_verification`, `security.cipher_suites` - - `max_retries` +> [!NOTE] +> Use `http://host:8095` for non-TLS connections, `https://host:18095` for TLS (or your own custom ports for a load balancer or proxy) +> +> If multiple IP addresses are resolved for a host, a connection will be attempted for a random one. If that connection attempt fails, another IP will be picked to attempt a connection, until all are exhausted. +> +> Connection string parameters include: +> - `timeout.connect_timeout`, `timeout.dispatch_timeout`, `timeout.query_timeout` (in milliseconds) +> - `security.trust_only_pem_file`, `security.disable_server_certificate_verification`, `security.cipher_suites` +> - `max_retries` -## Query +### Query Run an Analytics statement and stream rows: -Note: Results are streamed by default. Use `QueryOptions.WithAsStreaming(false)` to get a blocking result. +> [!NOTE] +> Results are streamed by default. Use `QueryOptions.WithAsStreaming(false)` to get a blocking result. ```csharp using Couchbase.AnalyticsClient.Options; @@ -69,12 +72,22 @@ await foreach (var row in result.Rows) ```csharp var statement = "SELECT * FROM `travel-sample`.inventory.airline WHERE country = $country LIMIT $limit"; -var paramResult = await cluster.ExecuteQueryAsync( +var paramResult = await _analytics2Fixture.Cluster.ExecuteQueryAsync( statement, new QueryOptions() .WithNamedParameter("country", "United States") .WithNamedParameter("limit", 10) -); +).ConfigureAwait(false); + +await foreach (var row in paramResult.Rows) +{ + Console.WriteLine(row.ContentAs()); +} + +/** Output: +{"airline":{"id":"airline_19433","type":"airline","name":"XAIR USA","iata":"XA","icao":"XAU","callsign":"XAIR","country":"United States"}} +... +*/ ``` ### Database and scope context @@ -86,19 +99,58 @@ var db = cluster.Database("travel-sample"); var scope = db.Scope("inventory"); var scoped = await scope.ExecuteQueryAsync( - "SELECT META().id FROM airline LIMIT 5" -); + "SELECT id FROM airline LIMIT 5" +).ConfigureAwait(false); await foreach (var row in scoped.Rows) { - Console.WriteLine(row.Json.ToString()); + Console.WriteLine(row.ContentAs()); +} + +/** Output: +{"id":"airline_19433"} +{"id":"airline_137"} +{"id":"airline_18239"} +{"id":"airline_10123"} +{"id":"airline_19290"} +*/ +``` + +### Options + +> [!WARNING] +> Option classes are imutable records. Each mutation returns a new instance of the options. + +Initialize, or modify options using: + +`With` methods return a new instance of the options, to allow chaining: + +```csharp +var options = new QueryOptions() + .WithReadOnly(true) + .WithScanConsistency(QueryScanConsistency.RequestPlus); +``` + +Or use the initializer syntax: +```csharp +var options = new QueryOptions() +{ + ReadOnly = true, + ScanConsistency = QueryScanConsistency.RequestPlus +} + +// or + +options = options with { + ReadOnly = true, + ScanConsistency = QueryScanConsistency.RequestPlus } ``` -## Cleanup +### Cleanup `Cluster` implements `IDisposable`. Dispose when done to release resources: ```csharp cluster.Dispose(); -``` \ No newline at end of file +``` From ed11b78ef366a358424a225f45dd6ff939149ae8 Mon Sep 17 00:00:00 2001 From: Emilien Bevierre Date: Fri, 3 Oct 2025 11:54:38 +0100 Subject: [PATCH 5/6] Adjust code examples, add .ConfigureAwait(false) --- README.md | 12 ++++++------ tests/Couchbase.Analytics.FunctionalTests/NewTest.cs | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 tests/Couchbase.Analytics.FunctionalTests/NewTest.cs diff --git a/README.md b/README.md index ef8ea78..b15db3f 100644 --- a/README.md +++ b/README.md @@ -64,15 +64,15 @@ Run an Analytics statement and stream rows: using Couchbase.AnalyticsClient.Options; var result = await cluster.ExecuteQueryAsync( - "SELECT 1 AS one;", + "SELECT i from ARRAY_RANGE(1, 100) AS i;", new QueryOptions() .WithReadOnly(true) .WithScanConsistency(QueryScanConsistency.RequestPlus) -); +).ConfigureAwait(false); -await foreach (var row in result.Rows) +await foreach (var row in result.ConfigureAwait(false)) { - Console.WriteLine(row.ContentAs()); + Console.WriteLine(row.ContentAs()); } ``` @@ -88,7 +88,7 @@ var paramResult = await _analytics2Fixture.Cluster.ExecuteQueryAsync( .WithNamedParameter("limit", 10) ).ConfigureAwait(false); -await foreach (var row in paramResult.Rows) +await foreach (var row in paramResult.ConfigureAwait(false)) { Console.WriteLine(row.ContentAs()); } @@ -111,7 +111,7 @@ var scoped = await scope.ExecuteQueryAsync( "SELECT id FROM airline LIMIT 5" ).ConfigureAwait(false); -await foreach (var row in scoped.Rows) +await foreach (var row in scoped.ConfigureAwait(false)) { Console.WriteLine(row.ContentAs()); } diff --git a/tests/Couchbase.Analytics.FunctionalTests/NewTest.cs b/tests/Couchbase.Analytics.FunctionalTests/NewTest.cs new file mode 100644 index 0000000..fcfeaed --- /dev/null +++ b/tests/Couchbase.Analytics.FunctionalTests/NewTest.cs @@ -0,0 +1,6 @@ +namespace Couchbase.AnalyticsClient.FunctionalTests; + +public class NewTest +{ + +} \ No newline at end of file From 7c74374b4fd825c3c34fd47d505b910dcc62e8c8 Mon Sep 17 00:00:00 2001 From: Emilien Bevierre Date: Fri, 3 Oct 2025 11:57:40 +0100 Subject: [PATCH 6/6] Fix typo, adjust getting-started --- README.md | 2 +- docs/getting-started.md | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b15db3f..bbb998f 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ await foreach (var row in scoped.ConfigureAwait(false)) ### Options > [!WARNING] -> Option classes are imutable records. Each mutation returns a new instance of the options. +> Option classes are immutable records. Each mutation returns a new instance of the options. Initialize, or modify options using: diff --git a/docs/getting-started.md b/docs/getting-started.md index cbfc1b5..d58ae22 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -59,11 +59,11 @@ var result = await cluster.ExecuteQueryAsync( new QueryOptions() .WithReadOnly(true) .WithScanConsistency(QueryScanConsistency.RequestPlus) -); +).ConfigureAwait(false); -await foreach (var row in result.Rows) +await foreach (var row in result.ConfigureAwait(false)) { - Console.WriteLine(row.ContentAs()); + Console.WriteLine(row.ContentAs()); } ``` @@ -79,7 +79,7 @@ var paramResult = await _analytics2Fixture.Cluster.ExecuteQueryAsync( .WithNamedParameter("limit", 10) ).ConfigureAwait(false); -await foreach (var row in paramResult.Rows) +await foreach (var row in paramResult.ConfigureAwait(false)) { Console.WriteLine(row.ContentAs()); } @@ -102,7 +102,7 @@ var scoped = await scope.ExecuteQueryAsync( "SELECT id FROM airline LIMIT 5" ).ConfigureAwait(false); -await foreach (var row in scoped.Rows) +await foreach (var row in scoped.ConfigureAwait(false)) { Console.WriteLine(row.ContentAs()); } @@ -119,7 +119,7 @@ await foreach (var row in scoped.Rows) ### Options > [!WARNING] -> Option classes are imutable records. Each mutation returns a new instance of the options. +> Option classes are immutable records. Each mutation returns a new instance of the options. Initialize, or modify options using: @@ -153,4 +153,4 @@ options = options with { ```csharp cluster.Dispose(); -``` +``` \ No newline at end of file