From 2ddf19985024bd540ee483392f4e8e307073a0e0 Mon Sep 17 00:00:00 2001 From: Jason Stedwell Date: Tue, 21 Jul 2026 15:29:55 -0500 Subject: [PATCH] Phase 4: shared-write hardening + group lenses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - vault_lock gains bounded retry/backoff (CHORUS_LOCK_RETRIES=4, CHORUS_LOCK_BACKOFF=0.5s); atomic_index_update and recall-index upkeep retry acquisition — unlocked fallback only after exhausted retries, loudly, so an already-written note is never stranded unindexed. - Duplicate-gate candidates carry the existing note's author; STOP message says whose entity the capture collided with. - recall --author filters hits + linked context to one member's notes; recall briefs and --json surface the author: stamp. - load --all-members appends a group-wide view (every member's scope + last-session heartbeat); roster parsing accepts folders as trailing-slash file entries (the REST API's actual shape). - operating-contract.md concurrency section rewritten for N members. - Two-member e2e suite committed as eval/test_multimember.py (26 checks incl. all four Phase-4 behaviors). - Manifest -> 2.0.0-alpha.4; rebuilt chorus-memory.plugin. Verified: 25/25 unit, scaffold, routing-sync, 5 mock e2e suites (incl. new multimember), run_eval metrics unchanged. Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 27 ++++ CHORUS-PLAN.md | 10 +- README.md | 4 +- chorus-memory.plugin | Bin 192337 -> 194382 bytes .../.claude-plugin/plugin.json | 2 +- .../commands/chorus-load.md | 7 +- .../commands/chorus-recall.md | 2 +- .../skills/chorus-memory/SKILL.md | 4 +- .../references/operating-contract.md | 11 +- .../skills/chorus-memory/scripts/chorus.py | 46 +++++- .../scripts/chorus_concurrency.py | 32 +++- .../chorus-memory/scripts/chorus_ops.py | 25 ++- .../chorus-memory/scripts/chorus_recall.py | 22 ++- eval/test_multimember.py | 148 ++++++++++++++++++ 14 files changed, 302 insertions(+), 38 deletions(-) create mode 100644 eval/test_multimember.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b2625d..a0c5ff8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## 2.0.0-alpha.4 — Phase 4 (shared-write hardening + group lenses) + +### Added +- **Bounded lock retry on index writes.** `vault_lock` gains `retries`/`backoff` + (linear); `atomic_index_update` and the recall-index upkeep now retry acquisition + (`CHORUS_LOCK_RETRIES`, default 4 / `CHORUS_LOCK_BACKOFF`, default 0.5s). Index + lock holds are sub-second, so a retrying writer virtually always acquires; only + after exhausted retries does it proceed unlocked — loudly — because an + already-written note must never be stranded unindexed. +- **Duplicate-gate attribution.** Gate candidates now carry the existing note's + `author`; the STOP message reads `candidate: acme-rockets -> … (score 1.0, + created by jason)`, so a blocked member knows whose entity they collided with. +- **`recall --author `** — filter hits and linked context to one member's + notes (a lens, not a wall); recall briefs and `--json` summaries now surface the + `author:` stamp alongside updated/status. +- **`load --all-members`** — appends a compact group-wide orientation: every + member's active scope + last-session heartbeat ("what has the team been doing"). +- `references/operating-contract.md` concurrency section rewritten for N members + (namespacing as first defense; member-tagged idempotent appends; retried index + lock; member-attributed lock owners). +- Eval: the two-member end-to-end suite is now committed as + `eval/test_multimember.py` (26 checks, incl. the four Phase-4 behaviors). + +### Fixed +- `load --all-members` roster parsing accepts folders as trailing-slash entries in + `files` (the shape the REST API actually returns) as well as a `folders` key. + ## 2.0.0-alpha.3 — Phase 3 (per-member namespacing — schema 5) The core of the group conversion: one shared vault, per-member namespaces for all diff --git a/CHORUS-PLAN.md b/CHORUS-PLAN.md index 4ea0179..4eaa002 100644 --- a/CHORUS-PLAN.md +++ b/CHORUS-PLAN.md @@ -209,10 +209,12 @@ up between phases — there is no ECHO-vault adoption path; CHORUS vaults start fresh). Docs: vault-layout.md, routing-map.md, bootstrap.md rewritten. **Deliverable:** a real multi-member vault, bootstrapped from empty. -### Phase 4 — Shared-write hardening (1–2 days) -Required lock on index writes with bounded retry/backoff, gate messages carry -author, `recall --author`, `load --all-members`, concurrency docs -(operating-contract.md) rewritten for N writers. +### Phase 4 — Shared-write hardening (1–2 days) — DONE +Lock on index writes with bounded retry/backoff (unlocked fallback only after +exhausted retries, loudly — a written note must never go unindexed), gate +messages carry the existing entity's author, `recall --author`, +`load --all-members`, concurrency docs (operating-contract.md) rewritten for +N writers. Two-member e2e suite committed as `eval/test_multimember.py`. ### Phase 5 — Docs, onboarding & eval (2–3 days) SKILL.md full rewrite (operator → member voice; drop the "single owner" diff --git a/README.md b/README.md index 833967c..754d5a3 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# chorus-memory — v2.0.0-alpha.3 +# chorus-memory — v2.0.0-alpha.4 > **CHORUS is a group-based fork of [ECHO](https://git.alwisp.com/jason/echo)** — one shared > Obsidian vault serving a group of members instead of a single operator. The conversion > plan and settled design decisions live in [CHORUS-PLAN.md](CHORUS-PLAN.md). The pre-fork -> ECHO v1.5.1 state is preserved at the `echo-fork-point` tag. **Phases 1–3 (through per-member +> ECHO v1.5.1 state is preserved at the `echo-fork-point` tag. **Phases 1–4 (through shared-write > namespacing) are done**; the body of this README below the fold still describes the > inherited single-operator behavior and is rewritten in Phase 5. > Deployment endpoint: `https://chorusapi.mpm.to`. CHORUS is a **clean break** from diff --git a/chorus-memory.plugin b/chorus-memory.plugin index 6176a54677704391a273a3904b5967aaf223b4f1..14afe84f4c5b3312e7ffc372b236ab623def2b32 100644 GIT binary patch delta 54612 zcmV)1K+V6=-V4s|3mZ^N0|XQR000O8001FeXY7k1$pHWW;sO8w8keEb0v(Y!5CLMb zNun4IbqB6SzXJdOqXqx~7XX*9(gGQOjg;GN+eQ$E@A(u1$3P@jD>hAl7Df{w@F6iO zSb<|B7ex`S$f39uxl8OWB@10!no>9~t;bL8`N5NAoSbylRI1?_xx#e#YNTg>=gF~i z$TuTzO1Ynr(kt^YO$5p%_m0WeOlexw#`aDOb<&jFMl}sWs0m$+<+a((>9*G~=BSS} z4ZSM8CiGBn*;_`6%9@t)&%azR7W1~u&tep-b?wPm#oEiDGdAyN(n`BwJEOHVeMe7P z_NKS^#}!-F1-oq2oYjoVE0%tL6!y}QtEJ_VN~xOAt3QNC#j{v`$UazrFLZ7+q{ya8 z(|AHtY2wMCTX@w5b1b83fqtNB5`#s_ov-P;!D~@kRrx7NU6Si7;R#jk9-InzhH%{;l+8g{_)X$U&mvg^XsO&EEl zELz+ur@+MI&G&Cycz&QXfJxcFAOTolYjy}j;g!R!n8gO!T4UXRfK=7UHQs9KwOASB zowu^Akpji1w%X&SR5fW1?IGXFNW!Lv{x+JK%(GXewP2Q~x1Zd9?d13TRKkOF>h(eE+Vl`NhrdQE> z+iP4^wDoNLaM);24o|G~AY@#w%7xUp;+0xsb(N6sHjzr4R+gUKj`7^k*(5@n4H#ss z%g#V^hR&y9(PBHIB*gxAE@KYWb_VP7=T7?i9gGRkj;|bD`+PcXB+CMVMq6R>g^7r0 zX(3}+;Bkr0=~9o@ND#*&ES=+Bdq%t3WV>2=d|;u*PzlDjJffo9ID5UPr>z%UZ#zFv z{smA=0|XQR000O8001Fe7v(eNF#`YqYLk&1B7fU%)G!cz&sU7nO0=uZM!?$&Dpdsm z63}YtiU))mZ!%fC_1c!lX*Z%sd;}67#GmjbjO|pw8&8REXU?2+?5e7Y4ypCZ1!c_= zR@e%yK|ruhwa|OJgR|G?tMv!i;m-OIetr86I}uu`%odCdNZ|B95F{!OTA3T{z@Xa7 zjei}yw6-gR-wr!8q2e=P3FW5*J_m=MteJ!L;Jm%YHheCNiYXOq!UzbnSu3p{sLI7> zGoTyA{DK9anYPvh+z05bUlzp)9G3+TfBB&(R)a|>)?k%3PiJBaD)5M`zQsfx z0{R_@tx$$Snqa;vjG#=1`#BH_-%6x82!GQ7?j3(90)w;;gtjb3b8x`=X%Vn%k`RY+T$U?qHp`}-*n&kv6@LH$6ep4B@O>V;>hfE8zAtJ3WMRe~ocb%(dL8Q7qE zkSIE+9v=h10i4;7*53fJnj5=^o;}=%_NH)Skk&l?i{4~#`6mTsLJ%FJRbt@%9-c9W z4f>OqqF!lsKK?~7^TH#_xh@XiBY)d(?`R1F2eQfanwVGqhw5nqs(+Y{gLIIQ;NtZ1 z^&&b^6qm_k@A!%kr-uFx*VYRsIppaAO+tdU+Z>#0&W#Z|lbOxt;6=*DX5>CK-U`zq z{QSX}6iFIB9S0OdV6Yf*6s-iwK_|&QaN-G?!F4e!%cgGf&Sg%d^VqWv34f{Dk4Mejm$40jSux*P`iG@HUqqMT7OW;SSs3Mj<;i&&K~r>GWnm`HYt}o|No5zZjg> z1-!84Q2-;n=k6xX!7DaOFN)u@$R9lt3W{m5yOBl!03W=Q4>E9n_{`WMP{_)RjEvte zBI7vTE7EzkAB``|YE{ScY+hFDy-8M&t9-G{%VIxzTW8VoGK-!*KR$VT8Xce4`6N$^ z=qg>!mQh;s%W{!b>9VZu){*?H&g*4XEF&E*O2<`M*U{5ix|(F8r{xc2^**Yzx|Z?l zAzyHPnHAYpR<#CylfmE1@MTnGGSYcg4Wc@|$_7zUF6F;x<;5V9r^e}GxvH`#E!NA+ zyts%at13O8WzpaMqeWFt^I0|;m&G#supC6`WP%^-LwRvte&EXSQI*Pg zX;fs_vdHp}*?2jO&Z_+4LWn68Eu!mud5MYIW-KnNv<8(xa+15s{d3t>noys;(jOJV|mzY zhza4%`2sYkqa`hACDGU~jrkK~hHRF};{G37N*dpel0W|5YI$jN6paEmf8AhP7=_|5xFmS2JFM$VYb zFJuJSFdLP)V4%fpbs?*)FY`q$vzI-TgAV~aj1nc&aIsFJ?p2<;58f%klAbK2E@xM= zl^K{|nrE{~G_A_{=h1qg3?i(b6<2wGRTezrr4XbN5e|~ukljR2%e(JSj^DnK-?_hE z9ld&TbP{~<M<+Dk>FBBE3@DHI<6vy~Bmf;hj|1yUn6jdq9F>dG1jdY}ck=wVC zPN&A2@sRF_Fd~#i8uewbgxi)`-`-tkJgLHBHRzS|uYO-oKrRYH#IhwHCB%cA&q;YLujOS&EK|{@t$!(Yi#{2 z9A5d7Z#X&n-P;!@N6+?6zVTTRZ|}47^gJG?q7d@QAe3b$%0O32uln(So(kjkTlrb| zQXUSzQw$=Z`#OT1Nqy^ikD?dy(~G3XB(O-EJJEM}Rg(-VU4_l$2YAp+_o;Fl*rXBj zDwINIB0uuX=nrvBgunQ)95wk9;${(Q2&L~JBE!kf*O#8*XpYp;s%Tz0jGm}fGbync z6V_l#Xs7qWOfXJEg+kqb#ue@F?cE>BM4ri!62nalghLl4mM;&;Twu8gLGsxw4o_BM)X$52ndlyLS4B2|5$>6Ya)qroE?1mR zO%)Z8a_<4Caah0CttNkZO(9gv&5RHN2m!%D%M5HGC#J}Z~yx5QL+#pp)9_Cj5;PhI*zL1k_f{^j~40j zGG3N3=}5czG0cE;mQPYFAXlqjMbzgh{N6B_m6BMA`-v&x;Ks2Eu+HE9<$rhNFQaWo zrh=Di`v13?Z5D zoQsBfF%2w#JjfY%b=b2CW)Tg&Zjmh^o<_-6_a2Dh)K8~NIc9Ewa{g<$%s4Z5YcrYu znd7}}MiE}erig}~mDg%&rgkQUXXF88MCBrxBo365{<034>EY}eN>)g3hviU>hF?;R zJ3Pt6Y?Q-tDF$j*4Wl>mx*DEvWvp(C6l(*9hgh18;)Rh!M#GH&A3d~Ffej;ojQxL}&>KF!p{d}=pJAYABSejQh_*mqnn2Y&^Zot96a)-K`4R3L0muM~QQ8z$kAh0{i`e^H;^+ zmY*-nawft@j)6!#k@>XE$5e81fPN6}EU&>t>G=3m>GCo!Rv)4+nLf2)qc7oZWtF%r z*tfi9{3{o6aDYQ`p4OKTXD}U>a-imau@9^y&^1Yq-0LSExTVgY?f0ExQV)1M%Vnnh z{(}672${xI!mYWG@!#PgPaV8}Gv;oH zO#e7*eTgoFiZy;N}F2<%*+jQwp zva8Y47YB$@%KWm{+nQ64H;tMvR7_-k0u%7hT&!FPca1N|6jgd1ff;(xkTWWO*;=(M!zgxce)VS+-tXSLeEa>2*Y8e5c>iTY)lzR5 zJ&BrUSLOSxZDJ%)md(kr_$^IkwUOn!H-~4>2Mm?kuM()a1o4G0VM2*|dPCI|L;I== zyP`ttx;Vd(;k^9NgGzd%>)btindb|5@0Cnj*s=X{ofdfpl0^79QVErR!tM~$c&X+H zwWIw+LkP530;8ZBP3fo9u*VWLqXP9RdSpeBGKY^Mn`8u+hevZ55<0zDf1!hjuTeVh zU1y*yBjQ*#)yvkjIn-c{Dg#+X7Pw=Yn8lZjl3%@i@%jw^d-}uC(VHZy3%ICD&j>S| zq_wa+O$xPZYC72d4GRr_=8ON3v`^wdSo%847WVHJzpL0x0#@f1-z4o;wK=x1JXCdH zVk7D-Z1@W~-x;*?EdM3bXu?3a@%h==n;7YYRjub=P63!PrCXbsA#Wb4NUr#otSV`5 zA@nR#2tjk4oLNr)dMx6nhQB1<+j)r{19_Jf6~k8_KEUuV#KZ=FUuIQRA{I}b63^(4 zPsBth8RHhRiSk1hsH$L-C;R(qfig~!Ru>se<52Mn+sP8-!&Jo^s2|g|s}TK10KbOL zoR#DEN?urDSq#M`ubE9^O>vk7&#iujx|2xPT#5s9M> zrDDQ(eCf>Fxmt#QV%>&;)*N~|y^=k_snglZBXHj)B{tG$vm$J1WLqlVS9La+qQkLN8|bAaU|Zu-cM0H4Zip}`uNd*jO}lK)tw26UD{*R-zg~i zpE;%I!Q&D1QvnO@BY7{1@Ao*-4Vmb+b8mazOo;sy$MS@Er}fW~`_G+#@AkQSzZR(u zBSn1?@Npe=zlci4ozt0~ZRh6JW3jzQGjW+?TXS@kXV<+Q(~!ND_tAZS9BuvQPW15J z!zg~NA*Y9b4|lDj#)FSUkmC0T(T**Gt=zofj>rT}SB_u}tPsYB-MeG#S{zI{0gs@@ zYuVz*JDyprmQk~UM~pm#3m6Nnme~lJTV+<)3jt@LOm-1Q<%}D*^9XY2ai?YZh)&I@eV}4-7ug&f&fhC5t5IOJ3BdF zNG~%s){JvGzq^N96?`^)vWY)G&o3_H8M3|3=_zFsoTVmbrp}z=Ha*-}p^&K}1A7cc z*N8ZO%x3ArvaNH`#d*xQB{^oK>2?AK#0{oCLOKY#j9)-Z4~6el69KP!yYxU48){XW3$Bb0!IeH*o>)vcl9lp(Lr(;{QBM~y5Gq19YHSxb;wR* zp5W2*afx9Ud7Lz>1X8}j^_EQmJO-vpFeAcaZG4NTg0sjphXIynV4rH>jGm#pT?H&7~a`` zlbuI%jVmw|pBr^7s_xx!kLSEh?%Lm*1+a7r?-1`o%cnxFIQr?QlZ+69 zpMT~Eb#(YBe*9#|_)BpRE<}vPG1NeRq@!+A&4;KaeiKw_bn7e=Hv}J@aj2e(gjfzm zVmqF=Fxx`@l_qGsAVKV z9CL9=jP&soiLo9)OjYg%Ywx@z@Q~p0>DqqqOlZA!ljT~Jxt@oSzJ4+?IX}XGF&f#~ z8d1Ky!&-%TN17NM>B)LWY>N5>X@n)mqHL;iAtYQjbV~F!i4Q076xS*%QcX{Z-3SpV zZw8p4%7M><)JybGBP*h_s~frvG~--SxYSJWts^~kMrJ!DO$rsVB8qt8gb4x_i>qaTdp?KghW z)Giuu1Cc;YMzX2+uHc^j z4*fZa{`PPG79|RAAreod%NqYE0D%}Z!ODTdj}08?Z2-lT3hQTcfW*eaJqvNXCioYU z9ekGRs=@yyiaktBZYLC(@7!?PnCk48-O`}Go5i=pleu4D;tm;U`aX%gQeBPI-7QXURM?&ea+J2L&W ziYI=l3_uH~@=Iir@+o%)HOU{1G~TlkZ_XL#)XF>Wz?i zBs}@8R#b56r^U8G*L2JvC3S6YK%Pr^ZF9!+}kN zh_n10ITc~+eVl-KCcb%0WAqWs$H$2W9FkWIbxW32nQZprHUr~Ba6Q){#HVO8p>Og` z)7|n~Mw1h>Sn&P&I$hgFidB90%2Id?ufQa|E3;@0q)UN+45J^i^u0S+DWWDu1Ur>q zaBDFIJs*066VuX(J2mnywH8!xt}X4Und}DIRAoYqVpAP6AK0aPMg*-;am16aT9pZo z{*&^2bW#fGm!p%@zGjky@*;bxfwGa4nsbdcsRKA$Gv=gr8Lb^TrnFM*WYi4sI# zZBkDn=IzLTCd3RNLfX+dMC9O)^Bxn8YClMSrxsE@QJ)JE7Us5jBQz zEF3iKMQqt*OavB;X94K;gpYLyXb=bQT4CRYy8L~AXZP0oWhh#=4<0e}2ZDaEnTt$Z zOBtlPEXzsMHOp4*TEu2Ui>gNsF%!MD7uVUjXgtI^VQ-cT=s70gA>2wG5@WcWceOyQ z72=>}e_mAS;u3kc*~$ZVk*8B&-XCQyg|RUVj_yQMU3`rN$oQO_jibxGhIJ*prn(-W z3WtY(r*I;y#9{C0NKQqVGoY_Xb>(&1X2NR-pG`D4sQ}3$e47X{VST#WE4Y47UOo6q zHCew;%ohAMdd6nWB9NQTreY*cVUmv1bP>EIrR+6@xJyM2F?{vBFyUZ|e-<9X9kLV_%f1vHu{;-5H45s4Mj9Can=qk&AtyjY zIH1tL=c1IO2ps_>hHkZ*v6D1c{2eL?5?}MM~`JbHGP)u416&bI_r8fc>6nWJ7*$0cpBK z3I-YC-wDGZ$g~3nEM{Q6cJM*r5M}#30Q>a}_w80JF;d2zK zacT0*B_sBtH)Qb)J}gatx}Az~c}euY5JW_l2Rtikx*MctL1j4C?gl6O-Rcz z`CuDQPMyX8yLu4&28tX+hBM7)BGLwi8}RyRq@rJs4NhVOmlK{rPWKvBjwOvU^G7`f z(Et=~`@Q%m<=k|UvbH#c=1>1yWXsk}PP;rQ;jc#gZYhoJPnWU09k_(- zQp9*!0ni}B7pTvFoMg<%G3BaK*7jt+uOVlf;VD=UKrP_jw!r<&$`|m=48^)yA_tS! zzDN(JDd1)N%z|(&5R;e$bdXIx_WKn|5yuYMPIV|#W`vokIFnC3jRL|LZ`&EPh%QqygCQ?lHNLD&)gV)EwgpvSNs+zQ!!!pA&M*- zW7r#4hRLLqosMnxo)TW;pyVO{vWWDH$eRiXqVPxfP6G>eAZk}Zuu=2a4#RnK3LK;% zqpYY`t`^Z1m#U*HgCS1(V(Ka34qL`3jTm7pg_>d~FAvPpwDJJ@@`eSfMc&s_O(GVn z$wk&c#`P3`;4F#HhOtT87XCvG3T7iVkCcJaw2XS9*f$cTRSKr1gvSoL3-glFM2^}i zk-i%hpvs2zTHKpCOcgL>1(R^fBHH322K!pH!lTf~6}<38DijM6nXpwRIl0R+2!lpy zcrcPxfzy0~t|XD`m1qc%u-_j>zeVhlx-Ax3q!*5V+lA8NKZZ$?eZ;s$Vt=ve)eBE8 zQr$m_Nmi`HN~vbJVf0#;`p+EHI;E1P^&i30v zB(L?gtl(#j*`C#X5u4LeFKGUjt+e6P$OXle^SA%L_4a%7T(RRh%D46=yu$yjA!!nXVH-b3aD zT!M~K){$C640K`;^k=B)ii1%V^>@H%Ge0&b8uXmb=!EqsU)v6@mK`EC^5gN_lPynw zQ*p8b!|p*+!GtJf9!P-*9dZp$OcWF6ZDK=YjUMSg9*>~Jp^8*>_|683RJEMLL`QKp z4PC(4IzZaZ8utJpe&qYTp=LyX9unt;vMPUijkE_?BKG{|I7IZ|-aY+{7J8=fVcA0^T-a z5Y~fmB46&DNSh0S;De*)^B1R$|Lxj>1kZ8oho3RF8TPRmW;@3>k4bI2FQQX_{_pb~ zQhCi6ef1eHY78X20vpFVwT+*7uw-xqKFR@NZwXo>ZkULXdy^>&on_*g7CsRSj{^HI zR=C+eMvq>c9>*x5CKlqc=v)_o3R;6`cY%<=V!)M6Bpj~lU8bmxyZ3uyV$By#8y3V( zkp)MB|2xPzg8uAu`XLj)(!_&*OdQmfu8A!J@zT7mt?LS%ajWoSdlfwT*RRy85F-cz z>>N53M*t01K8TzbUDO4CP&`FRgJ_DMKbQa293FOsjtYMB?YDBO#5*Z_7PdhQS?gsP z8P2X!EnTbiG<_ZHzvTu-jB<^dmpRTd*?ju^@Z{*3CBm9o9-bsr7s?KQu>|9QG6K@r zVJr-c0zt2M16Ao{QUtm%p>IBeA*mK@Rl5ryM{g~6(nqgO~ z%G3i_>ijyG3_l-P1fW(KV{_2b_}$Z30ZV{*AYJIDwFzSy8UScb125h)Ta3G>fz{Au zp(j8(jUIX*oDgc;e65o<=X(Qg=}_!gy;=7kZd!;t!kr%kH6HMC3IAQ*TE<2D2R+;}I*r#p_7{>a4hN&uc-OVo4=$&tR zQLD>A_}#C2O)(}6eaoTa1k|=m3{?H~8+l@FG1+Ti_|&6goCy(k!zVC9ib54FGf64a zrkQnyA{0*BCuDvpI(wPBG4)wcSKsiyl^438@cXQG zO^O<96a#Oy58kMYDVu|cJ>O2e-<19fOA|CwYJATnxuOLNb9exjK3RuLa4}R@@BpWT z=YU|DD{Z1O@TaPB`mm*&8Sz=xkVPkYk5!Zs=)$F^&^;m6mm|Mr5Axk9U@2 zv{E3L(rmHhsd$ONCu1-cZV{b@kh1F=04qP#(|=q|F6P9s_a`NT8%^N*Zta_oF>&7B z0M6$(JY+~R=0rtcqr|TnBh9O)U5KZhH~dMbM7te64m1M)e%wi1{!m%%l%o?Tr5-^N z63%tN*kZ1KkQjQF5JcCh4&>})W_Gk!2REf&Y5Bj#mN6wPhwOS1IlI~1Tia_Y5Fu>Pvy5kOvWox((;};wBJ>E0kf0MqvFBGo~pck1A=wfEm6@FQAN^ zS=!+G2Zkwi0V$%bCpBMzNgyG4!82?ilEl*FOe=3gb49{IHlrvfg!9lgBLbvP0%MG9 z5_U;{)E;94=b1Ml*LoXtLN7{G<+RZQP~SUo%1Hxqx1I3VY8u?y8*kX7je{;XMOx9x zqY$w$wl<^-TJLDwNm;~2-8G^UYCx2}X7Q30>`g@7k}MkVuQauA_QSD@E$rXy!Z&7S zm$8B|SO@i23L|2^NM)ZWO2y^V@MJ3ro)rCm5LB!>1`W8;jO;o~QN7n|1jlGJA_^3> zlgnydBymvV5dGx&d_O`7t2wo$_TVHDYBReV%->uDVq&LW0rrW56d~a`jDE0IllBbj zMP!24AOS}v0>~oQ>Rf{v;p`V`Ssrdi)^=qD24*5K%j%*&-Ndyz5@Xs=SJ*JiDLK`D z?z-L5f^O5cV@NTmq|0WtZdc3dn$zGCY4bShoLyE~_8HPMOxh{EQ<@)EBg0XFFhgiN zQ+CPbzv;LZAVyR)X^KpfX1>Hzjucd12udR=O7#Ns6yiuO6kOj`P~CKWqvWCAZs`pE zTQhv^v}V|H$7k8-!om}e($yq4#nY632LqRJtBh{3SF3)bRkh)$y&wGcEn(eK zFS2*o)W7WAu@%K^jOdFZ zJ9u-);#9;!||v4S@%jBaX>Yp8pG<$-?)n(vN$LlMT* zL{O5u=tH4g<3{Pa85*;y{5Q?V`}@b|byi(z;v?bY0d-{=H!F}2yv7rbNUhD2eqtE- z#8-xi8MiuTVjwy25=;F#Hd5q&k6j2+9x;=p`A$D*8a}!@xD7~6vo2*5Pl+(br;W0J zs9b4_#X>_+br?y?^>@zoH%qdnHvt)@$`&R;JyLy+&Jc<1dt!!Z-E1*S&Q$@mPxfZ8 zrz@)Ekv{;eWF-wA1x;(H@DYV;ApwWcvHh&J9-->yYFY_-KFcY!%+_{)KC1TaUo%Vc zsu>b`=tRThGc^L<7!$nAr`dQto@IM`_ED|tUS7&(U7$2x_QIM)IEFKRsYh0+uU{*S z*+H%v=x11IrQJhcy*)h>`2>a0s;C5HKy$|ylVmpsy0=3F>A%zWd<+Kv7`?J)!y2(~ z1?=1ZMs%u~dc)fcx+VdCugjk=a5n7Jvn7s&+%ofTk%xYx;9Pa?HMqjQh#CiL-lRX2 zx8OhWg+tfspHB^If&rA8&N)`MUcsIg0upAFS28Bsen(lvQ0@8>`NICTKi{OQ+R&}4 zgxN0}YdFd36>&>jlQzIFNBkH9fbr)uHu6f(WwTLFrdhO-UBGyMfSWJ~4jodsE=xLL zu&&=%;^9n;Fq@*zm##ntJzR|iGd=aDIpD4us~x_6=Bh0kUNF;wOrtq$^k&rlm&L9P zQE_L#k37xf%$!%O2xuZJ)BFQ_w_>kh(!*KK)rmW$dxB`0O#HSOqN^V!{I!4~Rm4_it+>Z^a$*0cpsep(hx@ zBYeNLF`uqxKBnaq%XCG1zz05RvG_%>Srd3i*WJCULqZRuBU*%^T>L$&&1AjVoY{V+){lk5o0D9C2Ub4|EsX)#Cp&w z5P;SVYjrMD^uTF~5wJoyYJ_yCiD{)t2xwZBv6TdW%`BJO_Nj;PU<9gUx{2kJUc%5krQ_EsqTrd)09wv4Sju? z^-a^DK)XP~RfUHx+0c>=-c{LAz=W8nD@+^M%)*kkrK>O=;m6jl))kfc9tz9^?y6=Z z1C>>OV_ULCyY>t1u{CD%s?F9xiIPj_pgBMV1GxU0n9)#-vf4zvg)dF(S^usrMb^WM z5E-gh)2SGR5Xzb;COv!{Rm~}R1v6=!a$7TcGh%Rqr8L-SA`BEGw^?s(v&Q~aVmJ+N zk4kRDz|03zksxAeU$-VsuTw-J5E;93aoh#5GtQw)@Y@+TQW3n2E zXHTyc0Q<3aWrIet9E3Y-UU`cL5Rz|$Y7Mb^``Swxw&RGnMT=Lwd3$Ejj4FiFp?BHl zjyGBC4I9R6OZBXyXGbrO&W=>!h<3u218O|JK|yF`CKfPgIkFFlC7Z>Rn$YCtsy*X> z*fMeYSX^YiO{~_V-#2?qqt#=gW$AHhJu=rMOZ2{=Z*tYN4WglinJ&ZfSx1Q6Qs9`^ zk&8#!nQ&RArZm!AmB!rz;djC2wavA5gElpO9-j9$U^TG#H1g(7ElpD7hzMg;0n_id zUq&ljC(NHDtu9#B5rV-Pt2;2TH5}-FQwTch0v8S^RKm3Wlnvu{wmhKOg1}9t)##cz z{$#FO>o$lzQTZmCsV1y%CT0;D9HV71TD{8E!jR<0{?U9nv*lZ0VDRIA6`{?S+kcvdjbyBFj!M`TdmU~v~aD?9&zjD zP%&_<{UUNzTB@LQ&WbFy%ZNUIog(n|$L{K|fnNWC55L2LM(BNwuo?T20zlo0bm?a- zE3@8S!>D`6CW0hSaMeLjXBJf0%#n46r-H)A0l|QVxFJl??M&R{Xtl_~_4zxXPk3v4 z!eLK&n5LnyRNqKRU%+SFcWB)jX+#bf9%E~NSTmorsL;72 z+7^M^B?ffv?oA?78LzIaN0aqAo+}y_<+!&>S-K=SU8mGgKY>PB%G`e@J$@S9NZEFz`o^YwpZD|V4|~y8-@aCV(7P=lLg!FO;*S!l zcRa+&`C7f86q(KYtwE|8t=_&c6HIun^BR{0?yG~-45|Ut6Jyc zb+I`V;@EUKP1o!)ZgH}2v;@O7@7-w!T|Gd?HG(;P`{eZO@b%e?e?GEEnWB(Z^~eQU zMucW4q6Mynw)JCw`*K&EYsJm)&W@iQ{`hU{0NvCG@#g6>wT1MF>mERN8Td)82I%7G z>B-UI*->0pvF#|-JFbIZa1d&K#@bIpCPX*zDx+0(Vg6*-RSh8~DT7+L(A|%-ELT9> zxn>h^d@am|ksT~Gh&I*%-ePCZNbCA&$rN2N_QtFumM3n1MfHF(+TqhW0NZ9jL+zpT zTsZF*e<|H9ecX1r+@F@=HSyHh&(}IS{GH;3J-Q5 zHHOg>uuIUj0`+B@1Rv|&m-wW?M^l1MCf3)h-K>mpj~2SeYzvQ!7Al9N(18`@szixsFA&5?O zSL-T8SID1Ff$-vl;A7$%MnVUH81ddOv*MP{!@tpbzGo;xMO0oQCPuWP^030z!Zu3- zBbGug9emA-&=eG_)3dET}(+Y5cpKz@ZP?&?8UfIpHDM31d`p%CxcCg zpaoZDm`5L=E(%Lx(iVHiy4^I+vL4Oy{MMk$+%50FST_O zowQ$+URh{LRGLwm><>+T2B~>#wp*Q(5|7{httnbI%ebUVm zg-t8VMS5MROANQ49pca_L7QX&KsVp04srp0z@Gkk{~jGgxLDQ&kKS~xjU~W#nqJ|5 zVPVq>5p_%u+<%c+`iY2`F|iY1`RdXPUdQW5&bhYJpt8ldhq`*itmSy9ECDMn4AY+7f`ZtdzGv z6`WS3x8U~>!tN5bQc1~_sx67rwxtq~aSJUGl^=SBmR1vKK3r@P~ zAy+KAWJHrzN5gc9)zgol$urrfW9Z)*A$Vm2jknu@UFJ~qp_p%`js{Sw75WY9<4EaZ|= z3DF2YWZC=n$k+TthyLOET7fs36k#v+A09lUh2-D112?IFN+{D8r^kv;)LWOz#WK!$ z;gVL5=m_$5eQPkWSHfVI?U~Jg^&_|H){<|X#28J{CTSIM1T}5=dg7Y>6|}9h#ZZg9 z++G^Y>~||Mh;j2pIJZB!4|R6GD{OYSjF_5iq|G<91_4Jx`0=A-JRSIud=rkUoWvpj z)8p|{pQcK0mVJm>xz{?0Kt?@dlVDQ7?^ZW)`)}w=rCit5`pKt0wz3g_E=mF))k3?p zQX0cVi?s7{;wq}!AyntDaf{SFtSBdd+Kr4oZCmUc6+8X@jOE^w9Jk`R;_wASwpNX- zB{|#Ky@B~IRt|T;GIXjKMeR0iuKdh*n48X?*2|!G_zA8f5yO(M$AHOh!;f|CHbm5q zTk8kkX0Ewj*}1AA`lQ8wzFi|w4|xOg!EZe$?K3isdJJCROoaz-vcf%rTzWr_;YD2u| zqGGEbcU`G-%wUK^J1g=ZEkx|@Q-+LyP4eox))q5+Co9*JTCdrEvU|#u(l+Df60)PltkZt^7O$wvYwD5<>@)JkjHB)ii@4N zntVTfp{}Ejut7omsB7;Ai>4OI&-Fd^2|0{01X}#(1x%K9= zVsMXAqwf-+!Pc{i6`tD5V(%+V z;D=n!6AQe5+Ky%T?w@`d4u?PgoHQMCw!)d##Q$8_TZTG5m*?_STd*+ofxDbgWtlCO zZU+>wN!kzhzHV>TMrTV)Q-pieq&n>$>2QaJd*3K8>V*v>IKQ}!Q*S;DMlrY$QL$Q; zthlAZ70`gicVC3rWx94*>urJI3q(o(ntL12$7>^hd%5$?-94e|q@!1}_aq;A1c`8x zAtaM_C9Uktwc9`Jj|iXlzDRu|1ibeTnA7*{&8%wLrqb^lU;3fgwfLu>evcs)Nkn%a zEdfaJ9xlfytA$XT&$gQ=>wXj^k3V`zH}!-5;@q&l(0U*D`-&lAV8}NaU&s1sf5o)+lc8uVf9vJ!17?7lI*$-U`BxL(tXXAlo#@294SFR@A0dh>ZEM-w-3HkWZxDl~bURyFbA-~RRApA5A16a!dx zc%I1Thivy6HX5wy)mx)(f6$y6HaJ-(Ho9N+!r;Ai;M(fu)U+W5dU&&ObztQ3a@4=e z%60tg4O|Xo7OoEaUt!|<)B68)r=!iSRRV~nZLK+k319_y_}j7c281UHzC zU4**TfZ;AQSe#<(G$p6~>>wgp2_QQg+a1t$`ER#%&FV(|1kwC_loSgf`Pg|c!L3N`vhOf(NM z&9381F$B=coCbpR!fSE^vf1f;=yH6Gxo!u6qV= z7FyI5bnT$o?Q|#dJF0OthWy$g9lRy&lxY|maScYg*|t9yUYU`K&UmJ4DS!-1Bp{ehk za9>P7AwdDE&9DU4#uMtJ&Iyt1IX4T)zx4k~JAP4$c>TN3<$I_Opx2ZtE`R+4_ zIujI%1pfbMpXG+v*|9slrd@@LdSpDr54AD0HdRCL)WdI^%ezBV0}JgV8k*lkp7uqX}owZ!Z5`@X#w+fdYY z)th}t>KS~ML5EvAU?@KH_Jgv0m-7v?Z2>~aDQkXCy>V<-lm^z{lu2u=+@g zy-;H=^M9MPGNSD&^WZOJ%ibykS1VMI_y?kBWEl%r%h;WxUc75SiBOL#l4yv))Cr+zd&`(JFf97?kr?u}lHQ3qiq4S9rI;~l~`Y~+n07N*; zK(&aD9WZWL{ARO@uI+Y%6sVX{v)$*5sVA6|-hXOVQR{Bvtu=taQEnx9ANJ{#Ww92%iYGgd#qD5DT`s|PMU&aR-kVUWMA(d=Pa$?yO53R z4mJ`CV7#htBlzy-xJuJev*3+NXsrX&Cfg358N6k?#qG@@7N|9cL&8mk?(RWKdyZEI{ zM89v(LO&C8&Rw95N?$tx@=sp>h<+2JM0@+!NiQJ5>s{6F-NR=me683_p58U-YLsx{q6`d1fek^iD1bmw?l|DDUf zwsyTeB+J4X26xhfliwJOPXQQHwkrJsAX~^&uiTxev_eObxt=2S+T+^Ysr3yM4bCg? zeIL0vpA2MowU`d=it0|q5^qdIy16{tp>VM1$#!jLmrZmwo@x>_goIffKipAurhh!d zW)#4oKZVk1`lR0Ek)dJLl$xdijvrX!`lNwA=(`+ z4_jT4u#1w<3tE5Pfd++Vsa@S&S(C==%eBHT+*Pj{kjS zFMXdcEJjX^Lj^YFm+FwqX{T^nSGD}O}x%MH6cHwsY*OVKy z6&BSpq>l-6`KJm{77O44rhh|uLT@{z21j`~tH=why=xf)tupSWbGAzyS~zjWX5`Pp z+rIaC*9h~C6W2~CXt^fub@vo?&`PPJ-`bRh(W&n);9M)(6f*12wEp@(Z+Q{=% zp^@c!fifz2AkllNOiPk7J9Hw*WS1*ab?U`BsTR#C3SyaSS$ELc)_+|`ja9Gup`wtwR*Siwc#VLa$6_>x0(aMiaX;$zN;bu9Fi} z0jMtD%+zk0xaoqRnyRPvf(fM;t?s)HURZB*pF+8j?-dXL--U+tdrh+Dt|oRr>im%M zE->&BD;c9OBkk{`)PAGi890(?@g%=sUrZTX z;qUk@m8lS>XfS(hj@81>8i0=o+MJECvkgo;Ds3vqbh%aaoFX3gB{s!fg(s(qK=xu7 z9fy}CXdyuuujSkpXirPge-QL))f-|p`l}io2~jqLb`|zM90bA+U1>T`0U}vjUZi3M8Gevp;q2=VT##RsO98w!dV`S3Z1~ zv#<8RHNCSao)tejGp}}i@;)rXJ`QFQx;hu8m%0qqk7uRBTjHi?C8BXd+{}WU^3W=G z+{^5Wa+h?dx4#-2o~qYec52lZS{U(p7UqE~au0*h5P!iiJM-n|Zttyz@7A^^sNsp- z1vqnU(BZ1PVZ?RO%0{7yK_rAEQgyCU(=LVvi>b?-s4>uy+unz+lFtTmax-z$W8c2gZio7c|PtbA?YaU=Zxwh9O)}#T+Kv}#s_*Hfe5;j-y#AwBz4Ieq~HQF6f@xTVV8Is3O2+GF6;&usI!S!_>$!_LN$DS?k@ z1J=GXp)2Y(FPgn##!C+qQBFPG(x7>mxhlS|m||MJ-ZC`Uby_#ZbFsEuNzs7n?7&iq zc3?TNg(;dvHBmfGylFQzwr6O%JEG_+=O@gdK}6INq{vFED+pS)i#8i-i|u0fxBHPL>22@ z4Zdx$cHp#@)a<KVkDCimfKpq}9n|+GVt6O$o5yH@^32+cuR`xx)s1rKMqL&` z-x$g1wYzl-_&to?0J?x{RVmnlF63;3@X6)%`&b}CrNl6@n}p4USp1)Ua_hlz(N4<) z(6LxYeR+<mj7KEfa&$GgH9M07luC$~&3}kZl6SQy zQ;fQ`coYLrtiToF)0hqf+3QlJq2_bL3*3n@5-D(#8KcD2&KIk~I^7LB)&qrwG?lGY&?mBwQ zvm~e{qMm_(=(PT<)N8RbGtRZg0wkPRa~|>L?f)jnHb*x{pcm=s5q~)AYVe2Qh)nj_ zb>P2bn@CK(im2(D#-Nj3K<|46PI2+0X%^6&qL-6PP ze&;*i=#{$q>HgC%59&XE|ChS&Owh@?t-A6q1zn}t>~UvQ-3MJZW}&La8kY*|YSS6~ zaYQKW$RDPolJDrq`>I@0k=w7GuXO5QYS`S6?MXi4aHSdD24C-O#T(QRMnv(RPHesQn z(V^NE8yjL;s1z)Ufx8u|q2j@&YKNB>>f`0()lVzkQ4MpZWDGI*gF~L>pw6Cwsv)LElD;*3P@ZI*|(R~?hZE?YM5#O8MRf+v*{IB8;X6gm%;8JK@W59_`{M^fmkgkHi!pSnKbS>M$ZWRAK* zHk-a_28p9F`e~X5MX*QbPO+kpA%%+4IJGyXqYB!#^C4+eH72s{9RQubLaR=-p02mn{+D`&kv2e82(2q~IQ)2!4~>sHE8 z=pJc?qgir#Z8kEB9#GMBjVzF@U>M<=Z(U<6E5Pexrik1rhA%g3N^m)!!{~o~muyQ@ zL$Kg_l(w;HxDfE@c7#(z*_)cjc$~14VP51}7H_l}UJS6n_D&|P#TSh_J79Vyaw8@` zCmhe`WC-`>VBLTGQ?0*pL05v*)j=Mv*36>F%SEye0=BIwO8?E&OSW>;+30Iq{eLqi zKh1V{E$o=2iO~?56Dtn}?MQ#$vl8>uY-J>i4OS#k508yw5}M!xfC%6EP@JL)riG(>IRz2?_O%7w?Eoz#Rcghw^{NK!TaLAivJ{ z;Dng*frq@L%|w7C z5i+;y3IIZr(k}RZyW@W}ruBX6E8R@fxD@IFGIxQFhz_bISwH=^3?Z}d|BNfsR zlRGRTL+a_M{U8%d?-OZ{4s&*#uGMs#=WIbs2O$&lD3p%27K(qADNf`r97v7PRLm1E zjML?>cX_uE?~F^?Red0jgF5?}vMrH1hR5ZP&P8EQ8EH)W7Fl(e@uOy5+b^w5zvr@ox3k6DnQg#EVfJqEjK2P)7^vups_M7+6e%Iu`M0 zECVDv$qXTjm|@%EUu**D3&EwjCM;Wh7BtdI32TD(fc2C{vt1cE+B> zrleOSz1_;ngR~}bX9}<+q!FtbIkwOaI$Ia&3;rwa?uzSc^(XoK&liB}zt`%?YPGH) zS^Bu_hWvk-tSF+jqBIEF6d&&&9!aSHTI>o)gsPQt9}zoxJtldiy{hpg{K_#53zzto z&n|Cr#S{&58ZsksuFo=6HEXT1@zp*aMb1GF(gd1_JRgdVzTb>wpV7j%R`cawqIUoh zaZ$miHBJ-4#%=~_+BqMxwmlA?a>^rLx_*N0z-WJydrk^2OHV47_IHA&D0Q{RB(hUE zLVvxzzxwd?)6L_j_csr4TIVhF} zzo2yF4?e1X?QNiAPF{{=D<6{3JxWnZCSIAQPuFTi%9_><+%n-mZ)>GHJ^`R1VQWtH zdG3E|o*BKN=*+jB?s?l&+z_ld`f_NBkL9=zwSYWvA&2w6#t>3MmX*9;xN`6qFYp8w9uM7gZ zOT+|XY)2vE^8q}=9C1HB-hwQXZlslwp@e_)Tcd4DOY(e4dwtKpAb<;MIxB@B5SzGi zj5Sh1m-jZBp z-b1KogZ-#1O1i7x?{XzZs!w+lh#2Nz#ix{_t!XW&_K0pO? zh^LB1lPII{i9HLhGynivvj6}lmyt9ACVwt) zdEI^OdfP^l?tfiH54>{(j`?9b&P;|5J;!n6*k^3ZkEQHvR?$)*2}+1bf&oCwilX!E zMVxEcTR8vErRCtJJ^4)O~okuIW zK?hDROd9hqSsX8>7eTZ#$!3+BXhwrX1Zr_*;+6SJw3@}2X?JfKOb?H`CVyDX%_ks;gKU)0|PO~UpbOdi=w?djPdi0q zUY*k%FBAHoo=HDM1b0R=oW@B)6ESDQ;hDK06w`CPEJ)77%v{i>(}?HYy*WLXErSd@ zG><|;_d3W3TPYC+Z+}d05==kzXjStlS<+&I*~ci2X}wF@qNvBX0*a;|=!rd=R}Yj% zqc3JaenJyi#KG)L2rZq)>ku1zIY`5dDBx|FUB<}=EapQPu6wkZA49&iKxA)C1WiNx zSoJzgQbGbS=%AXef=Fn--Mu8-q?jl(80HY)Ht^hS7v+{8iW)?ite#+zegE(JIQ$fF@$~Swut-Cv70>4-@&DUXL+p z`u#qA7JTX#i&gy!+|s8r%vo3U&j;^cz4(q`&%!wq=0n3fnKP}SB}a4G@HvZL^X}W@ z;_26i&wu|sK0bb(KmA7%f=UTALn6gVNO}pZSg<^}9GprwkcuK9MGTz=a=Ba`^tw2k(yxFkct}LpM%0B-fyVpf+=E z7Cy$;)S1oU*Ux|<^Bw*5-n{93{WUZUi3by;#(&G=S#aeUpBPD0DnTclr2$0BJ}r|+ z%DyJu*V)_qHVw{0P=B$N5Nzh8M?!0%yO*BU_x_$E42L|<7f{{=nFo?d8~?tE*Z58h z$yCw11i5~U!plx+P{?ok`;z4J#nTpY!=UQ~wld9&*JH3N#J^T;C~$*zBRt8mvk@ziKGKZtCYuBqzvTCS(LO7fiWWJE~Yuvco?Vz zDh-2#EQ~LSrjje-jb?cF%s_4&q|tKCq*{PjZ(LNK09VcXM_ZJI1IQ3DQ~XIxmJACt zMlexgnh^%di(SWQwhQ?6o1baeBqmx2 z7Afnurz|qo>&4aSDUS-HDI;ErR+IRXg>v7JmLx7+#OI|!X5oSi?Ay8Y>x0(^#|Orr zk;F|lWF>tJpU@_+7txfULIh&-D}USx`A%qxFIOb4qgfkE1yeTRD~iEqsq%-T|tm2BcLNUNjLV0e)2jRHhjQn1mPviAZYlDpq9os|`z^NKU6c^6#c$<48nC-j`YUDSPTQj+Bx`L98UV2Y*?-RQJp$ z|AwXBePe0+K2$7GFW);>f-ECYEs7H?@Mjn$Khp$$CUF-h*{L&X+3IUI;(Tl0Fa&Vo zf_N{O#V~sVLR0)Pg5QJdq!EI%f2DYpR z;utVN;NtJiYy+wUPoD=6u7A^Doo$j3&y?(`KYXD}?Wqqr1As?F%wQP$_|U{eVhMYG z19A*kDKCKius(eBy*-xMg=eY{cqk#&r%NPVJ{8zm{I*7c&ymKx+P-9T5_x`2`x@et+I1i$yf)%M^K8 zxp9>BWqqk#-Z2AuN4~J>2< zHYZ&6W{3}vR}gO!@E-l2ktSs}|8^CD67VYtU=^)qcS`z3~i=hZN$8GWjsghDoi z5%M8uSi=%O02bf!Zxqp zLCj;5ko)X;Y=@Hto?XC9+pHk`(wMX#vH7}70MBHe8UZ*X^O5N93}WpHtUIAiHZ}|p z(|AHAftixHPh@)_IY_!<3x%5j0}=F`9`N2c>~12ubWs zMl&0N%h-BN_tbS9kv!@X-9%*Z^vNpoy^?E5yx~10c7OQI$aoLDz1(9Q5gTTH%cJ%# zJWMX7M;N?k-nBY^ee=wQNz-gY>YUAK#NkNoBEI1SN#JTCXk`Kd=>%lJbWg-bFWf=b zQRFxuX;*PhICchN3zIGclUOC2Re#SquUi+WH(`CB>GGaeoYKM-HGV#$PT#y59QHV7 z*p*1F+-Bm{V*`m=fSq9IAtFaCNTPljn9n=7 z@%BHZ3MJa<1qqWL85S$h0gM2I0aJtcDoKBtlz)2IgD>U7(*dxk7olTVX^E>l1F?t1 z8e$Oar(!-0$TLZ@3Aqmg@vCUd!gRoPci$Xc5YIzfeOSepi*QCZg-=sLJQ6y_kuQ?nw9Hx7hvnK=Abs+kkbDX<(oO=N$bC##n+MRxfs8)g=+k$6{)txB-+yG& z4%uJH99Mkrx8L=CyX^gTcKq9y!{5Fc{`Tl!Jv#(Tk};XAK8S_!RUR!3=2)~h@cKWH ziu7IUw*TXX>_>Vs$vP}x@d>2K3Oyy~ffhc1ECwVp75F+y0k~Ng{FBDdGaje>le0gV z!+oAanTW2T#cxD#4z6(PmVbl<;_`lx(%3;P5rYXnbbMQ*{&$opJLdQy^LWz9;;hse=M zQ0yU0l0;;@7WoNAFBx(+DWOToK}y#-reU@HUqVjvn8UXR&N2vOk-#A*xPNe|B*|qx zp&n4r(`4DM_ru&-BHMZ2gq%+V?g^ymc*#^=A`eR5D}Csw(TxyDlvUG2eaD92{1774 zu#eg5a56((n{CCH{nS}aDyA*xdu(cVwn-$|i#(p;%u#=DEIz=f@bmh7g%}h1|Jm{J z!JBu-FaSPNHp*>WF*5y%kbfbG`+`g-ve7p)L=%8Hwu=JLQa~#-U%x%7r6@b*5;+Xl zo}|46;u)&g=%f&;0OSFVi)lO+TXSN3#AgxnJ&sUcVs`2PMrC$m>upGw|~Nw@ulE`=I@8* z?cuR`e)#sqt8c!2fABT0bQN19Xo_B^9hZ?tt4%*JTD%hIxti^k8luDkXiw7#m0Dzi zPO}=+>+HS)Hsw!NBO#!LZ1+93iw9#Gj$ZC)AD!d#Q zR4ZifNQpjV-Shl+*?)5=iIjM!q)F(D=nKq1^u+~8cqF&?@dY-BQ7t1*W1&}Yg)LoD zR-`B}2hSlfQ5fwr^8vqWA#+41F<+1`sseJP-bH6`3%H|O;5~l)Spz`D=;`&omCzSH&IUesnNQM z0{?yUUZX(1lz-U}+<11?c_J2_RNg!QqZF}Nxb`HSjjytcM%!RiqQEqlr^vP>(K#v| z;`yAjQG6e1NX^>Qz)6IFb08ULqa`AaYU8LMz90&^3}+E(mc`W*6zQ;Rl~8d$Gl}eR zERa*IZh=p_fE~wWK7`yrLco$A&lOTlHS^VFn4A-Uk$<`No^co^`iboTZ%Fd{EAmEZ z3fCn6ZiqgA_d8$r5?p+J)4AC}j?o7hNh^Csj@V-PKJd!Yi_@hJwaa6$djI5+1?Akt z_mE?hjqUF87fyYS3<<4?E}a8_8MHTB<%H4m(047E&Mn*p@z5w5a`r2;N>`^X^fm&c zbS)o@1b^ja7-X5ORkpxQ!dJ4>!pcaxGW^;H&HEe*o+Yp?VHICllh2_tREbSO<&6?F zrGJGd-%2+`b9>Lzk@@_=1Exxg$1hFE1nilIWwbHL)#PFA7Ixd1eEo;@UlA;cR-3Sb zE0()1M^~kuYoYhwv%B$il zD1Wt!0<$hmwZG4diPrBz*>@mYCD-PusiGy8A0r!E4?d`t%oX7`2gkJS*83$9O1I5I zENEr`fo*2itAymo4;~NTCrW-%vu5mOq~c499+dF*W(ASLP6V=H5FGnNO%u*EO30Yq zZJ)$N1kRa;ELhoB9H7XsaDGZc)MZqbHh&^1u@q7&<-m)ENZO4T#U>jm&Ue7>3m*J> zzN`>rr0O4$APX1dX_X8eb*Xt0DI>pRt>`us21y=L&q(TGQ`jLd_9X>~YuQfh%Q#NP zfN;|nnIJfyz=lXgwO>Mr6F%#eoI|)*V#m03m>T48DmD??i;WYSxB8h}v~U57A%7LS ziCzCj36#QSlKmAYnzlZWOgieX*!00V@~z&iBDn1%u7mP{v_7(eg6{HN zeOjn*S+Z;FsMbZ{Qf)OTIhrb@t$&tqS0enMvVx5Z1}+gIapyMYAMUe2B3Bux<5~sc z7%7XZ0DG`AC?PH8_UQ$)yMNulKKsf(`<M`?B{5vJ2)B7?uhYvUMbLWNff53`DoRjZ07SYQGbi7-4MhA zAisi3J6%oD*PJe`Aox1WD+q3bBvlwN{Ul34JZ=jC{1*X9D~^&7WXXpX##~V+ICs1~QZj4x0maT8OF4oicxNj}OuUrP zp?UZ0`1wn)3OuP*$Z_L^{(nZkH+xa+7HQ2Kj7_*d5pt>w%(+Wy`vzLuXYJl+?_QZ% z9E#VB3@f=*2p!WCB)5Xu4*?Ej2y&c2owEo|CTo3QJ#YdX>^VD#?-gQb+Z&XDtvM!R zuRA`6K;voQIK|rczE8eiIlHQN%)Red*UU)tE6*I)S)0)>vL5nO^?$leDJU)2lmY-( z#)fxgpWjA6Rq{Y($5_f4eXf9Pqk(5rW{fampEh6?l;@1U|00+qD6fKD_!_P}6FY5f z4|yP>6RF|d_Z~fX^!wg}-}fFp@SOA=4@}76{}q3ox*3AGa?wL7Q?0R#Jm17K%GL}4 zb7^F3g~B(@Hp{ggrhf&Aur;}?!)2^;%4vSVL?IMNdK^tqmbN2o2AenlWrM#4F*Mfp)1P|`F~kE7^FsO*+M-z!<-sm-459~Yh~4OJ7WG+H@(Y$YG~}|tgS}#=FnhpWsn__&(&<3$pzqrO|?ejhaF-E2bwD&hZnBrMW49H@0y&uhA+XJoHA$;)4D zgBR(qur#T`_a*qmwk&M_)AA~RtVX#w?>k;EHmUC!O$;*#op9S4-yI%dk$K{_bOK=T zCk8RP{?V?eX@A|GJo8J}JpNH`xN~T?9L}u-ah>XnLE|10?j=pZ!Gk<=Xpd}0Y1#CB z`N&Dxl`83YfKs5pZDM)QkMJj`t3>?t|Bgd%>y0D%x_|6njhn36ob~{bNyys3_K`+P zv)k*v`?g64Ig{K?9zB->I=y2uksy^|9SoL1@?jQV=Ax(KW-`Of6@SV`ev=pJigKLuC~C_1LHddc zi=NbP(tL4@JG+wK`g%5H%tMf@T3q#%Jryv59e*g^)~QI;gl*PpoQiWU5|2W_lTS0@ zfN7wnD9%as>-JBXp9LxTkEN@9XRf@<-5pK)=5Uo8-IOxiuU;QKc<_)(T()Dg<}#Dz zh9sk`msb{GDK)mqbKXPU+MWf1S=%GkY`8E88kCv5gwnc(Hp5zeFSo2Ln6%AdZpg4bJVR40(PQZ=PeUH7mpPfg(F6H|5A7%*+nk=T^der)BKeC{5HPQ8L3T7wD=`ZQ;h z5;u8=>oBpE9yF=)kH>-%QIard`01o)u3j^f*)8_oP;iq{URnkU>W9L86{axtEh!K@L< z>QRdKA)jIiIL_L$*<=Z;;&_(%?%A8y1^_f>JK*Evb3Paumd>NIwsa!vQGd!6qN`~r zV|O{U(y2vFy%W^-fN>>=;?7x=_(yQO&Y$i)-7>@^ju#C>WXUFEl9QDQZOsuo&0)ze zwF*HCL2VZ#kFvy#BHNM_z(~SAcP8)?@83?I_5L;J{q&&s$J64Y>5m7!)8G9Qtv2n* zG@PJu9wivhmt#`ZVUmr3RewLvDR!kjjDAjd^TJufkpht5#I zi!L4@Y}sXJGbhqCiQ5^#yrP>JE+4_xx^XcZ`A*KW2NT#ieIt#tq=bzvAwnt}K?x3$ z(vK5@xzsXk`YjT#kh_uv^Du+S6qAUe4{U5Mxr#r^%;BGrf}X>_<$oSBd`vj+jK%Dd z6Ce+atjRU6o1E@zyYd^)8g-rg)-=z-IL4qQ4Y>jCDStY7aB5QxEVg>Ro|Di4!G>HO zt;J>!C4tS4b~lAC$<4~fk!3K^k9dbP3(+X?L-JRlg0=Hr(&2!o2o>%bMM~> zP5qE~eI5GJisxigg{!k8A=nK*d9ZSO)WwW7o}>We>ez{eMcv&2{~r@6>{%uj<9# z!(G=x+iHlj22K# z4?Rp+9?&HYwtqzs7vCP|!lGu%)smYHDK;A#F4^CXHC!`HdH=eV>|Z&IJxHyr52gn#>*W+NTr|7qE2*E3sbsEN=k zf%bfHLlrrU62*<@e;atcucYQ@ zKSir~Jb$VkDaJQ$VBz0duzJsYyW&MLTJs0_xC=;1I?$p~6v_G*?+=b%qQX|}64G*z zn0ckHz&j6;32a^4>=5PqTog{6AV)?>kDHW~3m2!RS&T*-{U&TNnixeLH#rH&KDVk; zOXJ5)gm4iYDf7qc-hrfbGs z`5F;QM;0P-`B}u(;6rEFbve|se{D%0ddfMw zayN?CiX@R-H5CbMggHr5D;=?2k4p!@e~d`{FSC7l7sK0kO{_h1LzL+JuOO)!jG}hT z?UKUsWK#?4x0PI&TIB9<)=VTM%ZR$OvE~hYE7z1*^m22I?!6Y=UWBq}D-X`@-G9ql zl|DT~!)I+i&!!rF&D*BuPHeo%oa!|sL?xN2eRwRT@-@tnNonp8tZM~zQyiI;xZTRw z#gyV=C7+bTzE0#yKv&LD=2JLMDku7C$Hj2|S#P%yw?4Ng)-Vjs*QlFW&!Ty!XSsh(SKBQA9cd1 z(yvqt>#O{$Ly?r={c&u{LWskG$M+;*j?rhhhEoFvLyF1h11>sI?$JN1)qZnWS8ffJJA;#%oy#lO;| zPEH#g$~sch&C-7;=lwt~0-dHecY@8#TPy(QC&PyiPR-MLlil*)P6rj-zfvCvq;FJY zHCO>oj_R5;BAM`z+MiV$Of3w zg&QPHQgqi1(rFaw@rf<HWAWEL@-;~|g3f(pK6Ddtl?*~((F9bh^iIy?g6c%cb zx;RUfqCTLwyIzIC%YPVh!|#2N&OYM-%lckhRDVxW%Pj@5XPRyY%h*BoAXUTZQn7}| z3z)R}IN3!DKI+3jt$j_x!hkq=I)ZH^B6=BfC^~Lax za8fLEs?*pZyK-9xuAHWZqLZXcI+_(sHd#ejx!E>!;8M1(w#f3q$z&g9L`K1yoAl$L zB7zt=c8h}E)8d(WNL8n#6ERA92(m{XCDT?Sp(o{8j&hpmv^&4tC^%Rw#%f4zvuF8a zeEwo3=OrTYUVjl1W$_9LI`f5*=CbJ0y$ZQSV9~QJklwep-ar};Ys1m5yw8U04{h@$ z?O1)cU#i-sPB&HVM%pPrrrb)Etd?jY_3G058KX-lF>Sd@UZiyW0h;zx=K*`a2qoN& z@_;0?CFwrzk~TQzq6l%6#au0p;AFDSujKZp=Gm)a6E;y_kj#5(#+y zCDJxvXU`+*#isGtY-~A?x%)VsCk#j&LXKvlwFJujz%S>UK-ZyM|_fl^%F*Kfr!XP0u~sOT`4l&s$s7)gJbqJwJYR_;yH} zEB*B9{eSb^M(DOx9nZ#(G7eKR(&~`ySKg*>(KNf8_ZbvYMO+hY_>>=Nzsa>z3W{ zax-J{b1ILj2-JDq>cLkZ&m|`VC_SG4RDV$3S5=^b^qZa+8nECTt&GV+G=I7@ zrhiD|+IWIe=ecSlYQ0-xU~R|y?wOa5hLQ_K4;N`cZ#0QI+wkFrKy5@hvq<`$9MN7l zpUbN`W)e5#3YO(MyJ|R#1n}&zmrfCKO@28hD>pV<=e|O@mj7>Lu728So2~YyQ^DQI zTMFFiz|tyz*@he`(4$KeNm?=s)?}+Mw|~l+13jNaLYB`bvFTik2siq4Xu{gRV&y|qe4(`UQ&L@FehgF_6UtkJq?t0S zTy%P0_0HpXCgrxe9MnA_Gtx*UBm9|bULyMfQf16#Lo_D@Xz8yK2hup$_Q0C^fPZu1 zSg5e<@hUcMZ9mZp&MWo5s2qtY1^0JdJHO?pY3-_4e5D`IJYI6p@oLLqxExGWv0qbxpO8Rs%@Mb!}UyV*>GVQfW zH3-%imgjQ5n6xlPvYJkbW2+O|g-7!f&s!Lk zw2QoRr}V_|mQGS9Ly~=`H=UY2X$uRE9FK}~b)}{OHP7t$<*OrWovZtidw*&Q5q-#| zT0?K_7DpA?bRjSBC<6*NYjqpa%_K|0&?M3MMaHRe>1?DBtp_GKgZz~;cuf-+D0M3g z;JWs$`&Ht4yJ;0sWiQ*qg*Bxv8<$q`q)6Dm*7sHHGiQdElCGrBg2d{E)*|g{pXHb? z{aA!Z)G*91__O3{Oum5I27jkUFt&QH`i2ktUXL7s_sw-|DHpxnOsBE4d08>D$znf6YOy160jYlnm z71!3ZbIzO3hJ~WaqXSA-0}-pFGm0}CXj1qcj5qtr@7sJks_uE&L@Qp)?#pNmrE1UD8T+<|n6R?w-ppZAwa|%krv57k)uou7##1 zaJ#-LC)ZAfpP#nmz?3;mE9-w>&#ULPi{~s8d{czgN?}iqZffWawAJG?40xM}iVH~? z5xu~WD$Dr}-afVnSK76c19dUKOD$J5Y4J*Jyh02IOf&L`b5eJLfqxy9S6`0g(smN3 z8CQ~=oc>aJUk6wGvg&$*wRY=0^MYTzf$$$*S(qSPDMd5hTz>J4ME8Gf_rPAdz$+nX z{%FeH0FkIfIS8*#Cas!Y1nV#reXS)HsF{|RxlHGM#SGfs_93`HDh)4e*AZ=dR9$6_ zV<9dYZqUWZEj8FV)>TGahbP0{!&5nY#$5_@aJ-wa+?DI*ui)>d%`RIAY}*X^gp(yb z{~E{N znq{YgbYav{bvUMU4AxRokUwS*w^q}PG}A5TW%AskRCzQIf*kf59@xJ^`uh;+G zpL)Hg$fMz$DW@XKsmdzK5Q7+B?2NKf7_b3ZTsS)d$XiRbX+D3C9-Jy3FG@X{J)i9A zToaH%-6`YVmEAYj%dje^i{BMZHtEhuW`6%rN#2Y|E8Su?dv6bq z51P8}vLF$9LznH3oZo45rk~iDBwN!}6V&GHb6STw&D?QNk?4HeufTK#D zK+6)eUeM9O0*-%+6CC%bZ{AmJNIj34go`V!K$FBszdh@yZ>b29^R$*?xNk}re zmkD=WmlR6=rYSO&uh(Lkhj`n%&F@^{-NvnJtkMXACOUsLW~;fU<5XJx1R0O!FTy#9 zl_+&}UUutCg)vPyVJFVPiiSJ*K0XK46nZNqpoS)Y-ze`5pX_uqXpK&o&rM<(H|_7N z+OZV*QM;46uJ0{RTFMaeRo1*Z_jQep?}`vi(B->M(WN1oi@aur$w;WjpI$6UnEalk zs*||5%eH@(t9a}Unktue3DU3`mu=3ndOc70)qVk6*19g#>4PgTm^g?~QC%*_+T(ei zZX6Ve#(|q+97s~Jv5Mqw=(cMw7HNZ!MKG*HAF4I^h_vrK+G&oCxl7I0k~hmSAHqp6 z>ETqiNf(=HJ&7*J^Z)I{ww;jwd#Bge54xW{yt#k*Co(C{V`RLYx%?)%xif3jIf1p5 zE4cfb#CAsNmPw(T?|-vUwAD1ffQreBf|@8YSPWO>3e($4`vZ_6!w*d7=d~s2OS17Z zo*CgL`#x+LaTZKP;`?;m(>wlgsP+Lq(;Qpw z@@JvEr-NkW$oproIg>2EwzCHG5dRS9bWy#E-jV8)5kwL2BM+rv;h6j5G;T89p*?@{ z@=BufmQY8fkjRZ|RL&Du=gfIxuVZuZ>>=!wiEo59i>I_80f*QmT0d}snY_f5W+EpK z8XrbKt4;-P;IfvPFN5`6ZeOH#x!bmQt~|l*p=tY8kews%zSm9+>kX~uNsSO>%=&dL zO;Nyq+6I{X^uG;c?Jjo**l@eHO%;EEjXu+zoc*dgmjo}PywFwrzjM<@1z_>WyNuDiMGbh?F7UG&=)%4dHK)q79R zTI9c|`G(!Kre>?=$Q63y!_e>Ts85|URMlsT;{ta@AJEoPjGFxrh+=Z}F4|c5X zyN8o~n<h?b?bPC9=}BGRe6_Is=~vp_4Mjr@ex6ud68j@BU;b=)_>27!r1 z+`=2R88;b__i~h^jG-qcUgD)^F^9!l)`*{4tQaGP6G!HyKJeEf0YQhGtGpZXbC~?v z145tlf#-Cl=exc?6-?vgYcb!*a zB_cyo;v&lU4R!Fwb30TTiTMF%((H>fFM*?9i6nT``{ZTPZcWH_xrpOgyLnFA)P#ee z>Eh&*R_nmc2(Q(vv?UqD|Z5uP0B7z>m#d} z%$oDN;rVuoCr|1zd3X@Ys>4Wbz?BVGB%SP0k%k3`ZrcW2K(Bw35XVs@?7Ik7T@{SP zt{3f+mJA@?$gMM%&^J`VnqL${uB0>~4twYLf%vxtJin^Bhqr2S{e2dE43d#|^!nRx zYJxoAciQM18EoZ~2x>P7A-t%O2<$BaWgp$14fWTe=cx~{A98A?0EWDZ2-8j(R>Pq? z8?&4)|Z2r7R~)QU!i)$?8>2?iGzI<0`!^KPu`QdK0kG>+}w&?lnt+Xs?>!M1UV z`hNSjx~=+N=7LR;%3Vb4N)Ny>MZ&gzs(jT})*@j{9tmO0)r}2j*wX!`051OS8+!H$ z8rJHBZuDIWw!2#`qbSMoVgWXsSS=KFZ`wX>ckukE!L5I@*u5~72a%Hkd~RafOA!>& zB`Q#tu9cGA9AYbw^RQZY?La^sMnh7k3IkD~Rv377+zv1n)oN{*CDUCXXt<~qiZ);5 zXXGtqt)LJ$YK4PC3;A?3f)5K}3phlJ+Tr0XG|9&F9aRmswUJbC_pG*j|3v+U-crH?Ug6=|(+W zy+sE|1gLdL?TNVyMxpD4l_mKgY5 z(%N4`R4P8Tk7XkW+mxK%Q=SjM-MI9wWTn0x-&B8V|C;OcayPwHsYiqETvFDU{+5~7 z8@cKVht9x7GL-GmAW4EN=iOJ28V?~kZwbgD)m}!>K9Qa05zkFL`GM|C>r*M)ISR4Q z!2)+uT0E|1R}l(oA`*?*Y@-pmrHT_3hc-N7TlD6{(twoG>;tkD0N$ZF-;<~oJW+ny9dXG(8LpQ5Bfh3LTsbic+Ic5S_D5`A$_ME;V;~1 zSZdZAoOhQjK8L~v7{e^%*=A8G@~z8Onc;0zj<}iLTfE>kkZJ~wj@3PZ$~e6I-G;%f zj&TM$Aa{GDoJt=X)W@ww{q|3yWx9X-dHa9NdAoL*H*SfrD9VsCB(ga6- zX$ON?(MYYt^TwIrdi(RR$40qj)-@6+(kuMAE1_z+#2*p+B(v#UF3INxOx0-2*b{$N z0$sk;ALLk!+`}IcF(CtZjPS`wnZ|w>df1^QPs1xPS*C6)S5oq#+xn31ZusTV-rgP| zcs#}dit(69eLM!b#$zRS5wk~EX%;RIKGCjll!h4n{{v7<0|XQR000O8001FeN8ecY z!3Y2V&=LRuG5`Pob8BgAY;!MTXm6LGp#l?^Pf7v@mmbss4u6$c;cnZ=5&o~Im{Wd) zbR^oj%b|c=AL=Ly5}acPj)Sx)3VB7Yq^&6~v%9pcrUCj8eZoFTznLW^%k~vl|F9@> zI5Ru*%{Mc8_QPT0-Qmnshq}6@dJ~qm`l;9N_w%K7ji2VW${Xi&m2a|oL;v~Lzv2A-<5D$+rm@Ap7x?&M-Ay{6SraI% zEjg`9aw^B0`p)<;>Jh!nh;{2Kn6M#J75a`0Yo0e{Ie(m+Qd4PFLBn5glAwa-tB;?r zC~40xuVgH9=+&)G;c{3)G5*dk@NRws3oyQoQ=scy)uD0vnsS7})69k?J6A}+Y*|D< zj;T~Wh_SV){Bcw&BKYUFK6~VHG0*(F*T@5uyeV4@U7mA(t)*IL(UhF5-!VM8vA=alj}*^>{a=bul{y5KM% z@>MbAr>W$%Jvkkc&utA?kmE`tp%fS}CbXx7ZKq3vOxY^J2suUa^h&R0+L>xW!DfsL z7{#*&$EuyZH3eQtREh*5;DMc9sY)%_z)}TLO@FXMm49u3E05EbS}~B=f)M^@#f^0H_eE>DsmC1XOf?-n^3?6a9=^5gWh=ZVbrpfu@ZdPOIHQL#q#r7(1uDv@^s6(KsECCm*j)&&Lx=q^2BT zxqnhMDiZ3JhOu$Hz3Ft|>XN*8t!aUvBb;2KDVN4jismU71h6F^)l~OkR#_YbkcF^A z?ov?_qsVb@gH&)%E9+LM#?$jRq@A;l!ylMddV<~Qbl$M7>6FZ>who!A0ALl2t$eT7 z-fL4_nptS3+j5Hy4igOjo>(mQGsfsT}e(NIT0E%2o_G3t^NL2||D z7M`<6?b;zh6&VRVxqRPS_ zvrX3BROV~LP0u!qr64P}U}J~!x{di|f|dIAfFGWo`u6ON&&$v>h9pNk|^cw*k zpS_=)UvVh&yq}7E8;cVlAn*~}P63e*lMk;amn_^*2`;q;YNzMsj#JnF7GM58?30;y znsf>Lx3Z{|##JmC-}?Ry?tgtBeuH~3hr=i7_dfFZryX%*?Pc2~B-JuaNYhFri6c%n z{gcjZrQryF3}8!|2+}*Vw#4nX3Z4vl4=8|(7gRW6{6YvoZmVk)v50$*ftqfS^^T{3 z@Tk*r%Jw?aao2&ETbW8JF;!k>xXyJgtckuYTK{4+*Z=hrAJO^i*niBs9)2GS377AX zT^=G(bK_PTsJ*&6LtW>kGAo9sOaw&N?OCts7dql5hy3bQ9e`zSxZbcEv2&J&xn)Z< zNh=A`@+C$LFZ#|8+UId}kQZf|tO3M_>SPR2^UU@!G`n3;}lRTg$kNXx;zTR*UDAL57l3} zMzlv?6$agmF5BcHJ2RBuP|xSFCl>AWv{L>ivh&Oqo9DtlyWD3Toa8eS(@FcuNV-RD z(Q1yz?FiS+Z?O~x1TS?EC!=haI$&GAua`VxLclId3J|M8KN18IJxa}xx@JStDv$!$6B3~=Z>3uF11@T8K=`#XXdp;{WK zU|lVSb`|>koA~qnIVEC;scMbMU8i8VKl~hh0~U8S1yJIY+?tz;_oUr(cr9hS$1-~w zy1#poi9PzaVt>>9MX=DM!^~(mki0&d938!sB6Lpz@t7HbT1MdI2|_oIT&k7#T{D%@ zI1WM6I2tE$y&BMOQSOcuPwN_k!*zTi5hdw0_sH;YljG8|*#0n;N=Lgt&Bm4VdE^?N zSU01%gmg2`fDR7Y0p{M2D}&9!0S~*}fzkM-Ee=6QOn=YVYBp)?0Mq zx)5?vbGM3BD_YBq7#jkQLzZp#z?QeKIq?*cdrt5FSWu9rANXcR3#ltd#dU zMVt!7@7{j_w}RUN?>-H|t57(e8UO$mPXGWamyt9AD3_)h0u+A*NOrQjDSDYJ$JW}u zjU|^QUn-^Opdm0M5rF`M0VFdFtL`E03GYd+KW2ad3ChkUQMpV481(e?^mq60(Z3xx zx;ma@#jz^x#Bx>7%i_xe&-0RbSv5K?mpWRm#Q*)z|B87wn}@l&Q@MEY`uzQe3sEjr zCF`s#w8-U3RVsfKWg+Uh5=ow^q85)uR;219eCAnktD}PhAu6TI{7wmixsXdC#RA4= z_+}}xT8l&$WsxN^7e!esv6S^(_+=&T=P(5hN-8DcK~@I@4@TyK;b|qSWPXG=6heJm z$^ubRVqU^Ld0EUDkz-vpRia{quf-H#CuLEnq=ps1w_1OFtN}6(6~aI^b561}gBcNB z!0+bKBk^A4@F2Zm$YP@Edj*r%_a&jP0Z<~BbyJxo13DpLd|zd?8i}fG0PbUF)zb=4 zSjf6ol|w<<)MZF0!S@+ZEX>QDf^IY67u1#cc~+%p276|-ZRXHxGB zi3$2MgZqEhGqY#F3{#dbjDq@ ze~(}newHI~`qjzP{uo}nkXmHv$9Peu507RN!DxT}vIG0zk$5hq%`d;Ka4XX+MRw6i zSpoHhtdHfS1g@{=8SqG6CII5b@WqWFauA2%;QP6(1q{1W)e4~I*{#Y~ASP+E%z;4w ztY4|08{k6`hQPduD-^O=-OJUH0GtQw}$O*NGX2ndisihEfV_;y+3tLWh6hj;O-=a;8qET(xWYroVH z=#vZ>Ihv{3_gG=XcAR%4yp!m!9&8(+a%xZs8I@LC1uR&IlLMCXvl0YGCbggm*wlZpJZy`+7P5wv6tyf4bB$jkDUbPX_PQAY$E(b5ia z3E8+qc96`nsYWsI-;7$fNkS0BE*oN)w73M^c<$Z}b+YR!NpXwQVNm2wy*V83Fnl3U^JL)?Qc z*Wh+2KudKdLW)A&69<5WSB-xrtu89?&}#OVU=cU17eFTKCh~ZD73}6{&w6kubanLbPWTG9I>^cAWsa+*4Qg_pjJaW$l? zV9(qOsbfTXBqn8<14#(UzCM$2GMB|nrTD7(3M1KH!vEu*n`kDp^R$1e%+A#AMc?57 zdM%r}eTe?~xc>}oEEw&j@;#gt6#v>oJ7nkcCUC)%eo8X7xUO9xL2Fm*O`QAf_f4>0 zB?E>-o4!xe^7~V-yd4oafv#&_%|`qkwqQLm7p}leJzu7vVMk(p`23J4+wKZ7yEqIF zH|xW1>Ct5OQQ-X-iW*`D8IA$px5Q%?+ z=OQT5l5C(**mW%@IasD<0v;&qhGmJU`<;?O9dOK-p_z^U>mq+iz8ypuQtUFkjpV@P zmA|Y;!d%h1=Y2?|Y>)imFHEHE`)uxjNK>UT1gU zF$K^VmOiHm!6ARWvCc7DA&!li`l$l?gO^fcctOrK5gL)ea6s3gnoeIO{mq)b;GJPd&VMc;dMdI_4(+`W@cUdK(9`=n~S=|F$<8IBl_#aAa^jd}{P2JrRd z^MSWW*FZvy|23l@;x2^tCa%IkfhK|{Fiky)z{M|9<*TYHD?NtT0A7K}AV5rO!t&|K z2`j0o_ed~Zek^`0+|4!DCI|6j;SEj(ACZCYduxI;`T_pJw{OFjFE<-lA>IqzK`$Xp z>z?$$ZqtA0-G}`fK<~>jp#YH&uJ|D@4Otb!vGLk_foYhc4lh?r3YRb^bG(q%ZCc(J z-e!xc@X#!@vzI+L#~Foew3qrWzrbFC9*H=od(_uo{5z~1;Rd6JNpybk zNg7SO-QD&6SX%w@l7u{piXU|b8j}Z!+out$==Ois4#}QhzIeT#X2WzLLYg;anzsMlCBK+|Sx(^$}AK;*>rx(;+eZNVcQqsgvLxb@@c0Z!=g&D*QFP1fJ26 zz?6U67_)M^hGqYLQ)mpLP4ZY%NV(XU&8^?M<75Wmv$cY*RkE%T#J;lFii;^iFDa7+ z(W=(4LP{(PEmz|E*XI|fOfAkh$rhcY%<~MRb&PW&apoAkX9CnZ3h8!WTdZC)I8DbsJiJ3Tph;y43ZyM7y{oS7{qO_ry`9R73>*TDKFPUAJlcjl7Z zi&)z$%m?uI9jU{m#wa@$5Y+-S1{}J+f?L<%{c*P3xz~5TccIpDwtsk^jdhh^sC|Fs zp&kOcj(!4H+6|g?z*z`Xs0KT9lF9&$^*$k@${G`YeSulcWqg*rBI9PbP=(d z0{Q2s@S+{IG1l*q;d-4&kh44`;Udnz;YD6u-;jLaeU=|iMQI={`rIYP7nr5)97F?H zE0wY{&shV^?M{Huq?7@8fV)A@v%-IZ3Egr?jxh%yywc+5CQ~NMg=och12n}4m+(8tVHWdX> z^KzkRZ_P{3guYj5DUi-Y7|iv^p3amzWD6#wsgV%lEI}ym*bN&55cYM$w#i zHvkRcAy|p5dV72N_S@6<$V8^LL6x{^HWPlPWBv*XI<+hU12daIr9hF>p19Jc=!PFJ zN}#4nXUK_wMARlC-D!s<#M*zCb#LsZrJdm-x0Z5(hN}2(*y-9e zz}tWv(fY1Vt`P=Ph!b``FC#eI7$}6^*g#{^Y-z_po{X+L3F3e8EFY*iLC^)vR%{4c zc+H^L%L!WMpqH)Wu%d|TGPb^_@8pru!VUT+17g)BdQ6PUsbq)-XdruhXvhrZ=1#I@tB{Pf72aSbOEv1SG;(TOFhOIi3OZ`37pR8IFqom56w1BjU9IzCmsIi8R7*42yd^3nUrRht8gvs^#zX z+XrK4BM+Y+MLQAn?~a~79XT7p`By{dKO=1Jh0OCO5HPo#^4S5iS#z>TcZ8>hb)eo*`z1DgF2z32t~fUSRZ8gFfEMspBguFwNDUn!Nh zTN~)ZO3Q`Jigu<+qfskjpFmbj%8%O>hoZz(^w!-za>J#Hv|7bgvvZp|R2~9HT`Dnp zyq_#{*n$D~Xyw_&y_=N-MFppd)_?GG12nEz2S&}yJl1u}PMOJekds6Ngw3XK!}Y|# za4?y7)oerPvE0d``%yLGe!14U0_sD#}B03ClK2dx=7Hpy_47sfaHtPNU=dKFAz z-xx5{G+>0;_6pD^T+<3;a$-C#GwMwbD%w0)#ArwJ;B;3WK8xFCEN)uBd%fWgmTO@p zY~ql-wvO4K- z%-eqyA#TOI0q0Thii|JZ=X7?~9&_EWS%AJ>@x1JMI#r{c8Zc76yye|~!u;A=Uf0gb zlx>pLt${U`UQS@N(UInf!rXA_MC~-J5^LU;j|t78u-6f&n%##a1(H`g{8WYk63J z0KGqhK&z|!wc#4>Sr8dmKE?atJ&Y3&-7XYrV?8I9!6qXC0UQS4Af2^ZXfdPiLYn2+ z0My5n6^s_CfeB&H!i`W2m)vC%8%uJD2@0-2avLunPWO4N9D0X z5rD{enyJ+2Binmz5}MqmC#Q9rx^&uaL#it1x?FOGfIGM;CDpdBYRry)c!yO~ZfifH zwq8oC;*5lJn~dr_APNMKpY6K4o%?N6=|Jw(G#MGTbfWa+UJF2_MIzs z8Lk7AArq4YR=2*Z6y-RT(}6uB$6KPygr^F&`@R?8*J)-6+G*R)ZJN0)PZis3*d}iU z%$7~5SGcCO(MViep1<4a0z`jmcPIfXTDZu!oJAu~gK})9VOv(%%?D_erO2ht(l2F& zCfS_0uu?+E>DDgbnq#*sd3fmJ;sa$IAX^IT?PEZ;g43242NB^0&FHFkC0w%hrtQ25%SQCGOj4Yu#$6gpP zsBNa+WqyZ$tjKXIy}jD81wEL5e2?muzk6+(CLPgxC%moF?T_ zhu7}fxtDf?Q3f5`=*fR4s4|Ri*fjT)>)(-`zUiOR*xwZ_ye++9&U*|W2JtpzpgCsv zGa`-cMjLBNP-%_8Zm{2T*q&tRsTXc81A%jzn_HqqgXy3BxX@EP&V_tDz&-YFvLg5F zsI5f7jdgN$$f9$2&5@^(AR}HuFL^z*UeQ^A5rM-^1z;3W!6ko+B3}9=(>wyd!M*il zh20i=HvHiQ^Yothjoh`vLPPB4J-}Cy_YhkctNpjXqK;2#s)W>UJ=(IP!cV4=_}gCu znt&tmx35j*&lun#zZ?&O>?raF+;(2J*Evqs;17B4`e~<0OqM9pa;nJp@-?so7iEb# zY=s4N$|i_z)e3(caV%28*bXG72heQvOayUiOo}&l_3pky8tmv^UyZ)(jw3+mQ~+RJ zCGQTp<^~eC?sLe)dQCs&q~SQFGhUn;9P`H>(_{&B#F-uZujf+wD7-cU)w88L;PB~h zwJt*jVk@43khPzOBmUk>(*Ua~2w)R*fE4>?&%`Yj-%Wo$j*@YMl7%WAojv4pK@vu> zF!^K@3vYXdq|@+JMo$VqAzz;*PPpGJ7Iu04E|t#RL2}0Ie2$G1>JW@?08(7n>-+9h zsCA%pnGu}GWH^{w-nOgb8jn~PoVzzFEu5n-MQ;DxGiC)fhc0Ul9; z-PNo<)aF=@Rd#r426lGQbu7>kFcba26=t>SY@wnaa1%Or;U3y{{Oq$P=Qg(WS#JzE z-rX3-v19@3Gkc$7`Y##Z6)~Z&{b?xkG!|u#|- znb_eJ0x1~)%yUx*sw()IO^pQNn;kX&_RU#*_WbQ>{N3rr4+gQzmZNZRYBj@svW#pDpgaA zs0M!k`~Q4%_Ae17@iB5=~wsEwhas`R$z*}NIjH24m4Cx6Ng|qlW>51|$%|Hnw^jI~9tll3zFqI&Q5j6K zFPqvJ30r$oizWS_g-NWbJ?lN#r zra9MN*cMDs31H?u{6(=FD0^S&PiIv!acc_2aYmCHu z%7$lk`)eYS;<^yTs7jTSEqVlc9vu4+qgFI4pcV_w%kA3o*c`wxBbPpy35wRcpF^48 z?^XnzDE7vEAL{L>&YTW7ytkpY#EN|eR!w0pCppDKY%D~hf+ z;P_QXeHSAL+`Vj9G@^qAL{@*}-xy8x;{5C%Z(g3BU4HiinTytKr#>Vf)uio}#rg*Q zWQj9DrO;MuwmHWpe@fX`^P>e{l3F!hExB%(U8S^*@SeYW2VwdJ?+t2dzzMn!-_orCIyBrsCNBHcl_pAPpr{7g!MYW zS$If6Qvj6JhI_2?kgk7fA)N&ZB}1-v7^>dxU>G_wJfL#zkzWT3zpZTUX{~fpntKjW zQ6B`wq3DS46h`SbOUfloWtMks(4Q=@ZGqt54El^CSPuVTa9~=tw)~q*bO7mWaC?l* zT7_5d&p*7wwtQ|A#vqgoF3RTqVyalpf!^d4MVA~*AzC(XE5uNLdPDtSa4SQYy zL;t>`^e=Y|xBIhwZhEkTxYymX5m#4hN1RCS@$PS~@jQghHSSawoNg(r*a^;o7A)UE z8jGG!4CGcb5AsCs_s`#-y*Ya|>VD?L21M(2t_^VS;gLAxqYch98!nk+4+|gR*i$H` z?hlNJU|2CT004GWmyR?7DwkGD z0u+CN=bQjG2}z!0F3d1l*_LB(d^?gdnHgC_K}1tT1OhNFk{Ctj>_hCk?Eig~eUkmE zsvBsKl#-bVPhyc^cXfAlUB0TW=A+;2G*!8Co@6^ZyHdrfUgX*D2A=257J1oJ(^Ai( zG!2WD`oI7BZ}n<#tQM>DGKp2HZxVc^{AYh}pMDXjC+eb%iiI-ml{&fF3wOEGbyDj1 zbTBy7MHgi(v|6?{7OgVY_U@%%OcevIZtkMtny5c7I_hXP`yx* zDx>UD$3vCo=rt&HT_*ZUmmnL}=#s@18fAH{6&`2mdVzmv$WM(fS1PGgu_&VogyVl? zKG&trYD@v0r4@A?Tt}6v>b#_3YU;0ViiioPd3M3=WVvQag)V7|D#k)qs>->=<5`|% zdRFWB@c?gYeN)ruRa4HvhFB#T7M|*>D4S^oUg$C$3|<@@z5eE%^3U@oi_z$O#k7ht z{{f^v!{nP%kE%LOlk*`aJBoEtDUg4!>M}~QIv5X>daT}<-ASVrIHSgjc1h*LCg#j} z9w)jA)w^8j<++aIB)h284%S)gGDFAx53hOixF2R6f$WwSMg>ELSa_i^-)y!T%}WjX zU~rmbS~dl|jZn1H4^^I>1;g!>mn6FQpS4|`&7yyzhM0qYO%X@6 zY*3&eMQYxpY%tE7B&|t1&Z=vz3mB-g?W9SF^$k{tZj1a{ond}SO~TJJBH8Xn57i-4 zj-zuJpvhO@U|G|9;q;-dAUc-O;B+!)jtB>4QT7?81mWko`OGKPWF^T85ebIY(#`Qt z1tpnX-YarMx6&nK2dsbI>03r@RZ>IeV1r@^ZUW`k5m+}@@e2D5Gx9tyi>6YOZhE|; zgLlWTkN>7b-u)!LnJ)71~lYR%#{wB`!$AZ<}a_Fu+8i(>Ag&uFS%qtdI@X^?6cOaAtWaau6+b zYtPthVv7&=-+lY~-8Yc4z3_`*Or8(ll6`{YivB-VytUV4NXS6JG*=7QjSBC{7{I@i z?qd|NoF&|CKUUgXJC9w#Q1THfiyvRuj>Ie%5zDY!> z9n<1hvjx;fJq^C3vH8Pj&wL4mg;Ri}5ng~C53F^}4Wc295W}-0#**;efSu)ZI&a9- zPNxc{1;!2pz(&@pYA`U*Xg^2~6=2acuI*zop!R<~q;g^3=aqd|YWuEQwGW#z1$YVJ zHY+W&nB{2-?$MZb8qa}$z$LOAV3IT=^MszZ$p;#80Ky@C5yA@Uvi5h`jr#PZkJUk> zrqdvVH0J4*_JdHobr9Iu2+rMVh1DbM=cj0_4nE&~+HXG<)`K6$i2huAK^$l=Z?@1M z90Gqhym>Q)CLR2B`eFb071Y>!*r9p@X?^tk)xq0+w12u~4d>0WfSxHULn?}aWXU4M zM(mU?D!*fNa!0fz7z`e%<0d1#bD8Dmz>6>RoV=Q783B`#=>#U*qH*fIrztrv-4 zBymtMkvRj;rd$mM)0c0j-+g$oe++CtQ9btiUoV4ySg-rBdVKQH`|R{<|6_lA`}y4n z|2{SU2428qgl$`?h<$K~oa~SO9*uq+oj&2-WWA;|iH+V{M;i=cJy%oFr72+$pG^9g zEP0?tU(sLn6GPH5%M}5m@@B|zg*46;?{NzjfX>UCkns}J3&uShQEGU;jA;y<&oqje z5$xlX>|-~ZA-V4alrs6i(ZJWfI5w8CeHVR%qh&?l(q4zzJEI2rAo z25moQ^rAm{u{Qd$GAj|~*jxy^Q!+8vFdo-;Yg2ZnigqVnmwcf1aX0YRS zZmzsi6Ck{fUhEglcmcNyTobw*D) zT-1bh5e1NNv=WAuP#n3jax-l!Hg&n`z9WJY@|IaYU_qH(~UHkon*NuNUIS&Iw8a~BKkMWm? z?x;1N0026ee*gY(!%CmPjP8#9bovB#@sWC)WXTe&J;*N7q*_o?5@L+dknI1Zrre)o z=;FC#zs@yTofu5XSftNa>H;fQlx!s&aCH3s1G%p<|4{=l*S_pN*^CILf~^INYd$A1 z1!Iy3s-cAFHNk%sN^fYLu?2>JM4W?>ENDeZ33g7L^b;xYcveXUYK#LZtI0V?3YAtI zCgVT)3k0+PjYWh|X%P{gK`?yH&}N2-&FGyMiWUb0IGN*vw;$d>&8LT(Zss39?F4?U zmqiLLR69R~k4N^?$8Z_{mc7)`x351;pY0zVyxV`vu;_o*J3QEb@%8{MygQ>)b$+R{ z*>hmTCgJw}Byq12H?!b=G1Jaw9jtMuY?VMnAnG{8r>m`h@%T|w! z$eoyU0J}R9oRCu8Xvz}{QySe5*lN|xUuws@O5P!$6 z9`h)0BV~VG(RTYDK(H5VC<-+by<`8vy=bDo_c5a$L-o6!^_EtDe}%;0CCJH$-;T)qh`H^#HqG#;1S>B5^ zPfvC@WFm;K`~bn)GN*`Bq5@#G0$>fM6#Y1o4W)mbs-sJDCUUs{y&!tdVUdPIp?IIf zl(`51L5)u5ytf8g2#uc$=}0Un5m8|AEMkH%2!0`^P3q~?C&DZOedkJ#!+1Wnp*c%G zw%B~cN_wwHlH>rHN0JH4Imb$zO6opQo2DK!lsaLU)xCr5IHhrJ?_8p{gv|t&)$_YP zJqUmM1%1({VMwe^(vl&Xtg>Wivb6~kL)Ry_mEIb`+v}lfAVzlv2KK3DQ)Ud@P5*gx zbuq;fB-(ZM2hl$Sv#IriJJeDom3PaeR35OLmzw*_;7vYVJev0=?iqj^T1Pl4`wpR^2#xjT@VPmmyn>L$4(yw_6KE zoUFlwMsGUCnp-aTn9EqC5_DmZ4f6 z@{x<-9@iKc_NB=(fz^ZWp@iq|`q8J$T@#|AogBMafLS+1s>SE3xAKoE!PQ+*3BE`1Icsw+n)C)M2i)D5i4wFw%z{nZl`vs##LG=9je_; zQHphzFWDSp^l$elB;3P%pW)Lp`T%M>eP?VPtobm7;!$1#bNW1h zZ8oHupGg`m&*Mm4UX9i0^6F&oG&mWvU7dL#RBzPB&8;jUQL@Zfvt-Xc$X4iwvGcQ5 zvSwehWF32DXK?LAWKY@mk|g^s#!|Mi??Qg^-gxWPJOA8sKIeO$bMBq{%s=_2U9yVE&Ek3ILIIE(LG}LvI3b@}3zlEhCa6WTO@FMkP`m#DvG<@VeZWdplbvE^G z2+#Q@Gv^Si@Q86YI~^4E?c9ulA*Ne!H8CG!;t%Yf>EgK!uxPQ#F9qY1eyDOwe^<{Q`B(x~!#y<^{9(?)UHq`5C--s_$ zE2#{(i1SKO5K!+lqQ#K-e4ScsQg-dyjIzet6!<6<+tT(#kLchVl`&e*=%LY^^+@8^ zOG%*!6t&ys!S(w4z5&U>{Fz!sJ}QeJtOIxvAua?|vxTpmG{uz@M%AUpwvEP@yn>kB zG6ifSd^~uko{ER5IOo{Co09%UkLoK`rXCjv$gqF;p_oaM4n2L`WwuO~dB=e46Ya-% zH6cLMynX5j*LUd7_v8SJd3DK2&eZ#wIQgyPKtho;xoCmZROrQ-@xxG3|07LJ#9;EJ z8>2#8Qazw9YW|5{3jn~C@yH{;asIrIK zRg5G9={OJ0**xTxfd-sjOM6_8aWP*)9JRSzHw*H^myQ?TJEf9q#0>U?*uJ0;jp2-I ztq}~>IvP^1Dw1O{jz+G^&gJ^o=COgxFL;z=w}f3p&CptkX-Cm}JqupA?eip|c?ET$ z6?B{>RzX6zE#$hjH6Wo?Tb$4>cT-iKPSAX&v&(L?P=7Xyi`e`wpex*M=QW4*<>mD?gq357Y!vW#%-CmzcfEJ+ ze(+DwFmzk_;NIl;Da6GYp^`XiD0pQxEK-a~2V=M{MrmNN`z-NX;-dV8&bDy!y-QSV z6O!e{%U()GHl&HNUbc5!BhvAs?4QSoV)ppp1)1op7frbHy-nug-igNxzVKAN%j3Oa zQus_Pn_j1Qi1Dg;vV2)^C2xJ!4@6QUL(mf8nK0P_Wp7NfY;&9p|Maz9%&1Q~O1EcJ@7W^P#j>69Ortk(Q>(XT#CJqf3 zx&$2+!v7>$NH_R{MlZY(t&fVkGP8XYhHBdlpz#tkeJtGkJbG)4F2*nIIbyPH5w&hM zujtM=K;PPC6_HnD!{n)s=|fuiY3;22n?4Srm_=HWG^(mPTE2GKHH%zKV_cZBOf)W;|I+stRX~M#Rdriq_!iELjFvx)`HHg~*FnPJ)63w3u3fGW*qyvS= zwj=z86+BPoQl{XhDxI5iZd$^l{Yu=>zEwR<7plc`+h6V4isd`@EIar}TI(}>9Ikij za&B~!cv#46o6Szy%~B-E>U1^G=HGEuLv(rbKJMJlJ4pyV^ILFt^Rk{v#LC(lf16-H zqpjcgOA~u~R*sf-LKO);joTLfX`N@tOy;pxduGZ2w1yPAXH+Fd?&C! zB$GVOjF~-nm%8PYvsE6cq?*0OULd-5!Mz5)C*pA#vi9VQ2vX}Zu<-8Ztj(!xP z?icUsr7VcAuR>!ciHyGEWffc>r|a-nm!HttHUZx><eg zV$TyNtAFQAoIaE>g13z{Ep*4=5ui1Q*hFJVIG=WyS%eQC{5Pk5kCohr@ui@h$#RFe z%9E;~*DyA#2!_3+`8Wk;g@a4WB%y<;&$GOxue`aRpQYrmH*OeteV-+uaHXrJp6GRY z%!Pca>os)%>cads9hC{4S6dLDpcvI+#97$*V1V?qG!v;t<_!ppK}|gwosr9ct;VTWpuM2@^kOM{Yo`fHBE2( zL_|4f{ZcpoW_KpWr(`_uz2is~I<3x(X@ViCQmC$-U8&MV-;1~$>G8%DASrvvlDE{o zHyrhhn;LuGWM|A%!7M9(l~Uyh*3z!6Fs46u2kB>JgNF(ttQ!+{z)k9OW=&VV_qS5$*m7vd%JtDud z0$&`f8rS%+T+=}x+2DDbjzX^MM+BYDN`-4$lGyy)FyH-5Vv_w`$8)#yLm7Q1rt!rq z3zO#rICb|3NE)R zEjRk)mb4WWA8)kQhfOmk>=yKD=2;2&&kMjLUlpGB-DlY^w#>|tzdl}wH4S%~?z^7< zEZ5ym!-Z^pT-SLmF4x^u$mU#PvKUSFqVByZEm&i`eT9N91*2hD4I1nd8J1HaJ?!i} zc(TKCvvZW1-2i^K_A^ogo%+C-%Wm4TZJJol2%ljeTmqc5asLdH(x~o9pwu7|~uWhm%hK_*SB6S`@wH z+q)L4zJe>G$x7cM)$-V-2qSf>-mYvcA~X_mWIGyOQ8j8-?SF#Sw=piM^Y(8rxTf<| zIachoqH4+)YvdMNMDb$A_MWM$GM%baHd#j6SlK&zIvWH%wkm>P}ja6BQ+di^PFeT8nTNRNoeN%tdAPY zW>?xxd`-9^Hr1n|p@z z?>DwrsPY_+R_}7h!@H0}lnsVrc6Yt>dUxMKKVFs`U592OuFc1l!YY{iMGT-vA6+55&m%o(aY)0R>$lT1v56O)GyhVK0` zt7>C7;F&%0Tz^8%fEtM->u!*#@KZALy~ljzPs`CWKiANoqm=byQU)AE`cPtZGh6S2 z4C>+c2-gby`3K1m@9kx-t$#SYEqsBgV2T*T6+c5z^}-R79g(q9&3y09ACJV4p= zRt;`g7OEGaoAmxE+U}^-%ApEtza=5O$GbAKE41_dzp{8TDW3h<{i*;OHJ4*hd7(do z%b2R0Oz&uU4aM!dXR3km-O~0w=9~#sFfavgq?OZXx@(H@VSFEj_|g=y1j>Cf`1y#1 zmyh~!JE~iLg>P#%-i_=%iP$1zZh)`d3OrzIe#Cbl{i+w)F7z>x=uXHpYb>WM33=MR z+!sTPGfsw)-OP<93d`pJ{W2RmY4K9}iIg2?%@Cp;ittMtb;X{ojR{TM#@pA~zkR&D z<{`@$Q1-fVnp^EC=S!2hJDjHWMhk)DHcrpQKtx)pb0yGzQF1f7eXOvg{ChzUKPc1T z9T*_KjvkkojMaYEV@ZX!FH>z@%J<}6`!V>9%$pa-DxwwXHUt-y_q096QG{9u*$CS+ zNUwd8qqwZY{&CSq`jN$b`g4~ZijP7|C|CEQ1VQxps zi0J(Puq1kh(mVm(u98LP$;4upN$lK)l)_`!f1sU6)8>P}lYYsXHjJX9twm>Dd^F0T zB=os1Bj0#5^+nMjJcV^?*X$CqC%^B#ZDqo|?ch){m(#Ty(Ef)eAF*ogy=F7ml|90o zA%g2)ix_|MQ116*{m=~AltC&FtMbodZYR1hU$ecmrEtFUr&2P>fa1WI@o~{$vD!zM z^vnJiWTPaG$*S5cfkvzImMdXQRiS+V5$vKXL5V`sIXt{ zJQ`?)ir=4?us(3RA5Z|q7(s~v=s3)R@n@j{QwIP}V4nlBuYlMAfFITck`6*)5`Iu; z5MV}xTD_@@QNY7vsE1y1{XH0Td^zYlbr6I0!;oBf07JgZff?;50egP=(le0H1+t9* z;y}dQi5)QlhyqLtziiAW94Yv71k!z2Jc;Ri0fc~O%O^43WpeP-7bxbub`ql>g<@aU zPi*ukAP7ipp4d~rY}V})TY3ztlducf!eHqblxwgD%3=W?kO&Kiz&b%0EMNji9iM1> zuuxtt4D6c&s4%@hDZ!iLfDCLKbQ%XN0TIIgR0gag#Y?J zaFS=VB2$1gV0ZTqp#fh_K_`}P_=gaKZu&4Puyhu<3?jY)w7}zd6a`_t|57c`6aV~+u-vBY7$Lo}Q{RaF482kKj$Ut!~7%9m04Ju>k z4ZBS8yXTj%M&C24L~qy?&|(@=%}ztj82g{b7-yidMFM|0oFK73j0-HCftm>p`a{S; zn*bObB>4)ZS_S@9pfmW4Drpvwg|ULYa{$+`fyhDPU>NObn(Q1@(frw|SUdzqe~K%9 z;ehAAus5t4l*IwGV00jq8SxD2UVzC0&WEHL|zmIS0(0IneZ{{l3>JEpKKzKzeRm**c$06IDYL?GKLge8Jb zvC}G4m^|u#HBSK&P-FzUy>erLv-fX&@~MDs4Z0An`M;d|0A3aNW(_a`{F+aLyz2lR L{^L;qYVm&n>VRZ3 delta 52632 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 diff --git a/chorus-memory.plugin.src/.claude-plugin/plugin.json b/chorus-memory.plugin.src/.claude-plugin/plugin.json index 7aea9a1..e0541af 100644 --- a/chorus-memory.plugin.src/.claude-plugin/plugin.json +++ b/chorus-memory.plugin.src/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "chorus-memory", - "version": "2.0.0-alpha.3", + "version": "2.0.0-alpha.4", "description": "Group-based persistent memory via the shared CHORUS Obsidian vault over the Obsidian Local REST API. Cross-platform Python client: one-call capture/resolve/recall/link/triage over an entity index, hybrid BM25 + graph recall spanning entities + sessions/journal (recency/status-aware), a pre-write duplicate gate, complete-frontmatter capture, session hooks that self-fire load/reflect, offline write-ahead queue, lock-guarded concurrency, linter-enforced routing, and /chorus-* commands.", "author": { "name": "Jason Stedwell" diff --git a/chorus-memory.plugin.src/commands/chorus-load.md b/chorus-memory.plugin.src/commands/chorus-load.md index 8a2c199..3eebfe9 100644 --- a/chorus-memory.plugin.src/commands/chorus-load.md +++ b/chorus-memory.plugin.src/commands/chorus-load.md @@ -2,17 +2,18 @@ description: Load CHORUS memory — cold-start context read (profile, scope, latest session, today, inbox) --- -Use the **chorus-memory** skill to load memory now. Run the cold-start **Loading procedure** from `SKILL.md`: the six orientation reads (marker, operator-preferences, current-context, heartbeat, today's daily note, inbox) in **one call**, then do the load-time **reconcile** (inbox-depth + scope-drift) and surface it in a single line. +Use the **chorus-memory** skill to load memory now. Run the cold-start **Loading procedure** from `SKILL.md`: the eight orientation reads (marker, group profile, your preferences/context/heartbeat, today's shared daily note, your inbox, the group inbox) in **one call**, then do the load-time **reconcile** (inbox-depth + scope-drift) and surface it in a single line. ```bash CHORUS="${CLAUDE_PLUGIN_ROOT}/skills/chorus-memory/scripts/chorus.py" [ -f "$CHORUS" ] || CHORUS=$(ls /sessions/*/mnt/.remote-plugins/*/skills/chorus-memory/scripts/chorus.py 2>/dev/null | head -1) # CoWork sandbox fallback python3 "$CHORUS" load +# add --all-members for a group-wide view (every member's scope + last session) # Windows: use `python` or `py -3` if `python3` is not on PATH. ``` -`load` prints all six sections (404s on today's note / inbox are shown as absent, not errors) and flags an un-bootstrapped vault. Follow up with `chorus.py scope show` if you need the sessions-since-switch count, and a project search if a specific project is in play. +`load` prints all eight sections (and self-onboards your member namespace on a first visit) (404s on today's note / inbox are shown as absent, not errors) and flags an un-bootstrapped vault. Follow up with `chorus.py scope show` if you need the sessions-since-switch count, and a project search if a specific project is in play. -**If `load` prints `NOT CONFIGURED` (exit 78)**, this machine has no usable key file yet. Don't proceed with memory — follow **First run** in `SKILL.md`: tell the operator CHORUS isn't configured, ask for their chorus-memory config file (owner/endpoint/key), install it with `chorus.py config import ` (or `config set`), then re-run `load`. +**If `load` prints `NOT CONFIGURED` (exit 78)**, this machine has no usable key file yet. Don't proceed with memory — follow **First run** in `SKILL.md`: tell the operator CHORUS isn't configured, ask for their chorus-memory config file (group/member/endpoint/key), install it with `chorus.py config import ` (or `config set`), then re-run `load`. Do not narrate the reads. End with a one-line orientation: who/what/where the active scope is, and any reconcile prompt. diff --git a/chorus-memory.plugin.src/commands/chorus-recall.md b/chorus-memory.plugin.src/commands/chorus-recall.md index 1fe514a..e938c50 100644 --- a/chorus-memory.plugin.src/commands/chorus-recall.md +++ b/chorus-memory.plugin.src/commands/chorus-recall.md @@ -12,7 +12,7 @@ Run the one-call recall — it resolves the term against the entity index, searc ```bash CHORUS="${CLAUDE_PLUGIN_ROOT}/skills/chorus-memory/scripts/chorus.py" [ -f "$CHORUS" ] || CHORUS=$(ls /sessions/*/mnt/.remote-plugins/*/skills/chorus-memory/scripts/chorus.py 2>/dev/null | head -1) # CoWork sandbox fallback -python3 "$CHORUS" recall "$ARGUMENTS" +python3 "$CHORUS" recall "$ARGUMENTS" # add --author to filter to one member's notes # Windows: use `python` or `py -3` if `python3` is not on PATH. ``` diff --git a/chorus-memory.plugin.src/skills/chorus-memory/SKILL.md b/chorus-memory.plugin.src/skills/chorus-memory/SKILL.md index c8d543d..ae3486a 100644 --- a/chorus-memory.plugin.src/skills/chorus-memory/SKILL.md +++ b/chorus-memory.plugin.src/skills/chorus-memory/SKILL.md @@ -64,7 +64,7 @@ All paths below are under `${CLAUDE_PLUGIN_ROOT}/skills/chorus-memory/`. **Invok ```bash CHORUS="${CLAUDE_PLUGIN_ROOT}/skills/chorus-memory/scripts/chorus.py" # call as: python3 "$CHORUS" ... [ -f "$CHORUS" ] || CHORUS=$(ls /sessions/*/mnt/.remote-plugins/*/skills/chorus-memory/scripts/chorus.py 2>/dev/null | head -1) # CoWork sandbox fallback -python3 "$CHORUS" load # cold-start: the 8 orientation reads in one call +python3 "$CHORUS" load [--all-members] # cold-start: the 8 orientation reads (+ optional every-member scope/last-session view) python3 "$CHORUS" get # 404 -> exit 44 python3 "$CHORUS" ls ; python3 "$CHORUS" map # listing / document-map python3 "$CHORUS" search @@ -166,7 +166,7 @@ Keep the reconcile to a single short line to the operator (e.g. "3 inbox capture **If a specific topic/project/person is in play**, pull its connected context in one call: ```bash -python3 "$CHORUS" recall "" # the matching notes AND their one-hop neighbourhood +python3 "$CHORUS" recall "" [--author ] # matching notes + one-hop neighbourhood (optionally one member's only) ``` `recall` resolves the term against the entity index, searches, and expands one hop along `## Related` links and `source_notes` — so you get the project note *plus* its linked decisions, people, and prior sessions, not an isolated file. (If you only need the canonical path, `resolve ""` is the O(1) lookup.) diff --git a/chorus-memory.plugin.src/skills/chorus-memory/references/operating-contract.md b/chorus-memory.plugin.src/skills/chorus-memory/references/operating-contract.md index 56ec1b9..0b6fc4b 100644 --- a/chorus-memory.plugin.src/skills/chorus-memory/references/operating-contract.md +++ b/chorus-memory.plugin.src/skills/chorus-memory/references/operating-contract.md @@ -35,11 +35,12 @@ You are an agent operating against an Obsidian vault that functions as a shared, Assume clients may operate without filesystem access, through the Obsidian Local REST API. Keep paths predictable, frontmatter parseable, titles stable, and all state stored in notes rather than hidden conversation memory. Structure must stay portable: a fresh, empty vault is brought fully online by the plugin's bootstrap (`references/bootstrap.md`), so nothing essential should depend on files existing in the vault ahead of time. -## Concurrency (shared vault) +## Concurrency (N members, one vault) -The vault is a **shared** substrate — Claude Code, CoWork, and other REST API clients may operate on it concurrently. The REST API offers no transactions, so writers coordinate cooperatively: +The vault is a **group** substrate — every member's Claude Code and CoWork sessions may operate on it concurrently, from different machines. The REST API offers no transactions, so safety is layered structurally: -- Single-line, overwrite-style files (`_agent/members/<member>/heartbeat.md`, `current-context.md::Scope`) and append targets (`inbox.md`, `## Agent Log`) assume **one writer at a time**. Two sessions writing at once can clobber or duplicate. -- Before a burst of writes in a session that may overlap another, take the advisory lock (`chorus.py lock <id>` → `_agent/locks/vault.lock`) and release it at session end. The lock is read-back-confirmed and cooperative with a TTL (stale locks are reclaimable); it is a courtesy, not a hard mutex. -- Idempotent append (read-before-POST, whole-line match, via `chorus.py append`) is the second line of defense against duplicate lines from retries or overlapping sessions. +- **Namespacing is the first defense (schema 5).** All churn-prone single-writer state is per member (`_agent/members/<member>/{preferences,current-context,heartbeat,inbox}.md`, `_agent/sessions/<member>/`), so members never contend on each other's pointers by construction. Only your own sessions write your namespace. +- **What remains shared-write** is designed for interleaving: the daily `## Agent Log` and the group inbox take **member-tagged, whole-line-idempotent appends** (`- YYYY-MM-DD [member]: …` via `chorus.py append` — read-before-POST, exact-line match), so concurrent appends interleave without clobbering or duplicating; shared entity notes take member-tagged dated blocks the same way. +- **The machine indexes** (`_agent/index/*.json`, full-file read-modify-write) are guarded by the advisory lock with **bounded retry/backoff** (`CHORUS_LOCK_RETRIES`, default 4): index writes hold the lock sub-second, so a retrying writer virtually always acquires it, and the update re-reads the index fresh inside the critical section so concurrent captures merge instead of clobber. Only after exhausted retries does it proceed unlocked — loudly — because a note that was already written must never be stranded unindexed. +- The advisory lock (`chorus.py lock <id>` → `_agent/locks/vault.lock`) is read-back-confirmed and cooperative with a TTL (stale locks are reclaimable). Lock owner ids carry the member (`<member>-<client>-<pid>`), so contention is attributable to a person. For a burst of writes to *shared* files that may overlap another member's session, take it manually and release at session end; it is a courtesy, not a hard mutex. - Status-check every write. A write that returns `>= 400` did **not** land — surface it rather than assuming success. diff --git a/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus.py b/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus.py index 259d28a..f10c773 100644 --- a/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus.py +++ b/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus.py @@ -31,7 +31,7 @@ Config (group/member/endpoint/key are machine-local — see chorus_config; the p CHORUS_TODAY YYYY-MM-DD to use as "today" (pass the conversation's currentDate) Usage: - chorus.py load # cold-start: the 8 orientation reads in one call + chorus.py load [--all-members] # cold-start: the 8 orientation reads (+ optional group-wide view) chorus.py get <path> # print file contents (404 -> exit 44) chorus.py map <path> # document-map JSON (headings/blocks/frontmatter) chorus.py ls <dir> # directory listing JSON @@ -626,12 +626,14 @@ def cmd_scope(subcommand: str, text: str | None = None, as_json: bool = False) - return 0 -def cmd_load() -> int: +def cmd_load(all_members: bool = False) -> int: """Cold-start orientation: the canonical 8 reads in one call — the marker, the GROUP profile, then MY member state (preferences/context/heartbeat/inbox), the shared daily note, and the group inbox. 404s on today's daily note and the inboxes are normal (printed as absent, not errors). If the vault is - bootstrapped but MY namespace is missing, self-onboard it.""" + bootstrapped but MY namespace is missing, self-onboard it. With + `all_members`, append a compact group-wide view: every member's active scope + and last-session pointer ("what has the team been doing").""" if not chorus_config.is_configured(_CFG): print("chorus: NOT CONFIGURED — this machine has no usable CHORUS key file yet.") print(f"Expected at: {chorus_config.config_path()}") @@ -725,6 +727,34 @@ def cmd_load() -> int: for f in files[:5]: print(f" {member_sessions_dir()}/{f}") print() + # Group-wide orientation: one compact line-pair per member (scope + last + # session). A lens over everyone's namespaces — read-only, opt-in. + if all_members and not offline: + st, body = request("GET", vault_url("_agent/members/")) + roster = [] + if st == 200: + try: + payload = json.loads(body) + # Folders may arrive under "folders" or as trailing-slash entries + # in "files" (both shapes exist in the wild — cf. vault_lint.list_dir). + entries = list(payload.get("files", [])) + list(payload.get("folders", [])) + roster = sorted({e[:-1] for e in entries if e.endswith("/")}) + except json.JSONDecodeError: + roster = [] + print(f"===== group: all members ({len(roster)}) =====") + for m in roster: + me = " (me)" if m == MEMBER else "" + st_c, b_c = request("GET", vault_url(member_path("current-context.md", m))) + scope = "" + if st_c == 200: + scope = " ".join(extract_heading(b_c.decode(errors="replace"), "Scope").split()) + scope = re.sub(r"<!--.*?-->", "", scope).strip()[:140] + st_h, b_h = request("GET", vault_url(member_path("heartbeat.md", m))) + last = b_h.decode(errors="replace").strip()[:120] if st_h == 200 else "(no sessions yet)" + print(f" {m}{me}") + print(f" scope: {scope or '(not set)'}") + print(f" last: {last}") + print() if offline: print("NOTE: vault unreachable — context above is last-known-good cache; writes this " "session will be queued and synced when the vault returns.") @@ -780,7 +810,9 @@ def cmd_config(args) -> int: def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description="Validated cross-platform CHORUS vault client") sub = parser.add_subparsers(dest="cmd", required=True) - sub.add_parser("load") + p = sub.add_parser("load") + p.add_argument("--all-members", action="store_true", + help="append a group-wide orientation: every member's scope + last session") sub.add_parser("flush") # H2: replay writes queued during a prior outage sub.add_parser("doctor") # M3: one-call readiness check sub.add_parser("get").add_argument("path") @@ -819,6 +851,7 @@ def build_parser() -> argparse.ArgumentParser: # High-level operations (entity index + cross-links + recall). See chorus_ops.py. sub.add_parser("resolve").add_argument("mention", nargs="+") p = sub.add_parser("recall"); p.add_argument("query", nargs="+"); p.add_argument("--limit", type=int, default=6) + p.add_argument("--author") # filter hits to one member's notes (a lens, not a wall) p.add_argument("--json", action="store_true") # structured hits + neighbourhood p = sub.add_parser("link"); p.add_argument("a"); p.add_argument("b") p.add_argument("--json", action="store_true") @@ -845,7 +878,7 @@ def main(argv: list[str] | None = None) -> int: args = build_parser().parse_args(argv) try: if args.cmd == "load": - return cmd_load() + return cmd_load(all_members=args.all_members) if args.cmd == "doctor": import chorus_doctor return chorus_doctor.run() @@ -918,7 +951,8 @@ def main(argv: list[str] | None = None) -> int: if args.cmd == "resolve": return chorus_ops.resolve(" ".join(args.mention)) if args.cmd == "recall": - return chorus_ops.recall(args.query, limit=args.limit, as_json=args.json) + return chorus_ops.recall(args.query, limit=args.limit, as_json=args.json, + author=args.author) if args.cmd == "link": return chorus_ops.link(args.a, args.b, as_json=args.json) return chorus_ops.capture( diff --git a/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_concurrency.py b/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_concurrency.py index a582685..c7e7b24 100644 --- a/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_concurrency.py +++ b/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_concurrency.py @@ -23,12 +23,19 @@ from __future__ import annotations import contextlib import os import sys +import time from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) import chorus # noqa: E402 import chorus_index as idx_mod # noqa: E402 +# Bounded retry for index-write locks (Phase 4 hardening). With N members writing, +# lock holds are sub-second, so a short backoff nearly always wins the lock; the +# unlocked fallback (loud, fresh-re-read) survives only a genuinely stuck peer. +INDEX_LOCK_RETRIES = max(0, int(os.environ.get("CHORUS_LOCK_RETRIES", "4"))) +INDEX_LOCK_BACKOFF = float(os.environ.get("CHORUS_LOCK_BACKOFF", "0.5")) + def auto_owner() -> str: """A stable-per-process owner id: member + client tag + pid, so lock contention @@ -41,16 +48,24 @@ def auto_owner() -> str: @contextlib.contextmanager -def vault_lock(owner: str | None = None, required: bool = False): +def vault_lock(owner: str | None = None, required: bool = False, + retries: int = 0, backoff: float = INDEX_LOCK_BACKOFF): """Hold the advisory lock for a write burst; release on exit (incl. exceptions). - Yields `held: bool`. The lock is cooperative (read-back-confirmed, TTL-reclaimable), - so if another session holds it we do NOT block: with `required=False` we yield + Yields `held: bool`. The lock is cooperative (read-back-confirmed, TTL-reclaimable). + `retries` > 0 re-attempts acquisition with linear backoff (attempt N sleeps + N*backoff) — with multiple members writing, lock holds are sub-second, so a short + retry almost always acquires. If it still can't: with `required=False` we yield `held=False` and let the caller proceed (advisory) or warn; with `required=True` we raise. Release is best-effort and never masks the body's own exception. """ owner = owner or auto_owner() rc = chorus.cmd_lock(owner, quiet=True) + attempt = 0 + while rc != 0 and attempt < retries: + attempt += 1 + time.sleep(backoff * attempt) + rc = chorus.cmd_lock(owner, quiet=True) held = rc == 0 if not held and required: raise chorus.ChorusError(f"vault_lock: could not acquire lock for '{owner}' (held elsewhere)", 75) @@ -69,12 +84,13 @@ def atomic_index_update(mutate, owner: str | None = None): entry: take the lock, **re-read the index fresh** (not a stale in-memory copy), run the mutator, save, release. Returns the freshly-read-and-saved index. - The fresh re-read inside the critical section is the core of the fix — even if the - advisory lock can't be taken (another session active), reading immediately before - the save collapses the read-modify-write window to two calls instead of spanning the - whole capture, so an unlocked update is still far safer than the prior code. + The fresh re-read inside the critical section is the core of the fix. Acquisition + retries with bounded backoff (INDEX_LOCK_RETRIES) — in a group vault the lock is + only ever held for sub-second index writes, so retries nearly always acquire; the + unlocked path (fresh re-read + loud warning) survives only a genuinely stuck peer, + chosen over hard failure so a note that was already written never goes unindexed. """ - with vault_lock(owner) as held: + with vault_lock(owner, retries=INDEX_LOCK_RETRIES) as held: index = idx_mod.load() mutate(index) idx_mod.save(index) diff --git a/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_ops.py b/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_ops.py index bbe8cb3..2a655ec 100644 --- a/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_ops.py +++ b/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_ops.py @@ -73,11 +73,11 @@ def link(a_path: str, b_path: str, as_json: bool = False) -> int: # ----------------------------------------------------------------- recall ----- -def recall(query, limit: int = 8, as_json: bool = False) -> int: +def recall(query, limit: int = 8, as_json: bool = False, author: str | None = None) -> int: """Hybrid lexical (BM25) + graph recall — implemented in chorus_recall. Kept here as the stable public entrypoint (chorus.py and /chorus-recall call chorus_ops.recall).""" import chorus_recall # lazy: only pulls the BM25 modules when recall is actually run - return chorus_recall.recall(query, limit=limit, as_json=as_json) + return chorus_recall.recall(query, limit=limit, as_json=as_json, author=author) # ----------------------------------------------------------- agent log ------- @@ -112,6 +112,21 @@ def ensure_daily_log(line: str) -> None: # ----------------------------------------------------------------- capture --- +def _note_author(path: str) -> str: + """Best-effort author: of an existing note — so gate messages can say WHOSE + entity a capture collided with. Never raises; empty string on any miss.""" + if not path: + return "" + try: + status, body = chorus.request("GET", chorus.vault_url(path)) + if status == 200: + m = re.search(r"(?m)^author:\s*(\S+)", body.decode(errors="replace")[:2000]) + return m.group(1) if m else "" + except Exception: # noqa: BLE001 + pass + return "" + + def _build_note(fm_type: str, status_v: str, today_s: str, title: str, body_text: str, sources: list[str], aliases: list[str] | None = None, tags: list[str] | None = None) -> str: @@ -245,7 +260,8 @@ def capture(kind: str | None, title: str, file_arg: str | None, status_v: str = gate_hits = [] if not existing_reachable and not force and not dry_run: gate_hits = [{"slug": s, "path": c.get("path"), "title": c.get("title"), - "kind": c.get("kind"), "score": sc} + "kind": c.get("kind"), "score": sc, + "author": _note_author(c.get("path", ""))} for s, c, sc in idx_mod.gate_candidates(index, title, kind=kind, threshold=DUP_GATE)] if gate_hits: @@ -259,7 +275,8 @@ def capture(kind: str | None, title: str, file_arg: str | None, status_v: str = print(f"STOP: '{title}' likely already exists — not creating a duplicate.", file=real_stdout) for c in gate_hits: - print(f" candidate: {c['slug']} -> {c['path']} (score {c['score']})", + by = f", created by {c['author']}" if c.get("author") else "" + print(f" candidate: {c['slug']} -> {c['path']} (score {c['score']}{by})", file=real_stdout) print(" re-run with --merge-into <slug> to update the existing entity, " "or --force to create anyway.", file=real_stdout) diff --git a/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_recall.py b/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_recall.py index fe1757e..2564ed3 100644 --- a/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_recall.py +++ b/chorus-memory.plugin.src/skills/chorus-memory/scripts/chorus_recall.py @@ -316,7 +316,7 @@ def update_note(path: str, text: str) -> None: if not _indexable(path): return # only entity notes are part of the recall corpus import chorus_concurrency - with chorus_concurrency.vault_lock(): + with chorus_concurrency.vault_lock(retries=chorus_concurrency.INDEX_LOCK_RETRIES): ix = load_index() # fresh read inside the lock ix.add(path, text) # raw text: add() strips + extracts meta save_index(ix) @@ -385,6 +385,9 @@ def _doc_summary(path: str, text: str) -> dict: ms = _FM_STATUS.search(text[:2000]) if ms: out["status"] = ms.group(1) + ma = re.search(r"(?m)^author:\s*(\S+)", text[:2000]) + if ma: + out["author"] = ma.group(1) body = strip_frontmatter(text) status = re.search(r"(?ms)^##\s+Status\s*$(.*?)(?=^##\s|\Z)", body) if status and status.group(1).strip(): @@ -414,6 +417,8 @@ def _brief(path: str, score: float | None = None, via: str | None = None) -> Non stamps.append(f"updated: {info['updated']}") if info.get("status"): stamps.append(f"status: {info['status']}") + if info.get("author"): + stamps.append(f"author: {info['author']}") if stamps: print("_" + " · ".join(stamps) + "_") # staleness is visible, not guessed if info.get("excerpt"): @@ -421,7 +426,7 @@ def _brief(path: str, score: float | None = None, via: str | None = None) -> Non # ------------------------------------------------------------------- entrypoint -def recall(query, limit: int = 8, as_json: bool = False) -> int: +def recall(query, limit: int = 8, as_json: bool = False, author: str | None = None) -> int: q = " ".join(query) if isinstance(query, list) else query today_s = chorus.today() index = idx_mod.load() @@ -464,6 +469,19 @@ def recall(query, limit: int = 8, as_json: bool = False) -> int: # --- graph layer ---------------------------------------------------------- neighbours = expand_graph(hits, nmap, base, max_hops=MAX_HOPS) + # --- optional member filter (--author): keep only notes whose frontmatter + # author matches. Group memory is shared, so this is a lens, not a wall. + if author: + cand = hits + [p for p, _ in neighbours] + atexts = chorus.read_many(cand) + + def _by(p: str) -> bool: + m = re.search(r"(?m)^author:\s*(\S+)", (atexts.get(p) or "")[:2000]) + return bool(m) and m.group(1) == author + + hits = [p for p in hits if _by(p)] + neighbours = [(p, sv) for p, sv in neighbours if _by(p)] + if as_json: import chorus_output texts = chorus.read_many(hits + [p for p, _ in neighbours[: 2 * limit]]) diff --git a/eval/test_multimember.py b/eval/test_multimember.py new file mode 100644 index 0000000..2c47e49 --- /dev/null +++ b/eval/test_multimember.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +"""test_multimember.py — two members share one vault (end-to-end vs the mock). + +Covers the schema-5 group behavior: jason bootstraps; alice self-onboards +via load; both capture; the daily log interleaves member-tagged lines; scopes are +independent; triage sees member+group inboxes; lint is clean; schema is 5.""" +import os +import subprocess +import sys +import time +import urllib.request +from pathlib import Path + +REPO = Path(__file__).resolve().parent.parent +SCRIPTS = REPO / "chorus-memory.plugin.src" / "skills" / "chorus-memory" / "scripts" +PORT = 8807 +BASE = f"http://127.0.0.1:{PORT}" +fails = [] + + +def check(name, cond, detail=""): + print(("ok " if cond else "FAIL") + f" {name}" + (f" — {detail}" if detail and not cond else "")) + if not cond: + fails.append(name) + + +def run(member, script, *args, stdin=None): + env = {k: v for k, v in os.environ.items() if not k.startswith("CHORUS_")} + env.update({"CHORUS_BASE": BASE, "CHORUS_KEY": "k", "CHORUS_GROUP": "MPM", + "CHORUS_MEMBER": member, "CHORUS_TODAY": "2026-07-21"}) + return subprocess.run([sys.executable, str(SCRIPTS / script), *args], + capture_output=True, text=True, env=env, input=stdin) + + +def vault(path): + try: + return urllib.request.urlopen(f"{BASE}/vault/{path}", timeout=2).read().decode() + except Exception: + return None + + +mock = subprocess.Popen([sys.executable, str(REPO / "eval/mock_olrapi.py"), "--port", str(PORT)], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) +for _ in range(50): + try: + urllib.request.urlopen(f"{BASE}/__debug__reset", data=b"", timeout=1) + break + except Exception: + time.sleep(0.1) + +try: + # --- jason stands up the vault --- + r = run("jason", "bootstrap.py") + check("jason bootstraps", r.returncode == 0, r.stderr[:200]) + marker = vault("_agent/chorus-vault.md") or "" + check("marker is schema 5", "schema_version: 5" in marker, marker[:120]) + check("group profile seeded + jason rostered", + "- jason (joined 2026-07-21)" in (vault("_agent/memory/semantic/group-profile.md") or "")) + check("jason anchors exist", vault("_agent/members/jason/preferences.md") is not None + and "author: jason" in vault("_agent/members/jason/preferences.md")) + check("group inbox seeded", vault("inbox/captures/group.md") is not None) + + # --- alice self-onboards via load --- + r = run("alice", "chorus.py", "load") + check("alice load self-onboards", "self-onboarding: member 'alice'" in r.stdout, r.stdout[:600]) + check("alice anchors created", vault("_agent/members/alice/preferences.md") is not None) + profile = vault("_agent/memory/semantic/group-profile.md") or "" + check("alice rostered in group profile", "- alice (joined 2026-07-21)" in profile, profile[-200:]) + r = run("alice", "chorus.py", "load") + check("second alice load does NOT re-onboard", "self-onboarding" not in r.stdout) + check("load reads group profile + both inboxes", + "group-profile" in r.stdout and "my-inbox" in r.stdout and "group-inbox" in r.stdout) + + # --- both capture; daily log interleaves member-tagged lines --- + run("jason", "chorus.py", "capture", "Acme Rockets", "--kind", "company") + run("alice", "chorus.py", "capture", "Widget Live", "--kind", "project") + daily = vault("journal/daily/2026-07-21.md") or "" + check("daily log tags jason", "[jason]: created company" in daily, daily[-300:]) + check("daily log tags alice", "[alice]: created project" in daily, daily[-300:]) + check("captures carry authors", + "author: jason" in (vault("resources/companies/acme-rockets.md") or "") + and "author: alice" in (vault("projects/active/widget-live.md") + or vault("projects/incubating/widget-live.md") or "")) + + # --- alice updates jason's entity: dated bullet attributes alice --- + run("alice", "chorus.py", "capture", "Acme Rockets", "--kind", "company", "-", + stdin="Alice met their CTO.\n") + acme = vault("resources/companies/acme-rockets.md") or "" + check("cross-member update attributed", "- 2026-07-21 [alice]: Alice met their CTO." in acme, + acme[-300:]) + + # --- scopes are independent (raw files: the basic mock's heading-PATCH only + # appends, so real replace semantics live in test_patch_semantics; here we + # prove the writes land in EACH member's own file and nowhere else) --- + r1 = run("jason", "chorus.py", "scope", "set", "fiber buildout") + r2 = run("alice", "chorus.py", "scope", "set", "widget launch") + jctx = vault("_agent/members/jason/current-context.md") or "" + actx = vault("_agent/members/alice/current-context.md") or "" + check("scope set succeeds per member", r1.returncode == 0 and r2.returncode == 0, + r1.stderr[:150] + r2.stderr[:150]) + check("scopes independent", "fiber buildout" in jctx and "widget launch" in actx + and "widget launch" not in jctx and "fiber buildout" not in actx) + + # --- member inbox + group inbox; triage lists both --- + run("jason", "chorus.py", "capture", "look into starlink backhaul", "--inbox") + run("jason", "chorus.py", "append", "inbox/captures/group.md", + "- 2026-07-21 [jason]: someone should test the new proxy") + r = run("alice", "chorus.py", "triage", "--list") + check("alice's triage sees the group item", "test the new proxy" in r.stdout, r.stdout[:400]) + check("alice's triage does NOT see jason's personal item", + "starlink" not in r.stdout, r.stdout[:400]) + + # --- session logs namespaced; lint clean --- + run("jason", "chorus.py", "put", "_agent/sessions/jason/2026-07-21-0900-fiber.md", "-", + stdin="---\ntype: session-log\nstatus: done\ncreated: 2026-07-21\nupdated: 2026-07-21\n" + "tags: [session]\nagent_written: true\nauthor: jason\nsource_notes: []\n---\n# Fiber session\n") + # --- Phase 4: gate names the existing entity's author --- + r = run("alice", "chorus.py", "capture", "Acme Rockets Inc", "--kind", "company") + check("gate blocks near-duplicate", r.returncode == 76, f"rc={r.returncode}") + check("gate names the author", "created by jason" in r.stdout, r.stdout[:300]) + + # --- Phase 4: recall --author filters to one member's notes --- + r = run("jason", "chorus.py", "recall", "Acme", "--author", "jason") + check("recall --author keeps jason's note", "acme-rockets" in r.stdout, r.stdout[:300]) + r = run("jason", "chorus.py", "recall", "Acme", "--author", "alice") + check("recall --author filters out others", "acme-rockets" not in r.stdout.split("Linked context")[0].split("Primary")[-1], r.stdout[:400]) + r = run("jason", "chorus.py", "recall", "Acme") + check("recall surfaces author stamp", "author: jason" in r.stdout, r.stdout[:400]) + + # --- Phase 4: load --all-members group view --- + run("jason", "chorus.py", "put", "_agent/members/jason/heartbeat.md", "-", + stdin="_agent/sessions/jason/2026-07-21-0900-fiber.md @ 2026-07-21T14:00:00Z\n") + r = run("alice", "chorus.py", "load", "--all-members") + check("load --all-members lists both", "group: all members (2)" in r.stdout + and "alice (me)" in r.stdout and "jason" in r.stdout, r.stdout[-600:]) + check("all-members shows jason's heartbeat", "2026-07-21-0900-fiber" in r.stdout, + r.stdout[-600:]) + + run("jason", "sweep.py", "--apply") # index the seeded anchors (documented bootstrap→sweep flow) + run("jason", "chorus.py", "link", "_agent/memory/semantic/group-profile.md", + "resources/companies/acme-rockets.md") + r = run("jason", "vault_lint.py") + check("lint clean on two-member vault", r.returncode == 0, r.stdout[-500:]) +finally: + mock.terminate() + +print() +sys.exit(1 if fails else print("all multimember tests passed") or 0)