From 97f153646fb147d7b9370f74f921f865e9dc5a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E6=AD=A6?= Date: Sun, 4 May 2025 11:00:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=E6=96=B0=E5=A2=9E=E5=A4=9A?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=AC=94=E8=AE=B0=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E5=81=9A=E4=BA=86=E5=90=91=E4=B8=8B=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增关于页面组件,介绍项目背景、功能和使用方法 - 重构笔记生成逻辑,支持多版本笔记 - 新增笔记版本选择、复制和导出功能 -优化笔记界面布局和交互 - 调整部分组件样式,提升用户体验 --- BillNote_frontend/package.json | 6 +- BillNote_frontend/public/preview_1.png | Bin 0 -> 162483 bytes BillNote_frontend/src/App.tsx | 7 +- .../src/components/LazyImage.tsx | 34 + BillNote_frontend/src/components/ui/tabs.tsx | 64 ++ BillNote_frontend/src/constant/note.ts | 19 + BillNote_frontend/src/index.css | 1 + BillNote_frontend/src/layouts/HomeLayout.tsx | 9 +- BillNote_frontend/src/pages/HomePage/Home.tsx | 2 +- .../HomePage/components/MarkdownHeader.tsx | 167 +++++ .../HomePage/components/MarkdownViewer.tsx | 585 ++++++++++++------ .../pages/HomePage/components/NoteForm.tsx | 288 +++++---- .../pages/HomePage/components/NoteHistory.tsx | 75 ++- .../HomePage/components/transcriptViewer.tsx | 117 ++++ .../src/pages/SettingPage/Menu.tsx | 21 +- .../src/pages/SettingPage/Prompt.tsx | 4 + .../src/pages/SettingPage/about.tsx | 226 +++++++ .../pages/SettingPage/components/menuBar.tsx | 6 +- .../src/store/taskStore/index.ts | 84 ++- .../app/downloaders/bilibili_downloader.py | 12 +- backend/app/downloaders/douyin_downloader.py | 8 + backend/app/downloaders/youtube_downloader.py | 8 +- backend/app/gpt/prompt.py | 9 +- backend/app/gpt/prompt_builder.py | 2 +- backend/app/routers/note.py | 12 +- backend/app/routers/provider.py | 32 +- backend/app/services/model.py | 11 +- backend/app/services/note.py | 71 ++- backend/app/services/provider.py | 26 +- 29 files changed, 1499 insertions(+), 407 deletions(-) create mode 100644 BillNote_frontend/public/preview_1.png create mode 100644 BillNote_frontend/src/components/LazyImage.tsx create mode 100644 BillNote_frontend/src/components/ui/tabs.tsx create mode 100644 BillNote_frontend/src/constant/note.ts create mode 100644 BillNote_frontend/src/pages/HomePage/components/MarkdownHeader.tsx create mode 100644 BillNote_frontend/src/pages/HomePage/components/transcriptViewer.tsx create mode 100644 BillNote_frontend/src/pages/SettingPage/Prompt.tsx create mode 100644 BillNote_frontend/src/pages/SettingPage/about.tsx diff --git a/BillNote_frontend/package.json b/BillNote_frontend/package.json index 0f3eaa8..2b09562 100644 --- a/BillNote_frontend/package.json +++ b/BillNote_frontend/package.json @@ -21,7 +21,7 @@ "@radix-ui/react-select": "^2.1.6", "@radix-ui/react-slot": "^1.1.2", "@radix-ui/react-switch": "^1.2.2", - "@radix-ui/react-tabs": "^1.1.4", + "@radix-ui/react-tabs": "^1.1.9", "@radix-ui/react-tooltip": "^1.1.8", "@tailwindcss/vite": "^4.1.3", "@uiw/react-markdown-preview": "^5.1.3", @@ -29,16 +29,19 @@ "axios": "^1.8.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "fuse.js": "^7.1.0", "github-markdown-css": "^5.8.1", "katex": "^0.16.22", "lottie-react": "^2.4.1", "lucide-react": "^0.487.0", "markdown-navbar": "^1.4.3", "next-themes": "^0.4.6", + "pinyin-match": "^1.2.7", "react": "^19.0.0", "react-dom": "^19.0.0", "react-hook-form": "^7.55.0", "react-hot-toast": "^2.5.2", + "react-intersection-observer": "^9.16.0", "react-markdown": "^8.0.7", "react-medium-image-zoom": "^5.2.14", "react-resizable-panels": "^2.1.8", @@ -51,6 +54,7 @@ "tailwind-merge": "^3.1.0", "tailwindcss": "^4.1.3", "tw-animate-css": "^1.2.5", + "uuid": "^11.1.0", "zod": "^3.24.2", "zustand": "^5.0.3" }, diff --git a/BillNote_frontend/public/preview_1.png b/BillNote_frontend/public/preview_1.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9593ec0c07867c515fa629c88d289728f20033 GIT binary patch literal 162483 zcmeFZXH-+!`#&0Glu-m`1{D#7aYPVlN~AZH5sWki0qH7DYLE`0ISeqOf&}R$q7>;$ z4<#Us)Ig-h5Fj8Wv?LH9Aqgb+WWGNg{Qmwg?wh;TUF+VxfRpTV*zM_`{p|DPma#tn z;gg3!AP_&~#_y&ekRb4pxA4b;kI-(Pj1US7`L{vb0)UuS1;zlTtNdH}yZ z2=prm^83|0!P%>mk?CX3IVwB!BMZUNSKdZFHoWl1@mDhUrXIii;r>G9b?h$zScj~s z@#T`0z*0v3%Rb-A z1L(FkTb@enqu}8FkX!uwMl0%QVrgv^BC11A#3=Div zX*+I{;`GSMst}7!;UJ14SkpUODt%+9^G6RKgLoTLTgM!DL7>1egEV)je0Ll4ZdjxB*7+mnO{jD$@W~V3-+ZX$ z3>lC%Q7oy|*!TS%xP*R+)Y9m<-S^cX2;6=iqFxgy{C)iuc)o6kN6`0`pfE$we|32C zFVMyBAA0%IzI)%-oIkU_?faTr*M5lletfU~{1L?S-9uLn{S4wV=D#KCm)}4~{{71R zbnf^6HK19^ zkz6Dke(DU{vvSUWH;uS>b$)3CHBbKGyH@TI%`MI!&D1zrpDzoO%Gh++%FwJw;fBL) zZd$>G;$FIc5C>1 z?KE~k)2YwZWwkcnbKk4yZhmjv#lst4Kn>5gtWlV`4%uOj*X+c?8*5#KzNgTqv6^Dg zT6iLsIF7&;$o=ik2dUT%u_MEpQMEST59SrW8+hL|ORN%;SXA3`k(5|8%D3;oT66OH z4Yad39HT74wp-~MUfx(7_PXzV>FfOeb1nBu8}q*BXCM0J#Y%*|r9b7xZtqZQm28S# zvOrUc7jZy&Gffa)0FdT`IA6$v`?K#T0Xmg^s7d^MTW&dC3IvjK9LQFK!1HwD>U@E( z-%49T;T%t!%I<6Vk1oVqpWqN<5sTDt+J%BEURG09DLY|-;p|o`QDa$or+yftN5z1B zmKSsnynxO~mNqLaV_E&US2P|%<^eV=oKULP#wd6pcQJNc|Lm z=qDpo)$~n4$lC$y?^fUH_6?yPXsC=Bc7<2S zg4r)*9gs83)2$Vl!RX%M-Q@CNK!STjq0LDL_>Ny@gvAM*R#u-68hm{{Lpz-5;<34c zRnUUbJgGT*`e+*{b>eADW|wNm{I(KV8)+pl*}5soQ6BNAtU5K`Bs(10I@5F>m~Yee zHe3vK1oTd~X=6YG_@P{8A#2Y}mz0zQcsxBW*ZcbVQ)SkwkcnneX+>iRE@&@TX&~T+ zc@}bZNj-i~O*o`&9eC9ch9e1~t=?@O?D1Qv_T38f{x4Bi&XbS=MRMYF4DxnFuhV<+ zH?~!9!Id!*f;#4iNPovp6rslGoPrjnaDYeWf{)2H-d>Q;0hG>rV5*LNW!nQ9w7 z&n7;@*cEL)^lz?n_l{6s(y8_d7+M;3K#LUdLn`CFr~)8Ry!uL6b=AEOe@G%IpYl2y zms%mFR#q9p4q=xdLrp=HP4XnHT8X)}g5A;E!_-kZrjUbC9KQvHYHS+zU=*KpzN|B( zG4Q7SUEA&+o$ZSdQ_HlGWAHZua(xFJys+-O-cJacO$B#i>o$bs_Ec4CMCd~#% z5{t=O6UqxCwoUdWbQFs+Fqt-)<&e_?jjk4VS{F5_Zoc~D<~59&-?AZ1Gc`?jUv#2ZQAD=6T|=ND(o0!y~DCbTZp<%D&4gD_4WX@KGV{l98}p84)t;qKUYF)k#$(V>JhXLbom1? z3UKJ=;xjQVb=^1tFH+#15k;Lg>^TsH2xSUBA4|o0s=sA*Enf@V{e4(+X$lw#z`xz6 z!OI)9;x*nsZO5D|7rkPyP0BnX29~ZodT5{Jk&`bUe-s<{xOLFnd+B*N*y%I*dQj}C zhyX-fTXT%3mIl`K{^hR5F(mE{;;m-VF zCY8#p8si5^L2|QRY>@58gTpDwzALQ>H?e^$9_Iw53Q{L#Thu!B?=Gz}PRn%8` z2&g(kGLp}vO?S>L?%%M>(j2iO;h#k$m_?)}93eK3Y!zM*E7c z48a~QA#E_0AEnc~rM>ACE*7fj=5RZ;B1c=BP^|0QbBN^og_w05B)?F8tcOl<0E=wL zC--d>%iGwOBI$L_w~;Fh4@FG~sRpI8zK@h=(Yt(S;_IucX%i2b> zm>TE5e1}6QwP}i(_(s|iLLnV+U%aeQNj%0nN*(o-6#R8kji}#f8Qr>xA9RoRz58g% z>&m_Qp)L)c1oR@k~U^0Y>w-&WlaF2lhGkE~iBy zQd;Tyz)15NUX!{Qihy>71COAJKi?f31!P=7yuVzKt&VA_RqRV^N%LPys(^)G(A7)m z4RK5ucQOIJs}7xguEN#*uVH`@8(;METR`K!-12FS*c}4YrCjLoJq!97`SKp9p=O6Y zdJRR3Zp_xI(sU5HGgcSfhUv#l{MOfEtRv4OT8?^&u=RBo^K1y)Y1mnhJp-)3mZOmG zR709*8Li(uaUzB102oUm%yye>HhP(Tk(rrKBi25mMKzpe@8jgw#~hKgcu_w* zWlFw^VV~N%4*b5qT#3%f#dnf2E6!s2${o9$?xl4WJ#D4)%OL_C2eRs>+OG<`(B{I2 zOJ_bb(y5!1mc)sy$gKGQewu}BKlPZw#&mlTb^7m>;ec(Oc~_O3mps;+(fgw6NPsy< zYfzf2aen6J<}3D?46u}0p&{;z1|s;&6Wf4MbDJH_Jqz(}<2;mfa6DeaWrUbibkk9N z{dh4r+x4_R2-!5ofkreChfbnuYl{GjU|7YaWyV@(A&s3K>(O#;-B73?AfzCs` z-1o0}BW~o{-{IO?pGoVFQd~=mAqb>7+s{Uq?F{2r4uli>+mVS2V_B4eGH3n-@)l#K z&kpMp+(p9QH&_gsq5I98b#=Km$}EKvi-Za3gVk(l9=w;`Zc24U&!?w_uJfsywk+EU zt@Vky4^7nPyY&@`ddv10uSl4CMR-L9riFQ>GYocRAyGWVSZ?AMP|bDMoB)gCvUhL! zLjlLjs^;Nscz#ut?<5m27|9Z)7UkowHCS6K_17_brAq_xivTF?93%J(`Fd9haW3z< zE{d<@Fp^B%l9nmOEa`hU{j`?HN}DfB@;c+Rb61|(?wF-k?a`Q^sZejPBFTflx2*yh zs({Li2I)nt*EUrL?{4X6y?82lDh($L{di|KsEGLbc}%2Cs8e^h0&y{kx6p=^m7y{_ zxZ^+8SL~(wq@Fx)3&Z7yIaAX&t((RoF#aUQ;M^BMOBY5J{UnycRZ=C}+r)|{?{_WR zgi7g?Y*Hxt7y}oS(7W$+kdZrKU;>6hY;^7hcF-?6+E!!+ICTmVY9H+beeT&@#eo6W zQ?^khoVgjWZ#s4?_Pgk>t^k;Sq~}PU^YxBa$WUdKtgx76E<)23F`PJ|Oi$FQw*&lA zPyA8B)HuC+Z5Y#y>^fr7T6dCdSIP+yi5%Az3CG|?Wff3cz0X7$;>a>iYDx}lqXF%H zV$lfBc6I6{5xsuOWcRK+`i{nT`3@ekT=<})q{{j7r!8v{!sxl}vA@2>7q!_Kd5XJu*LtaMt>1=W36uz%qdXjTvKVi5wE`Bg}zyp)vDP) zBa@xBhR}^$%x7x%?=U0gdnagyNzyf5-EDo97y@b3C%{cIj9AfZD*JbnT7ch1HS1}Z zBq;&CeQ<^l(0D3iT}N|i7DNse%b?wLuYdLYK`Mtjr8%^wRjZ+hjey-4Y+~gEn+iN^ zP<8ZP_W^_64gBlHjQ_nCr+8)l(g(CX`-zk-e3-Fb!<2Q%;AcbNBABC!-Z$;^#D;v& zOzP4V`nLV>^S#OV+PnSmJ6m@vPJ<Tcjr6pBp&9Q0jc9R=z^giC z<*%r@F8pa^WGEJFJFsZw6h3B_f!~pj-~QE)sErK{*-m2gb}~zL{FzGDVQPGw&%g2S zYZLGSe7^S9J@S906jx9y`njQ2D5?*B)R!>3g`})AR~rq6?$;-p1h_k-ww|`n1z3kE zyD?=4mof3ic1p3uGS)d;CL&erp?EBqzFy4eF)4KY(8P~v&CzEwnxC;YBj>8v_{zTH zN^9-UbQtfmLpZTl7c3=hlks{}DbQ8Irs-26MnV03Q1_W|l?^8X;Hk|$KiC(bFrQN5 z6zn_3Lwxu)`c0+nsp3+1as%A zGm^HMia^5v=OA0D>QCO^RB#nbHQ3yxM)r_BY~fGsXy0}b*M+)EMGND4(N1YD?WDx{ z_N+w1k2H^(1EkCu4l6z^e9Re1FYB41K{xyh=}> zQERD{MPcFXV2$E%^7{!(r;8Us@51{5g%2_0-y4Ei|DEt6c=AFV*&!9dp#*B&*bV}Z zld_=CnlADl#ltq=qc5C{@H#s#*h8<-kk2_;p`&s}c$YOaw)i9HGX(t~3)1sa+HCB= zV`=ZL<*mXCC^}sW)4)BqAg^H)0G|6=q7rK! zA8M0ZDNC9U@wgsNBg0Q=z10L}GBz&f<&c6fZk4FKJRYp|lyJioIjP}(=~#z6dV7|* zfObH&d|>|Z2uoCvg7*7Q2~yc{Svs{l{T4r-44MGjX(&Ox{p#z~7DPZd$4bmg<54cU zf;u}sF8!G)OeRwgrlh1)TwL74r_lVuflW;l(GCkv&}J@r4R;U0{06Lshlo%G45LW! z2GPr}uQPl*qGYPfIDkk`mZ+^n53Gg^D{fd0E3O+@5);G`h!3#K5oNR#T*mq}gV;Z1 z{60V887eRC@<=OS_AlS5HPsgVI%9yHT+RO2H(ezW<7KgHX4k98o(RO3X_vdvk8o(m z)b5j=L)N&gp_PJQm$@AaT>1RIdwC^fIYtn^8#MWMGSqcOhH}h`pwbemOd|Kw#^fQ< z(*4J}91tM{GC@%o)Mh;QTxF{Jj{|&li#UPP>P~=AUZ)?IvwpcWTqHcXf~|B2rFrHl z9Q5k0a_&=f8_Jips*>o*#LP@b3l0DT27uE>35Z46-6X6-q!vbV!w@i&FEYTc3k7NR zz3G=6hgx9tC7t6x`IwuJ zHr8H$dfXZC1+HUs*8dhlE|-+nEf3VW;HsRFTVpn6W@gFZG@Mk|=^)!sI(c$&LJYQ= zq(%FDmWNjW4PYvY0m~!Ym8_o%^%&5iPo(ngi&Rxm;q*02q^NPwXRQle{I-^}v>^+X ztroX4%%CvkvqiR z1tbWsY);Rgpt4GbZzAOX<)}7+H$W(Jj70BsaMwNz60UOjbuBd4Ha$CHw#)IBM!*d{ zG1FWj9m4cI(NE5F(!>VWuIlLA(ma8GaCLMH>o(^s5{aJ3Rw@7d`&9p;j%LxFshmUR z{A1#~k0dpNoaFJ{?W zg!+YFjrQrub(-tkV@}Q-IBhNuhPmk+JvqRmHg3;oL zYH1RbJW(ab)ZObPd%gwMFNZcE67RF!=VXdbjh4M~cf)Hr zFa}c8W?C!I(G+Dm4y87meKo^p%Zz^vFb(NuW?Ezxa=ANv*o}0jZnTn^ByO9rL3S8# zxYKnTxwx(M)L}S+?r%W789hJFl5(1OuQTAx6J$cYn%c_rRwuQ(UVv{hmmi6!k~=k9 zJ_u3fKNxi8)0%`7+1ue}wg=+_?|H_<)~t}@~U*>Z$~2Zr>gQ@ zKOvqPah;@Pl~NVdBx85ss6k1oA_vfwDs&`&b~0P zo%s@$Nq;Ry>GNBd7TwO*oooP4fE5n&LS5(ey0SV=IJT|B~ z`%qD0@1M0g;{NwtOvIAyAysq;k~RSW+)n=X&HyMe35v)>5hk_l1W#rwY?0C>LO9PE z8Lajp0I~Xz>DQHro3P=H%F+9Z0#@Sx2L=4NQm0gESvgQd(LH#{tI-r&Q1GX=*4}1< zXM@GVc0chQdMDj`=Xy97oJy8B&FM;|(*V=G1M9x(%=nOTU9Vhu*p-GmzHi!PIa051 zf_=NqpLcjET?Wh^1T@ey7wym9gs@rKql`#2*XoI?ZIJO+$S1$-%4fY;?+7CN{RG8W znT0vE|NUEXw2C>s{SngLJITivK7vY{$7rUqa@{N-pnEa_fQegN$-xbq=;Q#_9l+0_ zZ-kPvUI$U8mH>0dHD5)D2zC8a?_(m@U6)#ro68Ky1;2F#ME88$QMHZnzmKqXKFew@ zQZ+~JHA4GJ3<*5&W~y%qJe6LO`AtOk9qcVjG#hD_lK(6`QJw=t&m(ae*}5T0BENiGt`wfWT0>kBA}Lk zcc?BzKzn-{5d2>iS~iDL4@BwMray7D%fvy{5q<{iYm`9qr1rwS&Qd=W$lgz#jdcGFV7aoRy+5E$e$B#%7enXU1^ZC z+&J%d7B_smo-w(Qma{XYDX|JAK6Vb~FWYxJE_Hr2=_5~D!E$vAoQ#-22}Q{?(r;8w zMf>*lNX=I!u4Yvn!*4Oi1|QvFZ)uo;x0j1DIi6`}kjo#I)MnQ;{78ag-DfLN_3PEg zv=rxFf_+DkT?Gzll4DRE363IZY!kT?Z`<_#BJ@4y8lIF@$-(n5hA4##Fcr3hpmzNe z6g=ONa71SpZ5uG~LQ?r4=yKXLB{o&wE>i**L)amT%&YVnO`#niw)XE~q$?m6m<>W~JtDWo%8G)14A&c2Y z68@Gg*}UxCDOuS%OAVc2b~sxybTwI<(5!k^nd9#3|B}{)#e*xh3uxU z3NusY$A`1DtLnZ8^%O|GB<6+0tl}Q6z-)Gkoc{jcY@@YHH{gYO-9zf5E`@lb-lv!= zd*A5P(NUSr@~!bTbkWu+gqXu}!Y$dsfkHMXB8=GEJ4!~H&5!I%a$o4=HW!#sGVMDC z`b=VT(#j$fo;rjp^R>JEUSGHac>`W(kE0lqtJR zOZJ-Y@k)Ej6q}bAl`C4>Bg5G_c3a3v> zK+@!mSbgVBv>8rZ%MZ9vZw9BvPkMML_mzZXD7Q%VMA>SQm`A1-T6afW*ds8r%Mq|E z&I2a!JB3h!1V+}NzhsM+HkG9jk&^%AZ(HA9m(C5Ex`v<@%+ww0U=yZqtiBLu6+9sq zLTh}G3@2b}HgwWt7CcLQ%w0@!Qt3~La0xO_$+h2&%eUmDD%cIa z*JtvtBt_Uz*OXWJK=*9aSKoC|=aNkpP%N?mWvT@nyf*#(;N$umaX%y7#*LOXmM^Js zqEe-iZsES`HN3uom0MUBVtlkhca7bJvEBP=-iYN?r~AiIsZRY-vuIYmsGWSAl2G}lyI^zd(We)sqy(f*ifDKw0Ox%+Ru5cF z&&~5?$aMb^2N0GbzmL17vtPF4;vg?=gZ7T+5mcLvv?7Ny6 zKd@l;1~5TiUAC0hoVZECWBV@<;261#LAqU)|iGG}+(4 zJ}ce8yApE27`;VUt?sD@-y`(CUa2j0hnMjSL#wVa$ylFqm|jAQR*H;=S@ngbiM;z= zkgdv!?qg;p!(N+PNOtK*DUb<^b}YlTC1Yierg{j69|1}Aq$|91rA{#Q%%Tvb7o4Wr zuO)1IT9s~&-cgX1p6iKu&eP^>wJ`<6ZTh2c^b&q;}C2M!ba ze4v%hTv>7VP8l`lI+;r&}6dB9! ztj#cwjc{2an)zmMEx??cWPz$m{UAzXo0B({F!tzvEgTvr&y7`hc_jVGr^e)h~ks`Or-yT_cg2KqA5V(P{li z2gDRCjc5jY>GI?Dt{~jaWj43NcDqT~D{*7!XR#L45HGR4J5HiZq5#R@rnA z-j$@4XUJ;4qI4;-1P6Xbs#FuTG8ksw0|$naPx*&b=s5cg;sEBg^=wh!Shyoqd;_5^ zT6#OD1gmV`T|ERudf=|Q;@Z;dH8e%_*sQlHKZ`l`rkQ5q{q~HtYFYJ!pWN_lah?mefDI_w2jH&4z+pMF|j1- z^Fsk{C$_@FuAVU;-BR;G0ij=jCTndWb9op)LuDTcsjI^v4LSv36X(bV_%B3z_IjTv?x&PMKV zr)Y-*OsBsso91KJMU)#P7x(oo=4reYCiKK*%iJ*2*{Hqg zT)>7WZV=%@}@;cUSTe=FZpsjZ(1(5R$vv^{0YcDsWI0V5BIkZT`J(l z*noKs;>I76aZ!9R*T{f!<<_!Rt4;m^aVAJ(#ko2PqmTsEuq(4IA=PF%PHnDZPX{6z zE^Z(g51YwiL?V+<`PryEt5sz#etk3}l465gGJxcUD1za0FZMm(-=H+C(Ct=_l_*Ak zjMRBBYa}0`#+OBP30z9v5D!zH#GFp$iwJ-Yhy+tIx8jBTc2zz`?olpvY1A?ASJDY5 z@1{no78=!9kLa8-%YAc@yW{)LPXz2@s2)Vl<_5bu%)!K}hl8*CwX1=@|3p-N7_GE{ z91T}=`XzkcaQW>l+_0-uF?#yLq$zm*k1z&BzP}*NF4F*`qkOhiO9A4n7qMJvPMpT8|0Her2U& z?1!jG&2m(VhFdN$(J(s-AX?z1sTLR)12N3JENze~+XKWW!$3rN%D4Lr*R>ihFi4Z= zi9aSo9rvi5$GIZ<0kjJK5B)lyi6oOJo9Y*AJ~tQ87ZR2rp*iWv0yovM7B09=aTj)| z{=vi+sWkDI`GNN(b5&&>5jU#{R!Cy(0P@R<4jSE8*^O41g#VnA44BOU6Vpqoaa%X3 zGpiHpP(bbaeOVVbnJ#DaA7fC9g9Jrl9pfWANXc69oRY;) zayc3RC^?zMXWVdkxFq?M?;|lLV_sxJ%__Jr4ZPa4k?h?ySJ+cOm!B!BxSIZ?_+)?q zdwW>OOex}SYaE-3^;+rzJcqo&O3pm{c& zL%d(S`p#u(HwLW82pWZ`6U%rVdbi?)BlT+yh{VT;XZ`&37~`!t$dFu@VRjN;Kghsq zYjuL9po8w$v1zKexZZf$=WfC_0?^}YABrc+{g`4?Dmi9JfbloJp2bKu16{GHFK@+s z3p+ibUh<%935Ay1-A1i%`!=51G$nu0#>*f#E4fKx+`Wbxe*D>s??bniHFr0MLzW8C zs{EIRnpxx~2s{DU<^~c#)z;d0z&_J$HBbU7#ydObeVqLZUhB8xvBte}^q_%b`V%i= zj!7-#5}|-sC8}nvq2b6O5}dwdL5K=dFXPB+O5tM%96b~_zT8(MxsHlzDsDHrZhTtW z@Vg2SiP4exM-y*9x}d|juSNWHx#m1g^D;Tz-$uuY^*?c?>`>?Q`$S^i2D7Z*G&w`% zc|VU|E*edcGwg4?2fcnUJIts;9A!rmhjBJ)u>UJ0x}Nxw40u(pIc3Ga3eFrO?ensQn>}3qr$QY56Y9 z18Ou&Dd$c>{ruk`{gv|F#DN@yStRpT1>2PPoA79%%X(i1J+7p=HLzIM`QVY|tloj= z(27RqyV~^07%tH8;;iqoRT^=15P-th2cN$+GTN%Tqotz5=a8L-s~mH}?TFw=Wg^Jk zm;GUqK(1dm-Ri4;xu-u|$kPU?TFr49iW~*JvoXH?Y3I})-3aLn%hR0H!QC_hf!Zv7 zO8x-3`9$kaz1L36RZuP0}(l9^6mgO4KhSCHtmJ=3_LKTeTyD%VjH3 z=H2n;F(cS|7k$972!EL-WvBkqnbXoowPYRhor|L02|V`Cp@^?-z^kswJew@Hw(rgX zFDuSwkir3v^JPU+oP_IhPwa)O(}3?$0hppYiBrwGUkMGc$46%gP3;(yi(r<=tPbVj4nPO5KiD@GtSkV zy$2SGeYPllA}{}^4}YFtP=4L;5T5cLDSX-cxYw8SlgAqI4;7_S{B1lYN>p6GB-ZdD zZGJ0!GLbDI02AUhdH&1o8{R)S`d|F%N%|GR_CNE$#XISu(@l}+BWUQA6E0C*v!}ot zyJ1rZI%{j!H-WgK7DD}Vxa&i7IiXja_*P~J-`OKHgt zDyK&F?+JWBt}h}4L6z1DZ-EJSIgT=4|7+}kn(V7gInadIt! zCa6rKKT-JGvg-Myfj-thH{0>-J@SwZVQPUUYKnA#_%CYMVOWd=Q21N%kzA?=`M|Es zOn+dj1LGe!@_%T(lE3ZSKm7Bd?fp_3@L%AJSVa&>^-@^Zo~`*PaNNOr-#>oh_y0al zaqlM)bs)mI*o~HVndeQeR~DwO7icLU^Gee3o#$*Kth@XBOvu6CHB+Pk41=d4U7sTD zGA|sDocSHPJM#b)WO6BSz&o5VuW+=Q3jU}q&Y=Y~U)V-)!5n;}%g3KPT0d%z zi&Oaawl{sbaNmh(C-wNiN%kfZ##er38WyirPmgFwKh$9z*+R;F;JxC@D({a8+Yt`0 zgb1kc5N@SBJDoZ~%Xom=^_ls!s}Px&UfhuoK~Bq+o%7RCXKwB7092&7?_N~$+fdIH z4AIzkJIDz)L(mC=<|+N9S)4AKDoiB_tdta;bEN=)rENFA`A4+-ve+-Eyyb3>@o<>i znc@ozb&q;_F-O7GazE?22=`wofa2X@nQ6%q&d}CrM zk3N<)7qRB?WNBcJSoupG!#=c1DO-b<)AQM{DfZ8&8A=tkGxd|71&^DxG=ExwF=<2B zIwK0xt=_;X=FV3#6Zf4sp%Fwj^z-wxwzf8vJ#~JnpBFcVkz`UM-p&3)rptr^h0PVcW{m3xhCtQi~?u z3zgGDj2K}yF3dPlwR*~MJ@xpL5zx0cJIO|6v@ zM@GKt`sQGtxC5}GaV+km;pwsQ3cT1mtum#2jX)@M6sA!}%GFf4Q#(-qWh!B&?3#tA z{6ZbXORh~^exb0AMo0ihcejFpS%MC@Ei{O0Ohe0xM>aUaMS1~dp0_w-sLiLtfR1|nS3I%jZPlBF*T zq)m-aXtl9O4iZq3vBxxBKgM%BtIT1_d60U|emrBYLn_oAWPF`V9SG#f8sKp0I|Ia! zmX_`T0%+dQqhDzfb@e*W#Vf5B76v`w)pSV*JN2K4!b1)9>F@0-B0@}8Fn&7ObNW5? zX|y5Doj2FCr_R)H*-UNZ?u7Hwh(~-znDH5v`U8KK>X@O+1aOuAi0MAY5s+#|W>%IT zu=E0(z@d`tYkCQ%GE@j*!w$cFJ2Ug?G3eqIoyNQprSnZ+rtJ6ENwt;1;xk4&w$gG} zKdEZ|hCJhCgsOg;pfER zB^wtes84*xPqA6HSmmkt7_{wF-x;r&X*nIOi8a`@Rjvds?y@ia3Ey|(RQ$&Whhwza zlK^kq9X%X#^y$aPV&CRsjMcz~f>a zpx_`}83?6ZQa(sAsylVRr#=gghri@Jx}@^lpbD&2zb$qhPd)_w{`}c1Q9#|8jUdm$ zSB)``XA(Y4&-bJXN;-DcqHNazbyc+tXcCzobR1uJJxT1kDnPk^OO%i<=*0BPJBEyR zbLA?0ljLlT*DER4#wfBbt8eEDr1*-L8UyKr2zB3~!2^#?9-6JiJ!MQO^~jSt{%r&> zKO)zFX6{_p5XqV=aPUX6XC6o%F{s+`0k3iO+sRQTYsBs2oIWXUX6&a&fy7182!gEB z!qBWZhjhY9`6BU~kaAni_5_Gp^h&|xW|az~Cvixtxe3T+>?l7&SjN=EMiRztyZtDh zySshj#@h5Z65_^slDMjZ7qTWUw9yKDU}r@kst{m)82r6Pa)w|KRMI<0*Zfj-=3zI@ zaTS=cZy;PQJeR+1scb2xz=~>nec_I!i!G(JiZ*!8Dn%qCXrrciw^ij!FwG4XNX*xE znapm?9QQmC(CoKom_F)407HxdhHUwrQ=bW6xm;@>pH^&8>rPC^ino2PL`*g-=0Tyo znc-IA;bJ$wG4Jt5e=NB39c|shPqnw6-rsJ3zlPSIiLGMj_#TWmdQh4oPuu+~!J@0ukiXDiBAhKZT}KYs8Y$RwVuK4V~Z zsq(_`xY_$k>}k97y2%(n)A0VmFcGzJ%(0C)bkYG0{CTAWP;`w4;-TBK zbE_>qmK0JLnV4&Y3NlhG)p|A&cZ^QM5PxhdE^l^>_QG}RV)gBEBB7!8-BLBN z>%~=uO-S|O(8*f4AF~`i-*{PPnOCN|b~cw7%HXpb^+o-x>WL~v))Nmi z8Y~<@%v+Yj@6Xj=s#WsJX{{z68M)CizB6m?*6d^KaihNY62FF}bN|Y)y3&Ml%exDr zdPW1l)^sM^$vn07;*8H<$gD@j*(zuG4J@2T;f*hYye3Z@+Ls&kmrg3A(ck%7Iyx%4 z`|8nr1pgKGC<}m-Ky9z?SlQ+D*3@rXI1S{1Ru@KE`n7E6?wau_rB(Tb6!wHJ|KF9^ z0@^4QosK<@k;_WOS(ahoMC?MkOvE9nUB;Q^z=v2jiHZB67ELC7{>}mDkZ5FK_Y>Nyh4?62^6_-nckT^^-nK ziq({R)T#yaspJDPltYtg^4F8pvV^@o5WJCGi@WHqw-9gym(VH;)|2Zg5ti?3u(ydy zt}-Y!#jQ-fxuYy+K02(9A&A}6whCp~+UVk>pnDiF$_%iIAdt_^3zVbxyn4qG^}Fg^ zel1VJy%9*Gon!-b`q=!P1^aQgEcmm`mm-sY)XXX_wNo#r*0+RG@?WNzEdCN9*H_ag z<-9w1^cTbxqsnptgoxl~$P98$}g&&7P^s;RkPo47skh_T~8)Dn5KI#hDUVSN4p zY@6P$R*WiiMAu7uh}*%8#s%wjQH4m$5Q-$ ztH8clG0|rZl?MG(etm6O$iR~Na$y-1u|e!J+ptx1v^OubGs{`_Xsqz!|IKm}H)50O zref(jew%wF{%e_jxCsL_cm`Lkl(V$~XUy2axq~^k0Cr4VkQhrZ?loKq@ov@Kl>=_stVni}iGhgSleY?)J1H5NF*PYKsJ^LftasZU%i zLFjd}QUiV^mP8ChGRK*h?Nz0d?I&OG6Vct-e(q*XPHsa)`xYFRIH#oJZGrirRmaNr z&}hJC_ZN`-(ZkZmpGqG+jGR8T?;fyJV#3+O%+nfbI~#_BQ=hUfyXY?DH-_56`-=@c z-qkGM(tu*F;>AS$@c|FVy+)5eY~f0VNYFz<(tL8&{Sc#*>N!Er0%=DL$*+bpq^_Cd z&GlPt*g8t~=O#5bo|&IN3nmYRWW0BTSnLM-0Vg&`Mn`B=Z9$da#8E2pDWjvss|~AL zjU%!qfORaKZNlw1b(NnSenB;q*SQbfgJVqB3RTj1w;?5^r6pQwk2f+$¾`n#di1#16mFbpgOg@ir&bxrnAzoy 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 ^PdVQ`(u+k7=?sh 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 ?2fh zo9tgTuJDzO6^$rIz4rX5Y9V&ceS*4orO298fMioRl<1#?jI!@;qR=sMHF^o(l*_@u&fJ^*|s*QROTdB4=m6Kh&{ z4%q?57i{^Rx|$geO^NsidEds48g{cUT}RqqdlpcW^63rb6Fs0MQ(TL5>n`Q)8F zWr}!nrJoOpR12Bl^TwaN833Lv2`8cYZiqDcSd;pP7!vP)yb6TYeGwgsRetiVeOl>B z#R(<}j)9Dlz(Df=$UT6l+e;;27ObGlmA$8U}Q)M*Xeg z)nHp{06XilBET*oW+A}6I-t9oU#cP#WH+PzbxuX?kC@99W`orkJ57Sg?A zLFC>Oq{CL=h}u9Lzw`(80h}%BhDll>v%(x{N}V$G@&3vSA=VnSX`1GYE}b;9Ur=+k zM-;qDFNp2XLz5BlE!VgkFlQ*~*V;#i;)2`mcLjk^y4O+tU7gcQCne7>7nKbat-L0i z`F=17^>&X=tsU_UQq@r^y45Ady>(H*!0i*=tPm-xYF3|3Qf{oxevr%Od&NI6rApW; zkBiJHcQZxr9CI<&^a@cLTYp-DJAQdMdy!dXUg~WAWagrxm9mbpT)urdC>oXsp~Lv{ zm-9}V#`UWHo?4X0^e{HE?pUPAq;4`R{FvW;c(>Dt+U1V64qqh81i9YMoOFC-FRvoO znW9iO-1DwReOTelEobXK5Qjn1{X6vigzy6y)8LSn*@p*7>wQfNCTm8&6h0SyHEV5Ja%RhRNm2n}SKb#C+ zS8QkM#9CVrOG(RZnnU2ki4>u>VCDF3!Dn11xNhpI8$4SZq?2H$IQyev#gbXZ*_W75 z{GitR?>F)w-P#}mm*oc4cEocR-D;81)g++P@YrrRl@ol|*eYINQa$=wbB@^S7|mRU zjuKEDRK??)`Vd3f4q8N7_fe(5t>NQu@ia=-#lWX(T9sGz61*K3@Ycxa=VM;oD}Ih% z_>a=xwa4SEwW`E|Es}c`}w6wtm4YibUp;zOl02E5ujdC|JuuQ|bu zp?u5T#8q!BUeEK(D}nOGCPmAq13PwCwx~Y2;wj9^WTq2gbUY}R4Ne^`hQQ@`HaDHg zB5AcSYEs`kLr19NIUTexQ~kKJzHj_vFtlM~z}AwvH(IQ|-7ZKI#%Lz)ZLb#77h`Lg zU|3561)nmJVV$-`3RDxYFxTeJp=Kd8XuG@3d-#6~aNjQyECR{Sc$)i`Y(!uza~t0L zsMq1<%8TZZFhBCMmq&6sPa;z4(6H?#Iqu7J)6>z+T*7X5m+P; zsxx9|v#{7H>=vj1x-7^p@73XYcdiq}?|e@4IKVS7BB6btIDyYz$uR>bP}_nrwA6dT0~j5&V+PPi_*Kz>vAYr>yX_+w*@_`kN}5O zYt_I#^SX^Ljry(5@$$tm*B20cMFs7RLNqamk4G(J{ zg-xVIhfPp7h}D-RoL7>?@^IwF6c939#H)Nc`J81viZBZ;LC{BR)?Z3nlADd3X4*3S zY*M+v_%|6rKPKIn;+WE1LN<{XjuUX|Cn12x}kZZkmz9 zpUoN(cJfeRtSp6VqQ$luGAup2K&;lyR)|4cwb?C`9@!|fE}z99;(Zdiuzm>I_DX9h z$tRcmR+>8K=bJ}N6lyE-OIxq}S1J95UZYg-Xn1a%L#v>9mxTNmXO|!kSDw7}kiM7Z zjwTPz$zEqmzdL0u-**c?`<1*lntuN|KD#c{Z$(Gz4WV7esJVOr9+|@2DA@ayt3wuN zZp`!r+8LTBr**g(E(T0+0VCbZ$SrB zNwG0{QaiV*vA5M$_Qd_~_vGD-PJoe#ZXDQ(feHr`p5!lG(O6aAG1RD9hRYQ(6H69ctdhBmf~52qn;YXBXwHoh+=Ijjtx@FiNGujK zSPxmZOh?BhRCy)@<)?}XTg8uQnP4k%DDilrluH19M@SDFk~Xs2$yuQcDwixWPoIG4 zKiF%pe!NbnIKir%$ly)KPE?u`bnPU#GuIhuQz28Gu|b_kY`|$wBn9?TGbooW-$pxh z!`s`U0_LMvEa~wXjuiZ64iQ#8Tf}s?u7cs?C$v}9sjJej`_{dnNxk^r_KW_3)hGUA zwYmG1V%Kp7FR;NJO|gzmD2lBPesZ_iith5<^{dtEXY$J{SKfN8yt^eb%}75(Nm;x> z>0yYPob~38fycUzCr4_om0&OOQ+dzbGYY?j9U%Vb39CC560!T-ASSnWAmySuDZLPgtvfS=H_sFv&a<6Ev`6SlLtP}q=-q%z$#+NV zPW$d4A(QBCM8E~9QbK59ZuFzYW(g-f&7sghqYLeTiYBl<~A-W(fJ$7CwnIN;=&G9Orjc{lhdDpWiEcH zT_q1R!e)d~suKFrI0y)d9bvQ#nufSr&SlGvY2hT`vBg&2b1@75=n{%)KLDvpR3=2n zOr&%*Fx+b4!3kJ$QSD0Gwc^)?TZ(=C{c#KiLr~58N$;~Rpaa5V4-Yv50|Vj&#Hj|0 z_^3vrR*N$xnSG)h;FiTAWv zRTMa8!wG4ID^t29KmE-@8q`p$&J#43eswp?=yB`bw9ZodDrzEDRwH)yc~S2*$M&^e zct%Go?mO~ZV!ZLl&Va@mabU=!9ivwMBhj2N2ex^eW0BBjyc-u%P(j;Hsh;}*i(W6= z$J*K08dY8Ur>b*n6_c1@vp)vJ!3pg}i9E^*AqID1{*IXR-I3kWTI+vl@4uroJvW#g zzZ3w_xTHrc*5{UWLAi@Zy506z>XI7;~S3EGbL39Tos@!X&(m-v@&DCNT z5DkZbxzop2MfJ)bE;SWD0ZB6F5^OLJDIa%zvuB8gnm>MQ@eng{wMx}mlgO%EVO~9w3 zrLD`UDSoq~ncwZk>WVQgk7BFpVYWgc?q*8N*n!%mw=13$MyRu@`|8C$ub!Ts zHzO6!#I@-!s-ClVfxS;Lu+@u2B0AB6F^FbzojRYL{FiuM*>)~%zg(j!&xB$PUO?7& zN5?6$LLELCW679F96E4BvB>kwnix7*bKydjoNwU(ekiG+dS`}*SPNb;Ld>+H;xA52VGxb%J*^%({Jl+iOtz)_sM=ffifl1S$32?d?nWopir| zLB=PGa^J5!dV1zT)CCPnwX{nLShM*Rf_iT-h<$&L=_osgeQ1Byccf$;f zW_sOrvc|6OO_xwZ@SQvJ9) z?Eb1UbHn?pZP24w(%sQS$8VNFX-3Gsy}EJcw{v;e)@?lRzkAR<+zX&I`sf!U0>L8u zTk)CWAji_8lKQK5 zFFT(K84Ag!l`$r^igfA?G#AG$x%wd$@>~4QVr1RcV$0h`EOnPE#ecNf3KI2cYHDg- zTPH@S^E+^STAka~@bJICaFo@({(8a`1t_8rCppr(%GEuSXLDA`BsHCJ4J6u;P`6#W=@4YNNC!sQJ z`s6JH*oa2cb4kK`&P9D@Yxef@6Gq^$bT@<)5Z?B4GSdM)80uvqy+>c>h)E56EWK9( z%`LH2immD!{BuhF_Gjm!?VX5lERi-hS#d3VrGc=$7>*B|T!mkbFP*HX@F8SD8_$`0 z0Ro|U4{qJMo~IgO$np-}d7IEy!l&24w{Cr@IaHR}EWrPYOH;{gi(2{iayr-e( zUW#Z=LgZ5kp8?>NriJ@Pmz*?&m!?mz`KSH&b&_>mRNG}wwjra+Q|}?z|O#ZtShvjYC5*40{9_s zNDcUtSurQ@i$N`(%9wOWToLx1c+*nB8zi)7;ORED6qaYG36g$?U3=vK|MMDQLR*aC1!oSiMSj7+iw zZhk+fU$!QZxwa6=%L!I#ot_WNE1V|1kwzyrWGM>c2pl78tpfow_j(cjn;46_K(D?P zaN(UskmtGq(fx2xLK)0+)t#alt7`$9+?s6b(b z9modWLmUR^+2P30WTgNi2iETG=-6^bEGgrdJ2r|DN4o$YcYtl%Z^)vW z5%O?GWWZ~0O>e-Uk*w`8$I<^B@TXfSJz?@q4WROE5#g2(+f>V49;cR>l*{VA<{8zV zyQgAsOZqOpfbf)UvbM0iGgM-!D5YF>Hn}V+RdSYdeM)@)DN8yZ?OFDf|J zbq%vE0!%0fzY14!uUpY$5z7ySTkt>IwWBCFMpGXfWEC5|XFFsM^wN@JXKRd{!&d-* zx$*tZ==q>JxgGs!nDGQ-H;}nASKz%hCxBZh;>S?Z} zI9jL9UfhkmwD!V6G-5lZ?!N@SP)52dX}c>Sic}QSEF^ z{RPR&sU3V!SeQub_W~=X`m^av9yu6g!uFuV7{J-CmmtmMQYTcI`e+AYi*<^s8DN}H zrV|X-T<&!rBtIuN*IBPgt7A4iz}#O8J-kx{b#rozsz3&KAuYLn>I)AimNfjjt_)Av zKV|pOT+pa$^$oZw@Q-t0SDGxZ=ARQO6Yo0GVxO>DHH0Spd0;h;oME!;(!>4XIT$*5c%&G$Ixe6!ZLx+XvTI|*tD!~eOcgUUz3>YFq~8P$)=6N z$A7lsV14oZ4Gx{ytmn6l?$_)3k&<9vC0x5xp3qFa^ag%z)Run>gRpMgzixza^PJVZ z8GO1tx-&Wrjua*Mc8}cy+!Qx$F&14q>>JR))PG$^)I`|~k*0Oqe43vl&FyO5&!1lW z^A?LLxlJDc`vK^w^9PpVtmD+(>naa6&u%>gQ^G`*MxxDt^>|5?E@%RL@HYxwl7asL zz7zVAEY1Dz5NuceS;6I%xB9xd8I~488Rz!vu!tw{KidVdZVP=T$jc^w6V27wo@i^g zCi*Q|S=`0-Y9OoWKxpehx*ZbKLZ0H){Oe-Di(-Hco{1+}0@2^?n0qSgtlgO&GXMFn zc;8^>9$~L-YeahZ*=k9kCIbIeXXj-@E zcWa$`)<9W7lstEKUxzjJAJkzA{J$}y^X)jsIuTS;z=2>|GVJ@ZZpZwI49IabzxCaO zHH5zAfko688ACWH0J4V^jW4AiG4d?b^;1lisjlWVD^NoGTMMAky7{gzRY8&W=a`$n z{g<$fK%<^+eZq^AuY{)0Zk-o1iqCCw>{|Yi#~SLL)&VJccNt*aPoF;I*F*f>)=#Xvt$kyfTYYNM{I7RPi&gNyNMNAhZG7=^N`+MHl z^w|7dvTy(MdLQYDtqR_|uv#p-5tQ3CZmf8SwXs@7_~7XLr;df{C@MIWh|7zWOUoAH zN1BRiC6Xop>0r^}+v$S@`^fI^q|PTY7C3Nl&;!iccvjt0;ez1Rz*jUg)Kh2 z&&<=Q02e7JpW7Fb8^Qmxpenx>G%2rl z!g}+Vek}5*y3Uf6V_P*sAf7t2f~fr~w7_wfGz{44*q9dVvRhJNX@~y~X>ippu{AQll7p_`@l%@-HDmY+s2>`Rtn876hO_tc<%wq~LG?s@m#9mjV_!1GvG4q9 z2$`e%@fXerJ7e8u=Z0i;W}uJIPM2n_`v?Hdz1*#Etppz)E|;Xx#}r2x`?;O1+Uai* z<##wv0S@3UaBxflaNuutbu~>pmrvR%PEV#*6ximQqztn|&H@dKsS8GkS%C=4gxUnwF4LyE|qy$Ka_F)lBhf-i5W!CEn4tX>XHt zof?5Z{;eDf{$?;Mab9^Dwd>dVU4f1?;{tx;2`FjCO z@1$(KT%xV7CGb(mB`J$ieFy{se5C?9R<*b6tSv=*_>;z~0`?(HQdB@{0G z_G?}OzyU@8cyNK_wf>Ed*dze!IAf&o7HIbPxH#|cc+s2Kh1i}R--y@s9DxSxFdJm`8gN=eA#QrB z{zhVcA-kF5!3OOgcQ^AkS~P13XHrZ+#tk#mdjljt$DIfd%xe?? z=9GK6cKgUPi|3?au=ao8|BMkMXPzDcq6ql*h;s~#0o1ot=K^H|z%i%6Lh$9X&F$?u z7M~ATfHhzAu`CvFnS47sRaVqIRoy!Pr~zW?NL1^2hJ_mNNn-$Hkz*<>-HqD0RL&@C zm|2JE=po|;$eR|#*}5@hVwjmlHn}u{JYeLTT@ts6t5l@yWvQ1_BS5_gW+_z!DPgDp z;V`{m&)&$2F^Q~H5Oa~dcrviP7E1Q2g?`<2>!!VibtV+IHaP`%T$$bE`Cj%cE{P>$iU4V+-r`e43b0CQCB67D`=AXsOjU94Z z>>lmC<8)!Wj@Q}jkP5N#S`T{K>SD^7Yd34ThfQIzHG) zYfn9;!tZw%>joK0@Iza*$@JL>Yw`=DAeAAzry!YzS2Kl;A<<)0Ik z^EwvV44i@EHMR^yBCNl?Q_a<2W36{D? zh-9817HJDY+Kz0h`#oNg7?SOTf^Aa7W`a6^K1|T;*h@q~!-zGpud!UZk?KO`V$S&d6ZR4!F*6ha!Mu!i2Q{ zUBn8(i&q1mCBbst(9*_$J3W88$+2qR+p^cs)nXI+)T_SQO_z!QTeareT34t;%BNp1 z84HDM%`8<=)#LjF(c)?N@l*r#hInP!-TSL>Ff!NJYIO8Y4OCATgk0PbnE(W^31}*% ziK^ew4cW{RCZv&qh<`_KZM4e@|KB{kh8gPDF1E{PGeUBTlnF27r97qE^!-cS_G9w% zDVDc+wAmA7(;jmqq*7%j@;|zTDUTMpB=C-Qt`UAi-kqyaLTF%xkJ7d5SG549*?#a zcff_aA9GDb<(+eSz-5pp;5X%%N*avR@3R710 zu~_Au(u?f!c-&+H6mE#EM`?q$9f{i+seyzg%{)yfB4PyCQnZyB{gMZ0k2~WH^fAf9 zVAQc#Y`~9~;+}xR7IU6G#t~4-MjGpX{c=ExPz`~v@_xPg<*~P)K8U}gwyl&Dcmtug zjLX^m7%0;668l=Rc8H9C1vjn|X)pv%fqVH01wXQF`+^Dy3YK9EC%olR=}CezuYt@R z2XqB`0hn+QIMRXTumF9VWLXNLw016;WdicB-N2~Htk(zTmZa|I4zw`RGWgfp#AWtd0zJv$uW)3Tv+q7(i4CY52_^((w;KcDz zDg0P+3H^)gO6w{Is9b$acqF-M+CtmnWH@Eu^iG|bsXoB3#ytOe62Gg znd-QX^H(z})qczec>MEnsG_1jTOqSqH&sd7r0*g{RQ??csU zXoyU;frlZ$-KTPlB`oX$9qXsV|zHnn0&_1`SXNfG69@@E8CrB^?%%b$-OR*r(2fze(7OIhSFLTJXLhHB74K)4LR8kPKq8-Z!D z&0OC9HtSb5dtDnQIg!YuHs!q*a@C9sc$G#MR$0nT`vvS}=+0aXH`BV`cS zr`UeKzioI@kUClWpu+isub~fcAu;zSVo*HrIJ@}&OC;7Uu`p`yH_)Pj8=-i9zZLNR z4(Q0SHoI@;fpkvZ6tJ>>u9AJ`nZ0u|O5^CRs(9P*PC8e76_Y^%Qi>} z?SJi8BIwA}?e8mIskuA($z_gjb;lxM-dz3vKt$!Sp;Qg~Y$^ck3`mw?O#z1jxfh`V z$(Mi8AOP^C6wRN^93Va=zegy1{6I2FYx%o>F(x)WflRUx#2l)7i=pecce4HK^ zWjNT!zqs~2?Ct344R9Ha-H}@+lWGv981MW7;yVLrM~fgb8H$WQJcfIO4gwd3bGTze zUP1SH!Tv>u9hpI9;h@4`>h~hUP@-Ni-bjV;_Q0n5*CP$M_%e=V$=VJxF?4sO_pPWo z1f4iwBc)#f{lO_(3fL>{-YtMXPKs}6pSuVTuKnN4S$PitMjs@6uq+4EvaO}^F_)$i zEDtt%AUdFzAe{FM1?tDKx-8|{lsi=+(Z>57s{ewU@ihj2=Ar&V2zWKNg-{}IZZi5M z>O^QT5T=L0Lwq9AQ>PC3GOVT#f+q$G3U2Pl>Y-0?j{+P6Uh8ogtex!&G6fvlyA!T* z{tP_W{AMRl<=zHVr&QTeN`E$ly0npvr&q<{MBIb50bbMHJIPWsIPZ5IFiq zlwRNQ@5spM>5UceBWPH_iMPG>3)?DBP8T4ss&h2?X0#Z&PC$uk{b0oV0iT4gxuHI5cEzh}m6(qMTNCcFh1P zDWjlD`{rmD03MJb^>CoEI$a5+o1GDh5p z+Z}uMhkFpmLFaS)_;CRM`ihE*vb9VHB@>fT^*E60GS36Z+<(W&$mrOyWA`ed)c`b1 zuHxI%U;bWbSU5wgWuJ`~wL6gcaaO&s9jJ^pK7coO3nZdi+Q2#yt+MpvV4Ga1{p0~S z-B9sdW&0CI9Y6~Fi}{V^ev1UiVlu7EDhD~6e|`|YK++*cJIVsMP%I*Vx5ScD1t|H+ zXz=oeL&a7yPv!n%_E*ypfO?te$N2i-z0q6ahZdn>Yg*NbA*)-0U!e31e>I5Czlh$j?W{%!p826r?HfcOHZcX&m}(xNq3pIr zGeFgmBS%J{uo4)bOb!o`9~o-*Ul{B&A3$jt_Mmn=(p7KiI?SM_ch2yiuHiCox&^{SoI@TKf~%OWgBd_Gr2qqlY|qAwmh66xS&cjE}mCx2MzN5`ii z@1ez7^8EAz)qXc(bB@R6+iXu!_-M13*#TTwl)%}yFY6VXOswxSuDi4I6B0lj=mh+(-6WD-Y6=N_Y?tXqWzIG*8?lN zRZ=R3wcRl%_IZc|%u9B{ik=Fy5)U3C79|K{CKMxmLxN;P-4YS4GpBal`N_B6)uF@0 z2OqXXi-p&yJrV90M~D_TIHHL)gW-hnG5=VcjHsGa1R^}VR9SRfOVe#qV}52lsQCHx zXldKZ&*>}8ufUSucKkDrBvEy$LizqQtA37&bV*G1Nj6kH07wv zrG}GrbSc=|bmNM}eAP(DqNw$8%Z1OYiDwY8QqmrEa<-V&7ty!dbY6+0DY&-lT@HnZ z^L1>3iT*S(@L~sdjY(^l(Pz&h%J?JN$E!RDrJ~&p#cH9GO^dxBFL}GY6}PjzSq)!b z%a~9G3~(^ax$N3pFGVTY;p|j<5BCq`+q?p|6$TDUc$PA6HH5G9%`6CY92-i^JzCUD zfD}cgzik6JEW{SWc3CWP&;rfxy>2?VJ@QKLpYKb!XN`s_$t&MpmAwfO^{U_-*HR7i z5l3vgJJ4oZeh}c;XeQN^G|i zr?tKGIPz?Lv=m7v*w4bKaBpBiD*9|Wu3|>_Pl*L>T&BGywgFLq#Ee(WE$~>lJe_Ra z>=hv6b3IKZ_gdYtUcE;6-LjstQBc2YE0{u=n3&uxAMa@2W@RSH8q6vb_ZP0Z+D{h! zgu+7@qmM}K{p0wkfp6L-M;rI$p-(8$^U&fr!h`YzO&iMfXsBnr{uC$;t3{jFCCGTp z?3k`Im0zT#-H54wNSJkW&1$*M?!4+O>P1g+UY?B=?>|?%JO?U?$GLm&xY;h>Tu*3K ztaa;k{Y-IGzQmL%h4IDq66QY&hjb?$a{s5@^9^DYYw`Of`5M_xamd#z!2@1m^o*tG@gAahPR} zy#1s##Fj=T`&~P7sjJbC;;S}an$Hp^fe{;DLGVSbL^GnecD2@o?d*AISf z1QvE3Ht2pmK?{2Xee$-$=x_M}qS}?axo6rB&~ToperOS(H&lCRbN0$-_F(C4H)Xuq zz+ulV{g&vsriuhy;e^}7q6wvqw4v!6#9eXpHo5-usEx!bVD?^OTzzl2q)T3fl2EFh zdW=^f#B|!mGYbz}-ck6=hF$@-mB7%=+zsbBgU<46oLpY7VPT@Q(L<5Sj2*Qh1=~(=Uj;e(da~cp(kQxA++LM<1@yMe#n-DhR?C~ z4)xXFh;kdT4abIPBrTpD$Dd5KldrhB_;>6)s%Xjydmwgm7@{~qNzS_5WjyQ6*?zqA zT(~$_)$Dxi?80A4lRI2%60tHe4y@rJ8R*x25!H2QMA3HdtHJ6*Lo>_8iTvQ`2MceH z(&8S>_U=uc6n#Wem54>8D5psKEq_^xYDJi#7yBDIKQ7sM$rPG-I_8`SG}O6qFY8{5 zA0zLniiy-uaS>PUQLF`N&Vl`Y1uX zjxD`J43gkQ+Z`(xT9=KA^L+ej!R8h{MU|ISl3(=Xh>YvO?qM+P>q<$csN^Zonm+XO z_)6at+GArkZk(LLa2*yK3pdAVzlW4(PMOkq7?N4^?b(xFk2i*+-3z=kFG+cG2iP}) z<5`DV2QQ_Ey;!+kqnAJscR3FDls70Qy0kgpyy^~u-)r1?!l=)?@s{6m*H(R^iT(5F zj`@`q7h!!+g)Awm$($`=J~?Ukni-YOyrdcXlR^FV$+{^hmvm8i+$m#lZ?pAv7=_<+ zX)e07AF=W|(*Z8^j$W95PYD}*Um(IXH#@qQZlxlDFEPDfcO&R>LZ@F@qi^-koqh+G z+G5G6@hLsqkcN7yu;pm$yv5~UGJxjP3y`~?eNLiYU#-2KmJtVOl(78N!$T}M;dEXL zqactz?BVa8PIc(b{H=NvQGr5?&Mez28HcEkjJ*(srA(Ut){pxJ=tn^McGe(0m;Xol z64Jg(xm{mTH&KhPe|U_K&BKyv=YV92rO(J(wc#qDI99Abq?Y9%Z&+9}dRe?Ek(8qy zp9?^k3@_m<()9ibZZ1(lFK;FQy|iPxO`siL#7V+yfqd9gOqTSEjlf9T`NW!ZP7amT zQI?CN%dlheLa>F~@93Eso5>#1NJRV+pY81b9L@dxWn_lXz{Be%XJ5n=0^NRf(lAht zc2)_i|5uUvA`3!Eh5f)X)6*Bmk6xynmm3vXgGAPN#i=;y5ClafamCgwYPBL^rJ#3SD%vENc4BpF zc(t7WUF`KyQMCb2&)IJ~lx=O=-A$KmzV-2@hbqie%a0F>4mJ6A)e&Nw$d@fz2nOR7 z;6(iF`^z;-Cx0TJCIQ}2l;nz>Yxrh)t95DalO5pYx2?6W!cvldI6jCTph!+|mmhW8 zD z(XD`bR^e?R6$SkGdx&wvNM-Y#hA$r%zi56A+Kkkw$j5Dg{0m{oeox*& zgIL9i@5NtN(ggg1H_SgWb^qLC&VV2hR(93gFOxe9AXrk@J~6ZAr+n^(c2`iGwRLPr zL)Ti(u30`|p!h;hfw&8s7k$XOANF%2eDciWl{SRN;r1$N&#UF>Csc_z3^ilMNGiOL zuS+nz#*z6Tr`%^L(%iiZn_u)o1kso1*g8G16a%m5K`Ma}nj;ILCpjRT)E{_t_ zLSyaMvd$h{@sK7*yuBB3n;j*FNbV2cTM2=$kK1rb$PK66Lew}8N{PqD%9>vmLnA`w z$F>UjUB-H@y!RV17{$f-}{fc>8T3o~ij;1$wn=%6HW6yPkRe3u;U+GHkE zyON?Nh5y=ZVdp&OQGhhOr!(-fbgZCz+BMAoW_l~&w{p=|0icc=I&+Xq6!V?g`i8Dy z)D*fs6Tt>oS(okzAKo?}YBs)MfueBfp&IM3S}G~j9dh*6NalvZ+}<}Cxptz!duNj4 zwsK5ktR8dtQnYwy_^|psX;)@^)nK-<9*4FU@5)r6$Q${#$I8eBjXM&6G-(;@-_x)a zkF`UptRq)bsIz*#BADtGPVOCjZ9EYY!_c^M-O@gH*ri-@x1$;eZT?`}#rwoQ;eqBc z$V195-!ptngzP9g6UdXQbQacvm9^2}G46nw?IM_{mJ;L$uleF7JJu7iUcK%uF=8=$ zO|%|1;XJ4?>jx!#a^ZoXC1+-2X~CT~6rKLj(t`H#g3=_{`084y8gpbhtNZ#+=q56$ zby~H`F(K`@d^jbc&eAsq$FAAkBF{KIR4@Jw?D{kM_wxzo+6f@jdc#~?z1X!&F_$BPC;L+c>IL#ww1PiZPLPYkHSlpwn0XBhTUH)nKti8p zfql|%v6Gsu-MsQ6SOJ4|{R4A1DckHHl?~3}a6!7VzUVSl_r&l(Clorm+$I4(&toQ_t}VZ4k6_fkVb+Y*i)vAtso zOfy-TCST&Fm`ieQYvJg_pic97(Xa%FOfD&txMav41?=_iE#-Yi9{n>>fxt0|05T_r zetq!F3HDyE+jY!LP2`mjGGJcw^MosQn3Wit__Fg=h4)Ed# zr(D>)TjOXXs^ID2pmWz-Zjk!VNX~Gs#l1q^lzJ!NRoz*~D~g2K7~E5A8FbN) z8}EuEwCqyay(=(-1Y4CLCMLz=Y-x*@b@e#ufPR%yy2-D1H|Cs)Uw+Cw#_dw`;W2?vGaVE;$$&tFKd=26He;!+?{vk~v#3^rihS7OUUcyQGHI$Rf zf!>-5tvCglyUcpmB4fRtMLn_^kdd2|yuUI+)F7xUlWK?+9!EaOc81oOxkkmGeyf3GEVQ`8M2l6H>@7-J01ZeP~aGK&t)voC=jk z%S*y<@FHRAzHP_r=yx31D$VA>2so9YoN!tj9P56@!by@eRe$ofxx)4 z1qB3f6ZrcP5fSxGO^V>Cm*qyIJ%051tj>&@?TOH-RX3TQUPhe|RFfWcm&h5UC%T#8 zlZWa*FZ<#s$NV9fEF&Xh)01_nbAOPl&0hOME5VKKBrm_As_OYz!@Ae`o{sot=HTVkzPEYvr+l z4NSq~$!Mlld*K0t(zb#8^gXBRIX`|S{%ZqaL8K~&mA!m2Fyu{bN`T*vh3tajA-Hg` zh|!iNNECkD&-`jf{t_1L`da}9bC(1&fdyTIgV5-+qbfKL!G;ME!;gJ;sjvQA8UXtF zeC^iHys;Q^Crf?R5i}#Owb}Rq^b~%{R9A{w+RMu)0Vh)zQnW9gD!{Syap?FVtD>{p zQ0Uwz>6bL2aZDa)EUM~q`X4fan4FfmM{n_7{~!Mc_+4{lU}bFPb@=0Sv&|b7yB05+ zmqX&bwR?&oxzQu_D>{{JVHF6H$5y83(n1twE%WX~(M?AVI4g|#V$2QGeXc7AW|G}6 z+dtT+o<^$rE1ztY^OE%w0{micCyh|~%!3!0sD^)SUV%IB6te>~aDhXzUMNB~YNgv1 z*iYt#`M7pKYtw}$j7DuWZ%@|6p|9~tZMa{>0U$T^-qDXrxIjJe6k4b@-LGhu<7t*v z$?<3+Z4<%cNtAT~QFmj9#{!bnwsiOf(j9$y^-5@g8KS==#xoLBIeJ^8`*V)E!|9Ll zc8big)!6T57K1oA^L6}Y|JeW|(Aqe?pHR}~`gJ;sO!40;6@Xdj2E4(jY)>vgUMFHX zw}u&|<*^dL#N_I`s~>=|zzS-Ra5-32=r}!NxYEA>Wf0)Xq=4E>(h5<(OT>Fkn#zE3 zS-=m^Sn97EZ7rwSYss_jorm!$Qy~vDNATB$<5W5Id~|w%4Tc??QSr_PVf(aZS3rM- zt`yby!-mffe3*Yx)v-TeeDmZKW@W7BT^6z;Tprn>l$-NnNqTPHQa3Vc|Fs5M4AHAWfTRTk#v%k}JWV}s}ggKW?n zRT+j{o9^sK5G1Xvt>shI<*k_ZE{>&ZWp_!hZ!^JsnrmmE{%KjdZ0Num1Ar6eyf^bGI);o0NQOFIbSLcAT-V{ zy?ZlzZ-vSgf}zgr)K_8DnIwvLL3I5 zODDX#qxXmd9&%952#0E&?mWXmLNaV(jT<~X=VGXQy{n!Ny~|G#qyA*bVTYaS?KW%K z0@k;(GnR6B!p~vnhP3CX+*W6&%1pP81B7pmq;1U+NE+`{EqGbUw3MHpvsBha9`w51 zG2v=%YHG?@`x_vRUqB!P-1W7y9F7MGU3Awra6fYFUIzw_uf$P3!Qmy{JTPWP#&pc= znm7y=71)gfE2}hLOIHaYljBn?xv6u~yQF1OjA(e`nf1LnarPM_#)~oEkbBFSW$W8$ zgnj!y4NAP1t5_ZfUd-4~#$1(+9T40q5|jZTURdBk(i`_G_QtfjrGMjP6%Yt*F4n7R z2{W~@IcT&K6oyz(aK9^xyZL~0a3$W?x0>_80!~3vt8Bd%y_VxE3mFGrCsNY>Pr02Kf>+pPCw08B?%UR9&x`|H?ciJU@)E~)o#KfikY z+OQt7Hu?6pMiC=JfQw(hRvH_4ssJES76135Z9WmX&?_{P8>E*d!jDQ?_O`u7T})S5 zrqhx(Sbnb}z2#`=Ilp8^zz=}_=#4>*gRZ;4{o)*&{R$X`6%-_ZdS(k6FAQ}XV)!5+ zBI5gXdnjNzB5p)mC_kI1r}RWq&pLCgEjF-3Tn`(Qc~I~Dee?fd<@s9mbuQLGrrRjT>O zs1c#K1+!U)j~fh+RYrDa0cz}+jKM!GD!91$_6S;QwLH7ae9C8`JU#a)Wbzys0RN^5 zy($OqDE&B2lz;x(j)L@i9F0ioy;2AT$h=|K#t>va)#-%h1rGiFO^A<@Lrqy3W*$G>^doYFYR!$shc0f z0e#72bM`1fU1sPQ=To9Cwp90k+KmxVv*w*=kU3P@RtBAJ0xR%WkyZc~RHFQe2q1wf zR+gg>U%H+hUx$cS2(osbhGZ)8v@l(aDq=M>ys>RCwNAjVPV#zdrYzC zm>-jnT5TQbJ!Hu05I+CEWkCA-2)Or})%dPCq$?Xz!$}#Ky;ZeP?e(C7Zu>V7CC*nS ziLS7VB#=O`+@N#g7KU-r7Fu}4#+uVM)J$eENAX71UFH3} z3CI7I0DAQnB3PBI^O7|Ul1qULT{4{zJZdImEjJen3+9lS@uU|WUq<@a28n;fTgX+x zm**+c>7W$VyT5Pkf+}&9^1@(ayw9S06;T_Q z9i-^i2u8QZq(lA8e%oe7m{H2lC&TU>DK6zH-iGt5tzJ?13kYjSOTnEzLu_|<6Y7*Z zq!;GVMV(GtMdqODuj${jvZA6&(05 zz@Rhr0CegN2hQ*?R5*wfR|*#OI9^$tDanBG?3SI)_Sd~<$p*;4UgyrG;_Hs?9XebB&iyz=HBBqxX1bO!*36Hsk3 zNHc($mcQai&A^nlX{~fCk00y>YAXpy%IP|$wcv${bRp_kDRrbExHRw&#pwD`O= z@q0VOlD48Vdk*RO1qBm*`8K_vBExhc=nH7LXx7bO$ z^cMl00+&owyL`@#pHe}*ktvS7fHr|PH~+2VXk~u0DX2!<0yoJbsJk24-KoI9Y}e%k z2}TvEEfzY7#XDz+Kd^0FT8g$Ac<`Y={OHm`E|jybl0jnpShs>#skC}jX{1ypbY z6!|;gNC`m!0wM8rbG4JWZauZsGZ_%_94)$Bk2nI*12ls>cAX)U7rjtE;~@t0qxyva zj7|8)`g(F^CJ#8O>}UM!N)pS4`t>2;@4u>?5dB#TkP?xO8?6BLCn;O5+^DZTc0MbJ z#pd!_R@X3fC>Zk90iv9z$ZA`K_|>g1<{V#0J7Xjkcx^4!Tc!nx)Ekj@f|k@@>`LdO zkfb_aGLz-Gvs4GLVxg<6+qLoz7xV;u(kL zv*dfkf$KKVLKtQq5!YCE853;)2&uT&0R&`vD#8LV!OW78M~>5uZLiHB3aI}3 z&K)3D7U2EQ4@T@v6w0co_Rd4|zis7$KRZ?_#6;I0MWPIV148a!g`5H4A(UrL0v~(_bNYqV5KwIulx92@b#oq~ zLBnq&=&N3VVpdw&h6V&6w(rPn?``1YSP&zmzVYsCBf`So{6aEd{`U5EgrUO8pZna> zMXFyLy5y{19PYT8M;{=xC_Ky_l>MF5^ zWu?BTgtvj-WXb|w8r=TVD0kWGUFkxFIB2Q{^`meEV&(p8u+|r8vXy`ui@kSISq7zH z5aEM%9xEH0sI$})KSf@`WZH0kcQ%^o$OoPmv?r8 zg6h7^TPwNs>_U1lhgaD4h$B|?Q1$Ani=@3J*eDjzm@QP1`~6Sr>=2vmw-$AH93O-w zFtn8)onCCFsXXfeqJ16GDqVb2nVy4>sGADtzV?C6M^w~Yi4b)<8xxtb7l1*@O-^cx z>xC4A9rO+Lln8@kTPA90@;3wo1Q4J?*|;=X(W zyx0A?Nzw??sTH9Lf)lH=K}PC4u}R!OXoJn>VvPOPvWr#{;2#;gY~Y~B_=cx3e5 zBSTvZmcXCXMh51QwV)HR%nv-<$}i^TSdzYiz2bRExXEAJm_7VXCv`a+#KZPHi96*Z z^kVak*Nu9ksMEc5^PAcmd8|A{6DNKEhdVNspP*3S4PWEKAd=9u?+*GT?XKg-3V~+( zr#UV49pD}-5Q_zs#9%u$_?rI-mB93RTDlU8MS-?8o&q z?7o9hP!u*XHdt!wWH#QX%SpJne-_T2TRWWp3Az);)D{Ku1EFyc1@yZRuediHK?L_~bb$G3ta8Y3h&y?vHEVe#X(r~Tgv@HE$Z zAvFeNuzC6F!uJC9zryhBAg;9kz#N)T`B1y;xPb>!yG_DFb7`p@#VMJ&`$vcP)LsSd z!jIu&m*FaBc6Ko(PUDGjL2wLDeM{E?ts7rGu!Hu$*fSxYG&Wz5n3;6uFzG!f>ROi? zLT!AhV2vJp{K4s$kf#qz=#^E3c*u+h=hekk#n!W*!y@JD4Km>YcxH%(E#19e{9qOE zUsG#t!t#1=;8@|^A*JlpceA!iy1Sh>z$cZ-!&*T1{TP-10MR&@WuW4XmW()k*nu-i zH5bQfWy7(LK$xb&FO{?0shJFK4NDC@aHoqtcYYytg(a%5LUA8h|Ak-TbUD}Z|J=ke zhW_aeVoR^yD{bya@?3v8-^545YT%Ja=`D>voBKzp;W0p?>ckJfAEiO)-0#)9Cz-@kk=TH#P9x<7rg)<^pf_=}4GD9~( zt%BWx*_=5DqQ+dmgq&eE$w>?;$^;PDnNh2!xwXjD+p1rzq8G&#wU79oZO8}yF)AZ% zI9cs@LJK1zcxqwpADguV1$NSi-m?2kCkFqrbZxC9RaR5G%)QQ$z|^R}7gt?A z1$Y}W-CNFmUZz^HXlN@@@$ zZPz75RXNO=KtKFfkl0v_GZZ_a@w`x=lbR~~C1R~YoyJpux^D)byYtIxY)`Hnfx`MQ zOZ9(6h@rP&{Ra`+{nz_{e2!iF4{QCucm5wV{zDodO7s6u+VG{ul~d^Kx1|=PsbX>3 z@i+N1r}KZ8ueDDzeS-|mh^`tN(QgXB&G_PlVzX^M%eH;Jv3am!g(9B(^3-U#=S7tQ zDYh=bUD~;h?tm>{avD<^>4oCAr#)%hEwvG~`WZ*ec-TJiNL{nudRg${>WP3BH0D9B z)V5ip@jvjmV9YdOVPi6ZAlH5~F5K`JaQ^3I!0(5Q|MTB3uZ&OM8kmN>&|gNyr8fF& z{$E*b)Nrk3F;HY?usYjyL+W( z2Ig-)T7tP#d+Og~i#cXQ`o`Xmn(}L@Zm%LI1(&E_-|gKG7mKtOOK(s;9TO2X1 z6?u6dCVL-F|ChYteu=0)MC0}TEsK!UXEi=)t0O9KzJw0$?5n>Zz9=s&gi^r1aT*@NbB zOWU7jfpXj@o+lHY3%cA4i_so_6r3$kI=l1o80~Ma_MDloqnGE&VMKQ(K3SI$?T1d_ zSP(`d4>(ifq}cj%U%FEqkx|Yl3+atlg{b_E@(ytEU%5P!QcEPEm`W)VYd(8at@jjRrlVpC;htOL& zFxAM&h9<>c%_gRiz{?&9H+Hz-YQv9e;(BgSB%YPN+BmjaU1%adc^DNDOh;Z5Sx_fv z7TVvi_i)m7m_5lM#RIpJ#Z+khO>A7wXv%)bP?9ka_}gU#nRi0WpKtt$nozVge>FZx zIq`SvF?fiTnRN4~T4lI>;bRf}tMM;*EJL)eki{l)FOu0Ne7Ah4$%#K@P-|1i!s$;B z<%_a(o+{7SSNlo2kJ7+f?(Cb}rD;bU*>+v3uC}rnCx& zE4ihwtGxPJW7`Yy)iM@8p`4B9XRuB7*@oVIZ(}g#54?`Ym$0RJRFfW8JP#6MnJS4Xf}ApVT}Kv7SRA9=zp%H>kT8oMa1Pj`@Qs--ZoH=%co`=B`Cv zCdLOPKli0_n7=Q*rZ{o~$)BvP0-7 zu}?vDg?qBA$enXv`>=dHW-D4+DzPFit}DOavrdG1fAF}+zHYFIC<=L_rLi6_eC&d4)hXHQoPs*PUrni_o38UHBz$WVqf%oMSQBo z#88Qe6X*e(}{&bj+a_&>kH}YCK(ctk@MQ3|=-In0P{>dwph_-Jk>kT^t;o~}wwS`18 zo)$i-i4t*Zn9=Du)-^^sGVO&gaOLt9#$P$R5c`ljbT`_LX3OSH*HmeOd@@UYmbqM# z*28uNNu8I~7FmiMw+t{d)p%sDnMPh>Dv^y4U|6#;HXlspc;Q`Uv`%#m(61eGb=E$P z3FYkL_mYZ#P#;YHKy^YTsbEZ8?2(If%6aMy)!&=7dXf|1ZK^3^%=R5qe97ho0ec&9 zR;zpV`8-odrIxys^YA3+zcB&K?l&2iV>hSru*C#Jg#l~Vr8IEj1{j4Ws2afG{ACm! zsvWX6)b}%5Bj-F0y4Cbvtk@`f*Gqj%F}aDhc>WdFvXh&#Ie+5Q%MtmzH9>tcm9B0c z6{RxE_^j`WS?-SyyG(Qv$Po|X4v!X}Hd3&Z2*XmU`1rfrHIJjwYXvMq8J&H{0=R3d zRZ>DrRDYL_YPt~7IQVDYIYWk>xr;Sf6YTu{m!>pWqz(2@@VDkw*T)5~BxG`Inyy3h}_%grssG%?0|pCXb$|aJt>S98GFr zT?kk?`H`gl_UamQbh?F@ntL+K`2hjkjgvMia%+Q%Hn|2Z()CBDLasAx-NwI_36gIn zkYCpNJ9k`=9I}rz`K|Cfn4>UOZ6WynJDuL-K&q3P)25bH;Hl7lMqK?p*TuR1;G_D- zi6MF&9%=YRCO4t9k0QR~o63G!IPS8vuMTV{M)iARX|8g8w9Ht%qo*m&Ir+rnz-Qb% za__%n+2YZ9%Mp6%F2*`G|1Wq0Qg4=~U-?F<$s^ql%=6hB`B>p2^nk%h>s=P(Zh1j!lXtc0#bPzfEV}1GVXW2`G z`$!(5gZ-CDRoNUamLRj2zz`vrOy#yFmg&%O!#P5AfvVZLQx|dGph)!WOfW6BsBrsG{#XiyE#*eO}9} z=giD$u=>M_g%!>b6PVc%q~*rt#rdJ45b^38TdPAvkMhWt&%e^mvrAishyj>&N!g$24VP z5;Lbw9M;k{GJCsj{N{{*KwkWCEJ)?Nc}H))6Cz5Ano{0JeJrnfPevMUfvNm(wREpa z&384sH%W;xx@1Qso4n|NBk1jX^)ZZ_ZBx)Anq_unlsYGrFf()x`B_CU==bGyrWf1~ zVF{VdD)6tG;ZOcHduWLK>B%Gl!{?fA;yOQhS}MqDq8*Pnm=jr1ILNLvk=M7w`F@d^ zAi{EORI`v|XE`QVUv8)Js7H8d(8qgo{c)gTxP4UH)SgseO94euH9>l=v*)v$9Ys0( zl7fYvsKxkwI~~T>8TRGVLwR2uj&>F|CNLy~_hzbcgr5IoDAZJ>s%mC^b7}sK?{Zal zlD#X*5muDvC7kiM(VbTLbVC}O@ASM8I=??+Bhg%7Fw}ChBo?&zo9M0OD45%n_VYC7 z@-$Z1yYqV6n-`BVt}%E~jD;=B%QT{5-N+@^(_Q0c^jVVC_pr(@&i!7py1cF5e~YR0 zd#k>nlUPEkKuYMMd)9_!VGGj*oiL+14SpTd&rSIT1y_q5wIWRm-cNcy>Ug5)$SxeQap>a?*TGI6wTne5$y^>MHWMtb4e;7LT5-5F*-l8EF--5u_&g9z z?3~RlD^mX z>As42N(RX?q`LfmbKMjF_nM3*l3KtdSkvV&gbhg^^Dfe z2yyb7U0C)&$2!R)BKG^DG=1dXnV7PBpF@0qU)N%?MwrUYcsd98qYVR_tK38vl&r_x zSr}pVIrVB+VYa&FkAw?#FDVN}@bE{mjQ>-UW~16&*w28zo{`7W8IhP;bSAfvjbpp( z%{5<2ic_XmZ0LB37S)0=e=9gpq|Zz?=(qDR^>)P0b;Z(1F2iU9gXqn)h;$RD2HarM zcEos>Eu;P0m%b=EP1+|4Z7#aCr#zg;{H7&EDd|yNL34ed3s}YB=DS9Y25z6g~aQ2ZnK-iFV^ryjiYXgz#5M@^YHaLqV851)w(DMx>!#}5ATiG zm>3kQNzP1eiu#<7%1dR9uXMj3I8%^LjG@eH_kLs|-Le|OGpo*8Cx{vKU)xZH6V|63 zE??F#CjDK*AVL-`)G3KnokrC6<{Lz<`T9y>ql1f0;R=zgunaTh{Or`FootzD>+)#2 z5|+-Hr*+FnS8yQVC!MV0th;a3Vt7OrHuo|4LHK_mmd#6f$+Op91{W61oktQYw{tEU zK-ssy-#%<%W;hqx?WD|J8=`?^hj$&9u%<|SdWv~@!_2C?z#yX1$E#Od|+SUSO0DwIk)=fb{FJeRjPZEwf4cF4(0Z_sG;FLW$* zkBi5~apql*(kkiDJatu@SxnJnMZ^vqV-NPoww$n;UwMsr`c zxnjc-SF5P4>2%90S&5+$VJ^2mXn8*MuM1*kY-8t$a&zGPT7UgG%5_n3tK@w3(8 zq5F0oIks8)j0Ki0(FXzP%`bocm)G3?KG>uIi2+Bkn5KVUwQ;lijv(@vP_j_)=05dE zHo*up9nEcd;)OZ;i0@xJlNn@6McdCZ1gO6>HDqXQHS);YeXFbM!{aPzcdDB8Tz`A^ z1Ml3HkLz-oX_sKJDIoHocGmY#tNUt~<>U`HaVSMMTpr*go~?yBUWMs#i%)!)t>(tb zGzY5MhWR*;-N`;YS}UsQx{Vr>a7CHF?mFI|%b{OgKdi8D_aQ~)-0|%>72B@b&QNrA z_&xt4m1{x5`OPWGnhiI@Lm#dam87^|B0MN3oXFA4s{!Dkwjsd@(vRlxcG zHYaEzfEbLxFCcCw$?Ft<6K6QpbVlE1sR7^l=5X|>G{R+7RV;&8J|f&Ah^_0N)%t`Q zyToIkjgAQ|IcD-y9(`p(3HT?kE8oC6omGw-9#{}r=Y9PQ`?|I9ZTheJ`S8*>tBjm5 zC8dq`iRo^|6p$mK_UI~AmyWY*3ACJg<{tW@rn!FQtVZRe+BkFHnHA64*Js|gM@9-aX%A*8 z1#8e!2hY`?-G01qT*K(4t9@T)GjDo@d8;CfUkE z+;;_=$|aW^cVZ8S<$rcGj-i4sqd3;eF$}1HkRf!zg+ybUmau4>T0!yp@RtuG_}huCodec-n$@(~&xJNeA39ZAvBe*ezRl8j(!g20ug*pHV)b@c zt-Mm%G4oRW^f@!!S-I^Fj0DgYjM(#8j~6v)H*&NLTsx7&DDy%$3uUgw>5mO&mHCk^ zH$u17Um?!Qdo#4M`^vWBF|y^@Xu{^Www1P{x#HV&>^s#R^#^`RO4f*uGhND@Zv2|V zh9w!Bog-u%yPRw0h*S$X*J;^W|7}P@-hyS7ce z(3Vdj=C3cgh06Vt^eQBwqk0|8)rK@Y}ExAYF z*4pWFd|fu1l@DpE>Wl8vow9OiSz}3xKf!!sAVDK$!}IMS`APetT<2CJ?Y>w# zF}X!~8N?irmUp)3b1P@y1+dWp+G zX=bGlsna2{{m6tkqnZ-CO($G$+pb3E zm$$Kdm*wVe>l^P2Zl8z-to5QXZBtQ4PAD}yfBXO1`_8bYwr*W4+X5mgO+i2uP>P^J zK&c7>0@5LLA_9gMdJjcKiYP^T?=6&o1OlO}8>s;VLV!@DOH1gz+y#Dnf8Sx>bD#U; z{5U^Y56@b2tvQph<{Wd3ceFXVRhgEO?|NS*c?@(swbV4uWV89B>Bs$gesgot4A#CC zHS?=>4|3|>gof?gO3t?zauW8I+bOEit1Wq@ldmG=Gn>DDisOA(rjBdTo0`5j_*tV9 zH)CniN&Edl$V6C1ra1x~GmCY(pWy{DJK@rs5nS7!797_@X}Qq-j`g%>8S`%5-7U$b z)VqoO=*$}XTWeVKA;ys05WW5*)X1(ztk`Zw#?HYO0yzQ(t+_OQxW&Y+zYvp$N~ z?@d^_ENhmP zGm5kZR^3neWU{%m$=~$ybEBG|M7krFff+55zp1KKe`2CZx2LpGzwFXjVr}CaLnhJi z)nT}>>tv-5Ta<~(&N2mh1N9*)8HH)+Hj5T zho0vzQb6#m8)6`Q>Z9RgraRO(}kmVgmd_?*0nFG6=T@YbPZI{L8beTkW@+WsyvbfK9fh%l7p<&6THb9|Hu~mc`tbd3G zz?TIFwBqUXbYBm$B6{@9FK!C(y8cghrAi2*X1EJLw77Hd0b80|YEk!eRdZFTdH*$B8yEz|xc$mM?iInCnDO9RR~2MSv05aBl3@I~&Sw{~l+cR2S5e5!vi}UV{Jh0&fT)lRoKK?yYbzt&awr@w(orp?bBGXT7Wf z2v5EsQ0S$^DB&UP|M7esBJ|8q2?Cl|*2F3XoBNF-)pZoCCpo z3ofq0J&p3d);Y_miT;|-?45bXNcR@W54vWgvzwC;cICU~$0>X-VyeeWkyK?I-qWqK9WQ{4)cNL#Y4|WBi|G2oqa1uu`G6StZdwhNxTo~TO)3P-4 zfyCqH;MDY>C4V+rVMg7U+DU2=%COtpTL-&4NAM`KqT>WRa_iz2=Yxvz>@+)awMyNX z61y&$0z2)k)-mTCyZ1 z3zOm5z>*a+_;hslbzX=Pmy*>C-X#31g z0j^5+@V8iaEtM?;+JI1Tf)i@PCqBWJkhvvqbmqNrna@b9^%vgsued(;w2>EUr}ux2 zy%;T=Ja{u?`{NnzKelEv(jL!87WoCsOkMEFQkuhA8VkB55xW`uHM2gXGl)bFXB$|u zw0u87DybZ=fNFeN_M^_X)R-z0E561Z$<8h#L;gf7Tn>*kgt9s5P6XwKWw>MZUZV1o z8DH&+r=>Tf^_dmcbGExj&n&kPi|F@~q_)OcnZ#@oF8BOI2Jozx?Y4t*byelxF85M-4zoLRt_v`}EsU`pl0vg#|ACXrvY?o!A%2O&t>&P!{)B zMqvkoaC9LS`|EzR7&aX(LvUXqO{GLmu0G zP|i%g=f67YaxUI=YTAaN&14~Y977U0K8u1*+NjysDAS0I#KqHCd+|!CB-*fXz;>9J z=*gOc_j+-z;uQzY$~sqt^9S_&Ql8qBEjvP6MM^>}yT^cl6W@&$=jW*ughdVFI4bRY znldCC>>CU$qAi^WPNlPPg9iN^m45rv@6yyamD$s~H-F55xD55$6x*As^Zl4^`#X(( zwDXf*AFM5!ub{pyBVczw^ZjFu)Kft-9*d@!b|Q{y-%fJ+V}@{c)ZBDbrIMP}v%(7> z+e#Xf;AM(!rC?66T%olK*ms@Z8vItfb1&-9J7z#`vKO?if}?>1xB7Or4}>Ik#I!g_ zq0={|Wn<%3{!irWeKuB$v&qUH-$X2r{DZ-KV@{dhz2L3lB*~$*{sI=D~Du zW|)a;SGwLx7@O%8hTYASi%IeflFfhz>a)QhF^s$eAfgSsoE_cg*&sWQ$JJx={Y$lu zO^>t|p@8e`gk14Vjdu|DhKs*|s&>vutq9xH2Lt==D^-bn;hMoX=0{+-y<+)UTG2-a!ew2>+rpwUi>J38m{w)ljb!~u2;DfK)u;MJWfZcDn317Xo^UmNx1Oi#6gHu6oXEe|{}xmDJ00Dj)rE-LKRb8k3p zk|Um|q?@5F*IR>BO=RrP=w+=2Pj5@A?F^;|iW4LGnepAN`gsiVYSo#VNM-7<8B>Vn zfEjGhB0O$?qiyafTZ*BSRB6|&R#|1U`E!3zId>K!k2)~v`HcPGD;Pu!kD1!pv+pY# zz5O|6+*!kL|7*<6?+|P-Q_q?JT1@3Nz0t~k__C3 z!wIGJcRBUXHQv>kRwG#G+4ypz_3LR zT6TAw*>?)L1vIPJ#4dLmdh7Dd_iGP0>oqybEQX(`UZlF5`ElfHg^W{8ku>tp6r)K~ z&$tK^MXo&&sguQv)`N-rBH1^wMUXd z{d@uqn+iaW(!P)qHMf`fax69N$RC-A?1N@gRS@BCoI0M)rAjzU1)F zDQaUFGK9VJ$V<|H=pv{4=M8c|1R{w}&gQT@nYC)96x9B96cDDsINa4I zTV~!M#Du9cQe*j8-_q7n+?>@KE2&Meua!~|4>oOQ4OiPSQIWbmRsJxny91G!msvM_ zq3yJhLj5qsofTF6DX(aa8Tr*MZFL_5bl&-Tbw4Mh5~sUp%CGmQis6Qx3bR)HAHqmf zzgBOtPrY((S$180IA3LOjnjJHUJK{$C8!01#;WmYw^D!!QuVE zX+R^&GESIQb-c{CH*SI(j7T+{)Huwpm+I;2?q-W;!|8Od?KnFj?>R!o0dIY98Z)+^ z$02XqR|zyZoRJ5hE^jYP){W2gcF8je-zu_XN^MB0Wg~mVIS<=zI^kape3auwjE1wmtXXOXU+=Kmb(V4EFEj&kg7D3Q6ITn z-{}jRnWe=4=*~H)fD@dZ#3Bf}sZsr*|x!WFu`!k~fe!=zflB2IMd-mZ86dT`7 zR_0S!-&1ARpUGKb2%$TvRKB)a@|5)@a^1(>#!c9sX!WBB*A{^CO)&`dAj5!xe&r zliievi%)#J!k&XM6%`W(#@yab?cEtceD0t~8(u+BuBTomS&5vY@?1wt&KdjFqEdn62QIF5~{Q_ zJmvT(5ezJ-|5@un(~mH*&slJWOn!Cg7KY^Be5E`#x9-)BfHM+2f9fkv%77%gk!`a0 zMpc?MP*Z;=f*4gQP1zXbFNFA}JxAz3&R4Ri2yA3|Ilq*gHb=z?TH&M47T&sHsHwZU z{?J5>R`tOxbJOgK0rqVOjtgJRA6F#UGVT5pM#bB7_g>yAYne=~MflVw=Rubc%)&Jx zx9;hyKT>1lqTmU-s0ulS3zd$5W2+KcIR|=FP?zUV6A!OWEx{Vn$AUASX9%NTIJLXlhR<_O&ds>_@&~KNjgoI!k z__)m>ZpE3ccD)SGv#Vb=$*~ieGtY~A@n&5;$R(AnVnMO>=*z22RUGXu==P8J#k1V#-x+34mK`8dU<}hg?la+~+w5Mj+n?9eY-tNegV^sZ3b-4{b&zYi&*~}g4Ap%VgwDjhEQ_gssNcwm{EbJEp`|~-HD5f~jTv^Gc&Dpdd7VPnupLrw9uYxJ_9D=xXaU;4!3M?L90l>jxJ2cP)I^!Ts4|9XYoIP~HC*M|ppbvKX7?Z4V+KRpNJ+5g{;|3|>{QLFl2ALqGwRA>BG z&1>m*WQVyif3^JkS`={9D)3ho-R0w#`Trc5x=|YDh<2fzg#zZYulc@TZ})Ib4k4XB z?8$|*K1aI#r^3zrC&|h_sEkv9r)Zo&t?@Dmjw~?%BF1Vw%Qyndd%yb-)UoTWtM3-4 zsud-_7^@;OHHpn4-M!@|24$(uO9@RWTXX_!qU-C;1=Kw^-k2T!QccP8GWWkm?_bxQ z)N=zwHYUzq*Y~+1g=cpBl1U_0(We z+p9q}Ge^;FJUQfiWFP(!lXmyhVcedB?AS^1CY-}k*OX8L9H&rj)r^7iiZ!ayYU zf%iwV{4M5jQO)&{LB{Bg=2b7Zkd1B<1@`h|P2yh6t)Ie%tR38lhuX|NFK%$nRwT|~ zW|=lma$WRRK7*T52G*wkvNR#XJuu^C|GdW7h`op2I}6u#yQ*+Sgo6>OnYlVRxKyct zE?|gR%V~hjyJ4AceLjd)ZeMSUXLn>~j^G>6)r+}yI9NOuM<;LDJD6w4&MZ`iRaCa4 z@JuA5H4uH_d!dV65w#gQ|4Do`898zTb19?84F^j|rs|n&8>_gBUL3d=FRCm|Oa7Er z_)1jvot&#ZA`RhT2^Q?NuHg~rk;#)4oA;*4o6tDEbrTg&ujDfmd^I5-!8B*}zin?t zXhSmZR#@BvrTzpEz+J;lJb}%rrSQq-+Ue2<^wyLt=Q;aEHAD2mDoU4KJZF*%bjsN> zDles-fUIFS$p<+iV#4yN%Aw~&{6W7M)h)5Z#t!+(R0dk+JW2zm(fpS}ZIs`t0Lupf zN7~ zLt5CJ{4@5TQj!T{Opx)tGp^r!$UllqfY{t&v+!{~F^@>Wmj~m_xtaQAc9S`$ms#{$ zPp@>7GoA+?tIr8nczj|wMF4v4A-$h<5kR=j;EPnv^Z|6G&e6pM3poT5*jBlAYdzr7 zZ+2UD{~zy2c&>7vV3jNXq}o@ddxz6^9q}-L9-xF!mFz<3THT;4(#}c7{MP5yH3oN@ zoWEiLuD4fdSe#J0;~`Ag+wOM%7QlU41eK~ZrgIob(jg6XGj`+^(5b=lyfW9pqUH5) z(|O&Fdi_W}ST*^4H|m{m?LDFHip2fr4KztBG>HzQjW38O#3dOgmlkg=6;E-9jw}Ao z&t-(YofDCt&-_-~@P0vopd9_Aryxr1`n3A~;#afqO%|p`&I&xZcf7Acy}zsQbt$ z)}jVL`iu}SB*i^u32f&c^aK(wT3HpieUiNTT7(Ea9Tq(jby`fzwY%E-`EJ80h6|N8 zN?hxTc!CDCb(JE4|71vCqk zP{x;uL;Z0)g|`Kwa~|w}HF)Gb$2(HLz*si)g zGu0hHcMk<3zrKy+u;uCMald;wSYUr94ajGu$*PhDqJvWB>??8oS5zEDkrZK8IZstcN}yX!@}-q1hZH-V?WOv09lwr5s}^)_BgO1xmP z;HuW+m%cPF*ILV7;rGH}^clq0Z;YY5a-wkKSq09(?aN8qJUD)IkNJ={kwyL^W$Gf) z+U=Y89~WSVKa42Pq-jb<)u&;yl(O*>3gH&oK7IXd4E*hxpZ z4lexeae|WBF0bLz8A{^$J6zdSkzcJwo@}1Y3t&hu{P{-I~3W8!Ocd8n!^_uXlmWr;=<4>0R|i9;DUZhue1&WkmRV);TwO)xCjV zE6+yoMuK)(*MfnNkY&*9aMkRE!;z}Fb5v}82+$k!GVj0_iqC7byHDuy70j$?TI@uO z6TyPeXvv}@Y5Z&YuHK+jNOl?9uXxKrST$$t#H<-Ql4fC3V7a8sbpn#yp`ETJ zX3go!Q+tCkDw++m>_cUl&o-dHcKx{@$oWTZPfwV#*@K)Kq0DUNm|^YTzz6w{K#iN~ z=T2+~D}-q#)-by@OQxVu1*A{jo~43~x`m~9*F+DrBgz@*ZtNL0|)|+6o@aXBX(Uz{j)!Xt61puoRd8w{k z>Nl=`wQrVh|H<6MbkL~;S2rIKlxNk;NEQY-1nwnZ-{p=nu zE2zX`Vovs8kpN(0FrlO3QTorT@=nctS2P_(5gnh3L~$qIpkfcgbHaM&HI&T*O5!}s z)}AGADJyVupML*s+k?E3+dJ~UL1=M727Alk-stq72f)Z0*JhA311tJqE*k!1b#u%; zS8~Jt3#M{{a+~JiP~n%#3n#__5Peb=U?nv2&V{7zAB&-qHfJWU=*CqPxpeb#q4$)bzt3V%Lor*l;4hWes7w+Iznc}4aNZN;w$muNj<`x2AsKkE79w>%}!KU&q; z+tVHSp?;V3kMD^~TMo&}M4jgVs`!-_0mCx42u3mzKK`Bu*8fld3N8cah`!a)eRs*G zpeFbJImRLA1s~ywME-yoaM^y=I&RNM+bA5G2SIz*_)?rGT*zsVP%!BnEQph+;hF^x z4+&bnK-t??I2tbQY7(@e64sjBR`!LYAM&e+{R*kNzAS>3ttOxpO!fsty(@v@?%~O; zowl#c!1?q4+!|GJ9CbO5NY&(?dQ@{jTrAPTo_%mZ)rzkslIL}BGb=gU664TGh9*Yg z(k{q@;9H(E5=jZ0Pu?Ch-u4V^pE^s9lL}AH`|j~J@jF&tD)xY0 zrMC9_D&Yi<^gCqV&dS(Q|9K|kG5M_<74H} z^wQ6OgXtE{s~9 z`$m`SHal`%EHTLEWDni)&!1ewn^uK3#F4~ZS%<0l7HoCR_QuX83Nij++aJ{*Bk95L zNBc|W>-oF}Bs1{3VY|K4y_S$#7yCui58DI-`0VgOpEOq3*#pPm2cV3^FD@=_juFZV z-IaiaUiA6a4^3TlzD^6QxLAXQ`MH0%Y3XTdGP0enfx|UBfv03-`@lM;)rX~jpMJhQ;#DD&JYDzi>Vwjyf28$a z`i~VV4%@!_k3~feAKduQ&3F%={O4jThY!yEwTt569dLRaaQv^39rp@A3CFYo=)T7@ zh>Yx*uK*#W$K3W<1|7=CW669B5)KLB7$h8nghN6&1_?kn9D{^okZ?E~julm)8;(K3 zF-SO^4gX^x0n%G$d|;q_{baAFt5=ozx3Ti@H-OWH?0W0g&A~c_aYmExJBfI!@1 zxqK`#j#!BafNVTw1;?!5m=zqef@4;2peXz=H$HR^F)?VJkXEG;BMC(a=dhCt ze<8aW^!oM9$3GDx6!)I6alYAvH|i3x{Mm2B4mR}p_i=0vJvN6PQp5k4IrQJObx=BX zJ{>!s4k_Z&ag^k-^XY&Rj>A}iPWWHVZ5vGqt39_4XYJpo*D%6r@jSjj>+dJO3j{PI z8V0eh{+&DYcV#aSZ*K+fU2~mf|NGftVWC;f8eX2@P-C<0I14&j=P5e1Q!XkoWWDX& zag&(G4<9Ob>6*K4>E+t@IQr`Qq*W0rA~n ADgXcg literal 0 HcmV?d00001 diff --git a/BillNote_frontend/src/App.tsx b/BillNote_frontend/src/App.tsx index be5d160..d385195 100644 --- a/BillNote_frontend/src/App.tsx +++ b/BillNote_frontend/src/App.tsx @@ -11,6 +11,8 @@ import Transcriber from '@/pages/SettingPage/transcriber.tsx' import ProviderForm from '@/components/Form/modelForm/Form.tsx' import StepBar from '@/pages/HomePage/components/StepBar.tsx' import Downloading from '@/components/Lottie/download.tsx' +import Prompt from '@/pages/SettingPage/Prompt.tsx' +import AboutPage from '@/pages/SettingPage/about.tsx' function App() { useTaskPolling(3000) // 每 3 秒轮询一次 const steps = [ @@ -33,7 +35,10 @@ function App() { {/*} />*/} } /> - }> + {/*}>*/} + }> + }> + } /> } /> diff --git a/BillNote_frontend/src/components/LazyImage.tsx b/BillNote_frontend/src/components/LazyImage.tsx new file mode 100644 index 0000000..a28c17b --- /dev/null +++ b/BillNote_frontend/src/components/LazyImage.tsx @@ -0,0 +1,34 @@ +// components/LazyImage.tsx +import { useInView } from 'react-intersection-observer' +import { FC, useState } from 'react' +import clsx from 'clsx' + +interface LazyImageProps { + src: string + alt?: string + className?: string + placeholder?: string +} + +const LazyImage: FC = ({ src, alt, className, placeholder = '.src/assets/placeholder.png' }) => { + const { ref, inView } = useInView({ triggerOnce: true, threshold: 0.1 }) + const [loaded, setLoaded] = useState(false) + + return ( +
+ {inView ? ( + {alt} setLoaded(true)} + className={clsx('transition-opacity duration-300', loaded ? 'opacity-100' : 'opacity-0') + ' h-10 w-14 rounded-md object-cover'} + /> + ) : ( + loading + )} +
+ ) +} + +export default LazyImage diff --git a/BillNote_frontend/src/components/ui/tabs.tsx b/BillNote_frontend/src/components/ui/tabs.tsx new file mode 100644 index 0000000..3d6f3ac --- /dev/null +++ b/BillNote_frontend/src/components/ui/tabs.tsx @@ -0,0 +1,64 @@ +import * as React from "react" +import * as TabsPrimitive from "@radix-ui/react-tabs" + +import { cn } from "@/lib/utils" + +function Tabs({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function TabsList({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function TabsTrigger({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function TabsContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Tabs, TabsList, TabsTrigger, TabsContent } diff --git a/BillNote_frontend/src/constant/note.ts b/BillNote_frontend/src/constant/note.ts new file mode 100644 index 0000000..679e677 --- /dev/null +++ b/BillNote_frontend/src/constant/note.ts @@ -0,0 +1,19 @@ +/* -------------------- 常量 -------------------- */ +export const noteFormats = [ + { label: '目录', value: 'toc' }, + { label: '原片跳转', value: 'link' }, + { label: '原片截图', value: 'screenshot' }, + { label: 'AI总结', value: 'summary' }, +] as const + +export const noteStyles = [ + { label: '精简', value: 'minimal' }, + { label: '详细', value: 'detailed' }, + { label: '教程', value: 'tutorial' }, + { label: '学术', value: 'academic' }, + { label: '小红书', value: 'xiaohongshu' }, + { label: '生活向', value: 'life_journal' }, + { label: '任务导向', value: 'task_oriented' }, + { label: '商业风格', value: 'business' }, + { label: '会议纪要', value: 'meeting_minutes' }, +] as const \ No newline at end of file diff --git a/BillNote_frontend/src/index.css b/BillNote_frontend/src/index.css index d1bcf28..0fc8f14 100644 --- a/BillNote_frontend/src/index.css +++ b/BillNote_frontend/src/index.css @@ -4,6 +4,7 @@ @custom-variant dark (&:is(.dark *)); html, body, #root { height: 100%; + overflow: hidden; } /* 修改滚动条轨道颜色 */ diff --git a/BillNote_frontend/src/layouts/HomeLayout.tsx b/BillNote_frontend/src/layouts/HomeLayout.tsx index 7bb55f5..9e07538 100644 --- a/BillNote_frontend/src/layouts/HomeLayout.tsx +++ b/BillNote_frontend/src/layouts/HomeLayout.tsx @@ -10,6 +10,7 @@ import { import { useState } from 'react' import { Link } from 'react-router-dom' import { ResizablePanel, ResizablePanelGroup, ResizableHandle } from '@/components/ui/resizable' +import {ScrollArea} from "@/components/ui/scroll-area.tsx"; interface IProps { NoteForm: React.ReactNode @@ -47,7 +48,9 @@ const HomeLayout: FC = ({ NoteForm, Preview, History }) => { -
{NoteForm}
+ +
{NoteForm}
+
@@ -56,7 +59,9 @@ const HomeLayout: FC = ({ NoteForm, Preview, History }) => { {/* 中间历史 */} diff --git a/BillNote_frontend/src/pages/HomePage/Home.tsx b/BillNote_frontend/src/pages/HomePage/Home.tsx index d72ff2f..1dc1d16 100644 --- a/BillNote_frontend/src/pages/HomePage/Home.tsx +++ b/BillNote_frontend/src/pages/HomePage/Home.tsx @@ -36,7 +36,7 @@ export const HomePage: FC = () => { return ( } - Preview={} + Preview={} History={} /> ) diff --git a/BillNote_frontend/src/pages/HomePage/components/MarkdownHeader.tsx b/BillNote_frontend/src/pages/HomePage/components/MarkdownHeader.tsx new file mode 100644 index 0000000..65e343a --- /dev/null +++ b/BillNote_frontend/src/pages/HomePage/components/MarkdownHeader.tsx @@ -0,0 +1,167 @@ +"use client" + +import { useEffect, useState } from "react" +import { Copy, Download } from "lucide-react" +import { Button } from "@/components/ui/button" +import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/ui/select" +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" +import { Badge } from "@/components/ui/badge" + +interface VersionNote { + ver_id: string + model_name?: string + style?: string + created_at?: string +} + +interface NoteHeaderProps { + currentTask?: { + markdown: VersionNote[] | string + } + isMultiVersion: boolean + currentVerId: string + setCurrentVerId: (id: string) => void + modelName: string + style: string + noteStyles: { value: string; label: string }[] + onCopy: () => void + onDownload: () => void + createAt?: string | Date + setShowTranscribe: (show: boolean) => void +} + +export function MarkdownHeader({ + currentTask, + isMultiVersion, + currentVerId, + setCurrentVerId, + modelName, + style, + noteStyles, + onCopy, + onDownload, + createAt, + showTranscribe, + setShowTranscribe + }: NoteHeaderProps) { + const [copied, setCopied] = useState(false) + + useEffect(() => { + let timer: NodeJS.Timeout + if (copied) { + timer = setTimeout(() => setCopied(false), 2000) + } + return () => clearTimeout(timer) + }, [copied]) + + const handleCopy = () => { + onCopy() + setCopied(true) + } + + const styleName = noteStyles.find((v) => v.value === style)?.label || style + + const reversedMarkdown: VersionNote[] = + Array.isArray(currentTask?.markdown) ? [...currentTask!.markdown].reverse() : [] + + const formatDate = (date: string | Date | undefined) => { + if (!date) return "" + const d = typeof date === "string" ? new Date(date) : date + if (isNaN(d.getTime())) return "" + return d + .toLocaleString("zh-CN", { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + }) + .replace(/\//g, "-") + } + + return ( +
+ {/* 左侧区域:版本 + 标签 + 创建时间 */} +
+ {isMultiVersion && ( + + )} + + + {modelName} + + + {styleName} + + + {createAt && ( +
+ 创建时间: {formatDate(createAt)} +
+ )} +
+ + {/* 右侧操作按钮 */} +
+ + + + + + 复制内容 + + + + + + + + + 下载为 Markdown 文件 + + + + + + + + 原文参照 + + +
+
+ ) +} diff --git a/BillNote_frontend/src/pages/HomePage/components/MarkdownViewer.tsx b/BillNote_frontend/src/pages/HomePage/components/MarkdownViewer.tsx index 0102f40..890c740 100644 --- a/BillNote_frontend/src/pages/HomePage/components/MarkdownViewer.tsx +++ b/BillNote_frontend/src/pages/HomePage/components/MarkdownViewer.tsx @@ -1,30 +1,38 @@ -import { useState } from 'react' +import { useState, useEffect } from 'react' import ReactMarkdown from 'react-markdown' import { Button } from '@/components/ui/button.tsx' -import { Copy, Download, FileText, ArrowRight } from 'lucide-react' -import { toast } from 'react-hot-toast' // 你可以换成自己的通知组件 +import { Copy, Download, ArrowRight,Play } from 'lucide-react' +import { toast } from 'react-hot-toast' import Error from '@/components/Lottie/error.tsx' +import Loading from '@/components/Lottie/Loading.tsx' +import Idle from '@/components/Lottie/Idle.tsx' +import StepBar from '@/pages/HomePage/components/StepBar.tsx' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' import { atomDark as codeStyle } from 'react-syntax-highlighter/dist/esm/styles/prism' import Zoom from 'react-medium-image-zoom' import 'react-medium-image-zoom/dist/styles.css' - -import 'github-markdown-css/github-markdown-light.css' -import { FC } from 'react' -import Loading from '@/components/Lottie/Loading.tsx' -import Idle from '@/components/Lottie/Idle.tsx' -import { useTaskStore } from '@/store/taskStore' -import StepBar from '@/pages/HomePage/components/StepBar.tsx' import gfm from 'remark-gfm' import remarkMath from 'remark-math' - -import 'katex/dist/katex.min.css' - import rehypeKatex from 'rehype-katex' import 'katex/dist/katex.min.css' +import 'github-markdown-css/github-markdown-light.css' +import { FC } from 'react' +import { ScrollArea } from '@/components/ui/scroll-area.tsx' +import { useTaskStore } from '@/store/taskStore' +import { noteStyles } from '@/constant/note.ts' +import { MarkdownHeader } from '@/pages/HomePage/components/MarkdownHeader.tsx' +import TranscriptViewer from "@/pages/HomePage/components/transcriptViewer.tsx"; + +interface VersionNote { + ver_id: string + content: string + style: string + model_name: string + created_at?: string +} interface MarkdownViewerProps { - content: string + content: string | VersionNote[] status: 'idle' | 'loading' | 'success' | 'failed' } @@ -36,227 +44,396 @@ const steps = [ { label: '保存完成', key: 'SUCCESS' }, ] -const MarkdownViewer: FC = ({ content, status }) => { +const MarkdownViewer: FC = ({ status }) => { const [copied, setCopied] = useState(false) + const [currentVerId, setCurrentVerId] = useState('') + const [selectedContent, setSelectedContent] = useState('') + const [modelName, setModelName] = useState('') + const [style, setStyle] = useState('') + const [createTime, setCreateTime] = useState('') + const getCurrentTask = useTaskStore.getState().getCurrentTask const currentTask = useTaskStore(state => state.getCurrentTask()) const taskStatus = currentTask?.status || 'PENDING' const retryTask = useTaskStore.getState().retryTask - let firstHeadingRendered = false + const isMultiVersion = Array.isArray(currentTask?.markdown) + const [showTranscribe, setShowTranscribe]=useState(false) + // 多版本内容处理 + useEffect(() => { + if (!currentTask) return; + if (!isMultiVersion) { + setCurrentVerId('') // 清空旧版本 ID + setModelName(currentTask.formData.model_name) + setStyle(currentTask.formData.style) + setCreateTime(currentTask.createdAt) + setSelectedContent(currentTask?.markdown) + } else { + const latestVerId = currentTask.markdown[currentTask.markdown.length - 1]?.ver_id + setCurrentVerId(latestVerId) // 重置为最新版本 + } + }, [currentTask?.id,taskStatus]) + useEffect(() => { + if (!currentTask || !isMultiVersion) return; + + const currentVer = currentTask.markdown.find(v => v.ver_id === currentVerId) + if (currentVer) { + setModelName(currentVer.model_name) + setStyle(currentVer.style) + setCreateTime(currentVer.created_at || '') + setSelectedContent(currentVer.content) + } + }, [currentVerId, currentTask?.id]) const handleCopy = async () => { try { - await navigator.clipboard.writeText(content) + await navigator.clipboard.writeText(selectedContent) setCopied(true) toast.success('已复制到剪贴板') setTimeout(() => setCopied(false), 2000) } catch (e) { - toast.error(`复制失败${e}`) - toast.error('复制失败', e) + toast.error('复制失败') } } const handleDownload = () => { - const currentTask = getCurrentTask() - const currentTaskName = currentTask?.audioMeta.title - - const blob = new Blob([content], { type: 'text/markdown;charset=utf-8' }) + const task = getCurrentTask() + const name = task?.audioMeta.title || 'note' + const blob = new Blob([selectedContent], { type: 'text/markdown;charset=utf-8' }) const link = document.createElement('a') link.href = URL.createObjectURL(blob) - link.download = `${currentTaskName}.md` + link.download = `${name}.md` document.body.appendChild(link) link.click() document.body.removeChild(link) } + if (status === 'loading') { return ( -
- - -
-

正在生成笔记,请稍候…

-

这可能需要几秒钟时间,取决于视频长度

+
+ + +
+

正在生成笔记,请稍候…

+

这可能需要几秒钟时间,取决于视频长度

+
-
- ) - } else if (status === 'idle') { - return ( -
- - -
-

输入视频链接并点击“生成笔记”

-

支持哔哩哔哩、YouTube 等视频平台

-
-
- ) - } else if (status === 'failed') { - return ( -
- {/* 你可以换成 Failed 动画 */} -
-

笔记生成失败

-

请检查后台或稍后再试

- -
-
) } + if (status === 'idle') { + return ( +
+ +
+

输入视频链接并点击“生成笔记”

+

支持哔哩哔哩、YouTube 、抖音等视频平台

+
+
+ ) + } + + if (status === 'failed' && !isMultiVersion) { + return ( +
+ +
+

笔记生成失败

+

请检查后台或稍后再试

+ +
+
+ ) + } + + return ( -
- {/* 顶部操作栏 */} -
-

- - 笔记内容 -

-
- - +
+ + + {/* 中间内容区域:滚动容器 */} +
+ {selectedContent && selectedContent !== 'loading' && selectedContent !== 'empty' ? ( + <> + +
+ + + ( +

+ {children} +

+ ), + h2: ({ children, ...props }) => ( +

+ {children} +

+ ), + h3: ({ children, ...props }) => ( +

+ {children} +

+ ), + h4: ({ children, ...props }) => ( +

+ {children} +

+ ), + + // Paragraphs with better line height + p: ({ children, ...props }) => ( +

+ {children} +

+ ), + + // Enhanced links with special handling for "原片" links + a: ({ href, children, ...props }) => { + const isOriginLink = typeof children[0] === 'string' && (children[0] as string).startsWith('原片 @') + + if (isOriginLink) { + const timeMatch = (children[0] as string).match(/原片 @ (\d{2}:\d{2})/) + const timeText = timeMatch ? timeMatch[1] : '原片' + + return ( + + + + 原片({timeText}) + + + ) + } + + // Default link styling with external indicator + return ( + + {children} + {href?.startsWith('http') && } + + ) + }, + + // Enhanced image with zoom capability + img: ({ node, ...props }) => ( +
+ + + +
+ ), + + // Better strong/bold text + strong: ({ children, ...props }) => ( + + {children} + + ), + + // Enhanced list items with support for "fake headings" + li: ({ children, ...props }) => { + const rawText = String(children) + const isFakeHeading = /^(\*\*.+\*\*)$/.test(rawText.trim()) + + if (isFakeHeading) { + return ( +
+ {children} +
+ ) + } + + return ( +
  • + {children} +
  • + ) + }, + + // Enhanced unordered lists + ul: ({ children, ...props }) => ( +
      + {children} +
    + ), + + // Enhanced ordered lists + ol: ({ children, ...props }) => ( +
      + {children} +
    + ), + + // Enhanced blockquotes + blockquote: ({ children, ...props }) => ( +
    + {children} +
    + ), + + // Enhanced code blocks with syntax highlighting and copy button + code: ({ inline, className, children, ...props }) => { + const match = /language-(\w+)/.exec(className || '') + const codeContent = String(children).replace(/\n$/, '') + + if (!inline && match) { + return ( +
    +
    +
    {match[1].toUpperCase()}
    + +
    + + {codeContent} + +
    + ) + } + + // Inline code styling + return ( + + {children} + + ) + }, + + // Enhanced tables + table: ({ children, ...props }) => ( +
    + + {children} +
    +
    + ), + + // Table headers + th: ({ children, ...props }) => ( + + {children} + + ), + + // Table cells + td: ({ children, ...props }) => ( + + {children} + + ), + + // Horizontal rule + hr: ({ ...props }) => ( +
    + ), + }} + > + {selectedContent} +
    + +
    +
    + { + showTranscribe && ( +
    + +
    + + ) + + } + + + ) : ( +
    +
    +
    + +
    +

    输入视频链接并点击"生成笔记"按钮

    +

    支持哔哩哔哩、YouTube等视频网站

    +
    +
    + )}
    - - {/* 滚动容器 */} - -
    - {(content && content != 'loading') || content != 'empty' ? ( -
    - {' '} - ( - - {props.alt - - ), - strong({ node, children, ...props }){ - return {children} - }, - li({ node, children, ...props }) { - const rawText = String(children) - - // 检测是否是“加粗的编号开头项”,比如 "**2. 算法摄影的兴起**" - const isFakeHeading = /^(\*\*.+\*\*)$/.test(rawText.trim()) - - if (isFakeHeading) { - return ( -

    - {children} -

    - ) - } - - return
  • {children}
  • - }, - h1({ node, children, ...props }) { - return ( -

    - {children} -

    - ) - }, - h2({ node, children, ...props }) { - return ( -

    - {children} -

    - ) - }, - - code({ node, inline, className, children, ...props }) { - const match = /language-(\w+)/.exec(className || '') - const codeContent = String(children).replace(/\n$/, '') - - if (!inline && match) { - return ( -
    - - {codeContent} - - - -
    - ) - } - - return ( - - {children} - - ) - }, - }} - > - {content} -
    -
    - ) : ( -
    -
    -
    - -
    -

    输入视频链接并点击"生成笔记"按钮

    -

    支持哔哩哔哩、YouTube等视频网站

    -
    -
    - )} -
    - {/*
    */} - {/* {content ? (*/} - {/* */} - {/* ) : (*/} - {/* <>*/} - {/*
    */} - {/* */} - {/*
    */} - {/*

    输入视频链接并点击"生成笔记"按钮

    */} - {/*

    支持哔哩哔哩、YouTube、腾讯视频和爱奇艺

    */} - {/* */} - {/* )}*/} - {/*
    */} -
    ) } diff --git a/BillNote_frontend/src/pages/HomePage/components/NoteForm.tsx b/BillNote_frontend/src/pages/HomePage/components/NoteForm.tsx index a1f5dbf..a381d0b 100644 --- a/BillNote_frontend/src/pages/HomePage/components/NoteForm.tsx +++ b/BillNote_frontend/src/pages/HomePage/components/NoteForm.tsx @@ -7,9 +7,8 @@ import { useForm, useWatch } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { z } from 'zod' -import { Info, Loader2 } from 'lucide-react' +import { Info, Loader2 ,Plus} from 'lucide-react' import { message, Alert } from 'antd' - import { generateNote } from '@/services/note.ts' import { uploadFile } from '@/services/upload.ts' import { useTaskStore } from '@/store/taskStore' @@ -21,26 +20,8 @@ import {Button} from "@/components/ui/button.tsx"; import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from "@/components/ui/select.tsx"; import {Input} from "@/components/ui/input.tsx"; import {Textarea} from "@/components/ui/textarea.tsx"; +import {noteStyles,noteFormats} from "@/constant/note.ts"; -/* -------------------- 常量 -------------------- */ -const noteFormats = [ - { label: '目录', value: 'toc' }, - { label: '原片跳转', value: 'link' }, - { label: '原片截图', value: 'screenshot' }, - { label: 'AI总结', value: 'summary' }, -] as const - -const noteStyles = [ - { label: '精简', value: 'minimal' }, - { label: '详细', value: 'detailed' }, - { label: '教程', value: 'tutorial' }, - { label: '学术', value: 'academic' }, - { label: '小红书', value: 'xiaohongshu' }, - { label: '生活向', value: 'life_journal' }, - { label: '任务导向', value: 'task_oriented' }, - { label: '商业风格', value: 'business' }, - { label: '会议纪要', value: 'meeting_minutes' }, -] as const /* -------------------- 校验 Schema -------------------- */ const formSchema = z.object({ @@ -118,9 +99,10 @@ const CheckboxGroup = ({ /* -------------------- 主组件 -------------------- */ const NoteForm = () => { /* ---- 全局状态 ---- */ - const { addPendingTask, currentTaskId, getCurrentTask } = useTaskStore() + const { addPendingTask, currentTaskId, setCurrentTask,getCurrentTask ,retryTask} = useTaskStore() const { loadEnabledModels, modelList, showFeatureHint, setShowFeatureHint } = useModelStore() + /* ---- 表单 ---- */ const form = useForm({ resolver: zodResolver(formSchema), @@ -134,21 +116,35 @@ const NoteForm = () => { format: [], }, }) + const currentTask = getCurrentTask() /* ---- 派生状态(只 watch 一次,提高性能) ---- */ const platform = useWatch({ control: form.control, name: 'platform' }) as string const videoUnderstandingEnabled = useWatch({ control: form.control, name: 'video_understanding' }) + const editing = currentTask && currentTask.id - /* ---- 副作用 ---- */ + /* ---- 副作用 ---- */ useEffect(() => { loadEnabledModels() return}, []) + useEffect(() => { + const currentTask = getCurrentTask() + const { formData } = currentTask || {} + if (!currentTask) return + form.reset( + { + ...formData, + extras: formData?.extras || '', + } + + ) + }, [currentTaskId]) /* ---- 帮助函数 ---- */ const isGenerating = () => !['SUCCESS', 'FAILED', undefined].includes(getCurrentTask()?.status) - + const generating = isGenerating() const handleFileUpload = async (file: File, cb: (url: string) => void) => { const formData = new FormData() formData.append('file', file) @@ -162,40 +158,83 @@ const NoteForm = () => { } const onSubmit = async (values: NoteFormValues) => { - const payload:NoteFormValues = { - ...values, - provider_id: modelList.find(m => m.model_name === values.model_name)!.provider_id, + + const payload:NoteFormValues = { + ...values, + provider_id: modelList.find(m => m.model_name === values.model_name)!.provider_id, + task_id: currentTaskId || '', + } + if (currentTaskId){ + retryTask(currentTaskId,payload) + return } + message.success('已提交任务') const { data } = await generateNote(payload) addPendingTask(data.task_id, values.platform, payload) } + const handleCreateNew = () => { + // 🔁 这里清空当前任务状态 + // 比如调用 resetCurrentTask() 或者 navigate 到一个新页面 + setCurrentTask(null) + + } + const FormButton = () => { + + + const label = generating + ? '正在生成…' + : editing + ? '重新生成' + : '生成笔记' + + + + return ( +
    + + + {editing && ( + + )} +
    + ) + } /* -------------------- 渲染 -------------------- */ return ( - +
    {/* 顶部按钮 */} - + {/* 视频链接 & 平台 */}
    {/* 平台选择 */} + ( - - + 哔哩哔哩 YouTube 抖音 @@ -214,65 +253,106 @@ const NoteForm = () => { {platform === 'local' ? ( <> - -
    { e.preventDefault(); e.stopPropagation() }} - onDrop={e => { - e.preventDefault() - const file = e.dataTransfer.files?.[0] - if (file) handleFileUpload(file, field.onChange) - }} - onClick={() => { - const input = document.createElement('input') - input.type = 'file' - input.accept = 'video/*' - input.onchange = e => { - const file = (e.target as HTMLInputElement).files?.[0] - if (file) handleFileUpload(file, field.onChange) - } - input.click() - }} - > -

    - 拖拽文件到这里上传
    - 或点击选择文件 -

    -
    + + ) : ( - + )}
    )} /> +
    - {/* 模型选择 */} - ( - - - - - - )} - /> + ( + + {platform === 'local' && ( + <> +
    { e.preventDefault(); e.stopPropagation() }} + onDrop={e => { + e.preventDefault() + const file = e.dataTransfer.files?.[0] + if (file) handleFileUpload(file, field.onChange) + }} + onClick={() => { + const input = document.createElement('input') + input.type = 'file' + input.accept = 'video/*' + input.onchange = e => { + const file = (e.target as HTMLInputElement).files?.[0] + if (file) handleFileUpload(file, field.onChange) + } + input.click() + }} + > +

    + 拖拽文件到这里上传
    + 或点击选择文件 +

    +
    + + )} + +
    + )} + /> +
    + + {/* 模型选择 */} + ( + + + + + + )} + /> + {/* 笔记风格 */} + ( + + + + + + )} + /> +
    {/* 视频理解 */}
    @@ -293,11 +373,7 @@ const NoteForm = () => { )} /> - +
    {/* 采样间隔 */} { )} />
    + + 提示: +

    视频理解功能必须使用多模态模型。

    + +
    + } + className="text-sm" + />
    - {/* 笔记风格 */} - ( - - - - - - )} - /> + {/* 笔记格式 */} { /> -
    +
    ) } diff --git a/BillNote_frontend/src/pages/HomePage/components/NoteHistory.tsx b/BillNote_frontend/src/pages/HomePage/components/NoteHistory.tsx index e720f6b..0038aa7 100644 --- a/BillNote_frontend/src/pages/HomePage/components/NoteHistory.tsx +++ b/BillNote_frontend/src/pages/HomePage/components/NoteHistory.tsx @@ -1,16 +1,20 @@ import { useTaskStore } from '@/store/taskStore' -import { FC } from 'react' import { ScrollArea } from '@/components/ui/scroll-area.tsx' import { Badge } from '@/components/ui/badge.tsx' import { cn } from '@/lib/utils.ts' import { Trash } from 'lucide-react' import { Button } from '@/components/ui/button.tsx' +import PinyinMatch from 'pinyin-match' +import Fuse from 'fuse.js' + import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '@/components/ui/tooltip.tsx' +import LazyImage from "@/components/LazyImage.tsx"; +import {FC, useState ,useEffect } from 'react' interface NoteHistoryProps { onSelect: (taskId: string) => void @@ -20,20 +24,59 @@ interface NoteHistoryProps { const NoteHistory: FC = ({ onSelect, selectedId }) => { const tasks = useTaskStore(state => state.tasks) const removeTask = useTaskStore(state => state.removeTask) + const [rawSearch, setRawSearch] = useState('') + const [search, setSearch] = useState('') + const fuse = new Fuse(tasks, { + keys: ['audioMeta.title'], + threshold: 0.4 // 匹配精度(越低越严格) + }) + useEffect(() => { + const timer = setTimeout(() => { + if (rawSearch === '') return + setSearch(rawSearch) + }, 300) // 300ms 防抖 - if (tasks.length === 0) { + return () => clearTimeout(timer) + }, [rawSearch]) + const filteredTasks = search.trim() + ? fuse.search(search).map(result => result.item) + : tasks + if (filteredTasks.length === 0) { return ( -
    -

    暂无历史记录

    -
    + <> +
    + setSearch(e.target.value)} + /> +
    +
    +

    暂无记录

    +
    + + ) } + return ( <> +
    + setSearch(e.target.value)} + /> +
    - {tasks.map(task => ( + {filteredTasks.map(task => (
    onSelect(task.id)} className={cn( 'flex cursor-pointer flex-col rounded-md border border-neutral-200 p-3', selectedId === task.id && 'border-primary bg-primary-light' @@ -42,7 +85,7 @@ const NoteHistory: FC = ({ onSelect, selectedId }) => {
    onSelect(task.id)} + > {/* 封面图 */} {task.platform === 'local' ? ( @@ -54,15 +97,15 @@ const NoteHistory: FC = ({ onSelect, selectedId }) => { className="h-10 w-12 rounded-md object-cover" /> ) : ( - 封面 + )} {/* 标题 + 状态 */} diff --git a/BillNote_frontend/src/pages/HomePage/components/transcriptViewer.tsx b/BillNote_frontend/src/pages/HomePage/components/transcriptViewer.tsx new file mode 100644 index 0000000..95c2e2f --- /dev/null +++ b/BillNote_frontend/src/pages/HomePage/components/transcriptViewer.tsx @@ -0,0 +1,117 @@ +"use client" + +import { useTaskStore } from "@/store/taskStore" +import { useEffect, useState, useRef } from "react" +import { Play } from "lucide-react" +import { cn } from "@/lib/utils" +import {ScrollArea} from "@/components/ui/scroll-area.tsx"; + +interface Segment { + start: number + end: number + text: string + +} + +interface Task { + transcript?: { + segments?: Segment[] + } +} + +const TranscriptViewer = () => { + const getCurrentTask = useTaskStore((state) => state.getCurrentTask) + const currentTaskId = useTaskStore((state) => state.currentTaskId) + const [task, setTask] = useState(null) + const [activeSegment, setActiveSegment] = useState(null) + const segmentRefs = useRef<(HTMLDivElement | null)[]>([]) + + useEffect(() => { + setTask(getCurrentTask()) + }, [currentTaskId, getCurrentTask]) + + const formatTime = (seconds: number): string => { + const mins = Math.floor(seconds / 60) + const secs = Math.floor(seconds % 60) + return `${mins}:${secs.toString().padStart(2, "0")}` + } + + const handleSegmentClick = (index: number) => { + setActiveSegment(index) + // Here you could add functionality to play the audio from this segment + } + + const scrollToSegment = (index: number) => { + segmentRefs.current[index]?.scrollIntoView({ + behavior: "smooth", + block: "center", + }) + } + + return ( +
    +

    转写结果

    + {!task?.transcript?.segments?.length ? ( +
    暂无转写内容
    + ) : ( + <> + + +
    +
    时间
    +
    内容
    +
    + + +
    + {task.transcript.segments.map((segment, index) => ( +
    (segmentRefs.current[index] = el)} + className={cn( + "group grid grid-cols-[80px_1fr] gap-2 rounded-md p-2 transition-colors hover:bg-slate-50", + activeSegment === index && "bg-slate-100", + )} + onClick={() => handleSegmentClick(index)} + > +
    + + {formatTime(segment.start)} +
    + +
    + {segment.speaker && ( + + {segment.speaker} + + )} + {segment.text} +
    +
    + ))} +
    +
    + + + )} + + + {task?.transcript?.segments?.length > 0 && ( +
    + 共 {task.transcript.segments.length} 条片段 + 总时长: {formatTime(task.transcript.segments[task.transcript.segments.length - 1]?.end || 0)} +
    + )} +
    + ) +} + +export default TranscriptViewer diff --git a/BillNote_frontend/src/pages/SettingPage/Menu.tsx b/BillNote_frontend/src/pages/SettingPage/Menu.tsx index ad23119..66d261a 100644 --- a/BillNote_frontend/src/pages/SettingPage/Menu.tsx +++ b/BillNote_frontend/src/pages/SettingPage/Menu.tsx @@ -1,4 +1,11 @@ -import { BotMessageSquare, Captions, HardDriveDownload, Wrench } from 'lucide-react' +import { + BotMessageSquare, + SquareChevronRight, + Captions, + HardDriveDownload, + Wrench, + Info, +} from 'lucide-react' import MenuBar, { IMenuProps } from '@/pages/SettingPage/components/menuBar.tsx' const Menu = () => { @@ -25,6 +32,18 @@ const Menu = () => { // }, // //其他配置 // { + // id: 'prompt', + // name: '提示词设置', + // icon: , + // path: '/settings/prompt', + // }, + { + id: 'about', + name: '关于', + icon: , + path: '/settings/about', + }, + // { // id: 'other', // name: '其他配置', // icon: , diff --git a/BillNote_frontend/src/pages/SettingPage/Prompt.tsx b/BillNote_frontend/src/pages/SettingPage/Prompt.tsx new file mode 100644 index 0000000..64752b9 --- /dev/null +++ b/BillNote_frontend/src/pages/SettingPage/Prompt.tsx @@ -0,0 +1,4 @@ +const Prompt = () => { + return
    prompt
    +} +export default Prompt diff --git a/BillNote_frontend/src/pages/SettingPage/about.tsx b/BillNote_frontend/src/pages/SettingPage/about.tsx new file mode 100644 index 0000000..2d11550 --- /dev/null +++ b/BillNote_frontend/src/pages/SettingPage/about.tsx @@ -0,0 +1,226 @@ +import { Badge } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import { Card, CardContent } from '@/components/ui/card' +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' +import { Github, Star, ExternalLink, Download } from 'lucide-react' +import { ScrollArea } from '@/components/ui/scroll-area.tsx' + +export default function AboutPage() { + const images = [ + 'https://common-1304618721.cos.ap-chengdu.myqcloud.com/20250504102850.png', + 'https://common-1304618721.cos.ap-chengdu.myqcloud.com/20250504103028.png', + 'https://common-1304618721.cos.ap-chengdu.myqcloud.com/20250504103304.png', + 'https://common-1304618721.cos.ap-chengdu.myqcloud.com/20250504103625.png', + ] + return ( + +
    + {/* Hero Section */} +
    +
    + BiliNote Logo +

    BiliNote v1.4.0

    +
    +

    + AI 视频笔记生成工具 让 AI 为你的视频做笔记 +

    + +
    + MIT License + React + FastAPI + Docker Compose + Active +
    + + +
    + + {/* Project Introduction */} +
    +

    ✨ 项目简介

    +
    +

    + BiliNote 是一个开源的 AI 视频笔记助手,支持通过哔哩哔哩、YouTube、抖音等视频链接, + 自动提取内容并生成结构清晰、重点明确的 Markdown + 格式笔记。支持插入截图、原片跳转等功能。 +

    +
    +
    + + {/* Features Section */} +
    +

    🔧 功能特性

    +
    + {[ + { title: '多平台支持', desc: '支持 Bilibili、YouTube、本地视频、抖音等多个平台' }, + { title: '笔记格式选择', desc: '支持返回多种笔记格式,满足不同需求' }, + { title: '笔记风格选择', desc: '支持多种笔记风格,个性化定制' }, + { title: '多模态视频理解', desc: '结合视觉和音频内容,全面理解视频' }, + { title: '自定义 GPT 配置', desc: '支持自行配置 GPT 大模型' }, + { title: '本地音频转写', desc: '支持 Fast-Whisper 等本地模型音频转写' }, + { title: '结构化笔记', desc: '自动生成结构化 Markdown 笔记' }, + { title: '智能截图', desc: '可选插入自动截取的关键画面' }, + { title: '内容跳转', desc: '支持关联原视频的内容跳转链接' }, + ].map((feature, index) => ( + + +

    {feature.title}

    +

    {feature.desc}

    +
    +
    + ))} +
    +
    + + {/* Screenshots Section */} +
    +

    📸 截图预览

    +
    + {images.map(num => ( +
    + {`BiliNote +
    + ))} +
    +
    + + {/* Quick Start Section */} +
    +

    🚀 快速开始

    + + + 手动安装 + Docker 部署 + + +
    +

    1. 克隆仓库

    +
    + git clone https://github.com/JefferyHcool/BiliNote.git +
    + cd BiliNote +
    + mv .env.example .env +
    +
    +
    +

    2. 启动后端(FastAPI)

    +
    + cd backend +
    + pip install -r requirements.txt +
    + python main.py +
    +
    +
    +

    3. 启动前端(Vite + React)

    +
    + cd BiliNote_frontend +
    + pnpm install +
    + pnpm dev +
    +
    +

    + 访问:http://localhost:5173 +

    +
    + +
    +

    1. 克隆仓库

    +
    + git clone https://github.com/JefferyHcool/BiliNote.git +
    + cd BiliNote +
    + mv .env.example .env +
    +
    +
    +

    2. 启动 Docker Compose

    +
    + docker compose up --build +
    +
    +

    + 默认端口: +
    + 前端:http://localhost:${'{FRONTEND_PORT}'} +
    + 后端:http://localhost:${'{BACKEND_PORT}'} +
    + + .env 文件中可自定义端口与环境配置 + +

    +
    +
    +
    + + {/* Community Section */} +
    +

    联系和加入社区

    +
    +
    +
    +

    BiliNote 交流 QQ 群

    +

    785367111

    +
    +
    +

    BiliNote 交流微信群

    +
    + +
    +
    +
    +
    +
    + + {/* License Section */} +
    +

    📜 License

    +

    MIT License

    +
    + + {/* Footer */} +
    +

    💬 你的支持与反馈是我持续优化的动力!欢迎 PR、提 issue、Star ⭐️

    +
    +
    +
    + ) +} diff --git a/BillNote_frontend/src/pages/SettingPage/components/menuBar.tsx b/BillNote_frontend/src/pages/SettingPage/components/menuBar.tsx index a49470b..3d02fee 100644 --- a/BillNote_frontend/src/pages/SettingPage/components/menuBar.tsx +++ b/BillNote_frontend/src/pages/SettingPage/components/menuBar.tsx @@ -13,10 +13,10 @@ interface IMenuItem { menuItem: IMenuProps } -const MenuBar: FC = ({ menuItem }) => { +const MenuBar: ({ menuItem }: { menuItem: any }) => JSX.Element = ({ menuItem }) => { const location = useLocation() - const isActive = location.pathname.startsWith(menuItem.path + '/') - || location.pathname === menuItem.path + const isActive = + location.pathname.startsWith(menuItem.path + '/') || location.pathname === menuItem.path return ( diff --git a/BillNote_frontend/src/store/taskStore/index.ts b/BillNote_frontend/src/store/taskStore/index.ts index 1d16e31..45fca45 100644 --- a/BillNote_frontend/src/store/taskStore/index.ts +++ b/BillNote_frontend/src/store/taskStore/index.ts @@ -1,6 +1,8 @@ import { create } from 'zustand' import { persist } from 'zustand/middleware' import { delete_task, generateNote } from '@/services/note.ts' +import { v4 as uuidv4 } from 'uuid' + export type TaskStatus = 'PENDING' | 'RUNNING' | 'SUCCESS' | 'FAILD' @@ -26,10 +28,17 @@ export interface Transcript { raw: any segments: Segment[] } +export interface Markdown { + ver_id: string + content: string + style: string + model_name: string + created_at: string +} export interface Task { id: string - markdown: string + markdown: string|Markdown [] //为了兼容之前的笔记 transcript: Transcript status: TaskStatus audioMeta: AudioMeta @@ -64,6 +73,7 @@ export const useTaskStore = create()( currentTaskId: null, addPendingTask: (taskId: string, platform: string, formData: any) => + set(state => ({ tasks: [ { @@ -95,24 +105,82 @@ export const useTaskStore = create()( })), updateTaskContent: (id, data) => - set(state => ({ - tasks: state.tasks.map(task => (task.id === id ? { ...task, ...data } : task)), - })), + set(state => ({ + tasks: state.tasks.map(task => { + if (task.id !== id) return task + + if (task.status === 'SUCCESS' && data.status === 'SUCCESS') return task + + // 如果是 markdown 字符串,封装为版本 + if (typeof data.markdown === 'string') { + const prev = task.markdown + const newVersion: Markdown = { + ver_id: `${task.id}-${uuidv4()}`, + content: data.markdown, + style: task.formData.style || '', + model_name: task.formData.model_name || '', + created_at: new Date().toISOString(), + } + + let updatedMarkdown: Markdown[] + if (Array.isArray(prev)) { + updatedMarkdown = [newVersion, ...prev] + } else { + updatedMarkdown = [ + newVersion, + ...(typeof prev === 'string' && prev + ? [{ + ver_id: `${task.id}-${uuidv4()}`, + content: prev, + style: task.formData.style || '', + model_name: task.formData.model_name || '', + created_at: new Date().toISOString(), + }] + : []), + ] + } + + return { + ...task, + ...data, + markdown: updatedMarkdown, + } + } + + return { ...task, ...data } + }), + })), + + getCurrentTask: () => { const currentTaskId = get().currentTaskId return get().tasks.find(task => task.id === currentTaskId) || null }, - retryTask: async (id: string) => { - const task = get().tasks.find(task => task.id === id).formData + retryTask: async (id: string, payload?: any) => { + const task = get().tasks.find(task => task.id === id) + if (!task) return + + const newFormData = payload || task.formData + await generateNote({ task_id: id, - ...task, + ...newFormData, }) + set(state => ({ - tasks: state.tasks.map(task => (task.id === id ? { ...task, status: 'PENDING' } : task)), + tasks: state.tasks.map(t => + t.id === id + ? { + ...t, + formData: newFormData, // ✅ 显式更新 formData + status: 'PENDING', + } + : t + ), })) }, + removeTask: async id => { const task = get().tasks.find(t => t.id === id) diff --git a/backend/app/downloaders/bilibili_downloader.py b/backend/app/downloaders/bilibili_downloader.py index f167160..1dcf91e 100644 --- a/backend/app/downloaders/bilibili_downloader.py +++ b/backend/app/downloaders/bilibili_downloader.py @@ -7,6 +7,7 @@ import yt_dlp from app.downloaders.base import Downloader, DownloadQuality, QUALITY_MAP from app.models.notes_model import AudioDownloadResult from app.utils.path_helper import get_data_dir +from app.utils.url_parser import extract_video_id class BilibiliDownloader(Downloader, ABC): @@ -69,10 +70,19 @@ class BilibiliDownloader(Downloader, ABC): """ 下载视频,返回视频文件路径 """ + if output_dir is None: output_dir = get_data_dir() - os.makedirs(output_dir, exist_ok=True) + print("video_url",video_url) + video_id=extract_video_id(video_url, "bilibili") + video_path = os.path.join(output_dir, f"{video_id}.mp4") + if os.path.exists(video_path): + return video_path + + # 检查是否已经存在 + + output_path = os.path.join(output_dir, "%(id)s.%(ext)s") ydl_opts = { diff --git a/backend/app/downloaders/douyin_downloader.py b/backend/app/downloaders/douyin_downloader.py index 7e236d3..869b8ad 100644 --- a/backend/app/downloaders/douyin_downloader.py +++ b/backend/app/downloaders/douyin_downloader.py @@ -249,13 +249,21 @@ class DouyinDownloader(Downloader): ) def download_video(self, video_url: str, output_dir: Union[str, None] = None) -> str: + try: + if output_dir is None: output_dir = get_data_dir() if not output_dir: output_dir = self.cache_data os.makedirs(output_dir, exist_ok=True) + video_id = self.extract_video_id(video_url) + video_path = os.path.join(output_dir, f"{video_id}.mp4") + if os.path.exists(video_path): + return video_path + + output_path = os.path.join(output_dir, "%(id)s.%(ext)s") video_data = self.fetch_video_info(video_url) diff --git a/backend/app/downloaders/youtube_downloader.py b/backend/app/downloaders/youtube_downloader.py index cf46de9..34c6b04 100644 --- a/backend/app/downloaders/youtube_downloader.py +++ b/backend/app/downloaders/youtube_downloader.py @@ -7,6 +7,7 @@ import yt_dlp from app.downloaders.base import Downloader, DownloadQuality from app.models.notes_model import AudioDownloadResult from app.utils.path_helper import get_data_dir +from app.utils.url_parser import extract_video_id class YoutubeDownloader(Downloader, ABC): @@ -67,12 +68,15 @@ class YoutubeDownloader(Downloader, ABC): """ if output_dir is None: output_dir = get_data_dir() - + video_id = extract_video_id(video_url, "youtube") + video_path = os.path.join(output_dir, f"{video_id}.mp4") + if os.path.exists(video_path): + return video_path os.makedirs(output_dir, exist_ok=True) output_path = os.path.join(output_dir, "%(id)s.%(ext)s") ydl_opts = { - 'format': 'worst[ext=mp4]/worst', + 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]', 'outtmpl': output_path, 'noplaylist': True, 'quiet': False, diff --git a/backend/app/gpt/prompt.py b/backend/app/gpt/prompt.py index 4073fed..0e11c6a 100644 --- a/backend/app/gpt/prompt.py +++ b/backend/app/gpt/prompt.py @@ -35,11 +35,10 @@ BASE_PROMPT = ''' 根据上面的分段转录内容,生成结构化的笔记,遵循以下原则: 1. **完整信息**:记录尽可能多的相关细节,确保内容全面。 -2. **清晰结构**:用合适的标题级别(`##`,`###`)整理内容,概述每个部分的要点。主标题用`#`来标识(如果额外重要的任务有格式需求可以不遵守) -3. **去除无关内容**:省略广告、填充词、问候语和不相关的言论。 -4. **保留关键细节**:保留重要事实、示例、结论和建议。(如果额外重要的任务有格式需求可以不遵守) -5. **可读布局**:必要时使用项目符号,并保持段落简短,增强可读性。(如果额外重要的任务有格式需求可以不遵守) -6. 视频中提及的数学公式必须保留,并以 LaTeX 语法形式呈现,适合 Markdown 渲染。 +2. **去除无关内容**:省略广告、填充词、问候语和不相关的言论。 +3. **保留关键细节**:保留重要事实、示例、结论和建议。(如果额外重要的任务有格式需求可以不遵守) +4. **可读布局**:必要时使用项目符号,并保持段落简短,增强可读性。(如果额外重要的任务有格式需求可以不遵守) +5. 视频中提及的数学公式必须保留,并以 LaTeX 语法形式呈现,适合 Markdown 渲染。 请始终遵循此规则。 diff --git a/backend/app/gpt/prompt_builder.py b/backend/app/gpt/prompt_builder.py index 7a1cd97..7860630 100644 --- a/backend/app/gpt/prompt_builder.py +++ b/backend/app/gpt/prompt_builder.py @@ -58,7 +58,7 @@ def get_format_function(format_type): def get_style_format(style): style_map = { 'minimal': '1. **精简信息**: 仅记录最重要的内容,简洁明了。', - 'detailed': '2. **详细记录**: 包含完整的时间戳和每个部分的详细讨论。', + 'detailed': '2. **详细记录**: 包含完整的内容和每个部分的详细讨论。需要尽可能多的记录视频内容,最好详细的笔记', 'academic': '3. **学术风格**: 适合学术报告,正式且结构化。', 'xiaohongshu': '''4. **小红书风格**: ### 擅长使用下面的爆款关键词: diff --git a/backend/app/routers/note.py b/backend/app/routers/note.py index 42f9774..04abb7a 100644 --- a/backend/app/routers/note.py +++ b/backend/app/routers/note.py @@ -217,17 +217,25 @@ def get_task_status(task_id: str): @router.get("/image_proxy") async def image_proxy(request: Request, url: str): headers = { - "Referer": "https://www.bilibili.com/", # 模拟B站来源 + "Referer": "https://www.bilibili.com/", "User-Agent": request.headers.get("User-Agent", ""), } try: async with httpx.AsyncClient(timeout=10.0) as client: resp = await client.get(url, headers=headers) + if resp.status_code != 200: raise HTTPException(status_code=resp.status_code, detail="图片获取失败") content_type = resp.headers.get("Content-Type", "image/jpeg") - return StreamingResponse(resp.aiter_bytes(), media_type=content_type) + return StreamingResponse( + resp.aiter_bytes(), + media_type=content_type, + headers={ + "Cache-Control": "public, max-age=86400", # ✅ 缓存一天 + "Content-Type": content_type, + } + ) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) diff --git a/backend/app/routers/provider.py b/backend/app/routers/provider.py index af1b2d9..06a7ace 100644 --- a/backend/app/routers/provider.py +++ b/backend/app/routers/provider.py @@ -47,26 +47,26 @@ def add_provider(data: ProviderRequest): @router.get("/get_all_providers") def get_all_providers(): try: - res = ProviderService.get_all_providers() + res = ProviderService.get_all_providers_safe() return R.success(data=res) except Exception as e: return R.error(msg=e) -@router.get("/get_provider_by_id/{id}") -def get_provider_by_id(id: str): - try: - res = ProviderService.get_provider_by_id(id) - return R.success(data=res) - except Exception as e: - return R.error(msg=e) - -@router.get("/get_provider_by_name/{name}") -def get_provider_by_name(name: str): - try: - res = ProviderService.get_provider_by_name(name) - return R.success(data=res) - except Exception as e: - return R.error(msg=e) +# @router.get("/get_provider_by_id/{id}") +# def get_provider_by_id(id: str): +# try: +# res = ProviderService.get_provider_by_id(id) +# return R.success(data=res) +# except Exception as e: +# return R.error(msg=e) +# +# @router.get("/get_provider_by_name/{name}") +# def get_provider_by_name(name: str): +# try: +# res = ProviderService.get_provider_by_name(name) +# return R.success(data=res) +# except Exception as e: +# return R.error(msg=e) @router.post("/update_provider") diff --git a/backend/app/services/model.py b/backend/app/services/model.py index cf43dca..61e4112 100644 --- a/backend/app/services/model.py +++ b/backend/app/services/model.py @@ -45,7 +45,16 @@ class ModelService: except Exception as e: print(f"获取所有模型失败: {e}") return [] - + @staticmethod + def get_all_models_safe(verbose: bool = False): + try: + raw_models = get_all_models() + if verbose: + print(f"所有模型列表: {raw_models}") + return ModelService._format_models(raw_models) + except Exception as e: + print(f"获取所有模型失败: {e}") + return [] @staticmethod def _format_models(raw_models: list) -> list: """ diff --git a/backend/app/services/note.py b/backend/app/services/note.py index 56d92d9..d5456e6 100644 --- a/backend/app/services/note.py +++ b/backend/app/services/note.py @@ -140,7 +140,6 @@ class NoteGenerator: replacement = f"![]({image_url})" new_markdown = new_markdown.replace(marker, replacement, 1) - return new_markdown except Exception as e: logger.error(f"截图生成失败:{e}") @@ -201,16 +200,23 @@ class NoteGenerator: # -------- 1. 下载音频 -------- try: self.update_task_status(task_id, TaskStatus.DOWNLOADING) + + # 加载音频缓存(如果存在) + audio = None if os.path.exists(audio_cache_path): logger.info(f"检测到已有音频缓存,直接读取,task_id={task_id}") with open(audio_cache_path, "r", encoding="utf-8") as f: audio_data = json.load(f) audio = AudioDownloadResult(**audio_data) - else: - if 'screenshot' in _format or video_understanding: + + # 需要视频的情况(截图 or 视频理解) + need_video = 'screenshot' in _format or video_understanding + if need_video: + try: video_path = downloader.download_video(video_url) self.video_path = video_path logger.info(f"成功下载视频文件: {video_path}") + video_img_urls = VideoReader( video_path=video_path, grid_size=tuple(grid_size), @@ -219,13 +225,17 @@ class NoteGenerator: unit_height=720, save_quality=90, ).run() + except Exception as e: + logger.error(f"❌ 下载视频失败,task_id={task_id},错误信息:{e}") + self.update_task_status(task_id, TaskStatus.FAILED, message=f"下载音频失败:{e}") - screenshot = 'screenshot' in _format - audio: AudioDownloadResult = downloader.download( + # 没有音频缓存就下载音频(可能同时也带上视频) + if audio is None: + audio = downloader.download( video_url=video_url, quality=quality, output_dir=path, - need_video=screenshot + need_video='screenshot' in _format, # 注意这里只为了截图需要 ) with open(audio_cache_path, "w", encoding="utf-8") as f: json.dump(asdict(audio), f, ensure_ascii=False, indent=2) @@ -266,27 +276,27 @@ class NoteGenerator: # -------- 3. 总结内容 -------- try: self.update_task_status(task_id, TaskStatus.SUMMARIZING) - if os.path.exists(markdown_cache_path): - logger.info(f"检测到已有总结缓存,直接读取,task_id={task_id}") - with open(markdown_cache_path, "r", encoding="utf-8") as f: - markdown = f.read() - else: - source = GPTSource( - title=audio.title, - segment=transcript.segments, - tags=audio.raw_info.get('tags'), - screenshot=screenshot, - video_img_urls=video_img_urls, - link=link, - _format=_format, - style=style, - extras=extras - ) + # if os.path.exists(markdown_cache_path): + # logger.info(f"检测到已有总结缓存,直接读取,task_id={task_id}") + # with open(markdown_cache_path, "r", encoding="utf-8") as f: + # markdown = f.read() + # else: + source = GPTSource( + title=audio.title, + segment=transcript.segments, + tags=audio.raw_info.get('tags'), + screenshot=screenshot, + video_img_urls=video_img_urls, + link=link, + _format=_format, + style=style, + extras=extras + ) - markdown: str = gpt.summarize(source) - with open(markdown_cache_path, "w", encoding="utf-8") as f: - f.write(markdown) - logger.info(f"GPT总结并缓存成功,task_id={task_id}") + markdown: str = gpt.summarize(source) + with open(markdown_cache_path, "w", encoding="utf-8") as f: + f.write(markdown) + logger.info(f"GPT总结并缓存成功,task_id={task_id}") except Exception as e: logger.error(f"❌ 总结内容失败,task_id={task_id},错误信息:{e}") self.update_task_status(task_id, TaskStatus.FAILED, message=f"总结内容失败:{e}") @@ -313,10 +323,11 @@ class NoteGenerator: # -------- 6. 完成 -------- self.update_task_status(task_id, TaskStatus.SUCCESS) logger.info(f"✅ 笔记生成成功,task_id={task_id}") - if platform != 'local': - transcription_finished.send({ - "file_path": audio.file_path, - }) + # TODO :改为前端一键清除缓存 + # if platform != 'local': + # transcription_finished.send({ + # "file_path": audio.file_path, + # }) return NoteResult( markdown=markdown, transcript=transcript, diff --git a/backend/app/services/provider.py b/backend/app/services/provider.py index 9266d3f..3958c8a 100644 --- a/backend/app/services/provider.py +++ b/backend/app/services/provider.py @@ -14,6 +14,7 @@ from app.models.model_config import ModelConfig class ProviderService: + @staticmethod def serialize_provider(row: tuple) -> dict: if not row: @@ -28,7 +29,25 @@ class ProviderService: "enabled": row[6], "created_at": row[7], } - + @staticmethod + def serialize_provider_safe(row: tuple) -> dict: + if not row: + return None + return { + "id": row[0], + "name": row[1], + "logo": row[2], + "type": row[3], + "api_key": ProviderService.mask_key(row[4]), + "base_url": row[5], + "enabled": row[6], + "created_at": row[7], + } + @staticmethod + def mask_key(key: str) -> str: + if not key or len(key) < 8: + return '*' * len(key) + return key[:4] + '*' * (len(key) - 8) + key[-4:] @staticmethod def add_provider( name: str, api_key: str, base_url: str, logo: str, type_: str, enabled: int = 1): try: @@ -42,7 +61,10 @@ class ProviderService: def get_all_providers(): rows = get_all_providers() return [ProviderService.serialize_provider(row) for row in rows] if rows else [] - + @staticmethod + def get_all_providers_safe(): + rows = get_all_providers() + return [ProviderService.serialize_provider(row) for row in rows] if rows else [] @staticmethod def get_provider_by_name(name: str): row = get_provider_by_name(name)