From 8b22d2b5d3d91c78e4a1e157c55c1d14aa836f01 Mon Sep 17 00:00:00 2001 From: Andy Lee Date: Tue, 5 Aug 2025 23:02:34 -0700 Subject: [PATCH] Merge pull request #19 from yichuan-w/feature/claude-code-research Feature/claude code research --- README.md | 11 +- assets/claude_code_leann.png | Bin 0 -> 75142 bytes docs/claude-code-integration.md | 150 +++++++++++ .../leann-backend-diskann/third_party/DiskANN | 2 +- packages/leann-core/pyproject.toml | 1 + packages/leann-core/src/leann/cli.py | 247 ++++++++++++++++-- packages/leann-core/src/leann/mcp.py | 134 ++++++++++ packages/leann-mcp/README.md | 69 +++++ 8 files changed, 586 insertions(+), 28 deletions(-) create mode 100644 assets/claude_code_leann.png create mode 100644 docs/claude-code-integration.md create mode 100755 packages/leann-core/src/leann/mcp.py create mode 100644 packages/leann-mcp/README.md diff --git a/README.md b/README.md index 868c994..1f8c46c 100755 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ LEANN achieves this through *graph-based selective recomputation* with *high-deg **Ready to RAG Everything?** Transform your laptop into a personal AI assistant that can search your **[file system](#-personal-data-manager-process-any-documents-pdf-txt-md)**, **[emails](#-your-personal-email-secretary-rag-on-apple-mail)**, **[browser history](#-time-machine-for-the-web-rag-your-entire-browser-history)**, **[chat history](#-wechat-detective-unlock-your-golden-memories)**, or external knowledge bases (i.e., 60M documents) - all on your laptop, with zero cloud costs and complete privacy. +> **🚀 NEW: Claude Code Integration!** LEANN now provides native MCP integration for Claude Code users. Index your codebase and get intelligent code assistance directly in Claude Code. [Setup Guide →](packages/leann-mcp/README.md) + ## Why LEANN? @@ -428,7 +430,7 @@ source .venv/bin/activate leann --help ``` -**To make it globally available (recommended for daily use):** +**To make it globally available:** ```bash # Install the LEANN CLI globally using uv tool uv tool install leann @@ -437,12 +439,17 @@ uv tool install leann leann --help ``` +> **Note**: Global installation is required for Claude Code integration. The `leann_mcp` server depends on the globally available `leann` command. + ### Usage Examples ```bash -# Build an index from documents +# Build an index from current directory (default) +leann build my-docs + +# Or from specific directory leann build my-docs --docs ./documents # Search your documents diff --git a/assets/claude_code_leann.png b/assets/claude_code_leann.png new file mode 100644 index 0000000000000000000000000000000000000000..12894efc8705e9bd20b1d66902bac11462013f68 GIT binary patch literal 75142 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

X~l0O-eFeN{~HY0JigP z2mUs$*2G&;iMP4}327cBfqzpvhBK7~Im`Qch|&#W+%h&=Ad&`0=F;zWx{`1ADrZ{c zm9_p9_|Ym`MAR&V{5;f3U7pP$?KV~5bJ@DpF0Os)qxByLPJ7kg5!F-9&z_9ZGN;&{iR#2#o zHo7p;mA*KZbTB(zCp&Z$*JKxk^;XHl={Hv3!wBT*h`_u z)rL{**q_yKhqz#JJFMohg;IbyWBnzJ%%8-h0|PQVPO{9gpOI%c=vy&qvY@=omr=BS zk2%TTDS-<+?c5r>@k8pb&jGl+PiOpwUokjA5{|!=kiO&z9W+N0`;N!2Ol-OhCxvB} z405_0+3Cw-CN1MbsS*V7Ba;~OZf$jS>7l9nS2XplOY% zz7PocDZB?B0m!dP*~}r$=iWmHCT3bYxG-=trAq}hfh=a;ml+x!1v(nLA0J;iiycs0 zlF`XTeg4@U-pg>DL7DDTl_{=&V_KW*`HV1Sl8Vhh7EzaoWD9D}MOrA0+Vsj*9^F>n z?-vmVXYzdxByx79uzAkkJ7etN=xvJTy*qZ+?v*Kl{iS z$C$*)sE9G-#R5R$a_)mdtC3Zxy-gn9{-`q45GVVS6O%km`Xl8&ReUzbHYV7Ndqcdg zSL)$^o8{4cks|5w-*yJZg&%Xrnx*fvgSmXi%8nw5;w3g~h50yI<;%=;kO=9QO8h)G znz5^_T`129xD@#Q#(y8}K}6+QmBgkV%fJcq9_0wTCM!%`gKw7jF&Un>{npkNRJ76o zBQ)x3I!*mvPxy`f_6ymmc*)13DsUux{AmzU(s+DPxGwG|pP6?wV}M8VRs%{brI$YO z{VHUbd{^(){Dx+8Lq8S;T3}}7(i9_6pNN5b#}wr-OkPE~QtXO4`qg^3+-VRjn-Gb^ zxGZQb*k39xD4U<_9Z$cTxMr7K3f58UbQpa+T~bnL=9AgryyMSCQFr$1yp~;w&0t%0 zjs|{Ph^DJDtia&oW9v!L9Z&1Uo-LNI{J~qkwf=32E2cA<)zqs5x5otu3LbWPJXaQ{ z;@i!+$dS>SKrRKQsT(rh<6ZQ{Q|i$m=!SZ88>)=c0%3D5K% z6*3m+-ty9)oF22j(M>pEJjqUHHtEiXGh`i_xo!-7ZpJXSlCwbIvgKD*n2+MC zl?U||${N;BmG0O5=>L3An2TV=W#0bL7xk3R@QIN>Og5G>i2@Fb5w&JnYq@Aiusry- zCwGichD~cG=d1+t(@?EgMsm^0ZmX1O)Fq)`bVDKteM+0n7>%<*))=0j7*}s+^6>%;H?6XZxB1|74-Z z9sk`U|6PPxVJbddr3|&|*k&Xf@-&OC{M-0fDPDcV)}=(D@EgWlO|o69|L2U`SgH-J zUG9a718HqY2)aaB0=WtPc$lN6spw*PG6~I@LDCzY4Hb%m-sR^B$(jXPI1D-smc!Y% zYZ2BIcHzc=XNHdC;(gunvYl}9D^5;GZ&e`v^1^Xp;+dIn)(iTx8}RY5pNv>(SUGlG zi${`@tSW{^b5e1yeeGRd?lQ`*7#P7yxu<~qlT+l-wokHyx2*He3lH|dF6x74(9d3^ipwG!*Qd||=W zJb|+n?aJYsCj0K|A)lEdpMMswzX#}m97a9kzQ5Bj=JWfdTW^zXdc^L9g{mpU3}p;< z*=_L|aHv+#@V78fjSMsfEQLkAMS zh8}2pfBJfuTJ#_1^ga~%QuQ|J-f)R0tGz@=s)L2<-5<(%HMG3_uEG1hL%*9q>4Up5 z!25V}x!2NWyZUQNt58fRq&%&;c*wN@9*@SyH#RoY2x%vS&5l~FMhlsFAcM_HJd3?1 z=ocx0g&%pj%{iFuB+#-EDuHcy`0<~@T!R^7{ZbYWtrz&^+p<9EkPN9qptT<2a9emu%d|^b zpEdptg0H2b;RUKU`0$>uPCH|dmX>U}v5sp@>$ASqmmK<-Q11EiDLyF{Xx###Fws4j2+{nq@OOYR`NJiNm zD>IZaskigX>*vtv7O@_mdep=`b8GU+%@4`UL>+&)nw`y|FL3FUr;y9AC=$hIdZY8+ zrqEX4u&MG%b|~vB7z=i)B(-a7#-`N z_=J{a>rMzE1Nrq5(zrc~mFveP3_92PHKE%5p(VC|zL?y~9Jhn+5&Y#fWI#kmGl9eu z(yQekMrca11Q@h2m6*dGgdv{PB7{1>eu>`NoU`XDOXF>T=1;-~KV5C^hH7NmY-S*9 zu?;J=s7&Lk5AFO079J{&J|Aj>3boO7>(Vd7plz)WIRqW!_C9E3!>#JN$Y3j%fMxlD zHzUNclCN2wwP!u#KGj)Ex?FcluaJZl-$Ny;8QV3+AS`(Wb;)>OGkj%UrTDz^*qOsv=$n*Z04q+F#8EAHcWV+@N=3WRl(p(x_~tf)*HtMrD$Ih*IA)>L{A z>$G8?+8z~1hwDp-2#Iu6hU)!9xS@G%z(bqy4Wiowi!lg_3R9(Q7Fy+76!E|>7aCmO zF(#8iXG+6jSag0e%8A)T?fm<)+^mBGeY(hQ2Sq7-3&LA%xi@nuoiYeW#&@_J%4J$jHE9UpM8z$=OLZj#whXII*tZrYj{_r!iZuA)Wk=;?!9P z@D=0iNi`-OW`ndxW+CIeOiK3Gns68So*#K~!^Pk&D-=EQ$E1Sarg7>lI%~4dI{bRJ zH)TLQbkZ5(WA`0|%A+o3+m5$#%ZP_OObJ~901}?{ZI)#9*UsitM#7cMAPDbL%wLIr z0hN39#9eQFoK~A~2JKhFIq!k!rY*gkZd=EJkkAI2$E<;c$y~A^gg$rC89GCHn~#4d z)K-3RUpSA?cgLD9uQ%GF#F^eDX)bwkoU$%5jFy*l5tMaKy^UlxB#yjMVNVxfOn!Xw z30?p=1e6k)(;v1{S;&34T@$dA8<}v}iZ8bP26X^*-jlW6z@~;rteyIf>~_j>3Csg~ zEYqKwGTGdeMA_=JY6B7&<^tmRkF#P^Q1Gj*%#MCP^2hFebXPMIPyXZztkpdlA(oRf zLWs_w!*>>^#o`8yX{{khNsQ|S<_KvM`a8A?ln*6e+`AZxK_zivluN(W&9?^7@G$aI zIPwMnoX<<>{R^t3JLfX9!B8nCW6U`g;Y@RLi25eN3_Z2#4E4r;amFtM=pvT+n#(ie*OOf`O7?rP0CUMj*{8Qdxl`v}io|x7 zmKXwIA-BN{wDD)2bMVd!nv_uGI2LxG@}cav zK@<&Z)q(@DKO9pX?0Vv(>;8O&t+TVUpLSWTblf}2ypH2f1PQJA>*<&=lH;SiQ;Q+M zdbLYf+L{%9UBmdPMBetfRx$W+eWX1Qp4@ivPPllH7z~4s;dO8WUh-F7_{G6u>iK!> zoNx>=WD2AkY-T)}(B!I&|+Kf|# z=5!WX{pA`vA`P=90IpmDM*N2V?&yH*j$i7p)9G5pTSVJ^iWUO|lk?&6^t?U4owWJYTJnx1{K2Gi@}H&)bcAU+7N3ItXThO~#WV+m=r2zfD=3+F z5dY-gr}9gc%E@Eshe)OTmQ+l1@=Og6lcXUTl7mvGlx}NLTm{Z$N_+lqVp{7rhOr+) z1WC8w{XOctUWJK|P3KMvp|cfVuM+RqPV(;jLE@KG0RqqSvv+`?>%p7zntHm8zoV{D z-akF4>uw(E32y0NBOtxW3|8>Du_8yHwPd6-NX28r81U9NeuctGr z8@j~+Ip3-qvCJ)7wvu^6Yzw|g-ZH$ubPp$4X_P&R_Ek-mTO%1RPJlD`z3l>1{9Jyr)Sml-7lZPuO!1JSfxu0WdEmpM#cv9PRXIW&q@5Uf>XSx2O<@JrD`4?pu z?9>01?(^L^DfK=J_e!d5c1!>J(dI<>{?Sc-Lj3byDPa;@I#E)f!i zD%BREGqE@-wsFh_wxBp`s~^HJ#8CE z?6cN|rJskKLxOeI-qe3cY*D=^&aj}ByOk;xSsOm_?S+(JZg4l+nQk7m^RnV)vIBes z&p5ke)c63O%08oSBkL?lVgK=%RVPM+PDqtd`N=&yZ#GpR#(r;VYq) zz^@(E)j#j$H%~N(t>xkq(Id!nd%M8`UHPto`96LVva<=UbwHiId;xAemWa!w> zyItV3QdU77E&%P6ePe9lN+O>k+~~(kt@7GWulM-%A-m6G(;`8i`)v6^7J0rr4sz#k z&(nMGAxhu0CY(#;u&pE0qK%se$FFdz^GEG!48PG!w2*pm0dKIJl+UcjTxl=y;l(+~ zX$T&l0%*+Bbf!#l(d!cq~vWxcu%R}F#NqxIZ!W1r918c4La4Lbr< z1u%05udcjAeBX8lSz&v6<7Vf3-yYSR5_=R`zJcUKsrBjm6p09pLeu}0(~-OA%@Ye11{>CiYI;EXQN(~h;UYca5|(P z@J9Uz%8ddbT?^|lL0s^jYC?rBnex}ell5j#k7vMWG>q@E?|Y+Of$SZ-7U&6~0zkCc z!o8zEYMn}E;KNN8=kw2~afjZh9+khN`^cr!D7RGV6JaHm-t&O+nTJ)fDcH<&XF-)+ z8cjjsEiX$s>4n_0*+=clMrA*^HNW$P%M!MX2{;T`x7uzloYbH58r+=|P>5@i#K;d9 z1;J~wh@vyLWDIgG2>1t0hEqUiiaiEGAJZy6kMLV%J615}+dbyHuwE0YCl9Sx*9Cu+ z0XXy7a;yfPL)LTYQ0Q%`8DUfX`ZO+kl;x#WSPM^gPCrS;O(E} z4TXBH7mr{7JjL7ZJkTQD@- z1F6BD-UFXv;m(qlEC4^&JkPvsQ+S+wB+fe1hS&%|a&7+jev|?({jK1ZDZZ&Q{*T{) zsD^9Y2CV%|Q323C6oF^CkG7~~Bfl$>t;v`9!_%VqdvQD1CRTwZMS05Y?8naU`-?g@ z+KWX*jh39zAM9(ZXX@2k=E;klnxM27Xy&Qs1XA)lCrM(%h8Xs|UyUc{k~N`P-mTSzi6`?90Pvbw_c}5BL7|RcI!ALB`vaY1`#dBfSh8khiX&e!^C_LI9kH zu-vB!rdN)8=eEO#A*&pf5G6{Ei`=z#He|{d)+9JKZ)s}G)U&Docgu=?3}i4!zq#gL zV@L-Er|r)`OEGSp9Zged>V{4GXhJx2F8iG@ya*MNyb{)_MH!9T;iB-v_&=0`l3cWN z@^{9yI;%hG`_xGHKE%ga_5%3i(ii{_&$at%I*s2&_+SC_(?QgMuK(m=$9^TJ2piT{ z<|FRLGSz7d#18-itQ*WXx^K^}QI-4wxEzu9$G#|s-rMx`B_tuagFvy+$Ai^8hnS$5l9ow}^oo2BuR z8@MrPl~j7;{aSYiJhD^WZE}f2AG^(-slLV|rw6-o%vmls+T>+v6gig3hlFEelwf+0 z2OuL2*+Id5F0_k!>XjWOEMd8#ShXCSJ_|NO<$4U~)$-|;@}aJ_*!aiPx&#>JQw4uq z^=O!jzWVlVK%B(2%eC`$=+QtDpL1Aa1Q%7X$fXb`Z4aSR%1K&%Hk^6=NpOBak<K z#`fDIssEZ#aIC(cini}-+u;<4(Ducu($GNc`i)&qEGwLe6s&|Nsg@U3Xb@}DKouw_ zcq%@Z#vzNZF7>_@?aye(2?~wR9DllTwj16;?`=61)wV6+WTZEMp)chceIgIt_scH_v)?#_y9|&TXPU%7bnoDoTDS8?p0q~Jx-G#k zc-(9n$~=i6Bc>e47S82i>_>k?cb_+B*CrmgH~(A`DHAXw54jDJdM#%3 zZw#UUs#5Dv9ZnCwUx`uCMe^z6Vy#PFE~`;RHYLE=KUW&Chce z({lS|HG+@Ye&CWdMEm3J5bH;11!_w?5Hwj(uh8il5Xd+?RoxzQyy{N`GH_SNWuG3n zQtUr{bL0{#(!>f5a6kJ7IQ&aU)YZ&yvHWJ44pe^%1pZvu+^mZYM_awJF= zIVw`2(7&`;t*C5Uw**d&X%=H$B=JGY+`l|TOYC=lmX}IUR2lLN(w?PjBTy2KZa7Vo z{vRC0e`6{}3_!qHo>x3h{tbK7eM3JJE6UTL|NIVE4eX7yl9jTl$;CiQ)tB+W%MA@qhan{{f%;WhlPcBZ^!f0-k@c zI)Z;uz7ZN@c|OFfe*iK>iO}EB(5PANu-rc&o4Eh0j{i=O{aR^NLy<<_uvMM^2 z6D1lJmj31Gzfs6E!G83> z@1iorPX@Un0~~$!O74HGf?zwUM61zFK_f{MWF^#i zRl({lLHM%fB^uz9yn2@zAoMW?Z&!TPM0z1!*6()JEvEk^fBMfB{Xc0)sCC!MW7k;GJ~Xqn2ny*yj`L_g+HCb0R$`h0iQdD7|7M*3(M&Cr zUbY|s$_1nk+&CB!g3uvCQOSX?{wZP0%jIqM97I{-F{pz67v=d4)~i9e81YJmP=B9L zz(i{$^LEd`_H8c;wop0gQ^f7clQ*JeQLeNg1|)xmMQo-D^KcX&b&#}|n)TT*d;)!k zJ%F(DKS$)BUns$Dzc2-4yf;)?(|zm>Ti1L1Q3ON%exxM<5MoAZIcOZsJIR_`ekYwLgI$ok6Lo zIaygYy4un=yrNXb_(N%eJ)L~ok262zbZc(E!+}Nvu0_1?GN z0_3tlDx)%nzwS-ztBzPx6!~!=Sj}e)C(E77($}Wce+1+tHwtn)FI#^K1S!pqO*!Jt z0DDtzY-U}XsNpbaDd(z9Xp8IaK)@zkNg8}_oAnlWmF?HO7QY^hHD%cb_c-f9mDlo6 zy7ckyJp}vxF%VGkyN>e1B?h(=&=j{+r_61!rt~F3dG$yqBIFv}9+aoMjNehyH@HXV zYBt2T3Q{`q%#`=XT+3iW>x{2bpSb%IkrO4|^93=2`Q6Wa zi08jg5JGU+5j~mYizYW@s6^KybRkkhuI6;fh;N5nPRH{5fH|N?x6{OGbVl;HAq72q ztV+Ip{-$1Y=gy$#1_(Z!(NXwC}X?3-pCX#zPbx#(2dI zdf%X>cBOuGzZtO!t{fkk!TFRQAS^zmVuFOvPHd`Fvc{RBD1!r`R%1!4R5+tEd2vv8 zu6OjXxu;xfO_asbbQRw`Tsz&QH-bN?vvRu)|Q&R6@_If!@q@qC0tv!bdCbdGZ2BM4{ zl=+EuSE8^Afm7|86+VZ`2M$*aRV2$9z+=pmDQnc*|LFsRZ}SUQrg`=b@FgRP{DC6D zJ@yooP5oi7#Is2)jg=|+FJ}ERw1iSX-WaJvqeN>&1vQ+=K?C?yV!%CE5ouSj_P~+I zDEQ=(BN zD^FEdr@+JE{mq4u?SCG-tg zC3a+}E-c%;8NcJv62q6rqffHwLQFP&rNtf9L_ThMX`L3lNd*005W%CuV{fm2 z)$l3{TEk<~66zdYCm0d1R0!cs1xX~G&YVW9Nqc#)>GYN?8EO}+C6PqaEfcDuV^x_d z%0@?Gt2NoIUwzB`l&@GlRf0dKPODnqjU&})c!=4BrW6ajm_+wSCa6$RkHdZqAR5gz+R%y)Jl}c>~+vr$b24Zs(IrLn$;HL z?36Tp{>ZJO5Q2ql<}>751De_Hh>tBY<(&W;jqxmI5F zQVI~n<8Z=?U-w9VbR|(if+-J5rrWI7ueIPesVWpF;-Q3KP!2;O9}pcipUSgkF%D;Z^3d za@1acbnG*k5%+7xp9mB+u#H-2Uz@7mAmqaMoAE)3L9MD3uRI`-NkG0(Oxjg-@c!<( zU*>$<3qyv{`snv7P67BQ@0Y0CbxOTS0uttbNPE8GcmuEqW<v(8DU5hSsQaR?xNLqfd^CWsqMu6p`s0mx0}=bK zb+n4etNnNq3tWN^Zea5tvFHE(8jAGNjs6v#oUaGuJ-{Uw*p$H}|1GEZKW4AD{Yz@V znMgJj_G$-m0~NE>9)8siuUHO%;sJj_@vPF8{r=z0`;YK>h3N&w1J$?odiUeKpm>ms z0v%pYh(Z7x-C>f!1jr`;asU7Ny2}p~0PWeu3tvxloF#y8D#W{-{ngGFg?=&O4plw8 zSEKq?ec%#TgvhS{-&FovS>XSPsl3csc=Qw9(SG}H|AX!Fdy)XTqK+qc@A~T?DSOg? z=aUkyalc1Yj9wp6CosS9$2Tfo|Gq+$#rtIo$Z&IPq2v8Z6A4F$1_MPLAC4 zyZitFU8r}H&>)T?4?_xMHaTF%`rHf+j>l-r!&)B{K*3vxLJ3NeK5Op*Y!-^dw`*BO zv~FiAS(&%;@?Wpm~wLy(|B|^y19E z{DwyQfC+>%aMW4WtKSt6pk#F+VA;`DJT?aW%9c=Lfqi*;%gus%C#hOYR8Tb*^JIq4 zEBh!o0JcXV>Otp1nffsUc{v(L>}NFKd-mk0M7wkpa_F?le+akER%}m{#RavQEDxdu zV-_i#I+!Yp#qirFX2k{0F7PXvT?XA=aSa(T{F zghqJ}ljF!=Bp~kR8;*67cMFvAD39vQYW3?OgQJ7rFAplugQBU4lASMxQth9ghPT%` z10$%L9gFt#ZXCeBj}Zc?#d3fLG*Zx7S5TloL8EZ(U=F-fzx=jz_s95c@sE4khACW* zM;LcW}2{Hyd;1l{Yg%13-rHJ=mpq+_3-#M5131)@I_bGg^ z{B<>!k6XFOmg8H8dN~Sn8)OvHNl0;DuM)f7-Y?aeS&cCE8T3!71qt{z*qf4=DwLoq zZ0%Ly7TxhP?XYUgw3(o`ZHwDVPXMG8&a}g-nI^ZEo3nyEy}O?-Yjw-q)YM7?)fBS( zh&U6NmwQv_>eWZ+>&=OuyHZKA9Y6Gi3v4K@CQf4id7TD${dSZW?h_6M3bk1D0zOEo zcmbu<e(VL7Q)w}-0Yq+eph!x3Tifbj zGI8a=UkTMzn^!a?A(+FDSEn+wU4*;ZCzouza(x0nBgHO9!HJN4afx5v^K|CMhW<0F z3CCdvk{c#ITmQcy)0o--WSY*AHjnnBOaD6YPKW6$tf8tlGI}*wSF+-q%Y{ z5q0_Pzi_88e9{iw&hWR)W>Cd6TdT3?5AH6JMaEGDuDRx zBrM}BtxDrVDAGs>0T&S{hMua=Cv870i9apxfY4`y+vg z{`-Q%*ifU|{Fj=rv^i<{b1RW|vQh(!xr#`u+?1G}$5F9rjhOjNtt3#F`UeN|$!w0F z#ZqC|L|MQlY)M4NX=4XgHZ>LIw)wkPLX(>ZZ;Gou@}m@dzED7bO0AHa2YuA`?L{7Q zy62;s-ex|c-gz`$y42yGUckeOZ%Z;k=6C0wp~ZB^A{@P$P+lTaTA@ttL&$-+Z8tB% zX8T<^s>2HQxqD;+VzVjB=#B%&VCJzl4tLMVJWZ0}G*Dn|@!>Yn*kvN!d{^=!w8EKu z&ald?lK8WPv0EJKk(RYxlhC-`ls2LD|_l=5F&W{FupdKGma!+twf3 zm|Yv1FRr4n(Qrx_E-OV3zF50OJ-pWqGk;FvauS#*)|C8e5EcD&!Ww{h*33ZMvWU}r zyl6c<@4TW;(}Iiq52j@-GdZK3efC;A=XX(*9!iwZJja5N^9dac*;RTMO&0*!!b1K^ z%k1|O$8|=O340nhQcK!1oqpHs_V^^p{j`IZ{@dQ%tj|cFBG`(2h%p1Ky-1x6gU@R% z`5SxT&s+QNw)K1~`S>57CCXIdQO&#~Y;KU9fxTEhI9ovSSiVTxa_^aTGkmX)SMfWd zY+5WBmm((*u(qV1Pd8?lXDwTMp2Q-_G1t7U$p~>(GUfxb)cB1~nct965!iq&h2L+^ z;fJvUAKH$+R7jUxuI(^RAC8kRtU}WOPK!>?zd0>02JEue|BnH;p%MVp)5o~Y@9dloypS7#CO}DX-cOQNq`JQ*z;qPvZMsJa;A=dI zpIb^77L>->wydkI%s47PG{d+=G7zwV;D zprvNd5{lJ)&U8`#dXek%43PYsxif`Oz0-ZvoTzqS9&Ho@H;bY9N}+O$k5}Y?_fnVM znXJf&4*(XZy0!Q;E0eAcwi}8uF#R$0T<-CX-ItVgbj0GiMIvHV{Hh#ucq&bH) zPGR%e+W733WNIu>5P8e)`97%X`pKgKv>)BK=lvsulM-Ir`BZzYgn^f2g+Z`?m$^CF zcz}9BL(N;E_@F^It+E|@1@3nAZ2#FsjQhFac}f*5T7JV^8-=?RN7Rgsok*Aj{Nvqv z$wrTVMS8yluc9@&S83}ANZ^B015G>)&9CutET{deB)wC;ypcwCj$EM{zz-E^)~K3C zGGM|Kn(NruZ|pE_vfP9#kn=OTk)ZqB7%x=oJB6NMnqbmu{P5cgE2c7Xm7dYgGAqoPNANtjc(cY=sEJO@NN3cYw-o^lk(D)k=8X%s5( zv_D9~;y)Dxcq`u;((^hUCB{;5y(f+`-skXaM-ZoiF^e6t#qNz`-rk@MF1O+KRO?-= zuL}Wc$k~P4jN{CG-6J&I%vFu#Tup?|zxkYxB{}CJ3@SDBns{w2RyzoOA6Ch`-(d1u zpM+k_R&-ozef&LuC{5xv<^#EDo*IqL(yo;0-cwimoGLm25};(gyV@lNMbgqw70!}c zTeazJ4|}0MVs}av z1MziynqyERq~pekz`MhF3*Mae^}%tIl(aQHm*!dzzMcBke8lfY^gjlU<|?!YqC2!t zc^)5vtpb#vp45|A==-V4^^Ge(IKuDFltnoo7}fL`@Rec4SGXkH*dNs7V>kK_Iwr`^ zDpKEzG+Hdy2L}mIh~85E4r(J!8bHqU!+~Ji%+=<@Va&kLdT7DF40jdtAfkho9AAt+ z^P5yvi(|3CVMnk|t%OJ%wQnxB?+8Ztbs)ob-}_Dw?7?a!TSOl=h~E7{C$}u(MWd;d zTkEi2qn7XlFf1lI7K1|HBE)f+T-fhe08a726*fyJ3pBe1TX(GX>2WGv25HS3W_Kwo z$@#oUS^+zI(y>4)(@zfUJ3g&Es;abI%k8IwXo_PJt78%d=QW&P8&BiYXV4iQh>R>N zUQZi~Z?9>_Qo{n1XJyv5TnwpkXhe3TVGtD_Duptzg_4c;I0V#u1aVk$$-eO1$HJ|b zD2H6F)$ujzdEBVr+JajiXC!Pie0}U51aVyb8y6B(ZqOG1Fp5fP_x{Zbnc0t=c4g7f ztK+>F-JIlc(kRKd12$qQ^dH%(uoU(XaUykSB(PcJt}UD?#G&0_^{wrM`CFph_@S{~ zFV`~UDT5T7})4r8^hH2_Q8zcQ7crQjZRLDrn*WaTeq<|6SdI{eu(7eN<@#f* z!MHC1V|uX|^{y(~HtUz*MY-L-_VT5`R2tfX z*tLRee|FxRACOjQyIZ{*wC0m0Sd1E08)ULAIip;?XYxkwwWnS(bA4|T6QwA z8Q%|mg!?Y@>o*2Q7Szg}xZElN0lbjSHL`-DNhv({?RW10y{2NAJ9dEIKX#R&;u0TY zM0&l9kjKw2h-_P-AQcC4*Tnpxb+tRGS^`D8$U7{R$ZilN|8K~Kki4`?$PUyp<87KA z+=H>^Y)_mp?e)8>(_WvNd?fnBkea1i4XUpc9$eyw_?85f;e(7A`Vf#rDlS4*ns551F> z60FLrS5@}sRA~&Z>0@~^?!^Def?iSO`@bBzx{Phu%S) zJ4@=Pp;0_q=rAL8-1@(vgNm@GcM^lXRb&05D|#|)&*9`;h))VHl8>^`X{}|I(g+su zga6j)=7h=Sv+BrhVsrTL#ud!X)Wfsn*W*CVf%40qY92|Je?S-eB!9Gik8|R4zJM+) z@`-a4rojkw1pTkxU2b*~taidD*Sp`?ex$>&Z}gZ|L?ZENp;94jYis6!{nH599D;*T zR6s}(F&h38SldJ@er`SpSEQ(nyS6b$9cQTAknZ!^_RABPWnM22X*L^C;;^ZSmGlRE zeLr|UKzqE_6+C4cMtth!@denL2>n11AcYA6=oDybx<+`u2%WA3ijmO~$UN2&&bKMY zG|HIPMsK~l>LVCbs+hW4jB8^XZ0$TSX|yJ&!J5-fq^96Ln~zMt{b4Ssw;A~Hgy{VG z*$q>GER8&GbRMnA-tO7N=pffjeHVU~{$w!gztJXIo&nm#0{8ae!ukB20Ecc;boH1? zv!?Z-2jd-$TjlIpC$mSKA`NVe50AfOK zYElxr=jnzd&EIB@3pGt*N-48Q{VqjP5|Ix8Z+1nEyJ1{*R1|10TY`B)=`JF`?}&C< zG>i60)v&yXD{R_@qa*Aip>SRZ6TD6TB1|ZD3`TOaGyLBP6RehV*>g<84=pXd_Zvu~ zX&(JDiiklilpf;pXKda#Ub7okp2fc{kDGmzcyB!W#DDjxx>TJZ37YVQ@*+gjBQCo6 zozZKb-F8&OBx$B4@=)tMwnJ_w@W#8JU}d_Ifx#h{fh{wr>8ze_-t2-_p+s8e-ZLgn zI~~sr*W?p|a4(VE!wh+~WpsVj+RR9xR=>A_~^8ABAcW+m}^>u{nlc(%&El6QQI7J z;gGa*txXHWC)w<+sd6bfxG%&O>cMC}S9bA}{zqo>w7vraa%+&!`46H8ezzeZf`fv59MexlwPt-LI9q zGagtqzFxA^Pj>j^=J$Ns2R&u|;i9-h%u-3|y=<-yk>c-Uva|3G2s}}l+|Y*6_0f%n z(;ot#y+}7*tUn3}CzPKZdwD4R#6PcManmwH#PS{HePC2Se+-YCjlhDJc6%(Zs5p=% znsyWIA~5`rNHbVr)#MTj0%XF}G);@DHZOv0%69%jK(M{onMjM7ylYL+1xFcnEnCQa zS@y;C8INlV_scFa|dYXV&_=ofmj18i(dlnA9i&8ao zr@anSl}h{E?1Zu=16|S4Be5;ajzd4AEis+L@lM2Y6ED56<18pgQ3nocVZkfMu0;BS z)W6^jBJ`wp^->r23{(4LbKCB4T2jeMyO~TAbQ2C+n@Im)8HhceiKJ7sk|Om`qAhVV ztqy>7Iq#36y$b+eo)VxxCoKKC3!>@ruX|c{=!~Z0QbYlf-R}@4L5cq-m?7?d2wC@K zL}!Ar&eg9IPW^&!=E+5}8VW@Xf3u!%V;s>QS3$xnQx=T>7oow$Ky1&kmd5R16;Pt3 zxT#L+Zxsqpx;{(IAK09v z!D|;dPdx#g1UZCuR}?UU%~*(_aJIL#;A0u?p=u57)_u3@2xU;qe{qGqSFu@Y>C7Z-MKUM16l@CA{Rll(OZS@!atA*=oJ-_troC zf&JYE?_J`_vuAOAbRt+dSZz57BQohCD-s>{;pH{dK$D7P2qX?^T4wpG2r_y7Cxq>- zv@=4_9;D~N{TD#MxJ!GOwL$h>_1>A_hZZ6q*Wj3^TLOcz5Ug8oAO9jlJsHV5P$k~3tgmzC2bcvCI}E^g6lE(B!jbsM<0RUij+9jKAQ z@~031t3Qy@KXi@nl9%-noDd|U606{TR5AaE)J-Rszj{wkJ8+|tBJRI|vNgT&vorL| zS=@}YldBpE!(xW zBV>yn3IWd59}#Pqh7A-7(J1Pu2~;m2!YYERg+XVO05NFUJMO0kU+%dIxP)?js|Y?rUY6CjVnHP09?(YT8D{ z)#YixmIU^Ce_qj@ih}n>ODcaPPv7hl3(BqQ^-iSG6+q$HP<25@E7YhMrADlPm=|Hx zUGKDNQMULcEFK*UD2mi}58t}?JM4_e(P}k;Lq1xDAD9d})Z7kyBu4DHe`4N$ zH~5b-cOiviWAdkn2)a;1K4VQ6PIoR(FVC2Y(c#>$J$(23q+y{9s47Tu4|p;F*QzR5 z@asBC-s4)l#a9idcRhW>3hbymYRih82~Tsf4@1%OaJwUq@h}8wo?P5NH>|HKm`_zK z4ZEU0^H0U0?5*iyVwQ^Z)OTw*F9Ul4&)u7s!X{i!_NqSoWQe?bIL_w8T>jYe99j?X)6 zQBm1fx*6GeXKds<=Nves8YERT(o2R_T)+@G6M!=c>MzHm`C)ycdwv7%^WVsT1;ih_ zx(aVP8>0uUiA&5XEJuGxn$g)|N6T|)X)s7_#&7qUGsKx>+>-IQ*qXxWjVpV%O^LkbiPs)Oq1(7q>TzRZ)D3 z#1PgzQ1$ZzujsGN&lEpzea0}pZ_86cmeK3ar1DY++-va-UsPL*zfhERE9sW5Q|gBQ zEmnPEOh-cdISZ-e9{K}uyTD;WPRIC`6b*JnZy-lrWbPZK3G1$kk}*ijn7i}@f4;199sk1MP_Ksm0LO0HMZwEI zsHIcG4eq#Nn^lo`2>1Q`*K98#PnK$31ZhRG)TP)a`;tgmQj*ZpKV*{*5jHt;={Pc8 zTrQ3`GcU)h;6CG%@ZP%1@i$`8@YwNn|4Y)}NI4eq@x*&BR~Jta6XzMwyjA!4MZGap zv=3KF7QZR&L2wF%KE^c}Z1)VYA1n6vX{IiMU7e;-4d2;k#!UXBhkod}xZovIe-TEo z5GpLEdw!_U@|ge=uk_>O7y}#LRD_M@zH4Xs#PoBgl~EvKLiGgfHhLAxcbFwuRJ z;h6k=j135goy2bgi5%LrtPi{;T1^7(%r;+o^Y>>>na=d6zaI#Pmet8MNn%0fEAVv0q6eD@|8ZYIWo66aGgP zJ-6$?@=~i)Wwe0u>if>8mZyRaLM1KKa6eIs@E=zX=BN@Fv9u!i}eA)W8IB%Bx-jC290e zW=isIjl11#XPc23?&=cZh$0WvihWA+1Nd8(nva5V^EGBv=gNxBRjD$aC9ao!Qzwc| zgX@AIV;gIJF7>;u)-nNWiP*>Sk1o+RHA}WtbB0fKt0r4cxZSsvcE@wTAqQ*Wio>B8 zpi#ue5IruYz{Zg9OO1L>Ug#%ckI*%jz!08?5f~o2$3Ofg(4%;aWupiKh{Ar&+q$P7 zK>5KN_UES?5szJhXC}ReHf4j5vx4^J0&bvo-&c~)Cw!6iUsCyxdV$@nVc{v(@9aC6b@{pH!V>O} zO?Q3F0u?4!o*tYB*j`Qm$x5k|+ryulY~LVo1{x*ff&!?B) z){^fB^}&MP&{>vX)eO5dY197WIHEd~k(=Zk=2q(bRoOnY0!3CF+@73d>n&?&#tIupN|pN3DSg{z*{KCOUA)NB$M<{n8udi)DlbMBnl z>AIG;t*AcIxV-8#UU~HC-1$8|cWI1DooiD(En59I!!eay&3R0%BjUAk>j#3(w8YN) zYERAQhF-0k%HyqkN)=+RU%nMN+pc%OepH%EDVn+dh_)g5ujRzO{Hz> zO3vFj@FL~DO`FslvNh<72w5gmt2(>ZGD&fCwt3vcLRR5Lhnu^~O2WaSM0tvw_t2{y zG@9awXT(njwz<`mr%nrdO?=-5)YXws@`-e33n!J1k+`LH6;@7aJrZBlPEO262e$1# z_squpi(}IaaBLpmzfk_J>b~-|8z1qhn6BXLGH~fvrV?dFeJ@RJNSD;nUoO~wpXevZ zDB;*6rEQg8>{HkHZ>f4Q@xoMv*!rE`Lhv~yzcmRxRljISb?16w}Ki>DTw-P<(HZadY?e&$FX zD=R`kUCn1;o(^UkcKJjgy`47~H@iotT-)@t_(#HPXs&d)nxn;~Z>z`gX}NWJhQaH! z_G-vtIXMHH@A{xajYB)-L3cTCIM|)+>iAEh)z(Aa)5KK7vseDFr+&`i@m{B#{DSI9 zpn`C6EGD_ATfh?`9GEk@cfB9!l*C2Gbx|}d^A<8B5N4#9G)uqSuxZ#~(uv!v%5JiR z8hPR|r+dAK0$41c2_~G!vwx;BVPICcW~~&h{}??WST4zTX_{<7n^_iLxLprf$Vxh| z5iXT*E3;Y;c|Lx4DwxKY8TR&C*fL5QeO6bDQC>2iHMI%*r2D`a^~)jv4Tj74MyQVO zH`7mhtD*Y0XTdmfx;7+1L6ljsy&pBj2Bpprdxs9JmT0l0)=4tacKZT0HsPN!h>49J zT^+#BXhaR{PL*eO$KNZErlU`lsE5oj6?xv47BKN_?&kA(MM3v-KRP@#A5F_A*M?97 zg8$A4aNg5?oyR+eO{~vP;oH)2=RID%WSEWI;ds)@Y`T1vaocuzaVK?M3=7EtIopd7 z%?0I_ii^i-eez!Pg9}~|O)`JCw0p`wiG3ZGOwFD5?Zog~=wK-62T!NeIoZ%3XeD^W*h zX75FZ%}v`>1LMcB->=BaAg_#>_t0^>;yp!>uURGRGDs|gah<~EyZHFbct6Ychrl;S z5>I^G&oAJjF^Jf!u(38(e4K@3W?lthzWdqoXquKdK z*D{-VeEx<dSg69XHLdv5g-7$i<$3NX16j8~6X?^9IHj=WVsA>yuwgJZGVsU%BZ6`!lBs>!&gl z^Ui+18R>VOJYcoOi|f8>gedtCV`GIuZGWU_FF#+-cz9^MkDG1xzqOpJ8%I@)d2Ia5 zpZXE3_Br4LUv3sdPyOo7tfgYGRqGewn=YMS?1Sv0C~v$|iB|mV{LgF|aG((hC0Hn7 zoo!6k>XG`Ge~bBi`$8yP%c`T>&#I)?6|iZJVh4fmei6fpI6F)O&F}r~8#8cs>fRNe z&RMeW?kJ(aQ*`>h0V8|^HW~2d-sgTjF(p1;R>8hD&(RnH?1}u_{@k+fC?AZ1HkkW! z%VRe|!6d|`07U*|=RzU^bkv%TQ;jsiz9GCqK^{c@`r~$iootSj#cULpfY}ND8qMAg zg#s)D_l>B4jUY9psnBRx7CN5y3Q3x)?rJUn8;HMt^4YxACf!_P@nF8adFAts4+a8| zw`u6)74ad#d3=BEx;HQiQg3*nXtwq9D@$`@F+Iva)gEhM4HB2Ki#ScstK0U6-H7qd z`;4Yb140Yudyf3E$bbLK32U&oHQ0r)jeOdT@vK%$!T_s;$gUPR5+|ysawTGu$WDSC z1?A1#zkG84K_yEPT2_Jxjx%=vDrU#n#2*H;R#n5N;%|Kcy>6> z)jWp|lxUaGKW>OH9Y61Mw1fi(moXGZ{76{8%Cu(aqwqhaJ~U91U$`xH*if*c1-gui|!Q{JHa@N$bJR3A*a z;?hJf)sv`KA65g$9JbhbWerLta~DuS%FEA>!VmLU%D32oxZ=4@NDr6HWM$^igOX-q zMR9m+Qzfs^WuKiG9)0Mwn~7rtD&&}{n3l4UjuCdIlX#O`eu6;sV^C=l?kGV5&|iB0 zYD{mub%?&LknnQLyItc)HaUn{9G6cQYjVkGXs{&lCQ-RRZ<=1#m@krylYBuKIlBln z;52K6K29lSC>Oil3p1_Io|SUfK#)vfRVoM%3(LqlL^FjwMZ$uUxObd^{_A+WMak6y z{KUoTtEi9~!)QkL2ozdl>OjxT&wqdj3>3)NgttA~~BQtM)}Xop76R(W|7RIZjxr zzx% zl&{BWbqg|U4bK+){RFAlbEiK}P(j^;`FG#NPsk2KcoPsZBrhhGHznUVlrPn9ACApZ z%0{PEuJ#3dYlVOcZ(dH}tFP`M_q$6Kv51py>fO<35-b89Pf&Foc{*y!@K8pHvQ_%R z0$AL1vqu6b1F^%<=LkyZ7bd#&&*j<^lkcc`REW;ix z`r*Dy`LKS4pZ;|*6-%EO=~oXgV8xrW)L&#Wixd6p{{TNiK>jmO@i=TInU|fi9vr5n z4IgzE80TtTu&RucMZ?|=fqQid37cxh1Lwj4KE-v{N!skuIbKHmcU{s`EYBhIrNAq8 zmLL7nO>00su#|+0VmU+0AMsH9!G>&v2(*INW#H|G+^B%kXG0TW=Af-EBQ-A_bJ^$vEn=qQ8K>awo!C z7+?c!$N6MaLl@slnSPGPOo4?m5CM;V-0~{_EIvci`X2`}gtr z#*gw2m_Ys%W;>}`M<fE*_u%VW7+$7|_U9Zb9l2 z5=Mpod|E}TRUaKqt4;!5*m!k~<*~?f2mXpbg<*VqJkSfqJ*)HnsJX!^LVmGSSDiom z0}u#kHrS{BKAgW3rs{<*lcH5Nth+uEvkm6^>#79&*e3Y~)2GejiP7zqMg1)bqcCtu zc4^wXR~{aiZ*0JP^SOV}y?X6$2z7$^TQPj7XNu?I<3Hhezv3f+x$7)UxDq5#Vi?^0 z>b>58@e-i`!V8x=gC*1bhzx#;|KU>ncQCbjBN?-4A75?$w{O}o6Q|-OJC)sNGvx*( znvKq3fIe0bkJCQ?l>77B)@;dTnL5VH!-+ijuC6ZVi%_K!EvjysoTEiIxzC^F_X0RO_1k&>0{-=ANiQds1_aPS^PN@PrI;E)H#^mk{ zA8}>{Bgj|ZDk5k#su15;hU@qAP<&?E>2eX0|BD%npncPmk?s(x&&>^8ay=)oKb%wa zpHeQ?2=FrHvC z2(C6r!^u37bsV$h{>_h2W4^Ev7OvuAyAl~+eq}YeIn8e9=iI$Bp2=nU^`3cYJ@9a` zLEQ|ECK|V5axKlrgvIdyf^L~I%=00)u-}6FUBw~y`wrE`K(rion$Lgr%ls%WQB81! zN*O@r#{N^_uP2ubX4H19p)S36k&Lg|*KWa$KSXeKBh9%gGQymi;XQ z(xRl#u6Nj%)ssUdBl|?6^hJrBdkV0JuZx&;YH(hTxAq&oM0$Smi>{ZsF6YrK&L@mH zng_EL5#_#qA83SJ7G`SM_ojYPH8s%F%dMV9?p$9~>OKQ5We~&sXJ(EEJucnTFXgsR-lfDDpG|OkJAxVKuIoB zFZ3E2uAt2u+~0ca%idIxIFH+9R2%4PX}k?umfUD|c-!w;M<~s@q%Js?`+Xl=>1123 z%Y)gT(v%Wq`WOMDdi!0e{i))!okqKrD3&x8h4yJ!hAw6CSjFbYsqy=rxhk`Z%RUAJ zw!(+X8sD#e_X{CQ5u1gbj@jImDbQDc3491=U{nTTzFSO9er>j~ft{0JwS4$-5%jsJ zRqQ*40YT&Q?`-sg#JQ*+A=rYN^;e;EDylcD(8r?Mes}aUIKf$ADtCPrKM)DX_=?nO z!fv;RjYa@62K{){qwZ#k++AlEML_Q#&0Ld;t@1yEXSNC1g#ix_6_D|Ar5^X_IGpC0 z3Nxi^zJ4CmIAUsZym=q=XnNm%mYw=?qpeV`cPkfFcy>65%hq{I<8a3m55zzsnVSSL zWpbfKJW-#OR8euN#?`-i-XC&iQ2%f-oPY1Q^@SW-W_3S|4^LAiea>ln*JV3*2}IS4 zaI3aUUkI9&v(14yT9X)95YcRKjPbBbS-2j}z|5-0(SK@0{u=%$wZwKV5cP}hFDr`g zhqo$#mjD6B z^qSNp)mLj|If`@x2hWd>207!5 z>WYgG*^wE}*X>QKazKx+BE!>2&c;umoo+OGwRi*{#K%xRU&Lt}cOYOh1}u5>*fJQ$ z)%(ug8}ChU?Of!c+0I@Y1#gXy^F2a-G8yxYhAB{~8n{6!8)zs`Wv(|Ng#AklCm;qy z99qfMZpUsicXL2=<5j7s&5*;k>>TxU8`3h01a3xA&7$A+p}$t0VwMt;BZRIh5^^Ps zq`EH_Sd($6A?p@Hi8@?J$mDNm?a7=LTvB|(Lok@lWwU&veodEX$2917l`B_2RKzIg z*0CFhmT7;kt{A7;s|~W5uZd z^v3jNa-vhUs6k3FEs1a`eiJDvDQvLt{$(!1`4;b*r*j=Q&DQOmR_zK&-pZE21MLBW zoEN

v!u3U^6?(}uVoAwB67RF>KgYa!RG2Hsg1_lr;-q(7@6)lCI^UooF z{$r|&W4X+9-6P&MJ4~qF{|gPI?9^$_<#cytfG0iV=INQtTKSFv=_w7}QB62ZW}19E zt}aARPtRnplFOv*#G+UH#HEfKo}s8FgpnTp1o|&2!RMdtBCK(<_`+O zVo>eSxB7fbu#^zgh|x>Xrb8x!MhFh6_s6FVk`u4fKL<}z(xm(%<>p?XoG-W+b?6Ne z<(0noDpheh`*4J&)cUu@CKvW45_Z&ozx3DNy%3uz@Vn-AkzU@5ff|D->>rS2DuGdbyrTKn>esvy?P2dXBQ zHl(`B6qm-0doL45$^6fYWp=gs)09P5 z>a3&b0>3#A$8ik3I@lh&JOaQlUbgOAS`fKIGMmgVIz0Q3I4D@)3-LEM1_MO&kIuv# zZ(!BuPHkuPba!)nV;Gasn_*O;f_4gy;6&;bL2a@bR#m4|xpy)_0#(Q6`^9G@)STTP zpF!V)*>On}&S$^Nw|q^EN#jJ*k~)xJ>b3Y1eBK)*P@T9?ZV*vn`QZ$Ry>@bOzEYA^ zG4GE8d+6HzW(%s*@TXq4Se@^O;2`t79~| zT55*F?+uShCTAO62t=QMoAbBW>d=p0k9D4@b%(SW(qi9gauUk1Eb||DdW9IA~a(=-@nV zFS3~|H6nK=3!|bX_?7&XdB>_3P*;wyPPs1}4XtS$3d7;$(XV(@x-??RuWz`quq` zFFM!+&p4K3l$7|)#V>?uH8R--mDDilXlOQVW~AdR*R>H|xvdz2+9iDlvzbr1^MGSs zwvR=(cTQ5^8Kls+N$;kk3BNz%$4Iv0z=kq?dLf@`)xIRFkYP7FtqUM?oOK^Y~3rF(fIxBJ7Z)B4KvuyEFzv*xaF^YH?yc_)DoCA$kV z8LJCjUpYe#r;bO9)BSoGuub+uAhlDe{XWgxfO@hsZ&gkp^Wnqmy!P0O_pRH;1Cd4j z?>{b+9P3sjDnc#<1m((mRFnEQK+*0mg_s(oqj&9)WRAI7%F~Z=>7?g9W@6kgNAor1 zS#sgKUqF+NpMi@?U)kdUzx}3&8)U<9?F#EdMqTUtg5S|H{i2mZKl=ZK`n?8T-U)gK z>N8YQvfZ4vN>=I1{=6OO{potU6qKbGzayV?{^02g0hu80t}e!Ur6Tbl)e#utPCR!h zxmz&KHwYiC6eAHm6`{~|i$%7=BFD!@@lTPt*UsHh>J68p2*z@09@hBix*Q#Bi=D_g zGuCCP9H2*g7pS9 z@)m6E*7a1_zD_zgh%d-7SsgEc3=f&jL7}G(R5d4g=oG+zsPY}ww{+RS*CIza-tIXQ^d}|!`*-jz4q)GjCKe3#Y;G`MMa4nxM(j^NTDvtT z3ALP^d5eWap0O#$7L^3}a1+7$&xsUQ(+`Zd<97!AX zkse!;{6tKkK2%_X#QwH;eFVS+iOh`g+W(SB18BwP=UHxvFcPw4j9ZTXf5#}odjKN% z>a3602=kWH;a`x4HUJI`n1B287r68WSPuOM`k~63dPu?1Lv%|Z@UKzzPP%!nF%(ns zFGUpKg^lt6I@EYz^MtGXsmHfB_ijNe{&i1061;c!Bj!U2s{iGMBB4P1k>V(4E%vWZ zx#i!5FyIk3?38;Jz{{^#xn779>8Cn7NN z%Bo25``?z!=s){h8&mGY zb)s$9H>D`yW2z#HRu|qBpk|<;q~~@VM{4vxPsQgYXd-~^>g<|Undzb2j=^XyBs2_X ziGiIxB#y3CNvho-AM^3^BKn_65Qb7cz0~cX%Myw|`EPr<=KknGKu z1dr?Ph9N7DD;j%~aSaIBKi7Yj16qN0HQhQ;0ut4i#7g1Lk5@FEG@N41L+5$KED}{Y zrw;5w8n0Vw3{ad$>a7b!FY6ikn3R@_ZAK+D&NeWrQ5&g+e<~ZU1605NlYFR1-dkM! zvC)X0Ih=)k-y(Co-dwV)yBAh=zun+ETX{Xpert`}zUY5W+nsv_kG|#U4P5`GpWzEW zI0!P?sp+-bJ~N%FMLa+LGuH`!VYt3B*eFW>XQo=F#%`5~maau9H>%ga!5=B*uq&0; z9bKqkpz_9kV`k2@GQM&*^&pY^#zs2c1=1Dk7=c;ZR~I97 z>i5b`;)Jua$uMChu86yUG)Sg5u1z_foAsOhA4NX5ZM?+(E^N#2Ecrr}V%aj&?ryGr zk__!>SGW~TdJ8`w#a*J3oZ0sMV^Vey1 zM}I!#XjZb(K7kiFZBLXZ6?}qAZPu-=2HCnWBt8pTEj$*Z$k(h){?&}+mFb^eMr!x) zi=Hj=dkSi5^L$vk-kIeDUl7|9ii z%(Nw5&-Se%pOn|}JF!fVmHpKJ_&{GJ1*ql4>FpgvGE0DeqTjOLBXP3W1K(x7G86O6 zCR#bFK%DY2JXFU%?ei2|)kEJHOvAm}-tYrbLxXKVehm0#raXMQIXrE3Iam|~6dg@% zosWJIa|gcTJWQz6iTxz^7U1Z~-i1+|^?LS4*PhPvj54<_)S}Aw;+^O5UhudSc|2-9 zYM4u4KAdC<#E%LRgot-Hl!%$UHXF#-#CVJ9X?`Yd@wBVEwfzSf)sz*bQJz72$W@tB zr{^wB_4?nA?5#2UHw2K<9Oa8gBDVdv7Y2U@lxS?4wqG9w2GRVj51wl=25uuMssx# z_?KbrzAImpM3ciQB#Dur8|zO`=7$ravP zoQ)9_U627wa`~!JZjw_{mOtrmNXP~Qn{%69?b&}Q`<^LFoVMy5Hc{bTs7mG)$%O}; zBL5x2I0+|9Fg~2T_#SC(kslo%Z|oC*{{%om?VUE}Sf7#%H2Sm$BwiwBUHz|5QF9rD zP}iBv#Mne#QRMqp%6=c#$hH#%U$%qdcx|1#>1gHo5e*z#h zZ@GXHf0kN<;u&)$78KtT^PICYHFe*}_j&Kn7yX)#;^!NrK&VCIoa|nQ<2b~MN9Zo2 zNbHo9gtZ|pOLyG^XU>nQ}2xXquv$9!~nK`a(z?buCEf&y2s><+)b z^2>j26%vYgnK7}p`~BGtGpo#`NK_#SoID8hNkz1C2jFWS4JARw588rXFsu=PLW3e5 z^B!GwGovya8V>FOaHd+Wam8#2{?_XZ9b4UB6Mzm90N*h_&~BBKYoK=Nt`8fHhYn)5 z=B<(WyWFC0Z#j&MUMi&F`M9kV7c1(;ej!+0!JGQ3R%h^I#yDevVoe}ly;nAtD{zi* zOm6#65eU1pz>poM}eOx7I7+)r^eAwQlp~^+vsl`b*l)m3wp8D;K zNP{W@WTDtGrd>A@;~O28yShS33!qnifric3{!-h$PGILb`g!ia-Gt9zL3@+=xH)8D zE1y+bmB(?Q`BN8h??`XAd?8Nc-D0tEGxzqccUR}9YiDbHnskyuI9=1gUg$6)Wz)%^ z)&y-D78IEnEF#_ete_?81>J$j`5tHR_18V$B2u@#Yf}y7(jC=D%&Ji?*T!-7?W|e#yngrAW88yK<<@ja#XBD;|!hD*|GkjVVG23LT`F_ zle5qh5Kq}@F^?9DpGt}8;pfOBGyW2h#Y)K8=Wb9DSgGUzo+fSyCfSHI35;ni`{}Mx zs+KQEOts}tBzusr-Y#x&dU)u&&i$idj>+=eQ7avUwiaoGcMe?ePIGMOI=BMZ7PUuG z@7PH5^wkvX8Z$j!ZL1tRk261rC1k#*{#-iZKx1m^E-7yeByW8)S<2M%bFm( zlTB^7B*VAkF3H!0yIRU7Ek)O6AJ2HpG}!xU0IIaoPv&BflxkHmKv1rq@2wb~@2`|4 zWkiBK!@fl>y7$W1L5)-8r1mN2R15)O zzsVd@R8Sdwc<-O$ zpvRjRmJilNAZNmo9tB@0H}2d6&!#44Gj; zhN-I6dAZl0augDB+{J*eS6q?|H2A?aVH=p(F=D_Bls36keeLRI9gnW*db5WS)Vd=qxc}Oq zLhEw@c;Ct(U@Fa=UgP{&;&p~prA2mU(h+>O&ZmK8$pY{A~@G3|g56ei*RJdWq{z*oFQ^&5-+w%ZZ7Rp2cz z9XL9Y04A@Q_iB=9`=`G|uEF^3mECC~?jMm40iUFL&v&NPeO&hT`x6^vY!oenD^_{( zuQ!fX2ibpJX!#wLoAZz!Uu zE&M|na}BJ9zKQ?XFq+N0PEFUCW>dNz#M&o;xkZn!L;7bSYp-=I#hqlT!aa%m@~g*e z85ezy8I(Kxi@qOqdWqiN8Bp?AfR{Cw;3MPog*?wi6m8gsQwJ9Bxr>c@!UaESj`ga> zWjC$sh>79mXysOHi;BO6tLrY(a@u>EjXRV*8pTI9EMe+*^|?64j2+E3=cV|hMiXUR z3eNu}CP^|ce^E0>nxu3DkkS<94Kp?X)_DHqFF(Y{P#@0Y{lStBi&|;?{%D}e{of~+`cc) zT*qoX$D)tWHZs_KskmgnmbErR?`J-``b4|B6K)VV>P1()^H_nU;>sKLGG);-gK6zE z;!m_LOO!M$rl##Ql>tDHc1{{B(Yg21 z9Xzx;W>NdcBnUsZlmeeEN`uO}Htwr7A-O7Z57<897Tz6z8Kf9%gF9bZUG^>2hUTVc zR*aiTw5#REmDnDXySYMugs@CU7XAqlVYep#mZ{U zxtldAV>p8_e@w~j4umyS^@{c*8s(zH zk~a!T{H3%v!@K;IS_561rl~0}Fp7jHIGWLQuwGPIzU^?WjvsSdS3)9llp+bv$ULAv zg5&BQ3p2F}k!J-P0^S(DLwVt8@&j7;N( zEz2bIc)$39D*YB1>^Gj*i!>qun>@%PZZ)gqQuj56` zk)vyVv7sb#odm+N9y8b>mMNrt*4-+kP_%Yz>J_tUjidXY`xkjQcU5NaOLva?gAuLe zR-pLG?UH_une{u2_N_youZ3^HZhjM@iKw!72<|>3eIvCc_QlI_9vN|cFkYFl`a(3` zdfkb{A&-lMUGHm;e#Ypyc^<~Yir|aW+9%}~Y0R6Z#M*RAdTFnv`9>p4s8o<#}GlUeJwYA-| zDE2qIOpM3C%g4pS?Lw@4q!QU4T!sl)>^R#ywgWTnD#+YUU{zoG)rlA$_7Qasml`@N z7A-HE{KnJXj&bxE|5wXLfMOUVSXmzhL}?p4D3)}2LCtL0(EJ@bIii=RlS+<@srVYP zQrq(UQf>*C+X{LWWXyPx_uLxky8}Ga6%LL!Wy>6sTG3%$wiUDW>#yoBg{(UJJHtaT zJdAgKV%?IE^Z^-UXyf?xaY{3LDeW9J)~sB;OFCbKEc8`^!;Vz=^)=vMCKnW)hkcED zVfxFqx-qdbv~VOTP89apD41w2Y3Ld0uo>3&ycWQ%y;5|V|%B*vAFl1$XlQJHuYs20W_isC&x`d_PS1l1boar8t zPcKPW^_axUoD1xWF9z;QBqCA9lRt?XF}e!Lr@t;5DwjEXr{ZxHL8Z|9iyDB>CbIs%d4TdGmla48@m*qNu}bgbNlGrR>Qp~Mw!m? z@YrJ-Pe|3}DfvwNE>7UraR@RoMd{~O8%B4%5NeTlb858YTXaJa^MkvRG|;OR8GziL zzBvY)1~3`3t8&6$0l4hVjc0`ck0+?zEu0$!&qkPUk@Xdij<`|t~S?0&7~vEH{9;oyv1LkV#zy@t|?h2 z5y;}{z3#lClCsex#`}&uhBBBiv z3eAJ7t4PRD%%D&Cu5$s97LB>Qt%aEwGO+`3sNHyQz|`Bu)7qN#YB`FOtTkH$kkOR= z_CVCyzwg3^J1hL=7{dvrUyqTU*4=?WO80!0K6V_b0TtoRZTxnkLbDdJZG@ zNIq(4(A_I~bHQ%MEthyTw@jGAN2s0CcJ6I#|F$uT2H$)*GbCd} zgtwzfT4!sdK=fjP1A4UaK?{g7=y@O)X!($ag0g!C8CA@SwC(GqHXCcbHh~0VZnEJ^ zTCabt8ch|WfR|Q}$Ovevy~MbMH0PB=^}Iwnp#DMJOlC%2@_e0t0CHxQgcH~@01i5nvuB|S|!InXB; zem}e|d-!)L0S$of@4u@KV}EmY2Ys>1{bEAOEaef}y&IC@l#MV&YwF|e74{eZonPNX zAYV1n?vcBtCs)11$9tXnr$Z?)Bn#dsIg{!qbqf~wZyY}z&FsNO9lPZ%>EeITa?lO< zs;2!pHh;>6-I43TUjhH;uRh%HX~Pf2IRBSFM{xtj`@I^(zwI0T0S?ff+!doeS&U_3 zV}&&ni)BPN85GV=MJQWT(e5BC=>*xvCn+y(^B0mxuDZSeV=P2_B zd!W>qVaE!8gXy1N-te`3Y}FK$J}%`ZV=ZWY zHU_sul>ZFPHv+HC+(C}c^Ra71J>G45zDR3v4^=DHOfo+fX;WDTb<@%?j$E*g&9Kep z;E7Sjac=4!TyvSR&f1dqXa+w-)d%vq4<^zWyqaQa{l8GPQ)DSuSRS6+U7huzUCd)~ zlyjbr8LN++I?4i{L-%5o&;u<#S~*&k;K5?G8{}lS7H%|4AXy0NNlozHYVkm)e;PQ* zhgvc3PM_v3l-GBWG(A6gT){2ievOgXT`f}l%RZ}I%|;;AINkkq{MF@>d6_AM-EbX} zwiE<(BX8EgBU22mDXaBW(&Q=04kG*Sq5k(2c>TtH1h{cG$SrbJt&4APhAL`5$H;b! zN;vHfTY{725%_rVTS7xyFzO;TF&M9U@HL8ta)>Vf+>^e4dR9I1+66U|Gv6aD`JDE_@empgZ8ey{cE-!Z{0N?! zIwgI%a9Dq!QIhiW8MH3_Wz1`KZRsssl$KHPnLh0n1o~N=b$QFYH4P~-bXW)tBk+6j zaeXK>Q`4u8^o=gK=~_>fb8{poWh?}@uH{T5HlJfK^Pa;k*UmpRolB|TW=iYhx;dGL zFK4N;)Yii4Ok!I*U)Fu zDoqvR#!=MwkF5>gDUK+&*Xvc0D!%t+t>sPJX{7kO7Zh54yF|pfUnVX311YJcLK14k z)Sbt(>gqljfi2KJb_;@lhGm|)PMx01t>Z3@V>*WuNA{QSh@uYWL~-{SQ%XSH0ruM-B3ogD2)1dTOCxWZB<{r6+zc+6CvE^j7Gx?yxA* zc-PT@(fG;7L2(56tjSGFTSx9w;^&JFTGR6)&90JF!A9E_m@Bs=WdEEOXWxZ8m>&`= ztAtN+mtjbMp4c8QOMIn8xvEia$L~PN7NL=fZ_AA|x1;^QuFCwb0J$5q^QRtEYH~P- zLrffZctTN2BShMJmQ5TGF*Q~*65svuZwt=rr2^o@YsFH6HlXl6$wss@V{>dJUwe=z zQ$B(bFH}yB=6bJWMavJ+VV+PG)121?+gwgHv1AKyjk5n$qyZ>2R`7i+irc!?BfqH3 zk?+K3%`(mJ3dq^fO`DZFO4r-O4ODi)Xz7zrah)U>PL8kx-X`ik!S0O_8vfoogmQC= zav)=gT&JzwW1z0o=;- zwntR?GoRiA?XNRoh!Q5Pc?eWIx?m=q{fa7EH0ZlVeE2$O@IcnrCJDbhV6cc_WP$ST z?E%SMn&%~fjn&Mh86f`F632B3uJm|MF57r4A`)%#eo8*5t`?mea$(Z|E2~2Vp7@&G z>sbOz+7ahRlk+yJ^MKHbPu#o@#%QNRU8dOj+3MZGxwoq*@dE`!f?8Z6m^UGCv!^Bp z10z*k=#q?ox#7RgKO!2wQ$Ch3#)+g?jWYy)_y2CB^tJ zm*Cy!H-X27{wprIry+k+?%hGV1jq^RP{rc?f7`#53YL#=s_d%R;bNA#ti&>yw;;Ly zI$T9!ZrC#~dvN?7-oD6ycf1q*H+zPp{OJp&7>2)mAK*yv-0LgzLs5USXAl1RLhmTy z#NRsHA-Q z+xLzAHYatt9u|P9nL6&@mAqFKN*YVqE`)Y8u7O-p9bu%M6uO@>&h#?5&ng)%(QAA)ZGj#A}@n$sFPU3Qie=`n7?Q>#2KBWUX4kejMHL_*zWP@|p!X*40`aFxW8>_zj`L8v6 z7qFa24yCL#9Su%RrOsAt*1Qp(*s)w;7C*q%{BAK-68`JTy1Y-6&17$I}>x0kp6Dr$+(~S7>5Te(xml7UAdW#G9;4o787!`dfA6f;>@IY zKDlFVFn8TVptM}rCZd0{`?E0a4Fk<40(ED}IU$!Ig`r}1^GM98orQPx<<&`VBJZ{) zOWc3_{7cfEUFuWy6gq&B@&zYr7h&A^0l)O&-T52(oOEU+FT#?Uv zwp=xJ9O||c1o)i(pe6E0e~2#ll+p4{&1|%U*d8%8_(f{YhJAbFgV9ANr=1|@$Ec_% ztsygjbRq*KVHKtMj#+TYH#%+~$!%MoCFt%hM9P=I#u6T6a7xBsky15b@;YK8AAku3 zk3s^Gl+>I-fbd=l(85azJTXZvFg$+5)#2n;TYji21Nu{qp0+Q5v5JGGl&f*F5~ z(}!laEgxAgs)}@CAwvgPpUUNGNtwNn?6lM{LozLHT*0Q;5zNtrUB-6Iy1me75Y*al zXrrh~8!+0E{x@ABdlM+@b@gRXyVXAus(&CZK2&JNsk_gc?1=@l?Gi|$hK{#0HYEQH zY(+(wj~8~MB-xwv8gd^kgvAi851iEY)|LreH{j!w$svbBh8le~nxx?5fCb}sppITJ zs`$8cN5!>tnz~)CWBoJy%+oIW2*`f(J{FPwgYKg7~J+Z}D zb>|eYrXX%;-m}MHfC@yxPAMt}yQ_oq0v$V9_SqCDp}329pt)hda*SneoHWVzqJmIL zYR2W+=Co7zwZ}Tv(k!K4Us8V*V)BCxH2ZtM1$jGQ;Z%D{j)!oM&a#{)IEax;5MZ7I z#}BpaH)kw1J8C)vAwaQ9_36a3beGIb?9+1PJcrk*b5HJFT{Vs)k^;R3xryfbgV%lt zJkQ#=p)d~MKPMm{Nd6VhY$rw277uZ&S?+xQqEyxJ|AmJA)n-}JHgqhj{a#i^t-;(2MV+!_593Ia_8;x?K za9Q`%*Xc4l<@YFPdqOG!PYIWGp`;gmsgj{`N2M?d8-~O0L88WN92FL`(tw?bLsq%N zmFll{irhEKb!z5S(HySzUl4FO#nILAALtV9DvYPy*ewxz)*0z^-lO|a9<_2;x7Y%V z>B6Z!<+XgYI0LHEBw1XbzPhk0?NsLXsuOgUc@2F5u@r(f$k47v`Gig|KLo6va)zCs zz#|~vCw_?4IC*%!iB78Gn>?%k;%E&}N?K}2)jq!XxdQa(rlm-06eKwG++O6*27pxV zR#Hmo^QLmffgKqlq2S$E_7B~QAW_8i_ysA+%hZHJEZ$4%SR4-{QUNz_au1!FE~?U< zvS%`M+UL{!Ef}80LtwGl>+{l3KD_wF&cr;8`hb&N{=8$tNgx77pz2{e-7N$-LN2Qx z1YM#!J6TQof=Vqncb`M9kL}50ct<7JiL#uhWSG7=_UyH|i>-7cJ22(#Ke)J{vK{JH zDUPEtc-~1I+%UyZ5z_8Rhm1)f_&lMX zq)}*S1+`oR=6dOYpiZq`S@KQ@@13Kg2Pf2`|hs?8G*F-fjFf-Fr_w#FA17gSEXv1C zD3VAt8>m^2!d%>H0J5X<^cTn}XKQ5i3bt8)ej>0VsN#Gw4Gzqe@dsXCzOLwgpIk;NG1RF8bPy@e zgu`I&%~$(%=Q{|9t&3JXStvTtQ?9(%wiUOPvhsB8V&!Dlf6nlJt)4<)BXYMoe`pO} zg>t&1iqY08KFqm9ocGbG*k&(c?}-|I(=GwP)A4A-q!WeIL4Vxeea`h4JSMGhOQaN|f;%?w-sDchPlZc%4 z{Ny(;8EK^iuqg)qY2sMX;zZ8=4@OIPv3%7&jc%J5sw zK}LQ<>;74xt4LT}Wv=C`x}<8phY>!)vNUGR>gxaT0ssR3q&_}$a>b!qN#h$)Hra6d zhgM4YZ)td?JyrVNKJ%bHp}bP=SbLNTfEz}aV!f?U)$6Wd)pVR@c=*I_EbJ1iNgJrK z2MB>#FKOFjiy{*=ydBrJokd$IHAR6k-OM-;R&#ANc&9!Y$<(`Zy&94KTK#kUn-Z$= zl0}`@)RISl1G0s3V@t^7{zS=!fv-}0wBrOaJC-eqJ_iD{(3!IYx($B|3J}dLp))EZ zgv?;AssOd!g294(MQZe^8C&>Qy|uHW@yU@+eT&RSK`iHLOi6Jb9L{Cp<7HEAd$^#x zHEP2dXcUL(2h!hOXU~xwz0@hUi5&fLum8}xIH6kJs@paupYO%YkgzL!FO);l*GBmq zlE`gX)*NQO>vP3WB2+h9i?zp=h~Hn-wK5L6d{5v=SU|N_cZ8L1mU7mZ!@)jXP$CE> zMpdN{p3IMD*t*8z)`cJcg8JzOn0OmcvdNSJ^LwX>SHUXCBcIo_Z4QSTXszis;V#AVb|)c-lNMh ztvXBO`_RT?;-*TAl&)7Z*C!u^qR#7ELh}I68u|Q?-1TJDL2bn?5C!pA$Vos6#zG_gaxK zXk^1M^vnL~rvafyBV2%-^HH5+%}lEva^vv|@=X z*->_tgtxXW-EFb1gIPZB)TLK)#kZW|olltz@+-fHn%oJQKx7A@!03LBEoviruN0?MmC{S$l(X0wIysuV z&HE=$DDBdgI12GR&m@;6IRc&!EQ=#HzBn#Z8hjrCcvy`+E5vouH&nZ)Vp*^U-r#gV zu6N=NU0)A6mEWaTSb7{S-1~U>tFY|L8_=Nt2;f!5(UMDAt*+LN%04_n6fiziZ(NXh zBUOlV;lI9mOIAvu)2tLc)?p^HEnURXNg(uwQMVy;yXiOC;;QK;Z${z#80AGNQ-k&JMV+d% z+16+NlV*)rJ*8t#Gq&yMp~Abv+iPCAJ2f9t2g)bJwWckL?%bs*HEHM)Px@ zLK>j0m55Pug0zQVoy^2a;Kcdo8dzUG1a|Who_{|5r+e%a!FTVy4)}WfSR*`SO1|A? z&Enw>;ovj%uy5g~+M_0qi?4qkV~3f8aagO<(^bq*{QaMANF6muSLyxs7LGPR-=ThyV0~1=K%DR5)AG_~n{rlh3NhA(X5F2s?h$=|c z{8w$Uy@ua2c3_m!$-a;>x4I%U(sr?;vES5y?noF$uEtt^R8KlF+;%-^`>|yZkoQ@$ ztA7fh_`u4_(vF4@&h0nZqB`00d6wx7&^1WhkJk``n6gzkAs{3BFbBs&nrLX- zH^1YG0GNIsY2QxS&=_1BK>L45hj3fW$dN|);FF*{PI0pZj?TQ8MoEQF2#mY9AguEWww(OhWpczZk%?Oi`ah8%xB`{m{z|mY>q4E`izS!+ zH4mqw6n@hf{|d(-HM34Za^Cm%(G`fet3u^}#=V8d5MkdD@dxIhr}IFjboqQmC)b)D zUWYOp=Z2vj;)Pzl8TYm6jxC~+*J8fB-#o$YlL(GH2kd_%re|GQuJ3~lpQRs9G;@xy zU9J1{n+#`?O?iN6A3hE`>yBpal5t!csB;dJEk`$!OZ(7N-%gI*7)Q1O%OEQ)7G6QA zyCHHjoQ<5PFgF+F48-18FWkf5k3$$SL`l_*V%|0 zIkndSEpWzR^|7M7VW}s+Ps};xBTUf0Eq`7eiHG6PURD-QI@K+I zVzhF9^;mDsW8se%3#m0?AVpuP@p{gaP!YKjHKZXa^pVrFw7uO6J7Vvxe&L@t%GUW= zd}ihj0;7T|m5oj)-zN|`7eyX0W|^dgoKRea?Q5u~Y2sgAUKasfDSQEyK+dtN##u8s@Lj1ud7lg&0FGrcKIENp z5UD%%yvuxd#~tJ2sKDE|0+0kD`F53KYYIjj_~b*t^f_=H2SwQ}R8;!q+fvtDn!D)G zClJ9$0@I=AUwxP-k)B+euhp(m4=%1+qvt7l>O5a0GOqw~TR_0OZeAyXP`k1bJAdF? zrY^Q(sB3#Z*i4q+$3!yWQ5{}Nn;Ut&SXkoFsX9*!Ai(RTx<_(7;8(b5eE^1@aHIaa zbW_4+Y0ZL83TT&Pv(Fn_OYp= zdAC|E>D-pKAM?5Cy<^)>+=<^7w+aE^uxrLq#6H`xJLpKn|hI^!bt}Ir_)q=(&0epNpBQ&&R$d zQLrl_=&mDTY%sGkXOyJ;>fJ+lP_7wtD&3pX3)#U#&-n9H5iAg`#6Qip>baG8&OsCo zos(Sh`z9|0$?nH+(m;JK)mx>jY{QB|d3t$x4mOx050F0Bq~H_xp8W8C_)qWTZ+w0d zM6{okJ8zNa`{C{T(u4XBn8_!3Vg5ggB{oK1s2qxkxUtA4yz+)?RC~ekA-g2p7Q&}J zF$SDlS55PSQ^)by)@c$)XK9Y6hL?J6*U;}+Te;%OD@~lnoUeUJ8Wbi$K?8h`gj1bM z#VjL0AKgS9Whip5QmdUdUR?CG2lADQ93a+2eIf9XDaypEvhAoxGh)e)kqYks2bvnet@PTky$DR{E&! zB|shrNMlrL9mx1VGjc?Xr_+zSCji-GnXb0ymcFT0zhHKh|GGUx2f@BzvD77K!I)T5 zFNAPcfGsLwaE^lIv(yMXw>dO9%peLj=GBRYLab$tOJJx|qq@Ma<-`3x()NC#IDhC$ ziAc+FVv|i22&{PIgSM(1nT98XYJ#lVE@wX4DS#$jUTa4VfzPPG*gfZdJ~dRYI)eH0 z8p8qmOu%;t@HG1ZY5p~-?!AhFB+o;7;QgG+kOohiB%nO&HE^ThCR{H+YZ6~%n7Qb_ z>YGJRIB9E$a+E7(d0?lJ{eoamXp35MH~=D`isAdjb7_f1O78feahMzc-g>vsyI&w( z^?a$M57z=jOf|CVJHE`hpSr+076j{l&DGa*IPWVxhthk-asPnz^pH-n_D_1m`tvMX zPZK)^!x}D+EhnE^ozwa!V&oDESRpH|tQ_h(ala22Xqg^#BfWjQO^bsAC*Qj+u2}EZ zxz{RA`Gf$KJ4V?^DOVo zI{GJwm%59pDZt;UGIv?)`#I%vfo-3Sa8K+uOiY-(;517X9l-P`*oU<&g{d^3o~3dA zL20`}rq}r-yu`~esH~Ak)__XVL$03?V_yNUqC-`6@}#{T<+(E(8MA0QUl@BOSYOKr zNH2*KsG#B!O5j7TIBENyX7`opQXGF|786u@d-?F?qLLVjnl;?^q-T#6-0xBgsar?o zFSSDfMloU3!dAw;(!5|4NbQr<1oJDOMN|?G5F}!kjd3Fd5uvB@TY03)Dc2rrPAwgG z0ppOb87$l}>|SV(@|B0gn8#bjwte$Wo$SL>ctJ6UEN!i7+u}r+$-M$zfKc>3^*uYBT1!IQ9 z09&^!7;<%Kon5tjz0)6LgF{ZBdd{kn8?|$8_@t4y;XGgrgj6?R>oMpHk~j6kF&dX+ z-g~9%AaLz{aMKKA1^(lzP3M zlh5>odcEHQ{|9s{&JxzfUP{JSRe3qIoyU530RZ=J0N_5`KGn0sBzBiJnB_k5bZfWF z8r(a)@hwO9?k+V#UWyVyUD{8(!yr57dB4@>s^M~j_q=ZOVu<#PtOCY%M*%F*@5EPk z;Gf^x9!#Fs8-gDLjD4<&i-Y`N*PF#&l+fEgjdCXFan1OiMma1031Zi1D%RbT9eI=g z&21xLy&v{<=!xe01>Oj#Jn;HS_uOG`FTlo=H08&^2Oi=74-Yz%`5gz*qoNJedETd` zRgA%=sUL|GHDSXr&aC%h#rcp*@?w2m$0)2q!frL8k#p$9G&87bv~ToNLge}?p@M_l z-O<92(MNFn#L-i6LFDTmfh6hPu%(rtpP-ApJS?j=X(8wDT~eT+Lo!Jw3`;|OUzb>( z@t|1b%K?FUUO{B_LHS|3P{Yeoi1WE~voIr^wBO@WVFK$I3F4=hmnbk;H5GHB)(axa z(BbCu+#aIjsZ^*cs%kZt)=9h0}AM z>%_teL#H8E&Rw{timS#{F-|4%P;YNNj8GGn`QCG44KiP!*Cl#I9#=I7l2C@?;E70; zQ_0bKeCh+JG<0 zjdYl{n?-Oz&<#=8=y)fF{l9r2-(KB4Bf?w^C+YEvigJ*Nzc#3))zi3p!{HhAz5}{~ z&`?o6BN>XGI1LHg;XeVaST)<9Do_5$IQ{GWyA|*y;TJ~VQ0+60m6l%xIIohQ{`(~( zVgT?n)>5k78_FxsQf#Q(pptg&>AHRw(rUkoqK;#yd`a`15-l}=E^edV5tIA#ep|f} z*)-~n+|qHT(~eX48|&*%y5i-Dkn!STYaSvWcAZz5r%ZgQfgwzkKTTZw1!e~moe#Sr zPSfeH`qmG*9Cv59=lKth)_SVfgGv1}awFZ~uLPbmFtU!Onss+f)nTe!JlEsfwt9|b zQ6={;GL1LRm(`gL@M>~%)4P9De6luyEGlo4lhkLuJ;V>r?MVL1KDN}^~K?7ip?H-aY0wZ}!HAfbg@2$W1bUL|U~k*+_9{?+F~ zc>DQRrB@DX7}Wno2G5#9OD!O(Q(e0!_BofwBjN3T&-VZ2HLG9()1F7P`v)I*^F1`U zc2)3L;e2N0WjE?F1$w&!`S14tg^3z#+v}@2u(0w{Y}fnEcewE05r4@^ItF-5>dFR}><@D-cCp}A8$zKuZTWdkgcs8av;W*5j(hV?%m@^>UD z;67pDF9zo!o=F%_+!gr&b0!(AImg@-gr&NxN#Do$P3OvaKCh`t>HpK-TfbGgZSTW2 z-6fKONVBB7LFujqNH031yF|LArMtVkrMnv>7Tw*v59fQf`y9__{|E2>!D}wB%RTFv zbBsC0J??wzBHy|#zyPv(G%+QW+(jfUH2PIm*LryQ;5mX?;MyF-L$)N(Q^LdA{uo^P8ilFga)$B6|A z4_ttO%r-xiB)P9Cd z<9OAfwUsIEv&zMToqa~*gQql^J67vssiNp)(TQWzwHIM{{B2puw+9(#<_UF@CKf1J z<*i|KLITEVsZ4?SQf*9<<2Ble_U<1jTLnSj+xhrqbYnm>uNoNviNJeR$QF9FDQLgh zA5Eu8BsY_SgBQ(?xlAU_GeuW@<##5HoHT^rtJLabYUOs*D`qwA z_1BMCR-;V`RGSmf=1-xD`xok+tS2hXRLHBKpC8P%AODC0L>l$u7#uU=u#|wIm%L%c zsymB5YFmOl@9m>b6J9DBjk&NYeHo~%s!?rM+n-e4EltTLL5GU_$t-c!`MSiA$sN!+w4<@s<1HB(-#crwbqs57LF zCOd~clo@nQW^+`%Oym&xWGyA9!SA`wTi|_&#hT(i^di~p#aR@aFYM$<9~2#b&z}3@(2G3N zoQasyCQi8IvZJd?*GUQ8^p}6tkrKZH{pmkeVKU^#VYODHqVMjhT45-*RVdfNydY|~ zQLPvoi-L@+UZlWGwCYNJ;bls`u?aUo`^3V!qw@Ro2T!?gL&J-#HmUlOeZ`dkyTh=f zB^}Mo40P(rfyI1TLZB3r;6BB_@o#ThBwO znT^L~>?=zI=ZBUlUNx&#O@`?V1KTbwMLFGUVQ(Bas?xVLUrKwo51l$o|I~Loyp2n; z{H<@^aVb|4RShp6gxwiTD6zw0im~Lpg9QDPen-X?z#6{xtlbdFS)w_ne6_lYH~h=9 zH44Md_i(h&0#-b3*JA=G%;w{D-G1A=+VJhLJ#^z5YTfBfZgH?I8Nr=Px&3ars6a_ zwYb0k+>NKnZf`J)_1mbV7?ArXO?!>#n~m=^QRRFQ@~Y!kZbYq*j#P2X6++Bd5K1#s z1(`hq!|bpwiQhMN6&UJB1^u#ydAprxv=3CJV>h02_b!vqu2=em%kbKxV|?7CFN5P1 z)>-$*Vo&^C>%l#y@_43+MoNgl7L~ox%{ZB+l7Xjg{}hTZlI(V08C|J8hV0aWnIIai zSdG8ydyp(ea2J(l%x*nv#BI%KcfkpVz@w;FLc%;m7juSJhPd=;Z?=+&;w5Cx)!Cl( ze@lTq;KrZ4I)J0Ow<}!Sl$8ItWduThaJh*{5#!%qotJ9E;WT7Be*F2V6fP8T19Ve^}6mBOfqj@#w}<^PhC^U1d8Og zi!?bBb|C9G2+sj-=GI1%x^4Hy%K*(eDaQGE6nsUl?{YFB8wDzMd)`7fJjXiyc5~gc zO=`t$lRmh6YFjtAjW+5k8L!aKl2of2<^z~z9AghEk_ry&`X&eRN}@8ryH?semWnMk+b$0~A;K#KG^sN{bkczVqL2zQ8WUuc1%mRHKPh zCO2$NgC3VOL19dk0z{WBkpNu4EWGf<`&0_GM*VWGcQh~tV-^~hrAt!5<B>i9ut-9%UGG(t8a*+rM;$m;unsk3s_cb@DXgcfZ=%olLBM%5k2@;D~Ve zlexvl;#OSFOt6kp&AHrm*!XF>?M0}LdZUuXh5p3i$h^f45IxChw zqp3QSEk@Bmr}n0m^rD4}fhL%?Lyaa_)bPrLQ>X?yt8ZK@?dPO#;{i)7(BcEXA#vbPU^p zT@gUsA=UK;Wu(q_ZoHkztsj*NHLMdnofjO{CO0j{%$}=GIX+)8-w0@-v$JH+)oRkd zy;tce=XD+*B9W{7IEV^tjFP)4`&2{h8S`YSpc)n6ZWp0xEZ+N}=XB+{$8J1spPuvi zu4A5jJqr{E`-(E!S;d8X2CAck$Ra6f#~?BOM@4Cl{$n1)q0Ny!L*b3&Yu^5`Nib!) z7-K5x?kt&LpO}=f(AE~MpKD$sb^x~G`T#4H6`|uHva3JU4R(RE>*oR0ke$QuF77st zd@q$cToJY(y+cWEKjN6AMgzGhqHp$Q>}BR2Zyb6uG`gYq?2s%wvtHU@J&gWucf?jN zK1Y*&`br&qe-cY%2z9bK5E|lsz@Z&*Kkg{grOYFVI!SUm=Haf9xO;Wxy;7hKN4;}s zH$B`0+$jN3c(xtHH_(WwV4D2NGb#c)>B?pc?~XMo`lhrr>u9lRn`IFFk8gDv*fgq; z9Jh-L3v~5YMve{m7yj8As_t_QrXWFbHr}! znw)>oUL)i8k06_2^xc4S&B>UJzq7G?UyMKUwsY7jvz-lmnqOv|H0ETCXEz4AKR<|8 zynHz%$@=DbHruk!{i3vp-_*6PrgwQ06V>8X3tMW*{%}*J(ku7>_lElYXC4S}5V(_W zKpSrP)ol71XYBDItMXdF)#|l zxuVKp!qUs>3~?`sBML`>-eHNm`gP>jvND%$8xE!gt+`TbK_^6~OKO3q~Bu0QVx5l%aj|qgFPFj2U?10|(L9 z(Q)M~US4KjWFl>|AV0lcoklJ=0{`pmSxQhaK-@O~QSt8*+tNbcc4Burtx2s@fbZ=` zYrh$ZvF^pPYA8@swdiHAt1{pB1-x=6Wz#}K1^8>^QieEQ^Gx7~RO?o$B|oRgCD9Zq z5l&V>6w7Q6ICiOCH7Bb94?bK|qR;y@I(iZVP zq=aVYTOfE#HT`44q;0CqW_+Q_6<;!*kXHJ6>qlSRKYe~rz~?6%WcXAQC6;rf>x)i} z+<z^63r!ef$pzI?CZZ#7qOoEbIW?9vjgtF8I9b!}~HUdxxV+9aT6}@jhx-L0cGe?+5@q}$*vTa2sy4I?4epGajo=9Ap^&>V5H3Z^XOYolN zC!k$%GFh~gM;QY+w-kYfO|WCCOk)>~V$;jGc|+sln01!NBD4awIc2FuILuVV!0rr; zq$#r7ax6vZ3=iC;P(?E`^kVgFUp7d5dNc&P3*MD`-}xJ9;*DoU*<$9(?6#l|wd|lV zgPs9KRqk@;GMA$iWeV}b3yr0w1tusCwYfD7$!*-uA+Vlo3}qY#N@lr^%tCADUm!Qg zZv3moLN;yQq$T-QA$RI5iq`)tA?W^yOJTH3V01Qjj2yMpbrFAC_(nI7n^TTdsvw3s z;$X=!{SaaY4veNg0py&NOuQpWtt1z%X z=B@C5cFLQyjYp2jt|d}BJ;hAEJ}b)p`O{(f2E<=(#S~**=MI#2G#WSV6i+HkFvUExSxYEf5E(Dz;?RQv5VyK@F^c+pTgoX_NzKW{YJPl$5_#qepWon1RP%X%lvlVV6w-E~ z^6saxzcz7Z%C375tjNiI(9A5InoHBkJ&mKt+^gg4P8bt-BHKK5Y_XLuKar)ao$Q7jFuVFXO1PNkSTRM2JPTB3K=w-M0^4Yt#TvkIZ(9xZ0Q3LXDWKv?Z{+@NY z=OOQGkr@Z~`DWtj&QjzJUcyxetItgzWlU$!$BthdXnwv}6~Pe^hGmBnJ#G9s0F29_tg!hs#`OtK?1Sa}_msl2@~g%hWFyG5m`{}RXO7CLodR$@SlasQ-E=Hj zu58-*2TClKh8NP6RqQrvHASx_Ohy!5gi) z%@OjrjF%kPeX6|dn{ApJPGC3mSk{^uY;ohZ=^!=`-Qkxy3GdblN7Y>V!Uk#u|+TaudZ!`SY#3(&*3z*f4b6PN_Y zK_{CN+)FbQxbZ&_1m93-ZJ=?K==vTlhJhIL>|u}zM-Gs#Tq#4rW}iaeh?F;}7}`=8 zYUDUwEVx<^U)!OSS$+9-$Xu7vKSe>k4VX~=)n1ZmPAC9!Ir2un!Rn8-`bx4K-LlV~ z&h_81FFq)lmWx0Bje{Mu-75;uqUsrzJw5k~vf?asoG(N@6OPcgD8b56V6 z$Ylo|9mnA?T%v)Iucoiz{Sp@&8IZurk(>pT+&EPS)*tpv%(m1N_`nt#&r-O-HbegrN$B)MO-#I-0G?~YBiS= z1{%%bVsjoO;lL*uE&H5Qwr6O@X>V$_Gsu1n~5v2S&#l5Y@2GZ(d8JITC?`b*F%5v}2!CpR`m6ymkl?2caU!A zd`~sZxb~vgj}f+ZH>YWf-=M{K9rQWwR~eSmjACOydrw5%V_XxdJn=HgE+a_n0Xp?{6q5Z4JVTa z%=t1s0euj=!9(gret+~q7<*U*N#O)>ZFDjI7(QFke(K4^W6ck`ugL$WZd~h8cqdw=ZAj0guu#oa z=>zTxf0gdXx$jYUWGorES8Jrv%E@8TBY}N7@pKTH!e-snJS+{dX*I0eNUO0 zuDS)GJQtTwct2RRAQRSKdzj~}wT3KMax6RcRap9jm32UYcXg1T+;`3uihA7lF9|+z z=x52b>c0NoAvHyZ>n8rw7tY&~LVGDn_h-0h`In^v^$$at7)k3@>7@^cchx4nk~28T zp)*!?!!3A^!I(0?{6gR++s&^%uHR}-)7yFeDd^JzR)TULnvkV zO}*V7E7Q{3^h)hy`#88h<1;sS2z|G0KelxOP6%5ej?|oIuLMh@(6xF4ja8p_Ece~` zb023)nFsxy2|nnb^ieXEkJXk|ZZo5zy=zaD1deO!8qd}(PcL=taS2@}R!wEkdmnDa z21Z8(g|#rwt+7P_tvfLw9Kzq+Zt8!Y9g|GPLntyjCchOOAB-KKI#W}_r}%80lOP)- zslasES6j(1&Ks*Ff;{+xURP9N=zOo2CFZ4F4!HgG>1xc-J?9w%?UKIcci#IESD&j~ zqhm_)n-#MIyt1Nj>BVK5UX*`y@=@php(%nqD zYNSflv?7+KdebXhqfaM1EBC9$uWvRQ_~b}iTrqPR;+jnkp4uu44KZJLMZh@Q>`+9+ ztwdoRT8c&5F%P_)fgf@~>Aq2?&Ce2?7=zJb)ZP~i5o8(5gHV<3z)=<;+P4c=wNITF zKkPinPD!{^OVG71sezhL5s$cG{&*BV@vI@JKi3R=;lnoeyl9uSI)xC5GnxGnX-M8m zr?fw$hZaWka;DsUxHBm(PN3QOh&*I4J*7m1rm!zPJTQ|a&XR=LA{xCcF|FKyviTQH zA_kfoNV8GQAMPkJX^}*a8~kf6m(gZhAt?*i@P|zDwA0UmjPH;I)4iZEgd}pQBy9L^ zF2*tsPR3(dnenN4X+?SM#HVWBr-Cl(C5)iR`vGxQD=PfL81_)@Fmsu z$J)E0z}Kh1zW{8w!W`>BHFTOu8msWMVM=Kk3jk{Ar(mD zFI=ThXcRw{QtTk5hl#n@G35d41UZtd7tht)j>yB&fdPeYe630sC$4maKl)#SCZ)&F zi!fP#0|vR2$y4$ghl+x+HhfhH?EGym0~a=c$FoWaMg1+gKP_`%ba3CQRJCH_MtG*l zrdQ~?v4aC{7I+$m6jWbiE;q5!ST{gEi1Xj(<;e?@$196&(@Ia&&;CUo$IuD_&TZsZ zi39CrUJ$z6gri2C%}h9XxgM|eY8O)Qi%GF1eZ}MpG2W-IiT~Rfcmn$q6?mxX8kT(+ zpMEb>Z)bM*Ld9}Ij)oTi?_)yr?S@anV3YX((r%9r{gKa4Dx{>-fgl0){XKfS1tQs> zk$%ATrMyA+yOvw|&)i=7G%}AIQZY`#KdF)OVF84|0SPct&;Ok0-)6Ptm1hq1tK!cm z!BXaCL0H27N7sMF=ebCp5P1=L3NilI8<7}p4F_|SJb7r!j>z>8IhJ5-u6pSzi0*T( zKtv}>dIk1?&b9gnhu`1SV@lbQ%!BU*Y=2U{ibyX=KKN+j_6g{-0F_?e z_wf*1Js;^`~yuBe3XNE{O#KQw%obU8b- zw>j3M15j=>+X1bH^Pi|Z3@@_J_gD!2wMbI#4+uzotDy^6RXSg823=35lovAtarz#n ztVvh9kdg9U+o%rhH7KrM+wJ?R+%@soY*Nsw?K`)!xXlmuauHN@vY4N0Nz(tQbOo8s zRH@y*-!#nUf&ZO3Q{eg6VnqO%R2nrl=Y6id`Nrfjl(peCxOUn;AyVsdnMi>0I~(S7 zho4q1{@S+Dbwi`KhdmW4NWbZuJ*tO^jWseh)Q}Op@kx47ywOSjqn_#3R_?2pM{@^m z`+(^BMCq85lG#j8{QW)6wf+%RGu73V_vt_yR%DDO-(yDc&Ota>p6CfWmKd?>MHp9) z;RX3k$E4abi>9;Ed+upwMz7Jau?l343Tc$turVioyx?UoyMxEcCNUd?v54P(%>y!c z^jx}~sQ^!Vz$`5F%ySrP!}WrfGKg=EwEiMM)_Ih3A(T)Pi+E=|TS3p9W6wR2_c>k# z*YftKQSSgXs(7%Ne@tKS>&Ydrq=>RMUElD%rsij7ZRJi2^pb$?Exn%h+qb8)KB_)iKN$ z&pu~@9E;4>%v^Zrv-trmU!KO|TCmU05pbC)!2(Q&mSVh40?NORBp>smn#&9F24UlXtk-LFK#B)i zTg=WWSgdxzQOI`lF^<(8cfol|(k^f8G2z!Wc&Af)L|;dYFU^X99llkls*p$aZWqz* zCZy43Wes=vqSRv>*4=-1qcl^6BQbWS_1Fcht>AK>rlOH3U^ZKku{U=yT+|3tc_n5t zl5l<6i}=RYqN~Ui5H){GKh%|*={Gn9_|4njM>@+u*|9S)$YV#k*_GQHfuPL+Q=EHO zhuu6x+B(a~7DL`Sm|CgXLs2$mMiN1Q0EQ{ZxPVM}W-x)0Nu4c!ko8V7Z>6SAc?(190XW~0iherzKpk_X+#9G}j1G^OF-ka84Njl18U?{X5mp{S>zqoHQoC8{bE zn}6PW`Gu{?@9O0_812ROZmqRKzLJ^oa0($n7SExVysP$IlciX#Ie5SRX8k)<_Agt- zmvRiy5PtY-ZM`)LX*>gPW7xJXF0OA_DnO;y=fWg!Ru!~`qkjBI2?eQqb!Tfn8VaQi zJl&m%b-P`=i|$H`z3MSI=?EX`cv`=^*obkr_6g;Z;Nft!R`t*eKv4Q!iyPj3Tnbm9 zt1(|-8E_v22m=grpFllm0qKOXxwT^<1W`KKF_apK0`*GpNrZuU=Z5^yrt;9ON3ZR4 z-o9e#+NW1*GIOy&tmbrW^+Ki&RstiCB*wT@VA5PqmV9I9l*9SKYsTq261DgA(gVF9 z-r&MgbB{Fr<|#*DXG8N z(3}AN?6VrcE8Dvva>=E&PvU@799p;tB^*fD{tyDV5f*p7PB*=v`$7q)P)50cdv zUPnR#2S@e*xI5lYGoa~yyO@@G7s!A-n6>w{H!2{OJ#a^7VS}6sUPWli@R@jv2kAhe z$u!m0Q*PT!)tqE3rw;?2C)MBvhcfhY>jkioATs8QgKrMnjr^BM`Z28f%P|E7!htqPTsw z6k#UiD@Pdw?7|FA^F-9+7r;Y{>g5&8IUo|VdF^Cttz7wl4eWJ8>)$u`c6#r=uQjjORO|)won)7cBJW^wbXE^+n0nxqh18P*c}n&!p|5h z)y=N(g&%Zz@B)3)Im8ug1W-#mVy#TtcjKBg`L$nCzhS%A2Rx?KWG45dSdUg4lC%cp zXbJ||e!LO~A((W&TV7Mgs`~DD->f-O-U<8QJRp>zN86h&V|;vG4Z8CJf(MM4L`!@i z90Y#=iL=$dJ2^2+q5%3O+qP$`Z~t1VxZH4n6STBQhev1UgDev?li{D~6mP0&b!5#T9{D*Y<}46%{mx z&kG!?aSs)&;5hcejS1JjfQ&|G6vNfknD+zUGOgVBQ(5lw1psAeGk3dvHP#C+{NlvD zl2q4F5b=HyKbcW?GC6C8Uiv9D$}17ZesMU5(5_7;K) z&Zm15XcfWW8VMBx=~yN??2)RM-a1l!kzZ}M$5Yn_@Z{USIn=paF#r$^(kh+?{T$h* z_I&(FI0SRb!f%?3J}ay(WU{QF;_uUKRTXRDT&A^Vap46UL|hJ-0sM)t{^AZpb$(0$ z8V*V&@(6ZGC8Ub$;KINV)>=UWCat*9zGpB9r^nN{sSINEfvzw@biS+?c+WbP$Q^ob zB#paYmWCghX$P0+^%zUimpC7|ZT}dVB#k?d-+ag63}~fviiiNAQcA7|5&JV-tYLD;iK}rO?BDtKr~8 z>8*ncJV!s=vRh!$NvIf47KoDm>FFQ%}70NY_UJ-h^M&CgHfHO^KxS8|}L_s~>QyKHFmaV1qc7 zqIZy)fM5pj+c^O0e@*!k$~WCB+q+EK1sN@YnAG-Q1cg0^LD|lX>5+fdU2^7m+v<|O zh2&Kd$AvnD8|oI%CwA8Y5{Nvvlpo=mY!sLRfVyUrtygRKPKjreQ}yW1V8RR`@(5`oW~-Q#7x zLf4}nnt$1i@3`e0H!qqKDM4p6lOr)Z@}$;t)y|`OdBVU>b_a$s@K%J>aB8r;Jv6(d zDp*&X-%bhuW)X|CQPYRk_UmKqsx>A+(3DOi)9USj+;?wfXIg>uwBA?+Q%K737(@QD3!)~89N}Fk&e-HF#>)-AbBw^$SBk20@ zxJgo48p){jK-gXCKn>*JJ=U4>lzVGcx@k0^NVU=1Jb_7|xD$~2kc@vHnE7kVsR;+} z%Ie2l-e=CsAyZ@~5^wkF1e`u!=z~!#XihhuU-8X&K0phZRxbE)$HUX+^ec(1O|(1S z6%FRtXq<^rwR;i8L+C=4_x10W`3O1cEspqU7e+a^)vxEwmroz2)ynM<5;-+#79}h) zjpVzO;;iG@+;XyB>p_N}Ef>?t413I%RZnw$3E4FuD}dEve;X~WoUsO%95UuD=ztqU zGOSYcnf9VMBU)5UO2PhaG=?sUIyEEn4QQw`+{b^URHJ-bZD4h?UvBzBn}U*p3r{|v zHRIh)DzMm_cUPy3J4r!d5cB`N#IkWLQwt7`OFkzgqk;Fki`7MMXG}e4-_78F z9_UocY=VnkuN|NOsxr73ZLE0%bd@VdZM-RwKq}v>=nZ>zW6Nn2j}{uUS`}%v=@kWO zOEq>AEPG40@G|4c^pX6mZ(phOj#6P9Oprd!gJv0#AZr^BV&<23x_?CjJot7WJxc-W z7~<%xa||9$Y=or`H2BN3<>DW|Ih9Y*JQ(6L#iFUg~9ymQ~vN9;isj^>Zkc*HL+W@DxX1wV0+UCly9f%+Dw^#RH4I7_1`P+|=iC|^ zEGA;!dv-z}Z;?4ZU4OlMKkYjv0BrJRp40_o*KH`6KV>>nk3U>opL9+&Lfq7}h^e*$ zb8OP@E#|FhOvxH~g&uu_iIYtZ5ukbry$3kE{Jfq(@wszBDEj$k_g_%s03ae-Ur_MF zoVb`+<@VIeOC-`cX5(2dotAqgbds!OSw~O{eOmeR9z4W3TDf9N_l48e{ z8P6yMhZ38AWjPLQ=b=6K1<>T+`l!s*j5RArWx|6<$iRSYrxX~(=E@*Hsd_Z){% z(SYlV@fV=Q0tP!*LLDQ%4GjWut%RyT4_*ct2|VrP6{Y!pueqjlS>D;DdSLNYa1EH& z`vZA^b%b6>mRLH@XqLE9U8?|DAV1f)#}7MDYF1;w91`kj6V<~VEy5HTk8la|?nPu< zomD6bR8}BB$A-b`uqZee4)4xH;X*11hvd z=sr`qo6z1UVS%<$_#6|eKM9v$0nWLY;GW0j$=O%PPuIhZ{Nm<_nIyAN{G(t`yb3w^ z^)(e3d`k`wJqR2%NR**Z6arU#^<(ai4Jx4H9^Lv*xb%ra%3n>;&j3 zylFFLg!zG_gPij6coHOEX8xd$CnuBB-n`gs;ntE7rA(9aBCKFl-z1y2xXHeqpm=PD z28ayO`3BJ8?A@@;-sQUN&7&A|$0Bdss76EgHf5hzE*wM`WzrnQ2hzrZfkJ|8v&Q=| zm4e>y=1L*HU&`g0H9j}qq&-3VcJ}NodchND_uMXFmLua*pgJ?3e*xiAi@`{DfFP^Y zwnA+^`q_g=Jd5n_FiDEeqrffyKKrLWEIEH2aDJ3J z-?CYKYvCDk0^9s9_THR=Db*JmaPNp*n0y~IUguXi{b&v;Wm3n*>Xi1~1APYl3>Nnc z*3tQ{XX;Z$bL&%+@TEeWa%rlpIeiWV*YX5;Lz*@7c_Pz}1K&_2vA1F<=L3KU%G~{c zeAlM1feVwebUcRX(Hn_2-0b)r37&WRybeDtUYoF9Y6_}%Z`rOx8*Y#$Nk~O$wxT!4 z4-Sexa~k$dsaV!a&66J2^%x#3_B6*kes8a~ChFlZud=&7*>+}~KY9!xKoXX%ayG3- znk>>6l6$8H?@}fsw!SnKL%@s3vT4Z8w+|1w1Uh7@tVi5flv}b@G!6$E$${Q{cNNCq z`#GZ}&vws%nZcOo7A35RJ|*tMQZq1*W}p&O0J=vT$h5RT!uC0*jt%)Q(pi~WV0|}r zcJ^n#f3Z6i zZ?Mxnpyt9ec`6Z#VKsBEOmcigXqosD9odJ`Xa#ofgPNGjrGN8E5E1g7GZl`$Ss$w3B#iC!_c>O-iBZ(hk0nc~ zkP5qLbiOJGha^^+&4bA77*T)~LAv0P+o=)tozwj5Dwkrl#vZ8qfBO>)sk!i~B|Pvw zaV?zGZSEcY3SJkd7N|Wqvonlk2#>iqzHs>v)=WOFY%+Pi;3g~$-`4=BK92cFf_-!W zZ(*#HcCJ!OV%zg;8%enAubISPu){voLhc-?PbpF#+)OWi5^OdYb2BsJ%e++9z-uZ( z6dU}T8l5i){qUg!HJw~ewq2i>ZmuejwP@~ns0UH_^Opy(>eL*c0Gd`xH^1u#ipWN3 zv?f?qSR&@z)pIW(WZn-(@NQ1JcKRkuXFo@aK|w#lVO(lT9iTk1hyiH8x_>qaufF}>FLj%#^Rut1-)zBV)zC?hV#7ho?WBGR(Kq=4 z3j9k=N_;fCizL(DK^}pVZzN&7_?TaXE7|aw4qt>opI-rSYK&awi4hZa*Rao=poUsuM zUR2f&`YqofHQNFlH`;V7TRhbBPz#i*=?%X<&kU0ocKV;NPgM}>eo%zm#)PA@ZGIFGc>ZR(IeUGVLx$B- zFNi}~@aQd0PDsoZ{#%8n!gV`Hr1lKVP4CqKj+@Xz-Bt8_35g(8WXlPg@Hj`)rp z!UGGn4DrE-bKLH^Ii@p8kpx5$4FOfVcbKaZXQ$8U(7j%^le;;vTAo7gWeLTSZmuvM3xiH;p;r;s-L^Nd z9aPo0VvooS)K3nP0m6+gekPMf+>Ljr{*mu{PUCUh3c%I9JIadiW#JBd&BG|3%RysX zww<6?Np9OuU6CDJZhKJC7~DyYGaZ0b4D*4NX=|0)Tr_pMGgTNf`?H(`3?t#3s@2nb zYYr6SCA$OC%A$yh#QS--gIR*)u>-(;*ucV*brPz%2OQ$RZChbp!^*+ud@W;RN6;w#TClfr41Nzgc0~_b`?WmI5jwaG;+>L*DS`D= zQniw)$-^W(K?E)!K91z5Oor+uxO7^r0o7z7Pq@XcD->79A*>rzCoV2tdE78x1NMlb zdt|Qw;x&cyKjGS+RfRtP{jw+(BsT9Vx|<@QS1)f9KMzxr0TBB;^65Sslm#J4zi5_*JbJ2NKD-G0s<+27XxV zVd0FmZJH~&Ty;fKW-F}cBdF&l4uJNu@!KDVURDt7d;X!p;bM)(kD_h8VMHu>ack>P zgpNa_JnPT2V%YZwB=qFwMde;F))jtXv9ag3YPGe4dD{*3vA!yG`+IH&b?mG_z`P)6 z3@O=gGWgsTZ|^>>CwxIn1mWhf9Pkwi;vGYO;1Tx)pq_#4x*HAkbk6c#$Ur=`ZFG2w zH;BOJ#txQ~6JYKb)z;wH6LRRWDvVv2^k~z2FZGY!hsc-== zmU`x!Lgn)9UgcJWTjLODP~@on(hZL{DE|$@zq1*DjsxE*T=x=*Y3uEEesjp|lgFBp zrMqRM!e;x$YuEAXV7*V$TxV(Py=%S?_pUm;&A*xGJ*UZmoNOttZ`3tnS=ssaYCMC{ zxBsfHBoY0!SsKyyu=VloB{V1OIq6KI=G<;kW*)^0XiwuYZ*#cl--Ts)u)v7(yM>fG z$Jj`tr^^oUobKrf2S-~H^u|I(Miq#ExeNc&0Qmi(J~m{)a6+Hy9rof-yyumaKD@^H zYYzVs&-hP}sRHDgtTLh!X(x7pb%p`Gwwo&0CFzup2X$oDxHKVuX*Z&#BUtm|?$Jiw5`?zPnqbq+jJXHX4Gp&Mt%+7z%ssRQ_2s~4V z1%DXA|Gmn8j77&A*sW3q`PbzCxGWBjCAlctX_SAi#lIDLo}&K$i}HUg&HukB|M#K* zN365sYPj31z@v@r9}jj46;Q{nQ$p3+Ui+U%^uOAC1&>h}B?IKuf7QhQAKg89iu0Jn zeu|>_j~x*!J(eBjGx}Qo#xML=CyzH8!Xuu+!#D3Ak34EV&`r=pY5LcYF`4~7j5+y4qN z|8+YnCbnQ{Cv@%K(M6AES=<#ZGtnKh=W2*G@5*5C3zfYGsk^o~kkc z2hxF>L)cn@-*PU6qrD$6gZ{%7{@v-nve|hrp9ybMt4Cefg?*IOoqKfLFQ=%%tC)MsX)S)+ntwMujrjqcMq~N`Hqn1PP#+$xU-xt8KWF*Z s=Rhn&3)o>5+ALi1e>R~XpFO}t9$jUn6>48S0sa#emJ%uw(E9rS0jS-NU;qFB literal 0 HcmV?d00001 diff --git a/docs/claude-code-integration.md b/docs/claude-code-integration.md new file mode 100644 index 0000000..e19adfb --- /dev/null +++ b/docs/claude-code-integration.md @@ -0,0 +1,150 @@ +# Claude Code x LEANN 集成指南 + +## ✅ 现状:已经可以工作! + +好消息:LEANN CLI已经完全可以在Claude Code中使用,无需任何修改! + +## 🚀 立即开始 + +### 1. 激活环境 +```bash +# 在LEANN项目目录下 +source .venv/bin/activate.fish # fish shell +# 或 +source .venv/bin/activate # bash shell +``` + +### 2. 基本命令 + +#### 查看现有索引 +```bash +leann list +``` + +#### 搜索文档 +```bash +leann search my-docs "machine learning" --recompute-embeddings +``` + +#### 问答对话 +```bash +echo "What is machine learning?" | leann ask my-docs --llm ollama --model qwen3:8b --recompute-embeddings +``` + +#### 构建新索引 +```bash +leann build project-docs --docs ./src --recompute-embeddings +``` + +## 💡 Claude Code 使用技巧 + +### 在Claude Code中直接使用 + +1. **激活环境**: + ```bash + cd /Users/andyl/Projects/LEANN-RAG + source .venv/bin/activate.fish + ``` + +2. **搜索代码库**: + ```bash + leann search my-docs "authentication patterns" --recompute-embeddings --top-k 10 + ``` + +3. **智能问答**: + ```bash + echo "How does the authentication system work?" | leann ask my-docs --llm ollama --model qwen3:8b --recompute-embeddings + ``` + +### 批量操作示例 + +```bash +# 构建项目文档索引 +leann build project-docs --docs ./docs --force + +# 搜索多个关键词 +leann search project-docs "API authentication" --recompute-embeddings +leann search project-docs "database schema" --recompute-embeddings +leann search project-docs "deployment guide" --recompute-embeddings + +# 问答模式 +echo "What are the API endpoints?" | leann ask project-docs --recompute-embeddings +``` + +## 🎯 Claude 可以立即执行的工作流 + +### 代码分析工作流 +```bash +# 1. 构建代码库索引 +leann build codebase --docs ./src --backend hnsw --recompute-embeddings + +# 2. 分析架构 +echo "What is the overall architecture?" | leann ask codebase --recompute-embeddings + +# 3. 查找特定功能 +leann search codebase "user authentication" --recompute-embeddings --top-k 5 + +# 4. 理解实现细节 +echo "How is user authentication implemented?" | leann ask codebase --recompute-embeddings +``` + +### 文档理解工作流 +```bash +# 1. 索引项目文档 +leann build docs --docs ./docs --recompute-embeddings + +# 2. 快速查找信息 +leann search docs "installation requirements" --recompute-embeddings + +# 3. 获取详细说明 +echo "What are the system requirements?" | leann ask docs --recompute-embeddings +``` + +## ⚠️ 重要提示 + +1. **必须使用 `--recompute-embeddings`** - 这是关键参数,不加会报错 +2. **需要先激活虚拟环境** - 确保有LEANN的Python环境 +3. **Ollama需要预先安装** - ask功能需要本地LLM + +## 🔥 立即可用的Claude提示词 + +``` +Help me analyze this codebase using LEANN: + +1. First, activate the environment: + cd /Users/andyl/Projects/LEANN-RAG && source .venv/bin/activate.fish + +2. Build an index of the source code: + leann build codebase --docs ./src --recompute-embeddings + +3. Search for authentication patterns: + leann search codebase "authentication middleware" --recompute-embeddings --top-k 10 + +4. Ask about the authentication system: + echo "How does user authentication work in this codebase?" | leann ask codebase --recompute-embeddings + +Please execute these commands and help me understand the code structure. +``` + +## 📈 下一步改进计划 + +虽然现在已经可以用,但还可以进一步优化: + +1. **简化命令** - 默认启用recompute-embeddings +2. **配置文件** - 避免重复输入参数 +3. **状态管理** - 自动检测环境和索引 +4. **输出格式** - 更适合Claude解析的格式 + +但这些都是锦上添花,现在就能用起来! + +## 🎉 总结 + +**LEANN现在就可以在Claude Code中完美工作!** + +- ✅ 搜索功能正常 +- ✅ RAG问答功能正常 +- ✅ 索引构建功能正常 +- ✅ 支持多种数据源 +- ✅ 支持本地LLM + +只需要记住加上 `--recompute-embeddings` 参数就行! diff --git a/packages/leann-backend-diskann/third_party/DiskANN b/packages/leann-backend-diskann/third_party/DiskANN index af2a264..67a2611 160000 --- a/packages/leann-backend-diskann/third_party/DiskANN +++ b/packages/leann-backend-diskann/third_party/DiskANN @@ -1 +1 @@ -Subproject commit af2a26481e65232b57b82d96e68833cdee9f7635 +Subproject commit 67a2611ad14bc11d84dfdb554c5567cfb78a2656 diff --git a/packages/leann-core/pyproject.toml b/packages/leann-core/pyproject.toml index 7078457..e7d178d 100644 --- a/packages/leann-core/pyproject.toml +++ b/packages/leann-core/pyproject.toml @@ -44,6 +44,7 @@ colab = [ [project.scripts] leann = "leann.cli:main" +leann_mcp = "leann.mcp:main" [tool.setuptools.packages.find] where = ["src"] diff --git a/packages/leann-core/src/leann/cli.py b/packages/leann-core/src/leann/cli.py index b239b2a..489c5d1 100644 --- a/packages/leann-core/src/leann/cli.py +++ b/packages/leann-core/src/leann/cli.py @@ -41,13 +41,23 @@ def extract_pdf_text_with_pdfplumber(file_path: str) -> str: class LeannCLI: def __init__(self): - self.indexes_dir = Path.home() / ".leann" / "indexes" + # Always use project-local .leann directory (like .git) + self.indexes_dir = Path.cwd() / ".leann" / "indexes" self.indexes_dir.mkdir(parents=True, exist_ok=True) + # Default parser for documents self.node_parser = SentenceSplitter( chunk_size=256, chunk_overlap=128, separator=" ", paragraph_separator="\n\n" ) + # Code-optimized parser + self.code_parser = SentenceSplitter( + chunk_size=512, # Larger chunks for code context + chunk_overlap=50, # Less overlap to preserve function boundaries + separator="\n", # Split by lines for code + paragraph_separator="\n\n", # Preserve logical code blocks + ) + def get_index_path(self, index_name: str) -> str: index_dir = self.indexes_dir / index_name return str(index_dir / "documents.leann") @@ -76,7 +86,9 @@ Examples: # Build command build_parser = subparsers.add_parser("build", help="Build document index") build_parser.add_argument("index_name", help="Index name") - build_parser.add_argument("--docs", type=str, required=True, help="Documents directory") + build_parser.add_argument( + "--docs", type=str, default=".", help="Documents directory (default: current directory)" + ) build_parser.add_argument( "--backend", type=str, default="hnsw", choices=["hnsw", "diskann"] ) @@ -138,37 +150,109 @@ Examples: return parser + def register_project_dir(self): + """Register current project directory in global registry""" + global_registry = Path.home() / ".leann" / "projects.json" + global_registry.parent.mkdir(exist_ok=True) + + current_dir = str(Path.cwd()) + + # Load existing registry + projects = [] + if global_registry.exists(): + try: + import json + + with open(global_registry) as f: + projects = json.load(f) + except Exception: + projects = [] + + # Add current directory if not already present + if current_dir not in projects: + projects.append(current_dir) + + # Save registry + import json + + with open(global_registry, "w") as f: + json.dump(projects, f, indent=2) + def list_indexes(self): print("Stored LEANN indexes:") - if not self.indexes_dir.exists(): + # Get all project directories with .leann + global_registry = Path.home() / ".leann" / "projects.json" + all_projects = [] + + if global_registry.exists(): + try: + import json + + with open(global_registry) as f: + all_projects = json.load(f) + except Exception: + pass + + # Filter to only existing directories with .leann + valid_projects = [] + for project_dir in all_projects: + project_path = Path(project_dir) + if project_path.exists() and (project_path / ".leann" / "indexes").exists(): + valid_projects.append(project_path) + + # Add current project if it has .leann but not in registry + current_path = Path.cwd() + if (current_path / ".leann" / "indexes").exists() and current_path not in valid_projects: + valid_projects.append(current_path) + + if not valid_projects: print("No indexes found. Use 'leann build --docs

' to create one.") return - index_dirs = [d for d in self.indexes_dir.iterdir() if d.is_dir()] + total_indexes = 0 + current_dir = Path.cwd() - if not index_dirs: - print("No indexes found. Use 'leann build --docs ' to create one.") - return + for project_path in valid_projects: + indexes_dir = project_path / ".leann" / "indexes" + if not indexes_dir.exists(): + continue - print(f"Found {len(index_dirs)} indexes:") - for i, index_dir in enumerate(index_dirs, 1): - index_name = index_dir.name - status = "✓" if self.index_exists(index_name) else "✗" + index_dirs = [d for d in indexes_dir.iterdir() if d.is_dir()] + if not index_dirs: + continue - print(f" {i}. {index_name} [{status}]") - if self.index_exists(index_name): - index_dir / "documents.leann.meta.json" - size_mb = sum(f.stat().st_size for f in index_dir.iterdir() if f.is_file()) / ( - 1024 * 1024 - ) - print(f" Size: {size_mb:.1f} MB") + # Show project header + if project_path == current_dir: + print(f"\n📁 Current project ({project_path}):") + else: + print(f"\n📂 {project_path}:") - if index_dirs: - example_name = index_dirs[0].name - print("\nUsage:") - print(f' leann search {example_name} "your query"') - print(f" leann ask {example_name} --interactive") + for index_dir in index_dirs: + total_indexes += 1 + index_name = index_dir.name + meta_file = index_dir / "documents.leann.meta.json" + status = "✓" if meta_file.exists() else "✗" + + print(f" {total_indexes}. {index_name} [{status}]") + if status == "✓": + size_mb = sum(f.stat().st_size for f in index_dir.iterdir() if f.is_file()) / ( + 1024 * 1024 + ) + print(f" Size: {size_mb:.1f} MB") + + if total_indexes > 0: + print(f"\nTotal: {total_indexes} indexes across {len(valid_projects)} projects") + print("\nUsage (current project only):") + + # Show example from current project + current_indexes_dir = current_dir / ".leann" / "indexes" + if current_indexes_dir.exists(): + current_index_dirs = [d for d in current_indexes_dir.iterdir() if d.is_dir()] + if current_index_dirs: + example_name = current_index_dirs[0].name + print(f' leann search {example_name} "your query"') + print(f" leann ask {example_name} --interactive") def load_documents(self, docs_dir: str): print(f"Loading documents from {docs_dir}...") @@ -203,17 +287,125 @@ Examples: documents.extend(default_docs) # Load other file types with default reader + code_extensions = [ + # Original document types + ".txt", + ".md", + ".docx", + # Code files for Claude Code integration + ".py", + ".js", + ".ts", + ".jsx", + ".tsx", + ".java", + ".cpp", + ".c", + ".h", + ".hpp", + ".cs", + ".go", + ".rs", + ".rb", + ".php", + ".swift", + ".kt", + ".scala", + ".r", + ".sql", + ".sh", + ".bash", + ".zsh", + ".fish", + ".ps1", + ".bat", + # Config and markup files + ".json", + ".yaml", + ".yml", + ".xml", + ".toml", + ".ini", + ".cfg", + ".conf", + ".html", + ".css", + ".scss", + ".less", + ".vue", + ".svelte", + # Data science + ".ipynb", + ".R", + ".py", + ".jl", + ] other_docs = SimpleDirectoryReader( docs_dir, recursive=True, encoding="utf-8", - required_exts=[".txt", ".md", ".docx"], + required_exts=code_extensions, ).load_data(show_progress=True) documents.extend(other_docs) all_texts = [] + + # Define code file extensions for intelligent chunking + code_file_exts = { + ".py", + ".js", + ".ts", + ".jsx", + ".tsx", + ".java", + ".cpp", + ".c", + ".h", + ".hpp", + ".cs", + ".go", + ".rs", + ".rb", + ".php", + ".swift", + ".kt", + ".scala", + ".r", + ".sql", + ".sh", + ".bash", + ".zsh", + ".fish", + ".ps1", + ".bat", + ".json", + ".yaml", + ".yml", + ".xml", + ".toml", + ".ini", + ".cfg", + ".conf", + ".html", + ".css", + ".scss", + ".less", + ".vue", + ".svelte", + ".ipynb", + ".R", + ".jl", + } + for doc in documents: - nodes = self.node_parser.get_nodes_from_documents([doc]) + # Check if this is a code file based on source path + source_path = doc.metadata.get("source", "") + is_code_file = any(source_path.endswith(ext) for ext in code_file_exts) + + # Use appropriate parser based on file type + parser = self.code_parser if is_code_file else self.node_parser + nodes = parser.get_nodes_from_documents([doc]) + for node in nodes: all_texts.append(node.get_content()) @@ -226,6 +418,8 @@ Examples: index_dir = self.indexes_dir / index_name index_path = self.get_index_path(index_name) + print(f"📂 Indexing: {Path(docs_dir).resolve()}") + if index_dir.exists() and not args.force: print(f"Index '{index_name}' already exists. Use --force to rebuild.") return @@ -255,6 +449,9 @@ Examples: builder.build_index(index_path) print(f"Index built at {index_path}") + # Register this project directory in global registry + self.register_project_dir() + async def search_documents(self, args): index_name = args.index_name query = args.query diff --git a/packages/leann-core/src/leann/mcp.py b/packages/leann-core/src/leann/mcp.py new file mode 100755 index 0000000..6de6750 --- /dev/null +++ b/packages/leann-core/src/leann/mcp.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +import json +import os +import subprocess +import sys + + +def handle_request(request): + if request.get("method") == "initialize": + return { + "jsonrpc": "2.0", + "id": request.get("id"), + "result": { + "capabilities": {"tools": {}}, + "protocolVersion": "2024-11-05", + "serverInfo": {"name": "leann-mcp", "version": "1.0.0"}, + }, + } + + elif request.get("method") == "tools/list": + return { + "jsonrpc": "2.0", + "id": request.get("id"), + "result": { + "tools": [ + { + "name": "leann_search", + "description": "Search LEANN index", + "inputSchema": { + "type": "object", + "properties": { + "index_name": {"type": "string"}, + "query": {"type": "string"}, + "top_k": {"type": "integer", "default": 5}, + }, + "required": ["index_name", "query"], + }, + }, + { + "name": "leann_ask", + "description": "Ask question using LEANN RAG", + "inputSchema": { + "type": "object", + "properties": { + "index_name": {"type": "string"}, + "question": {"type": "string"}, + }, + "required": ["index_name", "question"], + }, + }, + { + "name": "leann_list", + "description": "List all LEANN indexes", + "inputSchema": {"type": "object", "properties": {}}, + }, + ] + }, + } + + elif request.get("method") == "tools/call": + tool_name = request["params"]["name"] + args = request["params"].get("arguments", {}) + + # Set working directory and environment + env = os.environ.copy() + cwd = "/Users/andyl/Projects/LEANN-RAG" + + try: + if tool_name == "leann_search": + cmd = [ + "leann", + "search", + args["index_name"], + args["query"], + "--recompute-embeddings", + f"--top-k={args.get('top_k', 5)}", + ] + result = subprocess.run(cmd, capture_output=True, text=True, cwd=cwd, env=env) + + elif tool_name == "leann_ask": + cmd = f'echo "{args["question"]}" | leann ask {args["index_name"]} --recompute-embeddings --llm ollama --model qwen3:8b' + result = subprocess.run( + cmd, shell=True, capture_output=True, text=True, cwd=cwd, env=env + ) + + elif tool_name == "leann_list": + result = subprocess.run( + ["leann", "list"], capture_output=True, text=True, cwd=cwd, env=env + ) + + return { + "jsonrpc": "2.0", + "id": request.get("id"), + "result": { + "content": [ + { + "type": "text", + "text": result.stdout + if result.returncode == 0 + else f"Error: {result.stderr}", + } + ] + }, + } + + except Exception as e: + return { + "jsonrpc": "2.0", + "id": request.get("id"), + "error": {"code": -1, "message": str(e)}, + } + + +def main(): + for line in sys.stdin: + try: + request = json.loads(line.strip()) + response = handle_request(request) + if response: + print(json.dumps(response)) + sys.stdout.flush() + except Exception as e: + error_response = { + "jsonrpc": "2.0", + "id": None, + "error": {"code": -1, "message": str(e)}, + } + print(json.dumps(error_response)) + sys.stdout.flush() + + +if __name__ == "__main__": + main() diff --git a/packages/leann-mcp/README.md b/packages/leann-mcp/README.md new file mode 100644 index 0000000..bcda6a0 --- /dev/null +++ b/packages/leann-mcp/README.md @@ -0,0 +1,69 @@ +# LEANN Claude Code Integration + +Intelligent code assistance using LEANN's vector search directly in Claude Code. + +## Prerequisites + +First, install LEANN CLI globally: + +```bash +uv tool install leann +``` + +This makes the `leann` command available system-wide, which `leann_mcp` requires. + +## Quick Setup + +Add the LEANN MCP server to Claude Code: + +```bash +claude mcp add leann-server -- leann_mcp +``` + +## Available Tools + +- **`leann_list`** - List available indexes across all projects +- **`leann_search`** - Search code and documents with semantic queries +- **`leann_ask`** - Ask questions and get AI-powered answers from your codebase + +## Quick Start + +```bash +# Build an index for your project +leann build my-project + +# Start Claude Code +claude +``` + +Then in Claude Code: +``` +Help me understand this codebase. List available indexes and search for authentication patterns. +``` + +

+ LEANN in Claude Code +

+ + +## How It Works + +- **`leann`** - Core CLI tool for indexing and searching (installed globally) +- **`leann_mcp`** - MCP server that wraps `leann` commands for Claude Code integration +- Claude Code calls `leann_mcp`, which executes `leann` commands and returns results + +## File Support + +Python, JavaScript, TypeScript, Java, Go, Rust, SQL, YAML, JSON, and 30+ more file types. + +## Storage + +- Project indexes in `.leann/` directory (like `.git`) +- Global project registry at `~/.leann/projects.json` +- Multi-project support built-in + +## Removing + +```bash +claude mcp remove leann-server +```