From 5f222a23b3a1884eaf0b4c9ffd2c4a12fcd5c635 Mon Sep 17 00:00:00 2001 From: owenchen Date: Tue, 2 Jun 2026 11:01:00 +0800 Subject: [PATCH] ow --- CloudBuilder.Topshelf.csproj | 2 + Lib/CloudBuilder.AI.dll | Bin 85504 -> 87552 bytes Properties/launchSettings.json | 2 +- Task/AI/ChineseNameExtractorTask.cs | 11 +- Task/TTS/TtsTask.cs | 172 +++++++++++++++++++++++++++- Utility/SpeakerAnalysisHelper.cs | 64 +++++------ 6 files changed, 207 insertions(+), 44 deletions(-) diff --git a/CloudBuilder.Topshelf.csproj b/CloudBuilder.Topshelf.csproj index 2615ab4..56bd339 100644 --- a/CloudBuilder.Topshelf.csproj +++ b/CloudBuilder.Topshelf.csproj @@ -59,6 +59,8 @@ + + diff --git a/Lib/CloudBuilder.AI.dll b/Lib/CloudBuilder.AI.dll index 4b8118e5569f56133fc4d4d73b7dc0a6ecef4bbe..79307400571fded996a5b8d0c1731806c027b1b9 100644 GIT binary patch literal 87552 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 G!2bi`!wG8u literal 85504 zcmdqK33yf2`91vZbBEkakPt{1&2STPGZF+96f}V_M44m~6eSTTM1f!e3XV5|1BzC0 zR;r1h714?nt5&OtC`z5ss@19`acIRl4^^zgf4%GMlYzlnA3vYp^F>)%YwdmZ@b2N9 zd+#|ned?Mnfe48vAP7?PY^qSzKFJ zI|l~ahBmUJWAVGgPbr40xOU#c8f4VA3fjyVjN2>Uhz^I59;Nh$HkNK}D(l6}kKMf$`!!Qz91g(Z=6 z&B#)M#F`8kg*_vg^!4~4%dW`+EikDCCN2Mkj9;C5-0K;6)27{WY=;7B!pJhi+U>{J zVD`n$$WJMWkrUAdggv=?En2dq=Otayq?}Z@`nYbAb4nL9ZH+>azkm0F`0rAc*W{pp zn{(3KPR4gLIj7*jK5G=be9GN?k^ac75y`c`Bl^2NGHN3-biKIv7#B?3J>#O8gDk0Y zT=eMR8H%0ba^(H@Mmxnt3)n|oc;vp~GOtry^ynWG7cK5b$0dMiou7p{LV`eH(Yppo zN{J)0Fiu$G$>R9FGx0Hn{}%qZr9UBU1dy zekP?m5ex~E6u&d6-+m*uVv(Ww#R^_T=k$TLW= zUfdWUAbZ9D&D}Ew-Puvay<(8cBttEfK^mr6eG|5gGI-S?aLA$Hn=2UQ)&tm!9~WoV4_~-=x(HgdbmbATXge z&L>L}(^C8rlM+Zx2@Y9{mL&(0gV(3Th?5-Sk6Juf+eajH#4NU-zNPSW4;{>V@?3v)RkRG5Yd7jtQK+KdP`Gz^0Bnf{wGmWin; z{(>Q~$^Pq80)ob-MKHv1+VH|Y608{pk=`AFi%E_tM4UqfJ<|Xw;zlIdAA4!_fz9em zatQ6~gS~qN+83wo^GAleEr<&i#zGwqh5gP~gZ9S77Yy%aBBfvn;)H4%5Odv~gSAW0 zdM<@Te{2LZfXg&g^9@EPG6FJ!a|4RU!Q~)DfBbvbZsxnxZn~w8(v;WpQNO|V=t#O8 zSuI%8?m1-we&cMCERoU37bn4Z>jf$#X-?$1T{ zb*DhK)bzPEW8G}NlmPl1=rD_Qe?A9w;5@5i^Bx*pnBe}t6vKdX5jH2M;KaHLR_~@H zq$U;&55-=O+2#0>{gEt$puex?Lwm6P#=$8P>_^TBcu`Dk6g?>j)ULv>nlCjObG>F7>cUJ0%Y}t?5+90S z7cIa}p#e`wPACk;glw$Qwqub0&>2|Em~*k;rKYvdIbTeN@FR$JIoNr4tK2os*m-EA zH#*wIog=!NL^S$XA^z0(0)HB}NOwOx8~OCdsl5=bJ_}RV@9mgQ-3%O*Q`>-q+6{oZ znb0-I0wkyQHgy#`xwuSRQoDIicZ<6BcXrRh?t-eYR56u)x3B7bIYq(#Y(uBK+HOBq zrs$%>x#$cnsOC7dN{3O`P#Svk5NbQ14rlGSvoMAIL*79jYafN_=0AIqH;X2Md>1@G zXVLMj

A66c zqYh`6sar!_l)yR?TpUDl9&D90uorF@lCU-47M!1IKu!)7RWZiWeOipl@ zbC8SFuFe=N<@lN}xKe#JpW?T>s)MzK+SE@pAry31uy|cWa65F-Z9`&mVp|)Ml9Tq= zhD5Io9d?NQx1n^OZD0UmYfeHOc(o9!IT`fOIp1N!NKFnc%g~WYPEIZiB`4c+6(U!& z5SiSzVsC3}Yq#WX`)g~!YpZT*KP6tFlo)JKF_@2Kef2ykawPt3z)0eJBe-hgkDkvk zJuy-B9O6z=UBe-qiiW(51bh7vtSv`4YR3X1i_jNb8FOFK9jIn84DL|ekX*@~s6AEp zqz)5 zKx8Qo?3_Qx&5!-~$K}T}mCXOO_a z8PUx_0t4qI*C2s`6O(I@z`#k$HArCK{NNfSFmP&c4H6jG{au3u2DX3KAi-2jDKUC& zC%6p6>jzv>1mg-Mm|u)=r|AOIYa)G})Pg)+IG^#t5GUOPsl6RDq3%=!;dIAWgPsQ? z=xq=O)}WI?J?B%PKfwt4K!K(QBWNxKS{aO>WfW*oP){xtl`5*Nz*ZfMV25T3cI03L zn=u9U<6s2)E5!m8*hzxo$K~R|+Kx_D|Cl2MuUFl8q-bAjUqKfc55@rNSzJF5lqEj* zWv505^QX-`wo{+*QVW-xZk!$Ifq3JeH(!H}o-S}<%1c1JI9{%e;5z__s5{+B zF#nO{8YD1Qcm@fK(>;R(#u=VL0^>~2Ac1j~XOO@++cQXD;MI*=EeVXMXOO_C_Y4vk z=XwT7+d55Uzp*2BT&HWa`|di$rT!1DQ*4;Q2sTVEnWZY0S%H-t)G5dmgeMq5NGK4A zUR@E06{}R7XT|v{F0kT46{}UWE!zLNh59x~ zTYTL0c`9bpzSix|*q?XZ9v8Qdb-OtJmsz)3dE2t;v~D}4{PcBuE;`ay!OygA)7s}R z*6qbQ@@?xD^Ubc?-*}Us1gqgj&me(ulV^~?Xz&aY7>%Am0^?@SAc3*oGe}@;@C*_d zw|EALcW&s(K3tBrcQ{wxs$Fr{;5N+1A39gAMb^j_njhz=D^*-&#nmdVvEo`4*I9AB ziW{t0rvjm20fWg-*l|tXIfjm+UF(K7N%^6wS_(0uB|_MbD9K`{6Wtk zf$@-MkihtpXOO^n*fU6AJmMK7Fq%Ar1V*!GkidA1tSO%1tJrSAQ~MO-~W6h_mhs-qusjfd+nXp_2*rCU!%Oeu19~V^O{z^@3q${ z<)^PbUvh^Eex|k8r+toM?O~30SbJx*t-Zf_Q=9~I{x#1af$_R$kidAuGe}_k-7`pF z?DPy07%iSb0;AP4NMO9_86+^?@(dCfZ+iv_jCVYP1jau+g9OGuJ%a?syPiSPzMlIs zR!<;C9o94QcMa8RDV8ntEj1rH*-~=NW5DJV#FoM`qAmqUa!c2ka1|x_l1p*n2Ab1@% zg#WoCd%ix+#Z2DUx%k6wKkt4}pR$kr;Pvjm%yq6-zVH2@Q_4@@557Z3+A8>&_Je-y za~%5tRz!#W;Pkfr0H43OuM0`AWa2!71V+4Pkibar3=$ZLonVDSpOfZ_{54&ReWZ}=PJIi;@>L1wBjojyRG`I>2oDUVVh0v9-Or{h!O+>l)y|9{XPN&!qmmYkp+f zKGyuDJ%5=sua&ng$xhebol<`Kn!gntX{+F8TJ!1c^BQX&3%0|WKcj8UALK0y60DPh zJ%a=W?tO6=4hf7QoxQdBrt|~1__Meo`CGfxAs7ficoENZR*+48{uEO~*apKn@(dCf^F4zE#sbeEfl=)lBrs0$3=$Y8dj?6{xjBn% z#>UfeT^^}Tch@Ce`2OH)ZR}9N2zDhdMQldF2sR)J>^s2-_8JOoF~JD76$qjPpE$1jhNEK?36f&me(up=Xf5SnU}kFfQ^85*QbI z1__KcoiG zF;*R3+avDY{&C`exwfB#tdXNNKQ6N;tC(WNR29>#n6Ba&D`u#eX~nTBj)rcOTdMtCsg>Ax6HTvjBxp7O6#Z6f~ zFF6L7lN#LdH&h=vU;X3Y=;yooEJtw1>-+F~UNV_S?YOXWiFzas+JVo5J61$HauLk5 zONO}B-5iNWGi&g=Un~UyRRv>`)AMSoGZ6I zm!^2RW_Heno5O>3m$F7p(FY|E%CnE{oGY)rEKTtO-bDkBu(~%hbqx5gQQ{6=`65p7IP57*Bf!35;hv zg9OI2o`Brsm^3=$ZB@eC3eFM0+EjF&uv1jfsrK?38ioyM7->pyTW!TH0H|8~B{g-S4TvF69Q2-hUR2(CjYaQP98 z{Mw4kR9tSwS`}AVaixl@thidmHC9}!;yNp?S8;s0*4iW^njWJQCDMk{VsvEGUe zDsHjjRu#Xs;x-i*m?JL zzTTMg^PaDJ_20+&`j>iLqLuIaeBCMKr=PC}M>w9(J+g_Kn?_oh~ za(n=f1Pd_6Ge}^BJc9&AtY?tGi1Q2*81bG#0wcjQNZPOY^4P`)(Y6lP;n>!^>u`J~ z{)4aMA41m1pEN(#^}{M2v7$*uvlWl3*lNXNDzIbo7;MzR2sUR5?8*4VPDR@a`JXG; z^L?+;7}7@A}w|^7gu(y(s^edEKs+?|Xf8O8M#Q<3@C(t%9Fvec;j)=M>I8 ztPh-AJFJf@a0TJso7vBsxg?m%cwWU_FeEVWEQ)K8z`&y!u0a9=4_LSc35+byAb}C~ z43hTsQNT9hl-zNBys1rf-{<;o>jUR*e1xp|u|9B`#z)9j;EarqkgdSU7at*8!E5B# ztl)+58&>>Xv+Y#Twm$yn3iezdTQIWwS|86B{JiU9eBnOUNB5#%W_@VoZPT~Y>%C4X zKYe{1ijK5Z@H4HC!uGj`_0g)s?w&s;J7?o|z__!9V$ym~tm*RwgS|;i0^=ahAc1kP zXOO@+#4|`>Xqh}6k-#|AGe}?@<{2cX+qP(`rRsanAS3@UFTW*v7b9MG;s$KIo(N)* zkM+^XD9^COKD1q2*9$LzqWTbM`-`3f+$VwZ^WCR} zaPxnDaUJ%#W;cs-hCZJbxfU4;Q{0Ts8TwQj zEj*lw3a}LhqxvR5dj?3tgPex2Ra)kGd7kB|Krw%SI zDIQcZXy8x?d>g<*VA4{NFy6>G6TiQ~q6kk}T3fw%ex2r6-Y7Do2;Q_QvIBSWB*6=h znO0Gb-!0H{2SSfnsL%272XAwjW72Pqjm67p`PvN9hq3Thqs+#?!T5)loKk>)r@_?r zpuvKdE7IZ@LDkX=|L(!R6XD_g7#>^y!^$FenzN2L3yjs`{AHm*jKTk_v7KN zQkbp&SG^`$~Izh zALUz^rv!DyN#DM4ICfXo`{6FK))XfM<%q1aF)yybn?ynR(r5`!vgGf;yGdPM*PNiN z3g4O2P0r}2JTLXc^f)=(S>7W~*7jK5BUSFs9hcBs4nZvk$Zt{?X2!|V3{8#3Do)K0 z=Eupn{B+=^NNFTa9?lBp2W4aWiRoE#L!WNx{pIrB@5RQ+SaVN7P|odnBAmQF@5T0) z6Z=le=`XV~lpn`D@AbN;AWn+SnqK)bKI?&Az2)8XFSCP)`-$oKa-hdUdrEzZTpf7a9@j@QyiMV3 z0OiAXMHtNaukuZBI95v{)tgi?c*aQ6P6)3m7>@5V=tDKmstl^btjd-~RYG-xRRgJhXVqYqG9dQ%q2J)R(Nw*y8bfuYRb#0ZSXDtKRvk(8e8?^3D603Y z8b?)?|54s>)G(fEBUN{qK(z|05#K~Gk?Ja{Y?&km5t`KFqrAH%SB_@dQl=el)o(J- z&m1n3@t;PiTj9EbRD8?O6smNn-g26pLUl3}X1rWZbs$uh{82VhHAB55f0HMu-YC$t zSn~nZ)l56cB%>)w@*&cC%Up8^)h4E$Z6;Ek0X1A6H|J4(%AAjz)l|nJt+xc72dTzF zXUsJ7T+7ZroRQFMpI>ym< zz5}&J${asclxbs~E>uIHhRcyoisQ>nk`Ok&;WEzY*+ETo`Z_+$R=f?1w8>6JhqS3q zmXj&(Ctfd^@?zqRz`Mwsz>U;&eIQ`u!LHwD8hJBCc}2Ge0+|w<>tq@EAfroGrktAd zKwx_GUp*9e^;5h*Loqk3_&9kz{X0|DxiL$zS5PtDuQ(>8I50->KlDeD-^bMd5NFZ( zJ5xsoH0LRFP9qxR$&@XTZfMVoS!r3*qv`NFI>F%j(D#|sqmM{mq{cgntBB)?*BNzM z$)^!NB_=R`BU9JV=|RU3chR|u*o$}qF`cOolF!f7lHZ9{Op8;Tbbz-1UgF`z4~QFx zPY|yp#t{pNClX&J_905TmUAZg5sXZQPn{NGCY(+Ykl57kGlOz_qK;!jL)F?cG)E-7~~L zvUg7~0^hQa8jb1Ez1!*b?pU_O?PCFJuOzXuEAoW6AkMH}WqqCi@$y6&+gc zM%Zm(cb1S#bff(o%h~tn>_6Jlp7}25E|GmFICX&;m9sB!Zdb+>S?-;|2*cUe%9eeuU`#3%N-=p_q`qepB{}*P+ z9lyv7+4Fqi?Z)nTCzCsH8m<|P90R`p72%#`p657T#X0!_`CT1Gc7G$~o>QJ>&b2)D zJ@C$>w(s^B`4v}gKKH0G;mTT~8?o{WK&n6zmUG7=(hlxe(>4og+Hs(Kt{wMUmq?1Z~fOszb zdsxon`yJnE3P8M6PDw7)hn@;1)A`)|pmoaa}w_A1WF zM}9<0F6L2JFy{$43fIrwBAAUUQVM|wq#Ot|DTm;ySZ9S1cV^zswSOLWjQ6??N2;FV zyfeak-A3T3_qvUN{{>gXbhhVC^w-FTUB@H!Y3?c~u$(u!tGw538vHv`jsqT_G8;HN zWnR|7lHof!D;4h&ECD_t%jrbH7sz?Q&wxRR<~|Sz${L{NU(5X00Pixl0<#?D3y3#4 z_kur8?)NFr_Fa=TDMR1;I6w4SZi_K8!>W7I|Lr$Y>8hSLhU0xkmQ!t$e`bG><&!6@ z`nJakOie(1mGAg&s7};r+mKl=n zSz5|A(K17FE|r$K6YsHHWYq@=Nl;fFR zY;~%XxJv$%-6NbT4_WnecHeNCOvQ)JTINNOuYJAbOe*&{yw8CT1>I62;odTss$Lf4 z;e9okTEH|pH~ZjlACY2L-P-qSUtgv8*%r7ac4QbgN%3b};PmVaIiO9wlX_Gb&)(Ry zp^>A*8EvXp@1w&UW;ojdANM;p%mJbrmp&)VFi>3+ds3Jkry84B8)oNh+Ua3@>d&8T zfgZW%hS@orc2St!q1qO^Hq7o&U7C7r7;j?pXItR6sW*oQw5j(I-I6wSQP!p~-qPj| z`j>Tc_`o)Geb(>8gWA-l{ttxp9c}&D78o4Y)IqIH-PS?Xr#{_5HAS8eAM7567$j@XOBhqkFjSxItOoBBHKjqtEGmDV#UJY2qZ$B1*{aPhHI?noal37u4r zPU?V8Dz}p=>7<5sQX@L4quSI-I zjp&sGb*feO^n5csPR_RKiJtF5U0~H!=)-vVwN>lUhw*Z)RTty93DRKIO*n3X+(C7< z?CkMTc%p2j+GZNkKZn}UroIkOl7~2%x5+u!!6wU#R$Y>w6rL=fTeUddWKWSQDjnP7ey!YYmRGI`D_jrB5lg-T=HKl@bqh)QE!0QF6q z8kl{W?BGW1#(IUkYn8@&g@pKd={C_=pDs(dNo%Z!WS=9KyNaPMj~jt+?(?=ve!!D;Zz)lwUXv4_HV7ETc!P5EBZ~|dZnuUyFyB=(*9i`L#@*O zT`6T&Y5%U2BdyZ@T_uyP(*9i~$5}NG<9@Zwv1(~T8Pr0nblk6zrB>;Qbw8USB6yTcz{*I=RUzU1QhFZ>`cbcD-!2>QS`i2D#s=7tod)q}i&! z;j*dSM0 zrE}sI`KC;B>e{TyzFqo_pyHgkU2a5au{!Y%cO5=H#tg=eud6!&bmBw?kTxFHU zbFw}F?yIw#C3!Rz$GutlxQcs0 zvxKeExHLthP$$=M%ElDxIHC%Jo+1{CrZ@Tcvx!cG+Z=?giUr zi&Z*z|11w#rE~Ys^0-wxcb}4HtkSvrl)P+}&fTZw?^fyDeOmr$mCoH~0a=hBwM9(_c`fHrE}uf**jzqmClK)pi0}+y6oqra;%o= z&WXRsa;tPs{6(&{O6SCj?$<(dFW8X%s$?G7J||w40#|WPyefmN(mC;}46{n-#NVXc zDxDL5lkryRoOn&9S*3I0H95g5ofEIiudLEJ@w(`@@as88U+26br&*=1bKa1sRk4WY z-{nH9dLo{Gm&>h+6zmk71*{rckOXzJRb@D?MQ*q1XdKrfTc|Xiw`aG?Q&bwy%}}qj zsr$0ul!l|UWo|s*miw*Jc)l&KSf%lNM@q-D4_IT5WWOg>uHqVdPfm6fj3~?KA0N)iAsQ`&{~2RgU+NK9~Mhy^Z6(kYcO8!f{{7Ay#ce z+P~!pt6oCdzh$gd*CA$K$|S39N6fyInN~ID@072k%BpAcaTk-EWYwE}cgk+5wd%vZ zNl<54Rf77ymX%hOqrR_Yja9jb=YQl%s|F*U|B>HVbqTI9zmZ$4x*pe<-^lN*T8`ts zl|NXu2FHCXk66{*cZK;*p0MiKzDB;29af!~xKqBDSFBo;m;}{oRgcUSc%ycgRoVD7 zM$G3_I_DqHHYR=|=QZa1Q&2tI)C<{;xo{HG_`29{8m!Ve?>9|W>6{Ok2p*DjuP3&J zxzMVqxqr(}G=00Sx zCRwFxrK_1?m9CYprphYady-7GRl4^inOduK?@2bNTcvwXvRP@BuCZ?BVykqGbu(95 zrDL07)>)-vn__OUO4mbobEj3h9=e-9Sf%Tshk4j4T@O9X6ISVZNHxz{rRyQpykeEk z-89o;mCoHXv&$-7w>`}#R_VI!X}-2f=XEdROlNdMIAdc3`dX#) zx{t}WO6PSSQ)HFy1%1syR_R{Q*Bow@&g*_=v{gE<`D)cQ9AlNv-2+UeRXTUm z%>t`*?xveltkSugVOChBb2r1BYnAQ=ndTy^bT7y>S6HQcL6*6}D%}gR%myl*^SiRc z=0Pgm=YJm#nnC$PA5{yU+JGldRG?-`^~;O6Pp8d1WS}i+%pf>_W5KRh-F% z#&@h6d3`Ua(8OD%bGOiRw@T-3k?Cud&fOxDW0lU`VpC+5&fQ{juvI#D2bjaH(z!dp zjIpX4u9r&8M61$qy;NdmSoJLC%Rp0U)f<>E15LG6y7wGtPO(b&o&(L9R2s8yvj>?g zs5EB2oI$3cO~vI5HZzWEkJ-UyiB%f2gUw}DY0M5WU(NDj)-7k4>2*96V>Zl$UB&f2 z%oJFqF&kzETct4@ZiZQEzMV|KWiZk5LD2y=o}8nYwJe5>>`jZ#x% zm42pCYL;82pJ|kts8#xzMwwY{)pK~CVT8Hds@L#7!w9pEN@LbDXQa7@N@I2aR8yPE z$tgF>PiT+XXmgoW8ne-6vsD_iF{Wpw7qglc?j&P=!JoqnH( z$C=qy{jvX`obhJ9RonX?nlr&Hv8p9!M9xIB+^SD=#^y{i^;RWhPs};mthTCe_POE7 zX027a4^A=HTc!Kp6tmu{0QQ2ZW|LLjuop})jWE*`ShXoU zC+Ao*$f|q8)j7wRVXk6ZW|>iKIhW+jGUMBFo|bdGncgAi31)UDRo$kZ%09uIVUIgA z@tmC5W~EgZCte7(#;Ut9KP%0ZRy~CIS!sS_mFbQ5RLw0`CHBU9s^)iACE&HpiRKSh z^}}nK6U`%5Z3?f=nPZ-?>fZ2mIdjbps}9X=%$a9iv1&|ihWyI3x{7_DZ{D+Mm-N3i zXTJH=s&)PE%voUmV^#P5_vTa^--(QTD7XJZIVYI}SFx0nO%JNedu|9nmUFVn?39*I zwNeh0r0~h+K&y7h*S>{jc!%Q_nTig_Ei#jB&Qs*coJD4~Ro_4@HVZrCtTD@M+D-C8 zPK~*d%5BRMb9;xJOUyks=QMdeXNmcfRri~Bb51c&SXJP>o>Oa{x9SwAI`f)Uw>h8Z zEH&>~^(@ksnUAbW^nIRls@ZK-k?-{!eXhgE=ehVE1=*gi{K38&L;W%G2_E@yWJ2Pe zzUFar;+~p*?cDWU=gNp4>+i3rvAvW#naV$ctZ$ZWJ0ZA(>bKNjEjj56^z_|P7oB(g5IoY!MD=M473<&UryEzSMGz11xF zPbkxoAw4z!y)3_hEp&N1dPm{A+uKUeRQJd0ms^)xT1VW%$h?@Pwd{{~jPOt6|L&pX zD?0KD`+EvT!N^S<>p^IPPyUIIWBu|qMl&F8>QAd{@1uUn+JDKq+@AjOHSQhZj?Vv` z_Wa*z$uBul|JQomac=w={?pn&k2{#6BTKnwy3UWO@&CI#Kdmo6zCHhU%lFPc+L!%t z@2uV4-;Ozr{Jl`m5kFi)d!8RItz*gi<2bXsXX^c6fY$~;4rB2oXRNHo-DLXTYFrw0 z!N1kGFRUB>t(H`|MbhxE7yf1A+r46OhnT@vF6ez_y?}AJhwnz*J2H?slvqZrARbMe zNvr}IsRjn|8Mz*{8rTER#Hn)~u#YqnH_~|(m_ffk-XG9B)j)i{PFzjAoPHzlBxxm| z#izq&@#(M?EN8CVl6x=yGWb8UAHlQ0$`_K)m2Z1I2d=n+_u}m~C+GeHpBw8lWvfJ= zDcfyME$Cu)o4L7t%-tw04EzSKiSCx`6Z61(;S&H&9cbz69&h&C#>)U8{$%=k=!O^4goPN3MfJYWQi4rag zKWDC#K%~VCbxg0prp)<|^Ny)-ZjAg3{<6sD#+co`@cgecs=v?KZ4T-Y0@n2F;;ds! z)=7`l67VPT4ue0u$2!z)oW+sHoh_{QA=bN&y_o3~ zMc#BCVvUcnsQnB?IzmR)fA`CepcyUp*?5A*Gk?!89)G-64zOAgCk=Bsip z3!mxx1SQw|cFUpt&+}C~Gt)2jt#IzfyIZgG*qKgt!HsZUM42lbjmamhSNruxlzC8( zCwtcp-^vi%R`RbjT)SbS|oiA}8MH$|7OTq;)=a{4OXSew<`)l7|I>U(N z#EmSW(dk-H>u+>s_gwDZ$P(^$j_-B0|83-nIuDq?7GCdHyvP55(=Ys(|9$xJzGmmR z)R+8xh;6NU+*`4z>4Efp1uvA2mju1Yo=`!Murk zN)wFUOWNINo~dlrZu3Fm1A$lBwx?yIxgMWQr8qh>Pr}UXYwpi~JdjN+BzBP!`83c4 zPol>JyT}mf4jd*$z)~p%mdkA5SUD9qPR;{Pl52re<+s2YvKcr_?g3Ux6L7A)1Y98h z04@|0gFg#HXQ^}tUoLsTGo=(5m65GwF`200pdn@k7ZA;$qXOC@lN z%mdypCjlRl8eo$w1wJM#fKSTVz^7#;aEDw7d{Hg|z9MUZugf*S7Fh>;TN;7y%B{fn zWfSmY*$n(#?nO(!l0O2!kvD+YrbAuCZ^FQk84FA>)xadP2H4$f0`@dd1N)kffEgwW z5BX=C3Sh*X1S~X{087k6z`^D%;1CmvLxjyh;F;zGVAPxpTxFI6FEkee*O+U8mznjz zE6rx$wdM)nI`ay!!F&naVB+Gt$ZaMMc!wDR+-&+LbdfEl0C>L{0({7f2R4~mz{kvd z;FD%4@M&`~aEG}O_@a3P_=2GXXfn(Y_3Gs=-U0^MU1#)-u-7TE;nA%OpqJHr2Vd3+9ibEu7_S0TQT``MC*oDp!E zoMV8Gu_aHkB~P;@JJ^yJ*@jn~a8eg}-5COGaWrCYv)&}1_Px7L%kSx%g4DjgCBO`y z#v$8x9(cs3aVzv`+)8{Jx4}M*+Yny^Qiu7r0!w|`-*TVUGS>H0GNR#o4>-xEeV^(x z_ybBad>X4+K8;nSPh&OLr?J|=@^54Lcd-1;EPspd033Bc+xC!e5O|YMB>86oyZcWC_VjCy`ucSoGyFP^v;5k&O24*ku3uZVz^|=Z=+{;) z@oOZP`n6Td{o1NC{Tk1xU*oyTukpOlukl>t*ZyAS*Riv*9)_)st9b47FR&8K= zZex4yV0$*RJzLnG``Mm{{2J#bzsC77zsC7VzsC7#zxH&8U&kmZpl#?L&^Gi8XdC(l zv<(>nZ9{fI+Ykw8zX}7|uabbqd~iT}Hzc6F8y3*sl?JqTS+3xk&-=aS%E zz@@<^;PT*Wz%zsY21bM50#^n5_Czm&1A%LTM*=Sk9tXTKcoOj1;A-Hy;Pt?U;3nXP z;GcoF1z!W+5quZ8IruGbOE9Y!)OzVqY2L}T`4~_wT6`TS5CU^!=VlD;xV;X^> zn8$z#F@FUn#ry-fAV%Y}Fh=9EBu3}b(iojf%VRWFXU1s1qA?noRWTZw3u81gYhpAG zm&IuGu8h%WTpOd&SQn$wXo%5xZivxn+!mv8xFbg6usKHKuq8(0d4G(?^P!k;(T1j& zF8vUJ7>&u3F&dMnV|2dlh|&4>VvNS;l^E^I>oFRQmKcr3+c6rAcVo2g@5gAwK8|4o zVi z8VVd2(vh7MngBjEGzT~%q-~xR(l%FyxGRRV%?m=|3`8|_FmOpoBYzpozmnx&%ktN; z{D#nYEj{sXjI#Qp9 zbk+M~pM?{OeG8Zn`*CI_?#CUSnGS_brdk^%-rC&uB0Fz(aEb<1VhF zV^$+Iwzz@qS#LBN8{woDH__QjXFJL%&D{<^v$%!+Tl9C)-vu8->S&LAj+PMXX#QAd zs~lb&rjrLgzIY^g1^AreIpo#gb;VI0yVBvf;Mg5mtC_!n{(AcB>2Kt*P4u_Y-%5Ww z%W0wi7X7#A?}ER(DAuPvjrILSRu{+mw#wS#uutm>`?Rh+II+d$K8siiv z=2?$CiA5WkXCv}FTfCKdwz8b9%(E4F`W0x$h7YIOkK&;)o@~q*V9=~XFc<;NB&!iHX`-Y;;l^G%G9k) z-HOzEinb%w8SoZU-|}nZ-(u=pNZner3#qBaCUB3Op6d&+rvdG0Y(V>-34e2L7=9^` zBOB0h&kN|d=ONG9;xgp( z1!sJ*1hq#dc#jn3`GQP&ICJvCL0w;YaO#T7;9QqCl1>Gj-9=S!cI3^WQw?W) zaXp-v{FQW81+^EeSz06fBl0)0oM!N4`HwMmJIiT>b4UIz@QDLV%sujEzCT8fjg8S* zWy0xIkOy8lpbUIcK}C%Ar~=LhMOAPvD5wUHEv^T@w_r8+q5+NI9~Nu`KWD&p;1vUQ z@u*$kjm5Dc?iC?jDS701;LjFU04oPn)2RmkplCI4(SVIWlmkRLOx*>Ja$;FdEXyI! z14lW)@x|4^ImN4ib;TQjyNkBR>fG2Kt8-&JoQVT=0Y5E{jnn*jz&XVgz`Ek9INg)0 z!Lf_R=_u4&)ZKeE{D}h^=rmeXebXqN{zYDdL0=1_S&$EL? zO^uD$sAkZ~jMto*mTPJrQWp&6Q{B(@7@ zU6-wrR+0xSC@JltC0BqCE~zB120yAKO1>KW_>upMw-i+} zeX`$aje;1tNOC*_n zOy;ah)_IjdCxcF2vi3R;{wXCDC0`9br?`Q9BY0hL6Zv-V-9;_rySiz7c6HPE?1CRNP*T|1 z6r6JhW{~Hlu$^$WmXy+|03TmmNnQ;;r#MQ!8oaK!fxOY8j>1OxyNjCWG+R`EJN(>% zEp%Efs=o{V5d)<==Y~b~W4mvasRJ|UWLi|el)TKMIu+g5OF>~Johpm!SJSVjQ{P>k z)pQ!^G}77FUHco`LrbV2RuiK=v^@>PCSnUwQW>#S&7VP@M_x)^L0(B-O&%q0AU36P z7bR~YZy}d7Ei;2yN-VReZLTD*vZzj!yxyWZ4djg$)oCJcwx~`Ed25>Xx7Bj>O;1L? zr}9klO!6}FGV&_&Dst(?))GsJmBc8qf!IWBAxdxNCzcW`iBVz$v8gvBL*7E(LN0xH zEU}bWW>H&PNnT}9ohW&|MRgj;8!f8SMBZ#sofh&|i|R;UuI0Xrj79Y`=x5N$?5mN? zv|Lk5nOaJx%%b|0^egF9SyVqtKT4BpA$(>zV&Ekrqh{W^eACC?x)B~}un#0Fv$v4tqYl9!TKl2?*P$)n^A zC3z)z zlsrn_K;A&!MBYT+Lf%5&*k8+R?5{m)CT}KhC2u8{T+L%FYR(MuOpEH2l9yRjr;@zN zqB>FX`dl5addt;sAaAs&P7`^vMRi)pTP><15w^;rIvM1d5iLK{a`j8e%jlO`u6`wX z75ys9)sK=l5SxfC#0`0RPI-*@Hc|4m4gP$dYsj<7OUcX0E6Jn824WNOF{ZYVzfCR$ zT3QCNlvrM%C0CNqC6AJ?B5xqyK;BfK^P!1O3waB<6mq^5vSjiM@>23r@=Eeb^0|dt zW0bt!qQ+zu{RTRX7S-QCzllz>MfD$}-$JL=qWW*smm-dxMfLqfj3J#&i|S|7FQrpv zQT=lIm2|2ssvj-V{zmCEkT;NTDAIS9n&>pqd5lgAofbN8(~)AvidaglBu0r1#HM0K zo4kd*g|O!7?fGV(I=D)K7wdh&Ym#uAOI%Xhi9LO5UGs#QI%PeYYC3%%ab)w|;1G$zhSHFS0k$$7) z>Nk-$TU4ioyw##Qavpg#)YECC(@3Y0PBVEk zc`JD15I=BQGPbBCjH^AFW5#kJh6aN9(z-kxnC> zW;)Gun(4ICX{FOjCvyyU#W7k=<`^xfjJ%AzioA-vevFo1Pp6(vBaS^Zx0y~eomS>) zrPE5sjMbyeSoUtLmY+FRk18Wp5$l;+&(ucpM)GFzX7X0@R&rCpGAmeS1n|Jbw|u z->&F`ds6%2?^N^?{hq!&{1t~mU?U_G_qAo=d#}PWUvlJZ+`D=O{))r(62U#Dd2%cM z_SS7uARBRK;O$Z*o1_@`rVYTIX(jS|+<5zW?)N!@r+f5SoKF&zPe^n*{=5iyBJlHE z<=fL0wU@%*_^(vOv%-pZWGIgArTA3OWZ-X^b3OUqj$2MF>vBumnx@B2 z>#2BOmg4iQ@lXAfyS4AH9Jd6w<;Ue|Yu&cFN5v+l!EsZ2Ad%ygz?= zLVKB+k@gn4EqR%#pGUMM55#M#TUW<^bv)|Fw|th(?0|F@0?stRoFuq(v?L)e)de2Z#4b}YTC-jS|Q`u9;1 z!Mj5l=>c?bmwhsL8qmRgxGCV%fR0Q@I=*on=-|%WH1L@~JPC+ba1b({#Bmi zfeyX_upjtrpo6=2)4{8N_{+N34UNnJI=G)V3_cI&$gi+78t#t{?(oe8uLe5!mbyIf zIv}1>!7gd=9diZXr(&lx_?tFG;LEXF;v0p5j+~DB{|)Xg83=wR_Fp4s0UhkR2Z5gh zbZ~d@A>j2uN6wX@;46U+?iW4`{5+t8Z?Vz8PILj#!MCX$0lpgO$XY1_zXIsUl`<0i zDxf1*<2y3-`^83qUyHBdF?d>F4EXiE9_Yvm{3}C$0Xn!#x(@zJKu2E2xEc8?5YIDW z+>E>mbnp#7E5Kg^I=GYi4DdIA4!()!EbyH`M_Mp$Mp}W6yoqr$@)ppMw=r%;-T^xD zA;t|)rve?^bA18$CqM_^7PA`sGoXXJurCJx0_fmdT`mFt66oN*>|cZL20Hlm75%$N z{{cFKcAo|eU(Mn(ca{HZzf8}Jw)R-d^E zJQnES8$cStQ-D}^W<7WhAl99^1w0Mt;J)wQg7*SC_(qM5;C+A&?gZZi-Vf;Dn=kGJ zPX{`ZVeSIY1UmSJio3z}*$@YJi{AsD19YUnxfeVa=-~eG`@r*nj^vvMzzcv5?kIl{ zya?#vZ`MkW#>rJc>`NvV{2CzkB@+*R9T5AHNd&(Eh<(X)1^*2Y z`x5`Y*G)j|OC|+=BM|$N=>fhT=-~N)H1J!1j@)W`f&Uih;E91g;2VLC+-~}TZvtW; zGwI-W0I{~gU16MJbN)4JQ3(f7pDrmE6~By7<0grfexPInFrn-=tvJ| zK6omy5Krxtc69Ivr2F@0ssTyaw9S z>$;b>D{#SHUQ6K1>^+a&6>z^lzH?jF?Uk=3P`p=py8;jFqkRu#Y8?Y{<#ix>I0*j+ zY%)oc^sbQS%wvJlQcN%@%tA1yHh@NZjyn%=jCpn&)n$` zn1}soCM)1G)A6r55HO1aY3B3*3m;vzc+P@(iw6!Yk+Q1lx&`wBt3DOP0>7tysLYW>Qsc)%@D3B@5~fKhb8HJa2w=-O{7xt!TIO@PqX5 zipAAS%U3L}T2ws;+2$?RgP3smoY}L>tLv65tXeU0VO3q-!EKd|STV9@@vo}qFRQIO zapAn9m(?tt$AU{_%7S^dORCyhH}Jo=4q4o$fb6>|17*Upg$uQ&%7IcbYVoo~^H{H{ z@l|!`wcEW>iVar#1>VdY#16dPtxbs2_;J^>syUIaQF=bxusnv7l zvEPGi34^>g5B3VdS8&@>K=y3-V0+kL@34c~4m-#@3}ny4+Hws#*vkd7XRd>7p$B_q zdd9#ZGJoFE+0&+u9^xGivghGU^U{azoepb!&D>=R=N&H7E2d7FeeBrTV@J=PI(F3L zQB%sKe8lXjlglPd89A|h)a;50N42g|ZVPWZ80HI~kFbI0;3vB;}9P_GCDGq{bS~jORllZ5bJQwF?zhcd-k1A@6E8iz04X z)ZTbE1?m<~+68v8MZePi(Lee}fK40Q@m~Q7v_*lU?(cW*z3;v^?~#<`SWY*lG&Ap> zbMC$8o_o%@=YG8RMrX$(Fp>HEGc&@qa3%@#+f4S{oIr(SF84K;n9rVJBMqBpvokZf zDS-&-Om=>P=(*{0Q>F_AG+M5<7L7w1&gMu$-t*`NR;=cr%rn{i^wiYTd8fIX0(eW~WET z=jKQ-H=muy3$~41^0XH4IeRucPnc~(5FA!8LpwH`J&jlFo;!6mH!sD)+Mo$jk_fgN zre&a`(=#v!t;GPx3e7?zf|(aL1JRW4W?Vx&>6 zKtve0yz(&1%T_AYW`R*kV|Wh1;7UQwBd+oqQDKu@kvU4U${=RG?s)>$@(Nte)T>2A zK>`W4WY%l6%1uF-UI{>SIU#@%YzSt1`N@)ZDTFY@CX$p&*pa3pk_S>BrF}^4P z!F;_?X%r!vTxGGS8VC`>5C#p|a=D5+5yCpEP8jJX3zfx2u~2hVVTfPWm{<0ij!Mc3 zz(_Y%DwM0sEk_grkRsQZELAS}YzLAWJ65WD#b&j>79a`3NO!tgUnw-3-r`J2H$Mb0 zet5K6E~6|_m@{4lc2`u*qB>hD)~k)`Qgb-ls7-mz(Q4frK6_CM*7jF!QKTA3O0}>| zgQ1b)l2A6tTQmUnMF_Cu2z?tiWdzeKhzej(=8{lts5Xn(w5eFDw!!!b=CSi0-3ph| z2J6yAGe6P|nZAUnlFni-vx^#&Ys{hZix9YoC6LV4YF=g07r#2wDlMwVH2Y7K^7+#x zuMB`+WdNo*o`QbPRV%S@2na49fC_2(6BqLNQ-$J%Qf1lH(xKi_f{ z6zh~Z4j0nmD1k3RsB{$T6fug^niqu!)i8<;C|?w5`Y$42tBcVbR{f$F*Y%O&w3bD) zIQ@#^=1WaXWFkeKtCg#TMJiJiM*+oSrt46hjgY!YlhtCO9G_cDBOd3JJIW8{+SPh| zwsSSOdT$Zqf!8d>wPm#KZBD@Ua8@0ymYo`p$u(vQtwu~17B*LUX#>oBVL4jMcm?AU zOfrhm;yPQX)nd`CYo^dVAI&&dZNbHCh}J`KG~2m)ISO?BLZ=f^qcN|6c%;TbBZ>rf zh~8olv);uL*HNab(M%Y55PwAB*;ey>H3rU5pbkilht>Qko0P_WasJP@zZs5 z5W@*GqYs2DUG>h=Dun_{wl+i3Sic$E3WduwS?5u}H%A%)o z4XzYU*Pl9%$;VucpwaWCir4Vwn~f){SQv|$t;m8|7%qX5SxWQQ)Ko4wmC?C!CW`fG z?IgvZvn3-|OK`?(<|>UQ*7Cf-%t$q=tvVpUP81sFM-lES6BKh+pb(tQ7AnggRyFP7 zr^=C_+TgONnr(@)o%LX7ixY@)9gJ?!Kv24-I9;!NFKQ$#0_-<4sp7+}EkK4x~$JzY!wPeECiB2VUXGrBJ2NWE%}{Wud$#i98nfU5X>}JY1JFtz(py z(mG*mWXE7Fbe%9WSux70bUcmF4Z0rCIn0L_2rKgoYYX@umr0xO!;YiEN(Fv`9M~~m zFn$7-GwyE-(2n$mK>*fxvHTP#*HI4;g$$2*oC9Dn1CzEF^o(nG{50J~V6vqPKV649 zU#iwG2zC^^Gc8hyiE?>faptQ@C8^C>OWi~%(iD5GrLM-jh1T-2S3gy+UJ~Qy&;$wU z4V-MVSuZWL0GO&a8Gm?-4#e?x0X54Ek)f4CaS;NNt;e9|>0unDu0IU3+cTY10WKZN zYMxlX1J4)g=tW;>4q+QSQCfuH9UODs)=D64%cW90iMbC16 zw-_9`LIM$!1I~I&bA=_Zxi*VkhlYd8CeC=-V+cSa3!t>HWqoJXD;HMvN{`EGnZ12ZmRduyv8ALM4DORx0pjX`#eTF_$gZu=7K) zO4+v3>w>ak=&*c`h|s%GR$n_mT6v~bSuGW&JZ!WQFnB{qm{{0p;|$!pT_Tk7sSk+FBDKG5tSfZI0=+Mf;C4l zaRHT_Mb-cbvb<0VK;|z^G>~f)yW0UO7PN|w4>DxWv<$>w;|i{mhJAB3H@sLbi-a*1 z67ll)jMqfmho1HdD}v;ntKe68j%&p2lR9RHiZGfQH0jjB_h=msnSd0FnkN} zmdx6p5(Rc^f$B`X+NuT8kpW;@rhiI{z$EBU;M6c8B1RowEqa=U${cWj(!^j|tFyK; z*pLbLOq!X^lu|O<>-?e~w&VnX1r}>fds!>UG*l$)W}Z?+AgRYxx^@h&6ti5yA;PlZ zKdU+&Sdt2fHIxsuRBDhnZ1gF{3!C1V!uyrz= zHT#1w|3LNr_KPtWv^>^5~iOz~UDh*Fqt+ral)AnR- z6QZJ4O~HkfsR=%nX=+0iTa9LQ#S8=`@S1;-$I503yvCA=S8q1d_$tm~>6-M4oYZ12 z*?zkoCvZREP7$dKI08qlD;Anc??b5R1+g7KIBGLF7m^5&O&M*~xg{jIB)G>lx7_Tt&@e1f zSWc=pjf}!0mvn2~oORZFvE?l`5x<0{@}>i%39{agKx1C9T!4<&O`5()88GEGRH1|(D14CVo)9!DWheN~j3ynN zaAb4A@C&_TZPcw=sQ~imguihI`zcq>IyI0#Y%%E4`D}*t;FxCF{ zR?KYGyB|kVH&?c1^bc-_QLR=VM|yEA21^y@cKqt{EAu<&|N5m@UrjvvygK~yvrv&= z#Vvu);?}!|peQ5wcSKT;;-<@jDAE!2C~g#d5Kz+o^-GCg3g#qz2Y&l7lywy!wQVO} z)}*@dCh)Fjl=|E+eU$hpIWq9k=Rey2QDOx5yk?&N2sfK`9mpiQhVZ!$bVDPFu7mgt z;InfivF&-@9MN@Islh|I#qu#x=OvW=1nzTv0IE({QH+viMKgW^x5z&TINk{Sx#wU8 znx>AM6qjKjlCul%M%+%rU`c9+!>O(_O5GJMPj%rPnec%&D(sfTJvEx2d z6ZqcoMI#?v-^ItUKMzx))Ij^d^9J{~)qP0g33r*H%yV!wN8x6U!Fg!O-melz*kdg* zWe;|w+fxFMYexUZ5^pFLTlF z9+q-~6q=h(9y{~l4YDY?iZU`Ny(F#B-Y^5mB|ymUA&7~-zKU8dh$mDlow8ylw?ttM zL9OX6Z?EJ_sE;EGJM1V%5IR7$-O5V!7DQ&M{onrPcaFL%tW0Wq6GE<0AcLLaS3^O8 zAA*pALzQ}*-FaBL`Vu;sTE7BSrJxTny->*m-pkzJ)HM#EKC%y^D2F%tO~pn6@hV7pL$w@dW1u?>thlQ^H-65An5m_o$bn za=uy1zLk1{-R#@>`rv1s8XjiU?x@1vBPyA#bo*AykJah+zrE8s{mF@6-K{k*EEKg~?38O%X&Ipe z=WA9A=*#N(EX#KdG{iVfaKlj;9V4{eSV)G6Q z&(gx9P;gSRS@-Hmk`7*iwK{WNgeeweDzS_hRP#h^5ylx-E@#qPg-KB}i?%#k??rIp zA==#B4pjShqTRUFnDMi#KHdzUxwCG}g{HwiWnage{{O$4r0(5Hvg)`t{afi`wf=gX z4l%;lrqXF_@xJrZF|Ip3X5N~zZEgBnn0G6#XEtBQ=T~hb>T~gSs@A_7?eWis<>>IJWAIOUSiZ?Y_#4qayY(^n=IV;I*L&lYDUU@n z9Ym=0UyibPXVuCr59tVvOTS#QEg-t$il1F{a&$$&=z(yk7n3h8Uh{W3wA5tt1s$!M zUoK*K3ui$5rK!zbp<0W|Xyb0Y-CANhu>FIr2KMMUcXKP~8?AvjF@F->q3#NouRg!A zxYVoPjLQA?bTeG3Zu-wo$GAbly_hPZ^1LjIa@&L&YN!5mM~(-#J;Kdh&LX&-!U=yk zM^ly-aNZZ#s+1cnkNZPql*|1f)>=ZE8^(IMmK(&*6>6HYKrVzZ7N)m?9FMy5gNqn? z+d140E`NkuPadr81vzjfTWqi-w=lefmfFqvyvUT2DTC*@d^q@shq-baiL&Q1H|u1; zNj~W0NTCI)k?VW*m^tEkkgkrmV1RlcoucyD%ma!MTMAbvKkc55dYAAIP*L~lyw&AFYR z+v6VC%{tIq8)AYE)t&{oRcHC}hL)hKy~S{=dMjS_*2<3ep!a;H#2ZJ@zsO3g20PVD zt?!I#=j{chx9E8u+ZVao9nQ-xRCmV-N3DPU=S$nHW^vERotWjA78H=9(x*;>E<_*AamR4tnw`h= zoYSE#bnli{j?B z`g;==M4JDd*o{}8D09`DNs?F@3>(q6TlMrx3HU<8Qpw$k?W!x4UQeWk4xsn}K}xau za(i!2dRLNv+wctbRH~=9D>e8`s#kTV__r;SO!W2jj3g3?gQ}}P(FZDknQM>a>h48) zsCVG*^mAy*n?tE|A=NjO>PrD@VBk-1+cU|b)KJ&p`gU;EN8#>952$njm&moVcYA6m z1ro{IjpxFrw(m+L6T5~EsyQh~)YjAz=uHJ3Qy9YhihyUPNCDQBnr1~<7PzppN zQTT3!r-`T6??v833SzhyRVVvRB`R?o6-HXm4yY1u<3h%=w zX&TV(2g`S-*B?L?+cIisw;Jx?g_HgD*<)@&jE$tDr2sJ?!@6;4_3!*ih;cq)pn?_I`WSPc@K&Awo3nf!^J0 ztq}ve&|Ie1(yyf3{|?lsH{D)O!W7c$M^o(hHFU-SNHV>CLZFYP0+l7xXt8TDC6esx zH(bL!Q+<8lRdlci8je49BX|Vg>GnTPx8LfcT4V>;$GdwI>2g;uvh;344yZTsC!y-e zbU9rnw#MsPy2k4!ubb&6uUC1!nqKAgWnN!SU*3jmG!=<<8~-JFMUq$2?JJVJD#@$q z_Ekws4g*hbbZX5frKY9y+r9A%IuXFgV~G?4a7l?z_@If>*4N z$N+9^SK#AEXeSk=4+7W$z+m^*vdvvdv*_!|n|7)W!gTrw|wLKA3&M#0;?Z zuxXlz(a;I2gHcd0$6lgmB>D)RzDkYBn*M1Zxz3cfNf(!-vbY_Gx6MrB-&a-N8N4S6 z55QK*Q)+-WJlKC|4e3VJ1YY1YgBM(lt68=tSZwUvuQ1Cz zR;(vveVPKG3DABb+>uOk_Z1-t5(szUa!48^8MfTbAve3TBC@u;k=G#kuW-#A_x$2+ z9Q z%vSTZJ)HzHW9{V4>Y45RUBMxW+O{VMn1Zg*o-o?k4LS=NI0LvoXINKhJBVtP;&8fO z-wQ?xtN9%Kcze@OS4ajx&`Y)2={KkJ?28X97Ub*qg|{#v8MGwO7FMb%zY;5aOGrZZy03x*%QakK#-fXJ-y>P>fq+Qz&!+ykyAzXb%L}StSZz` z$3P$HZWM0+n>*d1ot+ov$98cPYMZg~?GUiBVAFI_`=dZx(t&8amor8KX-z}z^d^e~ z?w<*0Bcl{|n*P2x>2?@TPgpUu@<#dNPP1Mq35KF*mVH7cXNJyy6kuDciM3d2(j*WLTZAalm2RRmr< zpRG|vbxe1*HCJ1yJ}?o?;5ItfpT5(E7Uga;h1>iHW~b4{_u!{9_q7^&psQ^i~<}y z&$pKjec2CpEd73`+HO5s&-UB@;ZB=uIF8jqv<(b~FpiEJZ^2gTks3lN6!%Hj-**s&pDvV>R=8y zI^*zRG)uLIXik(XSY@!leHOq&XqFoe3%lIN{#9^}*?`5)gNtPqXxXd`4LZuU<@znN z8sq~wzA%D5cp5rskDE>6TJMfV=;y#O&zTKOn`36=ZV&6^9M_&Pn?eEiZ>*%w9A5qM z?W(I&06jv)>q+p8$*ri}XGgZIq2xt>D^Qc4&m&uiVI8ZCeXUj77_+F-PFL*Q_dr>U zH)z?8{=jC(O?&id)BC9Gn;$mar%B4j#slSBP~1_|bTE?CCrx(+`KPsq+D!Kn?VdoJ zEiwRNTtTb9FTCkVKdbHDIqpC%du%EdK4Q9;90aYOnX777=g{=(zT36+t(F`%8o8a^ zw2yFUE0dsqu)1*=D%9!rUFUHs*Xj9#*vt?oJ=@;YX^Y!u{Z**nN?KEg%4cA zI}j&Hd(@=;7oV;~t@J+L!J7Nyg%~dM;6_ATz=G7AE2h*WVw*D~3>WF>z6Th_&4|Z9 zP^J@Hj^(5w+0(ZJ`;m4hysIbO>h8hTF~8pG>KXicch6w^&yzjzH4&X z=4F{*O-WzDxq-p<|41Yy^-fn04vsL(b@{%*GXH`{3rg6cHNQy$|Mh?X%?3Lm|4|N& zxV_+T^4d<&yPeg6gx-0>`3yY0jN5N&M*z7f$ef` z7h}6zZ`HraU2&W@z##{mSpXd0^8d}9a_+&(X&_@VaQC|xo5AgWls?HL9A%uqU{?I^ z%g9j~DJ|XpdnqA%JN;$+LMB)GCH+s+6Zj=S7xQj<62%-yPhtxnTfph|-`53lKNwu4 z^bcx4N+H+l+(&Q!EBU?#-VgAY%>kf!&BpYhjS5}JCgBIWk?2P@uiV2!0_9|1W*d$X z;Lre1Bb14+3BD%yT9V)z!A$`-1>6*H6K5CtQAeVm_*KEL3Vv1as{~&b@MQsC7Vu^4 zhN8V%$Y?f?0JM|aG6V|hibh@0s4E(EMNn5Y>Z(Rv)u^k2x~5UrH0l};S)kw_>LiXB zu+rCb>NTD3HGy5%gx59dx<*|W)D4Zgp;0$93P4K!P1A30f^irGDdmT_w!k1^!XR$I zAU7uPLjp8SI{k{A*P+R52S6K-rg+Ctywi;gP)Ozii;@c*GYPgNc>}7RK>n0AAY7Rf zDmz%FKCy5maD7dm;o*^k%iV`?JcwV3u0tw?Pv5pfR2N+J0}L%W#H!u|l&zCQTM}jY zZfek#zC$>7#CGWPJID*Jh5WkyxzU$U-1k;E)B{_bPwsuHUZ_n~EB<>0=FjszHVM%6 ziV;7aQ2U0b#^?DMRlFeRuz9b?;}=g3;{?cjYLEZOYV%$bKHR#GIWnNwlTddBpJFtDRn%dh9&Xf@#7;Wj-FUrI#yipjxQCL9(nZ9haMVvWNBpN z#IdEKw=m+JeE8^zM;67?fKB)tco*=j|Aw@)+0JK1%LAJc#`OY8y^xdmJe&?ee2sFzW$p(efRHV-ut~9KmOi#fq3tY@4nyu zHb6(f=~lVk|K@8SeE+vXxsGj}>w|B;Ayr)c;I)5d>U!v=a((!Rzl*wDuH#$hLOVNi z9o;(D2Uq{}C%+YL*TYIZoKQzMlVMD*qiEReWIMTawjckC-+6ESjgUN!-b9zhF?oBH zow%uNA6};?2MY7#Y+bEK6{dPzlZ=&1cYD3$$()}2Vf$neB*)h3p zMn__@9fKfmqqgIa$dQCP^ueEf>nGoN3$ps~AHM$nJKv!Xc>f>##)rTEo0*XOP|3-J zI=)$NeelK~eeh@Bhu`ST_*ga#CrIv-Y_c|7xS zC+wBO0W!SaBuoRqE16g5&Aa(Vt6h&}E7i){O10I2NC`@6*Qz?_k^B3_NH>GwZ)Q$ieXO$CbR{&th(h0SbtmGG08u=wW^&5}AO{jDTWJq^n z=yX)%Qd0U|EYcE}&aV_|G9d9(nI7g?cpfjPW?0;VHw57IrMj&x{odU?9zrkUq0~)6 z#LV0D%NQk3LEhS`TZXrb*muP$l}f1XlBvn}@JU09`q}t-ygfo*=BsP6P}W3o*qR*` zhEP3-vP|6}!ZW35k`;{arjz*6mAp=~QOokWSi{m}{YZgQnDk5sP#~;ai;>UtS5$4yO9A3@4C8$l=xtMu&#-QmpVS@7OiN-5d3n2# z5s^>isNz-czEbgZy?irZzEU+J(PfZH%G(sFtE6QH08k})A%|#65H4EAS;&BDb!ySI;ykZ20X74dUklJFg?E?K z$I9iic;k;+ftJ-hPu|<6Gko*~l+xMcKv|z%-gybYYopSAO0~mvYrj1b11H@CK2Nt3 zY6g>3`!~~t7+gIm$FQGNJg_~7?Zs*AHRtg=gERc(7`tR-Tw^3*UJaHABo1boX z+m&=pXzcm&5j=>00cX;c`ZA=Hz%f}q?VMW}6|BnH)nS%D3XXURjz?Zw!k=DGAI5od zOi&>&=C_=43pjdE@@C2z!DQQ&^CZgQX+PJ_qj(toi2q@|dqB_janZ1jUv64C&Nt_K z813N}m%@X-lPG5rWh_exltc|O2t2M|9K?*&$2DI*;-6AxeYV|9aW8KxdAWME+-Fc8 zAHLFpkHtHP{8F|m2hU1SzXra;`8%cNWcHvsj(;O~)xuGHmhkTwYUJ7R5nM0fo7Bey>xr&->ZE#D@;?HO`FB$KEQ@~P(kvgHUWVi{(B^ROIX>8jpWxru SF`}dR%QV-|{(j*k@c#g1DgN^S diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json index ea2989a..efaa058 100644 --- a/Properties/launchSettings.json +++ b/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "CloudBuilder.Topshelf": { "commandName": "Project", - "commandLineArgs": "task:ChineseNameExtractorTask book_id:B000008" + "commandLineArgs": "task:TtsTask book_id:B000008 voice:Sherpa2 actor:澈蕾 actor_voice:Sherpa1 save_path:D:\\\\Net8\\\\FileServer\\\\Backup\\\\DmsFile\\\\voice" } } } \ No newline at end of file diff --git a/Task/AI/ChineseNameExtractorTask.cs b/Task/AI/ChineseNameExtractorTask.cs index acc3861..e90f57a 100644 --- a/Task/AI/ChineseNameExtractorTask.cs +++ b/Task/AI/ChineseNameExtractorTask.cs @@ -42,7 +42,7 @@ namespace CloudBuilder.Topshelf.Task List cons = null; - SpeakerAnalysisHelper speakerFeatureLearner = new SpeakerAnalysisHelper(); + SpeakerAnalysisHelper speakerAnalysisHelper = new SpeakerAnalysisHelper(); AiSentenceViewEntity[] ents = repository.DetachedEntities.Where(x => x.BookId == guid).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray(); if (ents == null || ents.Length == 0) return; @@ -54,11 +54,12 @@ namespace CloudBuilder.Topshelf.Task int totalLines = ents.Length; int processedLines = 0; // 已处理行数计数器 AiChapterPersonEntity aiChapterPerson; + List cps = new List(); foreach (var ent in ents) { processedLines++; - person = speakerFeatureLearner.GetPerson(hanlp, ent.Content); + person = speakerAnalysisHelper.GetPerson(hanlp, ent.Content); paragraphIndex = ent.ParagraphId; if (!string.IsNullOrEmpty(person)) @@ -72,8 +73,9 @@ namespace CloudBuilder.Topshelf.Task aiChapterPerson.PersonName = p; aiChapterPerson.ChapterId = ent.ChapterId; aiChapterPerson.ParagraphIndex = ent.ParagraphId; + aiChapterPerson.SentenceIndex= ent.SentenceIndex; aiChapterPerson.OrderIndex = orderIndex++; - + cps.Add(aiChapterPerson); repositoryAiChapterPersonEntity.InsertNow(aiChapterPerson); } } @@ -81,6 +83,9 @@ namespace CloudBuilder.Topshelf.Task UpdateProgress(processedLines, totalLines); } + speakerAnalysisHelper.AiChapterPersons = cps.ToArray(); + + speakerAnalysisHelper.MatchPerson(ents, repositoryAiSentenceEntity); } catch (Exception ex) { diff --git a/Task/TTS/TtsTask.cs b/Task/TTS/TtsTask.cs index 4bfe594..eff26db 100644 --- a/Task/TTS/TtsTask.cs +++ b/Task/TTS/TtsTask.cs @@ -1,9 +1,14 @@ -using CloudBuilder.Core.DatabaseAccessor.Entity; +using CloudBuilder.AI.Entity; +using CloudBuilder.Core.DatabaseAccessor.Entity; using CloudBuilder.Core.DependencyInjection.Task; using CloudBuilder.Topshelf.Utility; +using Microsoft.IdentityModel.Tokens; +using NAudio.Lame; +using NAudio.Wave; using System; using System.Collections.Generic; using System.Linq; +using System.Numerics; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; @@ -12,6 +17,7 @@ using static System.Runtime.InteropServices.JavaScript.JSType; namespace CloudBuilder.Topshelf.Task.TTS { + //task:TtsTask book_id:B000008 voice:Sherpa2 actor:韩立 actor_voice:Sherpa1 save_path:D:\\Net8\\FileServer\\Backup\\DmsFile\\voice //task:TtsTask voice:Sherpa2 save_path:D:\\Net8\\FileServer\\Backup\\DmsFile\\voice\\20260528112739.mp3 text:二愣子睁大着双眼,直直望着茅草和烂泥糊成的黑屋顶,身上盖着的旧棉被,已呈深黄色,看不出原来的本来面目,还若有若无的散发着淡淡的霉味。 public class TtsTask : IScheduleTask { @@ -24,19 +30,173 @@ namespace CloudBuilder.Topshelf.Task.TTS public void Run(Dictionary bodyDict) { - string save_path = string.Empty, text = string.Empty, voice = ChineseTtsVoice.Sherpa2.ToString(); + IRepository repository = service.GetRepository>(); + + string bookId = string.Empty; + if (bodyDict.ContainsKey("book_id")) + bookId = bodyDict["book_id"]; + + AiSentenceViewEntity[] ents = repository.DetachedEntities.Where(x => x.BookId == bookId).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray(); + + if (ents == null || ents.Length == 0) return; + + string save_path = string.Empty, text = string.Empty, voice = ChineseTtsVoice.Sherpa2.ToString(), actor = string.Empty, actor_voice = ChineseTtsVoice.Sherpa1.ToString(); + if (bodyDict.ContainsKey("actor")) + actor = bodyDict["actor"]; + if (bodyDict.ContainsKey("voice")) voice = bodyDict["voice"]; + if (bodyDict.ContainsKey("actor_voice")) + actor_voice = bodyDict["actor_voice"]; + if (bodyDict.ContainsKey("save_path")) save_path = bodyDict["save_path"]; - if (bodyDict.ContainsKey("text")) - text = bodyDict["text"]; + GenerateAndMergeChapterAudio(ents, actor, actor_voice, voice, save_path); + } - if (string.IsNullOrEmpty(voice) || string.IsNullOrEmpty(save_path) || string.IsNullOrEmpty(text)) return; + public void GenerateAndMergeChapterAudio(AiSentenceViewEntity[] ents, string actor, string actor_voice, string mainVoice, string save_path) + { + // 1. 按 BookId + ChapterId 分组(关键!) + var chapterGroups = ents + .Where(ent => ent.Content.Any(c => c >= 0x4E00 && c <= 0x9FFF)) // 只保留含中文的句子 + .GroupBy(ent => new { ent.BookId, ent.ChapterId }) + .ToList(); - SaveAudioToFileHelper.AudioToFile(EnumHelper.ToEnum(voice), text, save_path); + int totalLines = chapterGroups.Count(); + int processedLines = 0; // 已处理行数计数器 + + foreach (var chapter in chapterGroups) + { + processedLines++; + + string bookId = chapter.Key.BookId; + int chapterId = chapter.Key.ChapterId; + List tempMp3List = new List(); // 本章所有碎片音频 + + // 2. 生成本章所有句子音频 + foreach (AiSentenceViewEntity ent in chapter) + { + string voice = ChineseTtsVoice.Sherpa2.ToString(); + if (ent.DialogueIndc == YesNoPolicy.YES) + { + if (ent.PersonName == actor) + voice = actor_voice; + else + voice = AI.Policy.ChineseTtsVoiceRandom.GetRandom().ToString(); + } + else + { + voice = mainVoice; + } + + if (string.IsNullOrEmpty(voice) || string.IsNullOrEmpty(ent.Content)) + continue; + + // 碎片文件名:BookId_ChapterId_ParagraphId_SentenceId.mp3 + string fileName = string.Format("{0}_{1}_{2}_{3}.mp3", ent.BookId, ent.ChapterId, ent.ParagraphId, ent.SentenceId); + string filePath = Path.Combine(save_path, fileName); + + // 生成音频 + SaveAudioToFileHelper.AudioToFile(EnumHelper.ToEnum(voice), ent.Content, filePath); + + tempMp3List.Add(filePath); // 加入合并列表 + } + + Thread.Sleep(100); + + // 3. 合并为:BookId_ChapterId.mp3 + string outputFileName = string.Format("{0}_{1}.mp3", bookId, chapterId); + string outputFilePath = Path.Combine(save_path, outputFileName); + + MergeChapterMp3Files(tempMp3List, outputFilePath); + + // 4. 可选:合并后删除碎片文件(节省空间) + foreach (var chunk in tempMp3List) + { + try { File.Delete(chunk); } catch { } + } + + Console.WriteLine($"章节合并完成:{outputFileName}"); + + UpdateProgress(processedLines, totalLines); + } + } + ///

+ /// 最终修复:完全解决 No fmt chunk / 采样率不兼容 / 只有一截声音 + /// + public void MergeChapterMp3Files(List chunkFiles, string outputFilePath) + { + var validFiles = chunkFiles.Where(File.Exists).ToList(); + if (validFiles.Count == 0) return; + + try + { + // 目标格式:32000Hz 单声道 16bit + WaveFormat targetFormat = new WaveFormat(32000, 16, 1); + + // 直接生成 MP3,不经过 WAV 文件,彻底避免 fmt 错误 + using (var mp3Writer = new LameMP3FileWriter(outputFilePath, targetFormat, 128)) + { + foreach (var file in validFiles) + { + try + { + // 释放文件占用 + GC.Collect(); + GC.WaitForPendingFinalizers(); + + // 用Windows系统解码器读取任何MP3 + using (var reader = new MediaFoundationReader(file)) + using (var resampler = new MediaFoundationResampler(reader, targetFormat)) + { + byte[] buffer = new byte[8192]; + int read; + while ((read = resampler.Read(buffer, 0, buffer.Length)) > 0) + { + mp3Writer.Write(buffer, 0, read); + } + } + } + catch (Exception ex) + { + Console.WriteLine($"跳过文件:{file},错误:{ex.Message}"); + } + } + } + + Console.WriteLine($"✅ 合并成功:{outputFilePath},大小:{new FileInfo(outputFilePath).Length} 字节"); + } + catch (Exception ex) + { + Console.WriteLine($"❌ 合并失败:{ex.Message}"); + } + } + + // 辅助方法:WAV 转 MP3 + private void WaveFileToMp3(byte[] wavData, string mp3Path) + { + using (var ms = new MemoryStream(wavData)) + using (var waveReader = new WaveFileReader(ms)) + using (var mp3Writer = new LameMP3FileWriter(mp3Path, waveReader.WaveFormat, 128)) + { + waveReader.CopyTo(mp3Writer); + } + } + + private static void UpdateProgress(int processed, int total) + { + double progressPercent = (double)processed / total * 100; + int progressBarLength = 50; // 进度条总长度 + int filledLength = (int)(progressPercent / 100 * progressBarLength); + + // 构建进度条(如:[██████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░]) + string progressBar = "[" + new string('█', filledLength) + new string('░', progressBarLength - filledLength) + "]"; + + string progressInfo = $"{progressBar} {progressPercent:F2}% | 已处理:{processed}/{total} "; + Console.Write($"\r{progressInfo}"); + Console.Out.Flush(); } } } diff --git a/Utility/SpeakerAnalysisHelper.cs b/Utility/SpeakerAnalysisHelper.cs index e84b445..18b3b1e 100644 --- a/Utility/SpeakerAnalysisHelper.cs +++ b/Utility/SpeakerAnalysisHelper.cs @@ -1,4 +1,5 @@ using CloudBuilder.AI.Entity; +using CloudBuilder.Core.DatabaseAccessor.Entity; using CloudBuilder.Topshelf.Python; using System; using System.Collections.Generic; @@ -184,7 +185,35 @@ namespace CloudBuilder.Topshelf.Utility return arg0; } - //public AiSentenceEntity[] AiParagraphs { get; set; } + public void MatchPerson(AiSentenceViewEntity[] aiSentences, IRepository repositoryAiSentenceEntity) + { + if (AiChapterPersons == null || AiChapterPersons.Length == 0) return; + + AiSentenceEntity aiSentence; + string dialogueName = string.Empty; + foreach (AiSentenceViewEntity aiSentenceView in aiSentences) + { + dialogueName= string.Empty; + if (aiSentenceView.DialogueIndc != YesNoPolicy.YES) continue; + + if (aiSentences.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphId == aiSentenceView.ParagraphId).Count() > 1) + { + if (AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex == x.SentenceIndex).Any()) + { + dialogueName = AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex == x.SentenceIndex).FirstOrDefault().PersonName; + } + + if (AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex != x.SentenceIndex && x.PersonName != dialogueName).Any()) + { + aiSentenceView.PersonName = AiChapterPersons.Where(x =>x.ChapterId==aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex != x.SentenceIndex && x.PersonName != dialogueName).OrderBy(x => x.OrderIndex).FirstOrDefault().PersonName; + } + } + + aiSentence = new AiSentenceEntity(); + ObjectCopyHelper.Copy(aiSentenceView, aiSentence); + repositoryAiSentenceEntity.UpdateNow(aiSentence); + } + } public AiSentenceEntity[] AiSentences { get; set; } @@ -203,37 +232,4 @@ D -->|匹配失败| E{规则3:段落内最近人物}; E -->|匹配成功| C; E -->|匹配失败| F[赋值默认值+标记异常]; -规则 1:文本特征精准匹配(最高优先级) -基于对话内容中的 “专属特征” 直接匹配说话者,避免上下文干扰: -示例规则: -对话内容特征 匹配的说话者 -包含 “第二元婴” 韩立 -包含 “银月所化” 银月 -包含 “本座 / 本尊” 反派角色 - -落地:维护一个 “特征 - 人物” 映射字典,匹配时优先使用: -规则 2:紧邻旁白匹配(次高优先级)只找对话行 “紧邻的前 1-2 行旁白”,而非整个段落的旁白,避免跨越多个人物导致匹配错误: -规则:仅检查对话行的前 1 行、前 2 行旁白(最多前 3 行),超过则停止; -落地:修改向前查找的逻辑,限制查找范围 - -规则 3:排除无效人物(避免干扰)从旁白中提取人物时,过滤掉 “非核心人物”(如 “店小二”“路人”),只保留主要人物: -落地:维护 “核心人物白名单”,提取人物时只保留白名单内的名称 - -3. 增加异常处理和人工校验(兜底保障) -即使逻辑再完善,也会有边缘场景匹配错误,需通过 “异常标记 + 人工复核” 兜底: - -步骤 1:标记可疑匹配结果对以下情况标记为 “可疑”,存入日志或单独字段: -匹配到的人物在旁白中出现次数≥2(比如同一段落有韩立和银月,无法确定); -对话行前后 3 行都没有找到人物,最终赋值为 “未知人物”; -对话内容无任何特征,且段落内人物数量≥3; -落地:为实体增加扩展字段(如IsSuspected),或生成异常日志 - -步骤 2:人工复核可疑数据 -规则:所有标记为 “可疑” 的匹配结果,必须经过人工复核后再更新到数据库; -落地:生成 “可疑数据清单”(包含Guid、Content、PersonName),供运营 / 编辑人员校验,修正错误后重新填充。 - - -收集错误案例:记录每次匹配错误的场景(如 “银月的对话匹配给韩立”),分析错误原因; -迭代特征字典:将错误案例转化为新的特征规则(如新增 “乌云”→银月,“元婴”→韩立); -A/B 测试:对优化后的规则做小范围测试,对比匹配准确率,确认有效后全量上线。 */ \ No newline at end of file