From 63cd379682224e30ade87741753de1a2e5788f15 Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Mon, 25 Sep 2023 23:12:42 +0800 Subject: [PATCH] Add share link hook (#351) --- docSite/assets/imgs/sharelinkProcess.png | Bin 0 -> 164665 bytes docSite/content/docs/development/openApi.md | 159 +++++++++++++++++- projects/app/public/locales/en/common.json | 5 +- projects/app/public/locales/zh/common.json | 5 +- projects/app/src/api/core/dataset/data.d.ts | 3 +- projects/app/src/api/support/outLink.ts | 2 +- projects/app/src/components/ChatBox/index.tsx | 4 +- projects/app/src/pages/api/chat/chatTest.ts | 2 +- .../api/common/bill/createTrainingBill.ts | 2 +- .../api/core/dataset/data/delDataById.ts | 2 +- .../pages/api/core/dataset/data/insertData.ts | 2 +- .../pages/api/core/dataset/data/pushData.ts | 2 +- .../pages/api/core/dataset/data/updateData.ts | 2 +- .../src/pages/api/core/dataset/searchTest.ts | 2 +- .../src/pages/api/openapi/plugin/vector.ts | 2 +- .../pages/api/openapi/v1/chat/completions.ts | 17 +- .../pages/api/openapi/v1/chat/getHistory.ts | 2 +- .../app/src/pages/api/plugins/urlFetch.ts | 2 +- .../app/src/pages/api/support/file/delete.ts | 2 +- .../app/src/pages/api/support/file/readUrl.ts | 2 +- .../app/src/pages/api/support/outLink/init.ts | 7 +- .../app/detail/components/OutLink/Share.tsx | 34 +++- projects/app/src/pages/chat/share.tsx | 43 +++-- .../app/src/service/support/outLink/auth.ts | 136 +++++++++++---- .../app/src/service/support/outLink/index.ts | 30 ++++ .../app/src/service/support/outLink/schema.ts | 3 + projects/app/src/service/utils/auth.ts | 54 +++--- projects/app/src/types/core/dataset/data.d.ts | 1 + projects/app/src/types/support/outLink.d.ts | 1 + 29 files changed, 430 insertions(+), 98 deletions(-) create mode 100644 docSite/assets/imgs/sharelinkProcess.png diff --git a/docSite/assets/imgs/sharelinkProcess.png b/docSite/assets/imgs/sharelinkProcess.png new file mode 100644 index 0000000000000000000000000000000000000000..b6e7076e73f224e50a61a3207933983e965f64ff GIT binary patch literal 164665 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�W%1T2l_jGA3c^c zwe)wofTG2p5EuOp1}vp$&Jk!9TV0=+oW!?HDM>Nw*4w#H_jX3if;%E7-{9*PV?Utx zol#mSnCs)ME5;G~Ki)R-Id8qL4*Klb9vFzSUZFosxilT9Hhitow#*#d{yxPcyIq$i zFw4_UHBEO3#mX^sWwY)zc4Si|@G`1go`TVNp1s0^-2?=!IBv}A9qL#9t+kmz(8+!~ zljhx_ZTiU;DyY{$RL`*azkh&^)p}aq3bvADbk~Di!;b5MW{v>lVP5F$Z0ig2pwYRP z5ueLK!*8U=SG}wtfxs&|LGY|YqwBI3jse|FU3nB29%a1OTEreDyJ1jX&Sr?3qteQ+l{MRRsC8giz9Dzz~X9C^Kv88Jtdq3<$m9#!+^N#LepvkJE#ww!3O zHJo}`)eF~Vt%OU{F=qS0O`Gx5_hmCGm7XkgJ(siy!AOa{vAn~12S?On=?HYU$~Rf* zn0AVE0NIJQ>HL?+zWpU9XIbPQ!gwNjDW8T|JkbMF(EJ7D1Rj|__vhl&$jL(p6N-W3 z(&TnNv@$|~#mah~kWeg-E0oW+;kn2baA8kKSI@ZW&oR-qW3q>Z2SjpJ@?VZGFz)gW zKTUI;{mu(ZaRmhhvR)dRQW|W&lC&Zd2fH7i>$|8#ii&h(_i2)E@0KTQo@{DC1k)E3 zu6yOWWV1L5V={AYG&jHY;#__`@hPbC84LY@;1n5P_cC_ECh8_nGlk*(Ec1Sl#hve> zhAjU8<&AEh0kcn$6Xu8zm|%O)k98y`f>{n2;w9shffCzsJ{9`DTXi!RZ5yhGgb4e{mj>1&umqc>E~&z-7Gmm!4FuKiXA9DT zX}l4JhNuQ_T}P2rVH*d*M&S1|R36LOxi>?3$2cW|0&aDGAI>D6^~W2e~~(hfmh~HaI)4rvay70mMFC59{}$ zDkElkPjTeWyd-jUUCj92wF}}tk#8@;`1{fgOVL|C_ov^$ck9nw+(VI=2YS=bc+Vhs zav5QY%iY~m!CF6$l zS1}lc8B@;tAY6vKr?;uh$7zkqLCoaW{hC5xw!cKIFn;p2co~4*lIS6VDP=<(CCT9R zXu&~qB|;>uLMj#K*!lkD!v5DZH<&E3&}9fN zTTKS!_BuGO+0|w}a*k>kl_K||Hp?^p_7+k{Svfh+x-xxfZIVWBy9%+btgLzNp)@w_ z_=;J`ZY-3)mbpkf{ZfH%`Bq4Lg9uZvb!9h7RLh=%#IUN^KoP(CLTs$|fis1_dA8Xp zf_?u1!zugJkdu2#SAba480BE{3n=Ob+FBaaXd|BHvGRu%EZ!*~e!H zD}tCS>#d10&%Zqk_bl`p5*TDa4n0{Fw5940dvl(>3z+1}ny!6$<*zIrfM)RZv$*QM zZ9}T@t`*!7``=@uqAfMa?uLnMcczA3=*qk}`a_u6E+C-<`DH|zen z&iA`UmX(M1S<-x!>Jl_5cz59Go+_EKKrW<<7 z9$AjBbX8&pLB4I&da3)2zQvExj9BtE8ml_AFkJFb>N$-Pj&F~m!nQ?m)IsXPYNob< zB>u%($%7568;)vg(G=an!!sCB$&Rj79X?{Nzzua8ZLZC%j!j{2DND2*f3~(Z8I>K& z#KTK_X{3(Js;jTawN#WgEKJ2bD>3oB`WIu1wL-fw88y24y-+WmWv?x-hr@^m6g+b( zweLEp=4Uk}*bxOt3^L4p5x|gr2kJsKw%jZ=R95choK(4wHmk{gTw9@wPjudZFV zMwtfr1hy%f{4*zOC<4BWwp(ihXJE_W(j6@>%+u>L&S$c6olmwq8TPcOL@sX+^n}U~ z?v{DH%1jIzE?OENwzOy9mhIhX5MRf?$Lc9wQuxTo4xHo*SgP}FuCoT#)w;^hbfq|O z_)|1^A68E+SH-1huZI^w`5J4J%L4aQJ5JLftGj9`0tz^>j*ICB3MgE#$U2;wb&N0! z9G=H89@$#qAbb&vYem@36}xyH7#`-#NEA%Bx>k7f>UQ}A;IFeFvXo)zX}Ht7cA zoP6YM)JTh~y2{G71|}wy7l*hp&+2En@+7t#)|d~%@n64oZv`m_h57WYV-M3x0)BYB zWVh&X(fGwP>0o#?$VjBXagliG4DiTn;0!St21Xw{T5xed37?fC4YJXl?yBH*MzeyR;@!%#1-FY_2*pRi!b0+~Qu)qWr-{Te*AEY6> z8)q#9kR5$P5UQkHuNFbZ45ANIK&}!ka&V7rUkoRJU%B`x-8?2{KOewg4}LJB_6d&c zRgzGh`J>)t)?-iO$pX1(@!ZOxW1DpF=me0R%pzl2N9Mi355`$_aU5Iw>tgV{Es?v7 z$KLWQNFD+5;BWRB6`7qs_Xhm#Meu0Cv8OdQLat07o!2o}=HSthWPn=LfL>(ID9k+( z3IeJ03y-ZGz6G8)xqi>%*js*u5^q5#c$wnwI7lw3{1rTi<^MYcukz{y+aVU-m8VuR62`J!mTq`Els~6^@;ddNM zcn;x6!U{F;UXj(|*4Ni7pwV63010OCoq-xTkZcH;6Vk;X%erkfJJ(N7#_@q1q~Oj^ zoXj~=pNXsiF0ImBaW@jL`YeFL2H!mM?jNPbpRPWDKqO+oOR|TG(}(&`l-1OhP^GHp zKWL@9Z(W}RB}}x}KIuS(vc&udP{8GyDq?4Exq-*9wzBdJ;7h1MwWr)DZN|7W@<$JC znD!0Fo^(6tRK{$oF1vB>P z{9~DeVNhhEP5Xch-a%vl@&=8bMlaBirogq`Sx>-qD3(_;$)3&aZkJC@r{R)ws;Rex zn2)e@OB9)9WiPoIS}G{m?RoVWfnJB^BM&t+OMV!k1@71AzV{-xDW;hFqGKXpHnhX2 zHh!hnp@BzTV3|e8)ZL3L=TXlCO4} z9FGML?5evqMiLFohhewe%WT(BPR8sOo&|yJY=5S0D|UcI(pb>=g&D^zkOkjpBFy#6 zAHV0`!bMIo>T^E0&bBS>>3XxXCr+WBf~6!fnI2iJ76}N*Scp5CkDL30P}~Pp+FJ#BJbnef$0B=B z^}|wRf>DY4^!06fG1-GG43L(fsO)Ur&H+TQy)gtR;<~&%8D1`v@7;0(A>eprVrtKz z+W_y?T<_|gds$ikH5cm-134;2o1M& zIB_TIHkEB^4?VGWCY5n5b~GcKm;p8F?l{*=$reED67=(@f|ay;*7T^3l9yN(qh5k9S9_$9DmwpPb!W?n%j+ncX!C-2woYAB;B9VT|(% zp}t$+bVAB|Xt&G4i_BWBW++B{PflA)y&+y&qjEesL4e{ zna`qkyVe+l7HkfWho>g@?-7pr!z)!eJ+IGq*=crWu9G|aiR}zln0NPH9u^d*^DeSj zweHH?RBW?gzcexSbywg+w(!x~i+dBu>lD!=liUE1qsdxfSNyY;2U;EC2{v|s2&~&x za`dJNr7$+PC~3STho-}AO$u&N>hc(BzJ7YsFGB?=V)Ukc0NY}}!7W=30dmBdpUOVO z;)#G$A%uEQHalqcOz=iKJ4D>V^RTgR8`_Kp68S1E*Y;$NGs7)~neaKlS4c9M>_zHA44_B6^pFew6W)(Npy- z)?@3kW39DL&5zi}shkjl7ft^_V3zZ)#*x}%8XeKt@+Lqf8m?=uBH6UJAZIS~(dXqq z)XdMnWFU6WI04_zWyCy>5Z2dTi~c&)uv0v5+D!%FRI;Q)$Xs@M*BBWQhge8&GSvEb zUjhQ|F@-DhswEui3*VWbEV$+d_uS>~Z1b;Q%xiF7q#D*3?1p3{p z?MU00`amjU)PLdG#XF6cY=d~0KP-$4tDU&8nS#IWfxj+FM8FKAdYZfY^vhGk1(;ws zN5T6)vgTe5ND0GJGD4C)ggSnL<~%hf+{m;MmN)C`J1`zX+lnV4A;D$SX>&A0PBZjG z&U;-ZkbNZz5y)T0CFj5n+wRAPN;OUZ;^x)MeHX|8hL6#==^nzq_a00XmRC%}gc)ui#MIBqVR&8L3m@uz0!2fbU)AiNpN`uo$jwx-Lz*OK{d z-1t^Hq%X$L5>j!w_gjtA4?R4k@LY4399cS!`+0-C=IdM5jB~aImMwWKW)(%lZ6IMj zMonEF@m}4={;mR^tLWxNpn0plo<3rf6rNT*7UCS$2x&>8eahJy@qnlEFHqWs^$>L~ zp#zx!qj4cCSo1!p+9l2kT?H`E^a($X&3PM8EVh}q*LkilN@=y=^0aTc`ctMpEp@n^ zacw#isA_E15SkO+IIRf{ZPeQ^^qK4!*9t3Ft*tgj_uJeVxY3p$^QfX&W; z>Em(m@$-A&7U%KcN;U-BO9MOlsj+>n8d8hmABusU>H1a&tPDQ6)1yag+h1F*E;l~d zmmj&QaK&i0+-|;BJYg|k7+jNz-i&FYfcYp}PFyooMcO9uDp0|=+PUYCsMkL~ z^*nWx2^M_f^mxPN%OR*#;!osE90h3{3@q(7zB-m~0x<@oEF^&^;6gS-WBT?XfYo?P zxI$W|`~@&JLvhr1@v)>2Ep4MKs-EcXrBoq+AG`pkV$rM6G8iv**4}IulcCvdZQ>Sp z++O*4N>@ezB#JO4r6t2!A_U-&9V%{xEKbqydGCt~z=F+)oK00SIdH%8@$>33Z(c(* z?HS^cC()cY2=da>sj@LQv2V1@dy%xej_9D9EB+$3xVJadvty4Uzt1S~$EL!Yz{Xy; zE#3P=?;oQ|15)Y}S4dU={P`d4fPzZO40e5Ghm!*vs99Pv_E2)Z-fcMFqe~i#h~%^q zj!=L*GPg65TFZpc4gk={efF9i1T4E1wE3)B!1{3>!`MxQOWXWRgcrw*iq~oyig%aC zm(PbS=C2nPl!G!TK7e?5MC@91r0@Eys{@&V3ZZM;zy{Hh$kLvNQOyHUNK<#Pp8(}= z$31ZVJ(tNE=vVI>#=s1O4d~9A08}0X3q;#G0~6HV|E$G$L|sim*ksZM9b}aAK*09l zm9krZm~q4vdwmta7K8y(1p;}ZG`<4Wt%%*;(1lsAIqHkEmmz?-(@zOof8rMyPa>r$ca_#G=jC#<94#g@va-fy6w8+53tO z4jMjA`+JPvgs*J^_c4QMnR{HjN|>m?{A>Qu-0C!@@wSVyt-$c7O~^=JNT7^=4)mg* zT^4Z3EZiwjXD2$z!=0RJpBwp-!F*aIhqDmBajRJ}`y-9mkv$OvJvn0BjHGZ0R+qfY z_7-u(5mAIkYCteJ&cy)B-PX4O~pnh zs_~oPj>cUR6BBH&+#GNFoJBB70PBOhm0+-UWp!z6F@<|s-9)ReBARsp}Gv`>W@O#TENFYBF6SJ^j%?s!a<-3L{ zSIX_o@Wkj=gSworne9GaPiWyC_K`Cgcq3Eq?T!#wyj1d|wKgqnN7e2jh%Z4{k10)3 z|MbnSxX)tmE3yW{O#OO1mQbEtPCUW8B^6t{b^s@y(vg7DNYOtF{tmS>-n|&9? z>!Dkj)OQRjauM2_#h3XJzjx%%2X_eRZITx#K!nWboFW5+tjzj0G`9880-!C+^bcU{ zlr@*@FEj>eLOB-xe)GNr#>NBHN*YXX`7G!;eO|?FIV(SYMa2IE^T4iSU*m+@_A zFz@{oB;H;OknN15;)G+?p%btP;2~E%dAA#HNI;I`qfaM{vI0TtKoX~}W^!tZ0HD3f z4g5uPI3YU&VQmz~!%5}}bY`CyRmH~<OM>RF*s!=iAK-d-lj-ra39l)g*6Y;BIyW34A746`{LxYehF2D+2 zj#;5d@`-BRF*GsZTFne3|8}&}Eu91mWz3Q)vax0EiI5wOqw9F|)c&@pk$mn+81UhM z8Z-6ndSfbGJVVjNjlc_al;y7uE|3sC=;ZRe`ku4Mp!HGYQ;%UP0AssY2V5!{_Xgol z-L3_CCikf~Q(s`Y-G~NR9^sI0lq`l7gJUApbI=7KegDhDClPN@GloT6@m#|JnnOu*;a$i}&G^v+vL3k9bp74UUc~d8HL+}0$BX^S zo?3wGOiwseFQ&yY7|^MDM^y`;a7P4O?q8qPLXA2>4TJ7oWmZQlzVw%09(;(W6i!Z)|B1ik#V)UmRaFd=x|mfsD47l{!A*K>C!yJ4Eb* z+{r!=un#lQn7j7-JyrcyepF%;u7Kzp^K33MY8yL&vGnPqk4IY0S4CCAa&tMzSE=X> z2UJr`eF2w+h^cAkOZ3Z~yLcMy*ue!WO|8%S;`Vl2vUnz@rZsUdE2guRZS=l2hje_J z#uf1$PbpaRRI--q6z+r>&^_=`5cT4I$=Kz{*AD>BL*GRs7F)^YXX&fzSkn5f$4!Q^ z@-02@v&x=z2A3p)bR{Z_gV%kEd|RYST)w|FPD(iD`T7GahhSG(JF+XXTFp>4Evysy z-Qon5NE`t2E?UZr2qBdfSq->=*XcSnep7xih~Bt|7>YWImm8hS`^lcZ;KB>iw7?ky zw@ju9%-VaiZks}+s0(6h0d%rm-SD>sz0jF1pyCP&3cPv;dV6WQd*TQ;?X9K;p5`@p zujO#9TcRBmD60ElPnv{AoQ`hPVW{m5WigrGQ2&;?qaQBnLRsQ?yoMXcf2#Ew-2YSl z5BL873Z~ct=kWPQ1%ZJPsP<>Ui6@V#vvW`@9(k7#q#+bB5E;@a1N>vZIDEFWH_#y8 z1XTZ#qy*aZ#8D~^&E)@!HYLJTi!nIF0>ESvf+UZ5K<-z;2IG$ABAo|E$_Thf{IdOU zWk;!Y`wy@xz(U*KD(%PzaE0 zs7xeT*bQTSv`s|8I=DTZ0yT^%A{-#6+fS2w*2lT~=>uBlJGcjiUc^q9`H<^nF?E;f zmpE)Ox4{q?Drd#xNWhZ-*re)22<~zomEB)!bbkuM4w0LsB*Ju0Sr+$s)TRFZ%bQQboqk4yfq)wP1g1FC+i_TefS zRw|tZx|a3?Gco9_r_=4Ko6~id<6bHzOQW`tF6^dgAe7VzPzDAbuT-C}J#XG_Kkhjm z;gA#RWow9vjT@Rj5xUSz7=A0S%u0$BCX<`XdQ3OECxWs_n5tRfk&xq1ni(!)gR|l9 z*3BSAx0~xq?Xo)-awdFim|pC()6VlV)FWBGR~SUx2a48BH~QxLsXwR7(K}n&Ei0Eu zrkS52PRIi+`mPBZCFdC2R>`TX5}mnIEp{PD97$Kb&JD*XAr zx0Un9Suv0OrbR#h%zPyl8IV11Hei=Nwqd7$gO+ly{N2%H?ZJLBfWd@~Ckv^{Zu(bp zY)_pUs>?*+S4NmW2=+*R2}i^Eve%tFv`H^YO6R0C{JJIRTDu#*bM0Rvc z7r&wwmyqHaUPe8GwG)BcfG1|ZB_Zyz-NAyua5b{Hi7;?^?27_R-n^WC)e1JV0qzGfWePeKD(X@0li9U-*ZyS z-wR#aEG_rLa*69OJ@xJ;1Lo~whw3Fpg)8*-4;Aj^7(aT!Y60$Vc!I45tym1C!OmCA zyi$l|Oka$0EU&3erI42f7kh%3B1m_nqrWGeON8S+*?U|o=OvBNw*V60-(%mu&q|u2 zRfAdg7>sj4&k>kHt3tj&^@N2KlM?$Z&7 z%%q*l$JC_#ZpTR8U@iNNvOo*@5zA0{SyhKHo*GcjfcA%g)E@h*87n7G@42 zmN#M6Tj$Y|crbVtHURh6udaM!0{BY6uGp}<3oL^puQQOw}-8eEu|Ie-hy`Lh3VySFw)HnA=+a5qqf-L z`n}vedPzn1Xp#ia(j=oj4&jZ`isALFpc__ow+Z+Z?A(7yF)m56f2q8_P@58|J@xY47(rH{r}{RRxu@eDzoDsc=PZUdZ>hzNaqeA7UQENjtm z|*t+`zU3St+soWifjB#uF#@N`Aie8#;l|h!|eN#K7L{K$*4|ZQ#9kHH-ir zI&TKxq1vk8C_h?N;Qfw;w>}%P-uV4HO+_j?miPJe;pX|R`EVUp-hO=GEOwBx9JgJM zLHobJOfy-TV_N6e>fmC4cUBr+${O}ePN4JlJlh1M4ZpN4%1xe3AVGbBP1Cm5F=Sif zn3k6GUeo1rs8#c=7fOjV0Q9!82SI-0n7{_!6;o31E*&%*h}iwkIMkZ0d2Z~Y4d?<)FK4AXhUmaE&U_`zi*e>$d0`zbmEhejzum zh<`mc5rxX&s;iyo4wyXh-F5v!m(*#PYKG@!j$>+r=M#{R@|=pVNbEgPf)d!^yNMMg za+qB^IQ!A>m{w&~x+UMM5zDNm~ohZRgP)nCB{tQMK z9&vgiA(h!Sk;!^Ye1GlLS)gfyWgRi(nlNcG??)Zo%UvdV|Uvd0YmIV%U%T&DK zOGtTC^rfOt0Y;`Mr*@8mhSRILLdQso0rodomQ(3CaQmkeL}q{$OlE1on8GxYV!(3F zLCa|&U)Yr?sbrOw0?IALB`FTV>_6z8l|0AtfcCGWWw9`ixrg3zN@?l2({epWVU z1=D|t`MWcJ#q76B3ht2qJu`o`*Rxabhw}Oc}`fuK98W#kbt9nzPwKtZ=9HBy2FgEZGr96A*=|1*;Sp?;oA*v7p zELGfgbjN4csKiOme8Jd}a?5_g89A#oz`*{l~v_*}zRc!4wuZk}!=7|0N>ejnX;my>B8P-0^Yo z>(b6b7jTVkle1BvLIIJN#dsptL+BT3`OWZ5AD~D>?8c-URv|kCje?t?zWlKcQtBC|K^{!Z#%p-IVyj6t7 zpMDMf!gy5DksdV0-CDLf#!8s`1Qx_C&MxeK?%L1y{oT61TX%5u{=c5Oyrx<(YpuGm z@ya9PP{!5ORnwDUF*OSDvbR9ly=Kcg!rI#Uj*9*LD{Ghe)}pdrQH-4*Xee^ zxpR%+6$!i=#ZQem{ifS;$45PR98^Z29>f_euu&nAUV6ze2%4_R=WgjHF~O$v1`?=# z>xG}kwp0`-k+s!lFOO=BKL?sY9Q<#}Cn`?)vnVI=McdokAJSq9yX@o{44T>5-Q#f* z5O$KBnwpADHmc7{4W*`iw;UafG1(rI#2Tco^lr6#x;^FH{X!duuT>^JIr>Gi=gkxc z3iay)UK+8DR5kJY2R>K>BeR_*XVg_*KR$tZVq~!``HSEhy};|$LZ#O~u3nIYF`<*Z zXBc#In;lO>dlv8CftkV*_Zelr)19Ao>>41KB@BaA8qRx0gAAqz1a>DESOvI=lsSP&vI z*;5SwCR^s}HyTV0-}2r^oGlV{i4e1!h08{DMLr>8S3O6C*O1Nfh+jPtBsWfC1?m!? z%W$h7H+ys5js{g0%Y09;iTP!gIv`>c|D!Ov6VQcyP5|up-y`)pi)}*?w?sn({kyoh zF$)DDYr%;h-%Z>L+S=OgsHmJ*@@J81i(yUNeX5$6xcRhHJ_`GsY_KAel9K;Yb9PhH zvc~Qv7ImuX?uQv_ngCDF8wY?ovBf`&l>`YyVUwG{GYS5|roJynxE-D#Lr_-Kl)%9Cg0qSncxg+e6Zdj0} zg_Cw&Rlx?+YBT!);WN}qXO7#;P8QIxt~gwt7^ynOdUy_qi1@`dz{MwI>dBJ&b5t7Ie3kFGGi0PfZLbD|-~&jdx4cSbg8z`&cfa`eU_WEmK_xqS5p& z=Y!x7u%TDq@e-da2BK@Wc-`(astvCBUUwgTk|i)i3DnLXCDB1oB6rj<56l{4OBB-%ON>=y1sQldcSpb#ozF;(YHSciM9H;zF(TZ#xMc3Wb!;~cVk#=Cx1OG!R_adl zDCieR%|~~#y?q`Nodd&v8{al94`KmH@sa25l2ie*W1U(5-x3+y%We-qcT`^9=BCe= z0+u>Ez3$vspvHYuF`)Ro+HbO5dVN^+Iv)DC{K|Emvd2e0ysi7e_~rgt@mMTX|}FT1P4# z*Dh|mSY@I$Q6a-pKccm*L&{RYvY9=((i49=CVLg-5l-F>vkQ7KtGxk7eb%l?2Hn=WZ{CGwL!;k*Xi^cFd1(0Hv<2WXYu1*Fd0U)sY$bgZ^v3ep% zgawWxPpH3%GBGSWIq3Lqz)FlJ3h;5l6nY>6Uo8S1vw&j;I_b zz z{$EC=3X~iT^fc7}v5$vJiwuW{ho_3#>n&e}M8HF+kF?XooI&x^z>G#DHPC|v?yT{gm{a6LQHEjj<|Cx6yP z!?L)!QhKYvS->#$AD!!AOC)AJNIVewtuzdoy~_Cvc+jkZg0(Qw~I&epyq^^ z#5N5kVs&zsZW_7zB{aG~KGFJf9OCEXK*GniOaE&m!W|t8S5{WO&2{HlL{D^VQQ=U3A_|`3DJWa~8^(CAO$TOKji2ijYAg78#wZ$KS6V+PZpkdvngze$F zRLx>)`s|-}i0IsBpl3+<-75cKeGei$_#A3qU*FP1v|k08p{Z$Lk>mPU@kO?i_edjzNHZ#Bo`ECy#k zaiAPi$?v7s+f`2kN;jEd{fw5E8{2pqt*W9sd=j{fQUhqL=9<9nZi_rTG0FtUE^^u4 z4=vi;njZb}{nebwvzPy{zeMREdz^qF6N&z>bN5iS(DOr&^y~7u^^{3%aO% z)fCs#wh2QWJMt{9TQI|L#hhtSlU=-iJY)6R+UVoGorKobR=XB@+qoHk-~vC~cSqA; z;F-{of+?~DLUOD;HdHP_V#r6Zs42!T$ZCrS4qDlI=qNKbR?;BMqSSfmT<4@F+l1h3 z+t#WPx68PY;9W^5P}r8{3<(a7&Ch3w*2lw}dH3}z3bUJDOvQJgu@eCw%;L6xIG{tj z&650F8%klqe|R45HzB9& z8g&;sa(_!Y=+gCua1rXK6Z7-$0|V=x+&vel0ZD-vjEes4&R3%o4}q_Rr%=+-o+E$b z#*GJ>wYr86KfHL&tT^c^Tj2Pf)AbqwEfp0xAJ4Q%U-pgQkYJtdn`Hen)6@R=)a|ih z=7wZkMg{_pmqw~@X_k>|bj~=7wDFENge^aL+Y%?^-`_u2B2U40E*LR@Um^0I_x%O? zn}Hnn18Yez^54TGuiR5P>HZNn@9`cPt>=l;T8Xgnv{;|03-KUS5^Upmc^wWs>va;R z&05XC+yR%6{kzi|(+L#Exlno)s0T7WkGKCJWU@qYNpc#~lD6dhR zx390SqfO(sUU*R2dQ$}~LH0VWh%Lt?nIG+TVyJ+HI-P^TBgrR8)&8VUzHctoSkt1O z%g1>vhH8TaNbHWfehMo<1Gv*GB9W-;;N%w!h}+0(K$dK3J&0TX;Z$oP_H|bP<+`L@ zhMvoJHT$22`QB-8Oy1s*$3(u}Bg}*QwIK!FYGy@Dx&01CknrDzgnt7q@)a3-08m4< zFHeOvcXv~9w@gM%cciT|D@?^lMKy(_Cq`^8tHnk~b2svXq4Lr?OQ&FMu;IQ;JxSf` zu{5HOdDbSLil@~^&(2=@6(62wo(Sf6MyXl&xfT2Ul?Zk#}kGzqZxHi^VD4J}4Wq}Y`uj(&y)Va>j&(E^cozf@I{!cE%0`s7{ zMJJE)&;Rj@k0ZC><>4%H;od3jjg1WA;>u+R!~` z+WVsjw<0pdBr5lA<96h_$-P|Jsj2DM!a^1klkZg9h*<1cgbx(J?8q7{Q8kN;$;x}+4Cicz42KYQew4TM`_wSr~_K!c6|hun@) zjugH1Q3M*AW6_JqttPm(EyD7%R)R~tbWN)(0nTnLu903#lcG`Z`G|tKYX5m}wPKJ0 zU`m&ZY`&A^HwIyb)jo*WGYJrxA>OUwZwaIOYX zFwtx6?q|&opn3{gK37!S;6yhRwe7W#C`;?>!u~f``~X)R9j-9_2dGh|BZr#jgW zqYT@+(>YeF^{}Uu^A+{0<-YALl0a1n9onf=_^d>a^wkIzh=XRbW>#Wmj;Rg){ZEgTMP>Wm_w`aK=*jg%ICCC>&J_NvtxPiKV8~*1BFC7R{2^t zc6NWR@YD3y_A9d-ELmNzJ3eNAj>S7&4)XxJg?U;`;W9Ck^7{yL!d= zCL3|-B_CJ#EtGZXYsgJMw*fyG4gUDUZG#U%1?pfn?##IidfJta+MeTlsi>&Y=!i7K z_W)Q#PEARx`)oT^VbL@3>E$Ae2s+tF0j3us#Tp=^R*Y($@F8mWhEEZSIBj8Vtp{zp zYd6<94^ezgMEmlEM639HOcj@suWe^e*X=|J z=4!fHW7C4lwkC3!L)E*3@WlWa?7kD(|NU6KYQLZ55otrXu|?!x){R_{*s+!=|!}7cYL<+7MIi4hy2-iIpj1o!WoO=( zMbqIeM`h(#LR%|gp6CW>tqBR}wvppSfS{$pO|+~}nn;dTtI=eMc7}(9ChfDWTTV^sUv{q&WK7~^Jbb!a0LDb7H zI==@R{tHc$BC;q$t6X+i))Tkw^*+o#_=Z=19L4#i4+`Op^#oD++Y&>?^Q^J$DP0-r z3q%(i5)%@xonvE@K(mPGA)`x;A2G$!)GeNZgBboE8UbyPZGB}DVH+LwwZ>Fxvl6+kQ>2RHP+Oy9Hz*7*jo96Zqp++Xm?Y z2*C!Wn_H+&;OD7m_$RMrzrW{vms^^+BSHtdh$v3uM=F^;$Tu=V<#ku@414MYCVKF! z_{gRL_%e%L?*iP_)a*|3<#z$XEUXX#(=O?S{bFYXskRIkpHS5V2BRy8)O-zO^tvH%1 z#83|mm2HvEed?6vEyBB*tkb+E2ZvYW=H?zLI2z@>8^~e2?=73(5^)qBANUo0>v8JUJd!KE-Z%fbQs;7j%JAA)NZ-GtpDj zqH5=jQVbF(1Y9>?)2=S==LwJ*Y`ZHZA_}#eoh@CawQ01;0{H+5_t^%3cnsHpu$P&= znf@(WJBR}khK%y4|UM1`8mwa+p3FHqsi&6yac@Xchoj-Az%9rEB`oN~}HYvg)Djp$dB z1aR?@mI}`f5QkS_J2MWav}YjYVxzfq9(gI3s4IwUpGr@|lb?I)jj5E4Xfv&Hwow3s zgqP3yGoN|c93#;ZW)NU(Z!dROSZ9@L6-xdISBJ}N=GN)(^Lv$rooFah1=(z=YM z)Hfy+C&dZ0)*n-E^K^0rS>QB-ZT4QHzv4eV@Odn?Wik&4wJE>2SfDrGeADy7)(C!$ z-xkh!s8t>@qN)UVVo+3+%rUj8&{W055Drb6l4fa<&L?j(<`DFPKAU(gYfpxBnwmAX z2bn{hxbg3g-D}d8gkB9LqGJ8nYp4jxh1Yh;+llGCUkm3ZahrBoVw8`}47GS_m@u=! zPje)IXU6-{qUI64!q?{@0vl5B^XA&&Yyw26R@LZ$W>wiB-W)-kJ*O2Qgy!-`vI@ju z^KW+wl%bY0L`m~HwY7@c-aA=vg*!q|pLpM0D z4QfAS(4>VvZhNxn4W6t%W;reZBJB~E(I1k zIZ^H4myleaR+Ni!W*M*IzP!M5J4I1KU7h~13^i|Ty_wx>B*ods@N3z|aodoj&^u7R zhhb8WxkH?CvU0XgHfi?@UUB(E`5A-TVI>cbWD)3UdvcVhFe={}^Iki?lrP*ZK}3|* zXbOHiVaBxQ7K?Y-i+zl|HjY+nk58PqJnf<;5t3uMT`cWe!VzeHv%3}jMHHHX-fti? zhcQ!&urlBL*si?MRgc6VQ04SIjJ(?hW!G4|rY9*_Iv)l~*xs3LZl-Y3Za03j6x(OG z;8eMREzov2horGpNb;8J-d-?xQ-RUYjM6YQSP@-1Pr7f zt7VBkQE>aggPhsH5`K(NCjL(j_6$IU#=ZXXr@IB?{+Vp*j6At}l(3WCfEF(#MNFRD zbGh~fj01is1RPk$_veU@fR>z_S#KQ<;^Tn2_Tyeb$CEwBcAr&-C?)z% zCxR?kMIoCchJe7M4ctjI?Q{J#r6Gt|rgko_1E}QbHfM;uDRXnq)}8PBe)#hwZr^z# z5pVj-&ms!fXNEklk<*wQ<(Z1ZlZw1_j9$FMEnbu%bUsuJ(adw+=+V>UsL5!dAMcj@oT8t8cQd08HfH6Us zeT!SpBtqy8#kRpgVTjfw0pO7LDwh_WmmUT~micr5M!*^rdwrw2AouY&s zE*jgC(VSlte*;oOAL-XzA1dhzl@;=Fo0p{Sl5hv`brugY+zkN*3s>xYP~!|0w3l_I zL8S#4LwJ%No3Y$Gc<|tLMUABPigMZWbSF>V!1i2yM&qcB$TxRtTj=iWjOXFzl?!_d zE!__!Yv+n?ynYEUULR5IeWL{`ASk0uJ;?`5iX@7iV7@ zG)fc1C|VZYqH&oE&kB%!s4S6ea4`Y?X!10<`5Uq3g$k5zuieUcPuau_)Ij+esGeWn zpfS5Ch^Hix2TkvMkxqLgz?Z^(-f2>@&B?}owzaszG^4zF1O0ruzpR)y#?fl5?n+xb z?NDHS#Wt&5S=VYes;ib|`HAz!tHc_a{heo%wp)y{T@FKh*XV7ShN8CbmhlfgtRl0I zy8M9In76;cl6K4T-OmDu;Q|668?8(EjR2CrgZFP!Wj$g94k;1DVT%A#97-8>RWxV) zSs|b#xlPaz-UOj&yyuz_6b#;JLTr{o1@LlA6kY+>jYDP4S|7y4Sz}T|hcfIJh5{GM zHia$^oa+Vk7#6GasVVc&}cOV|KMh2rH_GSRTwz>3n9UP5_t?rF>x zJvnStUnyy9bBs_A(_%zoSKxyh!6Ph;!L1=&`iR~KMGxSNKLd~1Q zLgbFq@VNFJA}#r7702%1zaL8GDZF7u=4O&N`Y*YIGW@aa&WH;6&5qg_(>9UKcCtsze${eq9d{=KG})+vJKQF7Fd`g)C&+JK zUmm?>G;kX2bbP@{JiQ3}z`YxQawdz`jk93LCV7gJ-l=2Ew`Zb{rgT&Io}j~Mfrw9f`K9E^m+b2KpKIvhCswJ)i_a6T_>3bd zdfRu(>-PT?FOh;$f9_(n5Z+I(d=XyvdZG9$G`y4wvcYwYO0R3g7MT9LZ31O#u zE%>N)+%xflk`)sZBA|zLPUU;MDFZ;Ts6ZDxS5Vs%e<76LvfRdwd7tt{%|XvgTbOt< zg=sW66parK9xUT{N3YHl!l4~d_w;6O*(5b!5ska_gL@fd!kNp;1jWsfI2uE`l&XD; ztAy}a`?KKh2!Ad6%hF&Je}K8ZBGF-DCtSelOW`oBBps&YH;Y3E89)h%Q?o z2^CnncB4QwZK2mGda+AwqiS-TB@uBmY4n|9#d)?JJvDJy$IeE00dT2mI(%dW>(45Ly%5nGN1%q?CYAEa<~k4RU&rN(iz=s zoI;O$xk&p>2%W*7Yv{1~wrQwrXo{MJezbL84M*gNM2#!R*~h zOAE`-Z?2M!uPu!pwjlW~fM2N*CC#3URgf25+KMf(nrSxik#-o~9C@Km&I zl>_&m^?F`tu>}|vDa0eT*ex7@ zW;Xqn#EUunK&UY+=Qf@^_bWw$C`INWRsk`kMEC8n2K9?P)*WOL)0l&PC(w@~v0EVF zrW%S{yOEqGc=F}KX6?mRhIlPn(U+hCwYRx%&>`ChEebGb`Z2f)a1tL!i&yr2(qPaEaun*Ke#}zIj9^J zxp3Xyz5sMF?l>J4NUv3ZCBmnV$Ullv!?!-ZS0Kl59AwJp^?OUUe+QwJB(ptP5;Pp8 zhlwBWm?6qFY0lsFw>g9#Gh$Xmil!XA-ywBCqL&%G7NQAd1BIaF6($i&&OPmgiN5r0_v3d#EHaYtMQMeMflAb{v5xcwe8CH4Vs+UAL~(9rY-gI9}Wp>|i>6 zuIT1Tm+|DcfwJve^I-g)?BfNWLoM`fnALtur;uri&+YIo`Ux9QD0ttWC>?qVnp=VH zQm+zvWcriJGf069Os(?%Pcr!{l!9f#_~3Y|s;41!>RxW@_=NHU)3lv9&UFEoaM$~B z0EGo)N$D!wH}?W;fLbywi~f9JB*AC~yx7zi+`sK}?z|bKgZ^5lab$l!+JG9LJPaaW ztniA5m)9%BsXmytY^HJ_OoAP1b&IcE;(I5++P%?!>xU zud;_?wJlaw!|Nw$dKIWJj5wGWwI>q_IZgZZeLyaWXL{%Fz_J5baizvexvy+isY1UvngmtW5eXH3c4Pe%ortqyID#y zhMLW}3`x10Q?XLhwwhNI6)DP)tj!&Jb8B)9Oa~-&3v<&+Xlyr*5~$_g*2Ry64)C~t zUV|i%XoWf1h)-xYt53?{@lx^l`oN(k3Fy!}4XDwoHcN|k-pK6tE03^Z z2l#?uGrE^lXnibDi*iL3U_gaTef|CVqt(8>9E~o2Y3|>m+- zy-rqmhY+u&H1ClYB`X-*5cGx%MM>BOu!97qI_#r0<8TA)SW)Y(qMdT5@sxMz0crh? z@%j0D`L3I2^@3G{BPs`|-kMozb4W<+XA+4?W^4ilYz4Jjm(!z^j(58Z2%9F@*Md?e z=}Cx;a=oT~V-RXmk}2>>vKl`xKEL($wU{SnjE3&c(JuM>Vc$Wu@z>!b;?)viXJeKW z&zggvarhRCz3a*hJP=r-v)d4ZmS;NY?Tc~VH*I}!-gR!J*@p9u^U+S}LtjnH;~d+K z(?fI28c2#K%;6uCby`8{^{RcLg4V=RGe`B|OpV+L-;B$%L5iUJSfCMuI%~D`t5@=~)dzg~}KW}YVx?yR2L)5#Jl(&E-qqNRhn%P@2KUQmxpV3`BGd+Ee zv7L&=4@?cS&2mfaV>eM}1z{-Z0e2H~LHkvQvfF^*oz(Zn@zA6tjyF|FdgKdE=b@r5 zs0J@g>64cNnhJ?>TH9#J3;D_X1FX$M8=eQq>8ZKPE+X(+^kQrDTxPVhJ2$f7_(>$m zVO;t>0340~AU#+jTiJ0VQpfa3h8#hXc7)QLmofal>lG303%4e^c$qqirt&T8_${^_ z&H9pt+6(RmZmu-+FAoyHnI<-tsKf$~z3mSVy$8*u;C4_-^k_nCrv+6A6T5kDwR_Ag zpN)aj%yh`@@U#G?!ROVve$+baPr`|r1t56v78~Sm_5VjOUw`s1fr)J6r>g+zV6*`K z1K2}u3OM%A`-fkpL%pQabR#fDuQ^JX#9hk8+IcEFE=LhmOD4TUM+shqDjhun5eED( zv)dI~*CZvcnj+`tZ@d;TiF$d1n8y`6Nuedk5cn>oRR4=aMrcQR_dX(6r}g~60G_fqEMR%M{;EX?6EnDUZX|H<;hTtNanQS(yyCl~zfbh&3!f9}?PuMESF(cge(-IpXH zj=9u#sm{+61eGIwNn#&sRMS=~BLvJJs4uL(b(cze@5v#<+v_cgb_K;Mf)||Sg=&8E zqVw#c=6yVX!q3C;7|NODynfnxs>Pr7%|O}YtJ|6F8Lx1`o341UfPPM#u0HD+E<2b3 zM3f0N=EY-2Af3EeELN||+x89Bb#13Pw}NzUWf_?5cQ$cya`MXsmxWjI=&MVonh>mZ zuY|o0fl84fu6#la@}!faERU*vjszYvI1cHwJ^s!Tg&zoY7P@48h7$$2Z40FOf4>eTrFnuM&6=Walg}g(9$SAOd31luUeV z%=Nao_!_tqo=7p9mKn_4@gQnCIt6W2PW#4)v$*U%v82oMB1s-e4ab*F+f<#Pa9VfqXcxYH zFhwF^+QC(s_3B1#46~$#Al5qOega+#JF3f3k)=_R#TAD(If=D6OGD7KP(DbCQ>XBZ zq{K_+j-rJ~`Wp+agYFyMPOc8fN1M(o9fe$pLmdTHf&5RYuLKUQ~vACxFOV()zXI98@{ro41l?6z6UcWSSf{ST@pfec+=pwwMEFS$MH2 zH9H*}%gAZ-x#pm|ULcM{!(ds44hFQwPkyJ8@&8WvzI!(xU^fK@gl_KXfc!fLxp_9z zenG2fGRmp?Ri?{^om%EyF_rj3kjAI%8T`iYaVBmkD2waEi#5vHuC%htL@>j~Fr=5Z z0+B#ANx~TQ<4=ci@UA$6yfem2LMZeSoiP7&+AUR87CC$2({Ync`p)?#F3{Wq zSWwBrh`%Ez_Z_;@x+cdrX_f*p%Dxc?CXvUsR3$ zXWj=TtGYV?tm*(M^6+Z3)S4pgDG2shB8lXYFGT9!ySv)rWfo7Xv7YHAPiV??Z;jb{ z4S6nmxxZouHk_YBlJJp}hJL=*$2@(bNs>HX!vk{jEZV`Y2!w+)=_srOC8)^;t*52k zXuh$v4frDm4jy>;L2hg6a!cMsMg3UHIm^EBX=V5^vX|2s+f!4|k8!`vx?f#bIa(E+ z6CPIjBoaELQNH=I2MQ(ZG=9y?o2PK=)=O(Ba$Sz)@wA6c(IL@IavtZM88HREr}X^S?w>M(9BP>cZ#_&G8EL7(Xg%# zsElIwiJsoafoGjuh`P}F(#6S8P_-ZVh=bqRRx$zW?vBZ@5{t|9SS_v)4{YyKVQwH^ z$1+!I5;wlCfeD!{B_BOr9l0=yN1R z?rQnEb(@<(F(fH$230OFuEIHN!kl3uTyerl+W?Myq3hIcXtJhU5jCreja!gPd6KE4 zb!rrt-RCsjYeWGurUrM|7Jh2QEy95{gZ|XNb(=^2YBb5mXjDZPQv&!wD_(&Jw(-r6 z1)Mu$lG0&Si=%9aa}~+%l!9i8(wL_rn2%3J-76BStE)?AY>My5%)P2mikMZ@)I1#- z$yVd?43x8W3QxHOXv?WcFgyoN_-Op5W}M+58E5IROhd=n&WX4W%|7&6!8QVk`{=bF zj;wn!Bn>6%G*wp%mYoeQp4a3ybZi%qS>rA@*}}L1cK;CO!TK6JrYhnx26Vn$Z!?^J zP)P^_brEDcB=vF#jvsnj5+Tj1OpxOusJ+}YyT*N4WDRO(xlK0(oCKA3x3G4wA@l{K^;5u#Wd%R1*fEPL0wr?K?xrobubsrxQ6# zXI!KRVv4mD<4Ecau;tYYw`N*zL}AyR$FEpYlv&OPyNGVQ#PE{ax{fEPGnMmWZOIEw zhF1af+H*#cdz@E6%o&Y#FuD$+CTq>$ z4Kjup7l%<_{(EdQ8N7tQz_GIdJvXe3&VCQm@9#KEpB-nOfl+ohY#AJ++nCgl2Q#p` zx$&xP+@-jE*#>R5S<=-DRP5&Z&K@r*(Z4ntd6w*AceUJy4p@Ctq~LfJg=mnUU(?F* z!!Os6(N3$gFOlt*6t>za&mJ*9fL18sb#vM2;9tCKS?P`o&05afd>#R`VoAN&1g)EG zX(i7y*7I=k04Mn8h|tt?k;Hv~lj#T_+1gxZ8)*e;{6}V$>2*xyMB^JnZCqPVa0@qj zxW)g3;Hu&=VS8C`Ir2nuPZQrIQHI!}@sq|DCVpvYym_2E!8RD75E}}eCjLkfmK|xZ zSx)q3thkTrrYg?ByBT>ZY(9>P1Af_#5t-X6%_2R`b8AZvL6a1!8Jj3q- zh2gHQJsTBbWnBzYZ!%mIZB9*N5bO8bNTN*=x+9vZ2<6k3P}Eeqw&U&0A$cGqexo|z zw6$X{7d?bPaDrn0Cw9+7#yvR;CAjA|=8y@q`md`;c!U}_?I`!~B6gcTk|q_BE`3zJ z!ZnRwC+D51FTl9{sCkl8&M~sS!3zNW$}8pc^aib&brF{zl*UNCrZnC>(h6dnx8yHC z(EnBel!3PC>c>d&SwoHPv*WMgK!ADQC+-~YaH+h6xp9Bgx zv^n!ozMi|Ypo_vl$O5z5KNj@ON#KwAj=jw-Az1w#abY-0WP6NJ?7#4b5B}0qJ!$Wmj zVHj|&-x7h{4^B#=1(f`A{1g%~cR`JaC{AC8kQCQvMyW!>&W#sN5ToBkn*R*O3S=4k zI<;u(uYMcH@BKE9czG3w_o6f$xQ5|m^^T`|0`k9py#m^)Z({cWA75+{DZ3@agaf!P zUOe@+xHtFe3HyZU5?;&q?t>v)K<2v+T^uM~cj(O?zl!V92gUsx{03bY5Ii755#bXO z3RpRr_5cuP6%-Xu)6qTo(7tvYG{pxDH50b1EZk;R1>JO4o|zuXR0U1?Lqqb%@M}RA zr~@bEXH5{j%zLN0eQ(SX6m2dBu)Y-~(9B=-U>?#w)!hLI98qC`er7TU`i@LM1WD@707N=pcKmDC z5vrGh&$Ut10c<=ZMqybgfyuLaB-sQcb{rTRRyEjhMj|H+3i8g`Sw zkrAEbl$3ypiDqX02!VL2E27WM?*a<$3LM*N3UXK2tdnD;T4Hf=U${UDJsb>?eS6N> z#N;OIn6T(MFbjaG7qcQBDFCeq*6vt~4>@R0gx4ZCzKEzeRQ0_#+3KN&7X-fx@ci$z zlah)tfa#ts^3ocfu$$m{OBsj@agAqbuEu%WqK3Hig5G)2-RXGjy}ilhc}lQRVpOcZ zslighhH;SNilsQH5n&MUXxe!p=e5U5Dq54&ISwe4R+9Cnr?TsdRob8MgOO}y)>l8} zQClOInH;`B>`sigsJ1(BdAaKNyc&0z=@!7KMs9M`@vuI0sAuPANgdB;Hw?-gUK6{@&%A)|h4l2NR9{`#;Vey%i_=qA< z>(yexa#Kfutt^N)p7cP$hAC?F7@kieH2588}Y%4ux|zYd&0s}qA6O`5Yw2WmgKo z#ty&{WeSSwqeNFgEv?j0dV3JzOT@&+#ulHynp3>*+xUrliZJwLkjNsv#BCd~SjQzF zK1DAf6i9lXBuIsDNKG3~UqCaJuxirf?`YMlx)91QGt~+Z2dRLx95;Q(T^f*>xT!}S z39CUMI-Ul5&kkg7fv#8T2lPYB(xq#uYaq*P%~<-`@HXHK@5HCh-ydxNy;&1=OAnrB z$Xg@u-|wRp0dQxxg&8nX;!QiBhX^v=)S`%m=6we*&)Xu92taYRl}3^^ zb)Gfk6wv|bnQn)6$t^@XS>sqcXbiq_$3VRw|5o^4$tbThgdCxR&pMJ;co;7n?6&#* z!8}GT(CQZQYb6X0ra5->=wtRC5HDasjQMv6`28n;+ysG!(!xE%QT_q3W86R$t8FyQ z>dUvzY`#TrF2?G$aFDN`jf;!R{??6*bYU|(mqenLkg-}v4b4BG_>RQK%3IhMdF~T)NkWGq+gS!AoxvvT&NYi*hjm$o!VUX$-smGvzh;cqDKg@ z5Cjp$6K(PJ0l~Bt&6()LVn4`Kr1jbY;_)GJa`GDz5)vXtYM}Y)DJyX7SIka&!A|0E zO}v*(by`5{dMofDmzaUpWqG^Y0XQxH#RU=r^SJZ(h3k8lhn5^cK-M0>Bb;-yq^B0gpar0Q0aPGZ>WHCs0>6Y z+7)#08EbDp##K<+5^x?J;R&vEg)l&FToF@p){&mh zn>85@F)ZfwIO8joLXx60+hGi-XYvPcZIjDDnCb@gEyvG*hmjpL$hbubMq`Q7_DUoJ zqaIvLAVlx}%{uAVcM`(Pk%YE;q)^BKgor+UPA|<JOu=I<@|bLy`tbz4q>hNx_vs^XpkHnwy6Gx=J8yn!xPc}^08jrdNO zp~W{hix}C$0)9s}(4%Y{WOnYpZL)^)?^P-M1qxkB$O#=2raFHze-M?}6Q*!)_WR%G;p$pIEz^O_;LY^6X8!tHw4C<{O4jreG<1>x+)a=PyYzf#ylu5tU@0(;4% zC@+!=SlYJC@i$k^!KpkCP|UXWoU@E>MYg6H09mIs$4^SOL{BSUymX0@tpLmu!1Y@3 zcoA2Ih4b_{;)t1?6!ani7h%w9V6>>!@L6MB1+5R^cLBF}2XTt@3WFHXCE8yFHvbp8 zbh!Tz{Wi$2^??FywtuOL1}+lJN)iSwzKdfmA3Q+6^z`5xQ&Zv`P^cW=;O5Fy1y!?8 zgpwW{e0fnq>#~(h(Cn{>J`{_K>n{Ua47$N9H*7)cG*8oOMs9-!e{cg!P;3(zI&hK4 zM*h2|DRj|&eNJ(FR+X(oH!l$DvAtJ zj9FDV{`{b2B3_TneX8r|3Edjkb2TsMU&!1fH$9X$LmYD@Ep9eZ1H=gRd8pZbWpK1` z6KMEw9wqsB$0L{{@UKW;v(iV9Bwx)~<~?yZEp8WjcujuOI!1__K{kFq=I-`#AZC*fl;96^UFT8NCJ%SP2Bjr$qe2DdLpqpZjAq9K!<8HD&2;K7PJIaBgLj+PYZ5_^vD5s1f%*DY`}v;OS} zs&7I6+5WDazst|p-m?G^vHcOz9})dIMc<9;e;DNU=M>>m+dqcxYr=sWk^ILO{qaRO zW%!D0{0SHSM07wI{zPXCttEYDhebEiLvJ&}mm4$$pT(ae zr1Ym3$yXOCwtBLIXwR~Dha~Be$7$?I?oB~Pcc&jpD)A4_zw4(uxnVFEa=E`^tDod} z#Y3cM9mONM)5DM7dp<>6Pg(&J3j9f^m@g>^>z{ISJ2bpGu8Ax4G-(%Lujbj2o)O%* zqotu|n56^?g4vi@^Ua;8gXQ}PVYv3JJ%coFp9RoqUB3L0-AUfxiMo6_zN)6Ja^*zD zPT$PMtrzpG+LU&FZt?g&JKN;z)v1D1DI1_Ja6Tjnk9ki#ejhI~beH#Q%0xGL7tj$HK60aj{KutYjvd z{rkEQ$hG{^Ob5l(;$E4?id@ z1jOjFZFt!prqK}vP~Tv*Rr}4fDIh99+DnjrY2O^>JGkK$p70q#f0?6O?zMlX;{X76 z*QwSzfdWbvbk~*`HhoVH7_%XZkgU)b}5E z96dHGcAC9<#=E6c{i|#4jPYlzr)5f6fyrh^t`F~QOm$yeY0z4qs*LZU+OFT>xy7+r zzd_`9s(wNpEVuls+McPOF&f~U1e;Fw^8ZFV?`FZW&+0+(2RFa)g>FmQ-`2Ps&q!&G z7b%p#5_^?oL~igxyJ*~?y`8EEP{{FiQ@iQEK$QZ*02#ba%Bdaf@D4M-lAN_Ex6(71 zC!x*qdSVnNM{TtOI^nw#c&YtIBmw=x_EGDrUEw;%}nq9Fx`f5`T#W%V(k zQnR8>B!3w3qhNIZhlywGF&_deHnw9*7oD36B}KtI>k!+Ge)mE?q9|c8FtF6GGwZTJ z9i$Q8SDo^+`0#NIZ!My%*m5AU!hVugzm1*$5Mg6w5O_@m<`F$97xfD6xJ5e}yw>hy zSdY;@)?jBm&*l!`?ZYvs>wDDoI#5?%J@ww-oq0-fcXf+0WmmgpyIy;20V^)W!534eAHa|%=pCN016N)qrZcJ}W) z+iXvUA1IYce5A#lb+KK)2vi8fNu6zU%m#9s*VN$|tC(^6osk{VB4|i2ZsupOto)wl zC$|}}*P06q=sl+EZ@}pgEpgZtnkDlbVZv0}yUU4a_BSv>YcO83@yUzuL#(gCiar>r z9mOLFBP1mUk*$hbZFD@kc^tVT>SRy<)=&*WwmIEkEH_tcanv?}ujKk`UEY!t40k?z z(-59%Je&Y3h6(Lk?xDmb? z30B5TD7WI$o{O5+tBoEkuH)alt9~S2_T<+U(rhJ9iS>oXgbelpSn75P~@X)q^R&xbt$?8-G}my8`Y~*6g%{SAX~;9=;+2 zxG|JyD)`K=mj92S|9YUWe+g0s`;Z!G3+|o%;oFi5fXyuXlm>=R?RxjGcjnuBShK+Y zJPDsM`tgGpDeyEcjo36>ftYxXam&JBjbElMsUa`$b^%&Op`aBCN3mVcoKJg6L@xR%r91^f7^_s|#T|31r1s0X9*U9v678MH?Ma4Jx^82D32~YR_ z#Rd4bqPq$}lq_D#xBkrnAAr-tXNZUl+qJ+pGC-5&SKck(T^jh)VQ9$(GLz|d+`nt5 z-9LiAJ`sDh>tgx;AXc6n@TA=Kh~8b>&kzs(dQ&Fve_qAz4VB?wfb@;gzF*q?Nul7A zF5dL|H=hJ{c5u(K{jY(Vn{V8?U7EZ5`+t6kkq}S5d(Ymz1(y!Xj3$xp`TYO!qd;9p zaL*e8fT}UaDLvjL$p7$+?+NAY|6ihV?B+5 zR<>VC5#J-h-CwrnbMNB+QJmjy&>zM5y(;}toZTj6*G~OWoL$?oYp4Dw&aUm)?X~|X z&L743uL8+Git|Tt{wU60#`I5c{6FMbf3m8-)MQWo1pM+J#rgl6;sjaYPqCG`#AaC9 z8<~b5TD7!%*E336;#4UXNk@&4S{K*I$;-=2*^1XtW#6?ouQfpOUyD|b+=F!dtW^K} zr9}x}KOBOMKW<6FKjdtB+jZMvq;kBzdT#t`wE7`Fb63{$n%38D=UHDJ#JY~PqQor` z^NXJg_?Sqdt6|9Z@1sZ-;HCa%smBO%FC-ObH2cVja?kdxn-yY?AFn+0U~<;<7~;@B zUk8iP0g%A)1Z6(Z2C^sd|NR+YEr)UMhmGd8jLK;o-M2a$Du4a{grGo;`Rv1yc1w%C z!yM&f*)4r-hofArO_lNL1^LVl*bfw4a30SOmn45aAy)rnD8JC>_5;03+z4I6np7*q z;PI5cQ6p0_H`(0NLq7n5F|7bYJznOq3YroB_v`b=txxy(@{`y(bMDG^Ig58G+!uN- z^|kkx2(HWx2^+l5t*8(^0dIR_hBb7SRm)}2u%DY`OAnPh=j-0+v@n#ZO3bs5&&g@y zT-Os$8_X=JdVve4ll{`0z$$ciI%1}zu$dyd{LIR%GGG7o^ut@ zf~=U@TO2U$(xmG%Xdp(oJbdslzJN2r4jaIgY1r&35p(~vcF|nIqWe0^d+w|^pYChh znkK`X=o)0CA*YM(9V9vbP=L(Ixv&Sf3+MaLIylI`(~OomQTAn7O2SaGW_ad7$-#`3WWhH+iR7f3EuvjytTuYw}ZEdl-LUmSxU8 z7YDsdcG@P-(K6*3P8C^D zs0H6bTa7jr7%bS>HIO3KS0_>|RZiw=IP}K%7Ob}q=CGxz+1v8Dqn_5oX>EKf;CE5M z=Ly*$cX)GXe>nRL^0$B}PQ9f4-M0TIw!hz#Ld~iOv6(v4xSD@#1j$lBuKO6Tc~tJs z5yuTXpQFK>Yi-<^drukLzWaw`sK}dmEl2Z(=2n>0=71q0PUO%!dhe1=DT{3FEd3Nk zblF-)B^VYVe&D6b#&cd{ZiHcXL{;S$#_WX3ycDnqM6wtr2$asU5ZTo-*iJQHvXOqF zz!={sk8b7U4=dCMg%NfsmPn6(PRkFk{#x1OA?_E6V4T>2r)DYo+s_a1S1%eyJiQDb z+NdVKUEVWDCA-%0CAC4-qU5ae-R)AHNNjjoe!$rze_fU4^=o zTJBiNoqTgb&2Xwuw@k6I@3chrdhaz?!R4~pKm|#%+Uf-&*gK?~{ojg2OvxGuYHOjz z$n(FJ&Oa;u(E^^OVU>dLMAsc7h`N7q{L57q!*&=#bf<7Odh}z{T8SbJXTzh&CBts* z64%$RBA>Xo7i-`Z!p>hJ^kXaFUw!@lMDuFIIAd)r6+g;2Jn{S;|FqUFK3%T6(5koV zxlLSdOsx%sB%IXyGwnwU?o+Hk=zWj(VqT@~**ld5@15&FLD?X=-C-ee^D58W}4$Ssa zMLFJ^$vhk5kjYKqQ_ZCpaZ}Gl5Wc=bN{oK*g z+hD}yh(D%*92YjwJHz|6OeZ+~Xi`qF8HLI*eRa({QNC3i_g%YMA4N)NH<-RaYaOVy z7+fvmDwtUW!JIw0x&$P*bO&Bl`-7;DY6AXD;}44agGhg)y4RWIy&*;-Mcn)NM+qB+ zAW)Y3Cv6)xDOq$~ospp)1`ccYkpbM^G9yCEQx35OmiB9P=KNk14bl7wOZ@!i$M~2Y zOg(d$;-QePw&w&v>7tiumzN?fXM>g|@Nb2v^b88Jn2817f%eZbN7x}yk9Y8;A^y~I z)MBuX`yDXh|7N|vdbpTFgmqxn20`S7!rs9$Q!a?($g)1; zJ~q^_{?H4d+@pzZBFkwqBQZ^Wi+O_l-n=vE2hF(+^r$Xj(8n&TJuvz|?0r{URN2yR z69tKiN*0W$fQW!(XhlUNjsX!Qi4sJDk|fhZQb{V3Q!^?kS#m}}KuO(zLNUR|_=LjwKZL*L( z(Thbc`$5Kgb=kLKV|~4+EGuT;nb5md9gPG@q3+X%kN~oVuFOx73JO8)S#~;$-wIg0 z7FU9VWJR3aA#qcPZZ8;_*MQt)`zd9279wi679<*LnC-Y4d>v8?icunb!lck(xC5z8$siUU< zuAp3blET)VdCm?CYA}AAur?`wyly;_Mef8#zJN#MHc|a`GonEZo2aWnvnSzsCEddI zGlR~rjmNbzLLo-{V_~lN`8dDNHKT`iOG`rxodGh7kiruV@aR5MRn+}^geYtwcdsEc z!>)_CuDngaMFwo_zw(ylm`RSO3!0UvE1vbaHYbUpafCxyTDZAuy*Vm^yl#kN|S-J{T;P|Wt-#0F1vE4wTP!>j^sz(uu+#>ELtgpW*YEj$p zca|G}Vd6azt9xC`Zlb%QBB7qi8v+mO%9`E#)H=o{d1w$DCKeqrd7#ztt@E`7eH|U0 z^9*iPeXa{O?z23L=s0aoSu_0qJ~Cp`orCgW{@vlOka}Sq-&HM z0NczaXd74jifxFwa#48pM14J?H_jJvEbY+}`)0FPH?Fd^XYs9E zkA6@vmm-qHC^d*_sPt1~gqTC_gIT<6Q7_Gnzy(`}$(n_oiH{gvZ!XS(g&$KC&URc? z@InFK3$fdwMs;#j4mO}rO!bMZ|lEz)JH@wfH+CJaYyiF3E! zH-g!nnto+sT;}Io3a-m!Bih$!Hps{4RzL10n`qkg`rtURQt3Ia7MD@(%_=GS7-Fm! zwl#8_x&A8#Gw|Z+As!vOk+m=)aF#tTP0|+xP*;9rR}I^92wj&E#i1?|*EA5O-tREx za@f|sct@*?L35}8-f>d=)U9R(d6(sgj?ZFx<4EZO_`Q4@vPeg}0mizAU&1DxUPYiQE7G3zju+n}Fa$_i#biZ&>iI1duMK2S?R;esX0#(M5qrkjkp+HO7z`qpDAfnd^}L!Z@o@Z+9cbX zb>n9mZ+Z!nNrjHe4hY;@GofOJ%OxoY#P{T+D$;>=z&qOwJtPwa-RUXHg^-E!!^ zmU6TbP*=HAt9nyG5=6fc5Spzq-M?>H|Ib9;LJ<^Z20=>a<*A+D!ku{}dP&b~*}~H; zfAK$`@oEnc%FdZPaEtJa9Dy82@vidbiu5lQqO3vkrUgc6o-Gvp3;@||y{1-@)CdD4 zXA$k#v4!K<<487bm`k%|{jG%g^FLuFL5rha;MBJ2Sun&$QcG2uf6cEg6rm9ffK4@L zcb?v|DT8OgQ$BXB%?aeM$d495pv0H+VnVh&;qYY;&Xaa6hyR-QTaGA-pdo|By6 zR1=(e?3E#RYMFezxoE@Q1Pn3d8~V)${?)2z8W{aVw)Gc(-GK6Q z$;UvS$j(hvgZ*Nz0EyllY#~K|e|8u92)NI3`k2D6tjOl0{seD!38XaP*_A(e)2&#2A(0>KzFGT4lnEL+;&i_`y30-59 zA$HpkTH5sJg5=lFb_9*MP$t~?(ry$)yP_Jm*BBQoJK+5GhXH;qz`UWhJfy#_ytuI8 zls{A33(anaF~RFAj|di4YyAm}(n_f8gygSAo9)P7NXn0Y!o-tb({sG7RpK=NB}g+> zJ4BUgUNr4ptxy@4rfz|h%V_+zisbat&irj}ZO9ppW%RkNcr(Qm^QM&EzZx!SW9%7Q zo(qm!Lk+X&&?L#~dQ4{Ndq1IXVKpJz*Y+4W)tOBGRD2g9y}E8qq6mn?tp&ZfQdG+0 zwiN8XR};Fj1?ckh+-DD_X!SjV=GFOJj!oP8Yux}F@EM34(A6u^G6Lf%>8IsqhrW0+ zF{rOiO>z)5?A5Th$Q8M#O$gqsu{<&@ZY$%gZVOp)-ivX25ityx!7LIR94 zBKaTZ7Q}sxg!CmG{gPBX-g!~()h{|!+`2OQ-fDfStoZ2a<;e-34X`w}XWHJ?{%UVq zWTPKRh$hw+zlK@Tu(}SGzo$@v7pKe2=ee`?y1lEbl6@Y-awGyBP3iPGZsYoc@tihl zb^A5evR!gEghXZgOVtoEqu)|$rs?c%)pKk4lHj(X>dqWk;&K`!ID41*3ws6ZBdV_l z@zrf|Z0r5v8*;C$mpb{&BWpFqvmc{O74mR{r09MnBo2a_@`p2{IW8K#a-mACj z+qg;)FW2&2Dlej>`F#3Iu23JF=8gM}UoQIYm68Ty9yF4Xc?iS~UrcW0K2$eVBfsjx z{N>B#qH=fHi83*vhrujIUcZx+2TIFIwA}^O*9BE53p6(aeLFwT?s=Z$@DJ zQW7-0AxhnSfy#A&=r&3886SI7=6Z_D<>T1z6Ro*4qUrCN)n(b$R=?blsGlVT6Q@J(RaT46vd>Jc6d*u!Cs8? zo`mVUNpd~-f~h#QF%rAc7Vi7joLrSRqc3|ybnLnON(ZhS-enT?Lzvg{9tvuxlYOjeXc3OOh#>#k?1cUnD(+FHspQqc8^o1 zo4MiWM_JgG9GZ0cmU6AXnW%+lu4#p%Fw<1A>t7ELfHgxu_ApYl8Ta+e%^ZZvo$C4P zZD;-loxnswfyMkV3}7WAzY4xZQ+41Rxi@0^&T`)Uog`X61jBP~?Bakdt%v5R8R|_~ zA#?{kq_)>^h(8JhqC;v#<`-nznpS;++&1{P)|@9OQ{4i=^H^hGY9#G$u;Azxc;?m1 zj!)71;BV*}siS^r);B--$RDts9YvQM)yc6T0mY}W7my>2_>_Rdv4@9bI>rkcp+uR6^9C&8S6}^KRH1IcPvfm#j z#VNsy17JHJ(ysIdqfBofuwp*)43>LZXedNU^BiCX*<;-HrI{dPp{Xw#NGb+AQGq0x z{kAS0tw(D}*G{|DwRZBJ}nA{@?<+Y>(_olFa-$mqhe+jM+evOr;OjQrMN(k0oUh_x47EMjA1~A zd$Ik|UFvGGSe`RlzHJbftTnk9yvMsh*QUHFtKl`Zx#N{&`s^=G|H30LKPlX8V60n_vRT-c z0E~FDw*H1Mce_Vx)7`$qaQUiQ^M(zh1TjO5?M*t8LIu$z2$PKL)lk{OE5>d0{BSc= zT#`QU4S-5z1!l_mfWgXqb>0VEX4@~=aSI1X{&;r-gSv6sdPxCWdt0xDhU*`E^mNW9y(Bhg5Xa}ejOzc@19UsfbUR-fPALG70h4cDAjGTj5qf`+)3<`(9?Rik)n+_(}00~ew* z9}qHVvAdaszj@2JtbpqA%|tjTBcXhGg4CrqAQ#F#dcLGwlQO?P2Xx(2@@54f)+1x7 zDhB$H0TIuoM)!Sq6zb4BKQDknusH2+XCs7}mfs}^A}HbTF1rT{mM)#0##eSvq@1_X zr@&UnWgme?ubKvHK<9Q`5?*yISMo!863Xq`Qs@BB?`*M;DX>ak<@|-qsO-oz@oIR} zRDGjKqCgNxg`?B(L6XGz5uBC9v-J%O35~%DD)2sqMfQK(`TUbY7-Ap3kB`$q|KF&W zT8r3F23Q16zPWlWp-JU`^;by&Lf?f*5cGVtG1EO;0Yct2I;7B+b_lh6(?Ok$tzBfI zKz-%=voRvE$MxE|IJTtu=ZF<8F0sqJkKj78($z?+s60VKW<>UN*K@Et_c<& zN8Ks~zMaT*$nmS%fdOPy8(cdK7NisBfZUszyh{lw?P z$ly`MYaA^q)rmAcaL>JBRtSMc35gNu)Ko#w_&N#IxrUrU!F!U78J9nJL z!x^ry-jXbY3vxU0a>p19p8H9*NEyr{YXcW z>eL?tGZ!Ai3SPFf!)_LVZd{w3#hS>>9|fTrOYdtE%BrbnZ?*{CNLg|7 zM56DuQ}S#La-#toa&vEXp}0rarq4Xf`5feIVPU~7@H8$9e8yCaZypGyyLg0%&$<2& zxJNQE+}zN5v-^eHew5S>rOEBcs4xy?V9ML&+j%5y+zxn<8tl zM)OiDK>2DBcj1m;QVkkdTACVNL?CcQc zM>=1j7r_f@0{JqbKRiwccwYJJ+-xt!(h|q^UG;we!1*BlKu|2t@-}K8RgsvwP`H;# zuw1%B=MkEosCMP2!zlmkmlik1d(5Bf+Qsm#mI-MqV#)1IO)j8==Vkb5c~!Z{kBn%Y zX1;QXaOeAzsvB%Om}wT!*5CFYq`~aj$xNyE?BNqN?WZ@2_gyr&VybkK`nLtJ0~Wq;TsunTC=;fNzkca+pKo&ds!LqgTE*=+CZfBEg~a&hVM49Ap8m3c zA0TGeWoA=4l)}YiC(BlE8a;qFo=vUJN>`MvetmRsm(%xs+k6*i&&Mh-#2!5*^P{7;G{DMwp1XID+!MxAI?4X$ktf1!dR{<^;I1h^bCjLU$XBG| zl(#TF=pa#ejXBDXD&nSiUqjout;|*WcZaHZ7#N=S*Ti5uCu5~4m@vq+?=S+G;I=l7YfS8 zMRID2*h^qH@+Z$a66@PTPTD7NwKVQ!{dY()$RvrUG_SCe0iE8bXZDyeSR2@g;_|RZ+-4? zFu)QK%9DrITy57AS2XA7x>~i{hL#{EtaoSV!D@k}s7%W1BBk$)MwC}$iRYvHVg(Q5 zPtNn9Ix&VL*3H;lVm;reBFt*_(qg+(qEC#hEWuTghh4LW7$A2-SYUab$bEIW!Fcz-EQZbn1m`@6UC#RtBJ=;zDSMcFKPNGO0Ww42;$h&=d!qsS1hCyolzc~q$- zOvk=BAF%zvZdAbg*4z9OO5HWm37QjOKIs1Zf-D^4tdNvDKJZngi*na&D>-)j`n9|} z`e1VxQd6Tyi%L#^5wvntj=S3HGFyK*<<6t0;7hobbj?{zOMwovs#&F94Nl|C_vrD2 zy7xyJHYBdg-EbWk+E#q=1sR^nZ83jpwIR02>23eeM*b{6L0sJmE>=wGo#nD}q-ECT zTBqhja9-|9l~uPU-3uMgHGRqk>1&_2A^gF4(V^IE+K%Agtah{~uhXrsa06pKUOuWY znVjxJQ5{G-E3|%BVhyMJTh=*<7;Vh7$dun7gfmjd3-A*_7~iG!il-pU*&BQ z=bCHV3-|iG(JnKe3MAckFdc((e^QZ6EG$2JqofMA*Yl~nL+jYoMJp>r>Vlb#mu74D z)4htq`dE$^EM|Eg@4bMUD;RR{VY1t+ubnP)Bhu$LBVOD2nw}VuZO%=+w>iG4R9BrC z5W(3JX`MCGY^Gj5BJhChO3Xd+jM{?=7}9s@8h_W!2F_B*c$O*3P&8+ z?p=cok~+-Ut$t7Xaa8{=0=c~|PF`L>w=i3D^>WbWwnoI-`0*DSd#9 zQuM{qssVZsCPh_*Dv znxSm3C@M;Pd!i(UyVUVXB<4vh-`*tCg0St@-I#AS;E z8#1=YPV{?UkNG_-M=G!iKmP2MzEUBkiqD=hMr38|gjGX_m@56pFp#>^k%4Tm?j?U3 zo%(0*zS%k=1t97jT3N=b5(CdKUp#PA5kKCQCsLaM%lY{An^Go$g6`?hd5A#{d!%4Y zqdab7UL=m8q@?82>NUM#Rq~kWH)9{JzhS4qiWs{cicC2vzk(Qoagv;eiTRBqnJx&t{W7F z9W&0)c)t@{d-`z6y|Wx)x}c?FtyQ0BuE0IvydG(}{_A}|06}owTOfL;!iOO~D=S#% zJV>sHHe2=nA8zfQUO@XH5&PBEnE?Ge`LjcaE3GY?u9wqNWBT>+cj~wae4Hh2jjX45zD6y*Yo z^B(9xO6_S`C6uV5kk^Ynh=YD|+kupk-OyD;b+dhzvv2XdS!e#e{_=(KE>7L5#qAh} z;(l(!wlv*Wap#BF(zqKAprp8DZD_Og;34ya_6O0tJmjg1v2cGLg4$-1s~42TP9!$+o?>FU?C&F&TLvqd}+_%u~&MU zf?y?e-nVbg)>ofso0k&ZPn17$*L}L6aKYK6dY#}`d}F%Of$kB`7TsY=M24g@#;*i z>mD|>d`(ogm7rzuy?fyjW|zWy#a!|GD^cGHbIi}Q%>}On=oT;fWLW4p75F;{IrE9`4nugkE}`2-o~1#4<99OF$C&yFiykrAZQ2IS z399i$&gKtC?><;0;8*Tg)yw+2CA-w^Le(qAL_b4eTIsUCI$tWHMzg9GiPBP5WqeDj zr`UGb$iQaxyMwoHk-OYW@@mX=q@ZK zMZzc+>l+f|P2c-w5t?Z2%p<5*A`*x88+xe`ZeO;mwT_4x7 zc4h8HS-iYoMVg*y8-P42X-$9PiyQ0DFs$(THWV9AD=OX1i&_qodcN&Mx^BKH9{-iw zp?mK{;b=pW;RjK!rTKKBU-gjDE-R6pNZ@;ADC0U7l!-qSYvqa|R<_;R-7FQ-F*1112N*Jhw z-~aYJ<4Y!0#N;#Wpni=i8V|;E^<3nXkN2Nw>I;6n7q!+|SE-bUXG4{YKOMNLpUk%3 z->5fYwNswfIbkCudTOON?3qS?Pf+^y^tI`EGX3WE__^{1Ny5DNIpKdSS>fIlgHC(K8R(K#D5?qzEWbi$NU zjx*oNSLkgpOcy$>$`@MxRwTcavb z+Xj0s0aRz;RXaX%%E+T9p8cRt05>9e0%P;7c|w!t*xqgWs6-&Lw+$T{VWu*EwQ4MQ9~%pQ`WeDU;#{1 z(_#mD&QPI8odSGCzYAKGE)7O0M4FNE3JJh5Nl_i6@EOh?s15V&$TDdwcx)I#UcX(O z#$&-fuSNlzCvbgdV9fGUH_u3jqIDJ13%}O9oHfarGU=A^IpXZ>%(<+LZ*1IgST*vq zNkg%t&4{+q$mbxh>siJOQn|e-Q>XPi`|tsr;y&rnTzV_+=;c6_b#~8K?iK%wZl#X1 zgGt<)qlITVnRcQq`o9(egiw`*?aidp_3a+VqwURf_0(mG4yA0gD0l|yijFriD+J6_ z3T)esslwkLi)D{%ZxN9b{?0D#Tou<=Su9Ba2!%4!hk#UKxo}96uWuzB|Y2+6POckxEJz&jLU%lrP zmxFO}ox2iLB6bGK%)FNKOVKSlj3^+tP<0@8l#BhlaA8BIwmG@}iK59~>;3@0;5dd| z>s()xf3xc(`0{AB-JiE*vN(w15LcDPRP}Al=1rz|e9CH^A1&01q6cyYpDBd*i61zA zVrO4)<}Q?~Cnkq?l=i#WPE^3kt9|&z73ES_)q1tqfHZx##P@~n38!ndsaxdA?ysr7 z!roaLn)ec?LMuQXQ=`+i$i0BzWf`$}aUF)=ZOk>qs7>A2V` zDj!ZD40rqLWBxK`ibCwnUC~eDmC9C+`y~ zjIq0V%_Wp5^%S*pV9XTegxyzRLj|G{p;a-ILCXFJS^bOZGI3fr&Cx%u7j$T}2ARL? zk$3M~xs?BH-Tay5AJdPVtB=2MF0)IYY6xsxn>gjR;ow~`8TWKmhFUgRwoAXWCnkGF zi2^%q$zGWrzP+>n_g<&mJKKGwc7&3%eLC#^9PXNR(2&j}!@tkn6NL4Bl{;lfx4VIWL@ z!l5KsT~2bCTFSCJ-@bVHVXv74V*8davQz}W9W`0L+nFtVx3^f5)?O{*{;jxk5M2QH zI-ZaA5)e~mrlXyLX{?z{G);Wtt6%x;F#X=4A!%o)a(@vurjqmpA06Onwc6SR*KK#p zUyD9>nka}QC$>6nCPywbW6z5>}xFlr+13 z!$$m&#?-5|eo{k+$?z>vt=@el%a_7IX~_~l1jY)hT;EI6J>6tOn5fol=}bt&`R+vZ zfHHeWsTUoiJ=VMMac0Vzhzl-hY6zZAi7VRZOxo9AtHPzv|53{kL$KYQdV`;z4DU3t zt1no;46iGOk}|q@txSqXnh^f-RPA1U?$(Ww_`+UKO+-t)GfAuAb!zjjD=rF;EsbU2 zG)qiY1?(wez{4<^6-VSjtZMlp* zVhFxbI0@Gcw$Dp7>eT!wn^gAYQ>XZ49q3~%U5(B2N7JM^wXvDCW(vXl)KFQ5+(9Z@ zy!HmT-DCKaNhQba9trWaoNl(xY#VLcyzlHQec$VA?8VwV4}^+wsEZ)HtOy)!J2yMn zoX*&<$g_)jRHnlp_1%E1JzIGY-E*#aBDwy=-SgYJagW%m~vfC zr7+blt05lZ(0#j}khHH`c7BorDy@gC^ht{jcedx4Uu&YZ9q-KX>@}bH_DPA&7Cf?Y zRb`(u^`3_WAFz`|PUh4wA$>i&KTzNCy|0Za(fkg2NK6Pm)-bMwNV~B*zEaUH@6gKC zNy`~$w@C0k6kNLDxh>dzVXRy7%YO0R2MX=E7CKD>woYxIKII1n2A(i$dijkweY`8z zju_=W{EF_PQPUHXe!d>r7ZI4|_*g^rI&-j@8@kBL7bhMWbp}Ju8^K~)MSLkkg>L@x zrGQ^Z{myTDQ7Hmy^g4l@t{Uz5HLVL2nDmlqr}p))HlOfwvo($&MOQgQG%jTHvc}5@ zuzSYc!!33%f6RQ@eCxii>v>-zJ~!Ut^(vn7#B0adPCRHw$WN&MY>%Dz!>qdA7z%0I zKDU3$X=Nd<+Np0$8Vt-f%~qzxC7(*?cNKl2bK65y?TEYlotQTvadaNJm%8+RQJC3U zMzauNuJF}g{mS|y%~){gX=X*BJ;#9$Ld(*MbU%x-vnrc|(FY;_^7{}vWJZPUIWy`p0 zLZB=PWvV)uL;;14QX^l){+&vNPd&Ydo5kSQDRJ%>+hiQZ?kxL_m#N4FQHK~c zV@+3!Wxj+TUxbMA4E+^N=Mh?~iAN~Y`u*#U=-aPtGNfBMQK=4-0{$$h`ZK$uNtuFx z#*R}$Q8?H(&1Ip(q-(yvAN2T+Ak2N`TN$zz-+Ov(|J#-&EUtIno| z>LN_Msp#w-Mjoq+P+$=g$)_$ah(wC<$>vV^W0|#Q6sup~igTVU5%0Eb{)+FA6cf;O zGOusT)da6}5rQY>(U;r`wG>!Si%aHfk=yR}lg(43tAluW?8n+0t9GVAzY%7T_VbGD zQDrFig-nNnMmv|xk1K`WgOEmZkLt;ve)J4i zXg69;Cp70JisDd+6q=iRE*E4Z{v&pJ#C;}cq`%O9JQCmB9PA|kk(18yUG3G`aADW# zP`h=19{ODp++!A|2SG<8W(OOT&R|*i)aV`hN(5*zZZpA&z7rD@P%b@(gj&x&xe|Lg z_Z+{Wwf%9zkm)U)1RpmHj9M*g1FrC?$8yC&wUc0FN`*)_`iFFH_o&MJU@-WHS=ga{ z_;Ddw)|=h8Z_r0q zWmPkO+wERzBz4#x6~Hae>F7qhGtP(&ND;@kgOwP~NgL`8A;XvS|Cyc)SJae_ge6hQj|bp_G};P%;BdMsM4P%PCqg{hxdh|Fa3O7BjYmdn z`y0J`1FYrCcB5x*Uu%+3L%eY3KSd|+)O8_lhc;b@ zTyQ}|0Va(7So72F+vQ%g1f9OZGTZ9j-fQKL_@bXsUgobzh6?ky^aq({CE$M@&PYT1 z1aB01{bKC%N|fp6<4l;+g{n~{@#=O#5$eOueD;q1n9_E^?2{_tEhy9CYaGTF#;E)G zR;GI?ut?;|C1rf(0gjACf!?J`K1^PiZPkyvOaM5MFUG)--kW_qrL#B{qo$LnGWfPlei3u)E5xNORv25$ z+oqW=2A#ShKJu)B#mBqvRgcGmkUt2WVK!ZzeHC_`Cd;^f#3pX;#^nSRTF}+vx$6M; zXv{2f){(E^v?|_b>)_yL5W!)RsV)i1YQ$ zlWm=xWz$R@JHbAgW!?D-E{%H!Hi{R!ZUs2l`$K3|#$PbWz|@%QxixnT%{gW zkv}$l)o{fR*CLXQ3pch!sgCLtELk}f20MNDVlo#*d^|Y) z2(G1fmY5GR?DKidU*u60iI|Ih+Px4^_)LmjVxdGUUTiHSDFlGK=IaKp<9+huL6;Za zlLx-#{C@SCUSqnEap5Idc%F;Pg9@J$CFV{iEz~K|{iVaYUnfl(WcUTNtQ~ot%pAu; z5sqIaQuOFj@pZBv3A{~1MAuZ2yjFfLq4NHz(F^d>$ z!=dO8GWNE`D{rs5uGSWLxJ|5^U&MScrb5?Jcm?b#%`6&1{80A+ANg%gH-|p)xAuj1 z?_*GEEixH!Q;>BiS*g6IFmBN451Rc+gxbQ$RIE@f=7GxVv9aqgvU4b{l}fZ!QJ9UR zjeVqq{ONJ6!wg_>*J z+3dr>dB()VL{KUYR2KV$yna3Q`8>*WtT!A=?^I<_C{t>ypGnjnsxpQt))F==er2gk z4cyB^YLOxP%IExt$%XS5i=c2O=Dv2uVP>UozEn%QOy;0udxDumZOz(Etgt;R_ZWNG zMp1b;5%*f^p#70lyT0+Oh0(2)+v9gxa;xD_+Ryl_-wCzR|8i7ABC{mw&9AllI0BVWR)#f%K5eVOFgq@>Qz>+lLe zSTqqA6LY!ZK+xR_6PJ32Mb;gWxUsiel2AM=gsAn!Dtd7ghqT}MqHK!qI~2KgfV=-~ zwnrX3|1-GtCC7^C@1cOPv&HW&xTx3M2Rz)$5Q}uK*NZAuwO-7OTHG`ascj2H+F#eo zan#k?NcMduTmfY|)PT9Wi!6-Ue{#Fz{X0ydPL;@BX#xd-RoabxgjOwKH2Qv&ko4_#Ckk~Q;VlL`C_s?gHy=_@5&#hlnmiR2fl;1McbUf<9A_hwrnZG&4=k=R(JD`z)}-ji$5wWrFTon?I~uB?TxJCgd;7#1b8@c77s z+Tm-yVCXIu${|V_>|wn85>r2i10|@M>i3SZsTipreI^^Z17$H6!~F^MUCEc5wIRAG zq`gWlPFPf@RNryRe(f@ocS}?o@vY_D@sR#3W>kR5#lA$XNz>_`L^rMpx4SLY>1}i1 zH&pp@NQ+9y$OE>E@_%L~?naHL^Hc;v)t{lKr^j%xF01@^sxaThtOA>%gJhq~pz_*S zK1wa10|cBM(&svL_kqN7hm$=W%`9?`%Vx-20>K_9Z5+(bYt!k|6G;*O z3>SQ4RhHpqCUw4fYsH7i@Cwx`^hjoXGqIV?nj2ye`cHc6jdah_5~d%;2=Pp;JI<`s ztTm-2HA;;?TN;g>NLcNuy@(R+ogQpXQ=8bOfE`LJE`D>mEy2K>84&1)%t#v^Lr&>) z5MQUEAOolAJ1J94;3FjQr>T%X9tOb}^2NCf79XT^s^)e$h{3;)t@N{^>FLp_xE-du z7wWWEuEk8|_b*sO91>c1uT^Xq=gGlf6zXttZMiMX`#_LPW_C{rv6s`b(Ci*tN`)C$ z_xD(y)px?KD$Qvx;Ie8L+-tPMdr$Gy@9Fu_SPk+6YqCfEK=&D+!)?gX=i8Y6k(JER z3TZm;Bu#pnxi3ll;fac^?26mq|+FD7HllH(cu z&!pE&iLb2Jf=YMhmMz{GE^S%xo0Z#Wq&q{OSjFda&PW{3M#J3@9D@1|QhUawt%7Au;gIuhBA&GfxguqBqJl_xk&jRRU3txy&c$ z`PN5?`wAOXd9hK(NZH-_{+&(i;OP6qIe>m}te(Y{Vf)_Rq*-Wx!^1uo7y$3`d}4Cr zgguw;gPuQ{mH_}*b`ky)6>-`FEsR`h9yLeuNE43ol#~TC+_^?~=%CIA19SQv)eeHK(!G4txB6LdEDHH=`|oP*CBvs&Dc?FX z@R#;*m&OCJkSHP*hcyT}_TH>fbM~ggt z;k|wq*WQNM*jQ$FJ9{+-<*;7u`Fe|UsJRB|GLF*a7U^eeiFS70=jhToXZrp?95}wG zhx>Sm?dfna^Hz`1v9V!Vkp>Cb;dM#Fa<2?)f}LyOAECYqoRTWHhnmh04!T0*(98dQ zm6FE)Ihr4WMS#~*xCnoQ;qO=cPuIoEiO0Fw?aaNgusD*jevOGCUxog7ugmgPCG<(3 z6aBFRF~Ueh6a6aF#*E`afcXc!A-%Ju`*a?m4c}IVi9Cky z=wOFY<&C%MjlJairO2^G%Dam6^iI0FJ&ci0wyX3%UFBTnsNSAosPKT`9lNh3=cJZ) z=>^D05Szk(t@oPU#``l*2gusuz2wzproEDgdL_#`uH-Q-jP}!&tlp5&JexAVO$4-N zl|C5Gs`@&JiP(^9_2(gg%OAqQ56e#3+-qTc4wc+UIZVSHtA-)<#k=h*sa8yF8{Ze) zFl7)s_Dcz$Wv}p|uzM>Y-(^jKy_asfQy~HBWt=A#BPIYV5*g_C{uA4RKd}I+_ZRiv zx>c)zAGbZY?jr|9i9?KP46%2&eESu@L(Xp_$2EbVrO)%9)O zIQO}%S47i{cf%LDt*~NnFaE|th(xk3)7?9{VmwO~*9l|1WANe1wD`3m?}T6|qgnP8iq(bRJ0Dkq+`xVx8A;-} zA;|NfGDQDE!*#(g+M`V&@0*>7{-fv9F%z-W=pc!&4>Rs|Jl3wJ@#S&TItg{%p3_r{ zA2jaM%Q`|BqG5~Cgis2+Ppg!@0YFyRwC>JDK$-ZJwSM#pazV>$AZuQUB0&69G7@U$ zF(oeBLwGzd-Xf#P@iJxX<8_;xl^#wM5r2cS;4V+P1@s!dtg7Z6(G{`!p5>DB#o7@r zEHTJM=P-?QyYo}(8>4TC7kbiNbjk3VN4iM5HG(Mf@0b;Qz)j!A*cj=G@V7=4?ZTeE zN?G^54o2^1XtuYt{XBNCGn#w0>@g#DDLtN(nfD0~rsl`Bq496RX{~%EO=nr1p_#%Oq5~l8_w2(X zJ^G=)b!{DC`pZXPGy$oVd!}PAWh5Wq@nw|x;iTA5c#`10IF^sdhujf@D5*ImGMqBp zBZ0;AEiB;o-a^p>{SWjKE*`#O^c(z0>Y4&T$Z_5$LU2x(mRd7f=8p)(sC0B_t`ZsF zs#o8$br|KZ&W_drJa4X@qiz}l0IRw(UZ0}JreG%f-<9qUz&a(SV3VKF;l_OqZ{2_P1y zyc_pZY99u%IC+PYL`s|rGoXB)1NkKC5 zC0M-PVJ*7!0nno|xqy?jJkHb{j-Gowy*3Atbk033Fy`}P3VbwH?l+)Jf+IKy|4KIh zbOuv?WXWTRwY#8sD;ssr{v0{w$pf(Ah)WVQm_nfN=*^R)YJM@Wc<|Mw1|w#=E(lIm9zvF%_{;Fi#Y1-$^05=tvP*1yT_K)rKeKc)6(Y>cEGNB;T!5pnty5W~!f1 zfn6DrN2*~fVF5wvJZ>^_Z(zKj?UJsXFMK5_5P5(!#`B&4{OjvHPxL>VCD6Qmu+mam zTr;aW(Bpxa14-lS$jB`O;pnXcb_J(Ex-BaHCm-jX=KVY;KXbCN)Axd***3v}wNSz)F4dHp^du9(&RU zEmcT5J2n;Za)rgm+k9Ya7Ft)X?ML%w!N&-}0M8w-p&M_cl0$=!Cs($7m;n|?hFz58!}P%BdMSZ!*=j&myH@-C@G1i`yzvojQX|DW z5JBUFU5sb2$6=dxWM9rMQ&>PGC+^7E!_d6jE)0_AXA@o!rBHpLAtXU{6;Rq zYj~^Bi0FNzP%lK-?TmU7wrd2_mjwkByHCN7SCQfI&?4t zbmwyv8vI5p@FlmQQ;jkb@hbG^%t?_=Fcv=z=S&~N<}b4ep26M*QVYJw-9gGWLHtvZ zlmLMki6VZ&F;o)~P(k30_8B?8C&-7pEfr>){TH0&SI=NeKzbm_RQd2XVSzoKU4baf z8DRXL!qww(3h))zp8BVxF`k(XEZpa=)4cj{&ZVTVW{7XCU?rC}+^`=c5Zc9&MZ&+@ z*A^>-$pu4aF*;LtgA=4X*YG#pM<`4kd^FA#Wjv3CK^L!CNmch;5Oj;=`-LiGz<)Z8 zTh{=h|Fg*CKcL}1_xjNfSgdz!Aez!1Na(}@yueGr$y={?Jwl5hrX=2!fkYes(-2M- z89cK6#W|X6q^a%p=TlqW|L|+tVs`^;QZ;h70U`t(FRlr6llk=_;EnRfA<9hn5Si*E zK~gg$NLmHbsCF1TOsNfNSm#aaF6i(uh2x(I>l^q-gUZQYZ*GgwQXqtsrul|=UH$p{ z+T@fo5bi`yE=#&j13~?+*@%+{62Z5^(JgfK!psrrJ|&O@$?TKs@Ubqm>OIXBh@0kb zlBn)@O=QWdYGFq`fd6EV#~y>FI}aQFb7Vq_ZaN}%P5D)H@H^xW5QZvt=g>cxTu=!2xJ)P%CHOgl|1b5dg@Zu3aF?d}Y8CRJDyfLR;ibm(c zhpekii6jmC=S3TY!>%eQMPtx@;3#zHEv3mRw*%v~zt0r8Fv3?hTB3@iF&=GTfT=O4 zDC(6xzB(el@z@`Q@!wv&@@}o7w#Yt2Ee{$bpoAIG*etaNXgwpSu_SAj-nilwq$hr$ zFYLY(xrM+~3C>kyb$DL9bI`fzZ+Mxmd_4qNMT%6Txyh{@Yju|Wofei@D@s?!uT`rk zK&bEvP48BPGF>{b2Vb+j-47YJcEwG7`9pnHx&HWk?*2>pA{Z4qc)YyNr0Ya)?lRI% zG<>arK#Ev_Up{Yuv@-~mt=>1wnq2?FNAToXwl+VN2g3>N=vK!PgM5PJ7M?aO0)R<; z?AR!^Hu21l4lQ&KxmBM@`qW0rf^X9zliNhU;Rfxt&$4}J5X}QqUvpW@ahB_DW?35< z#I6b+J=YSks381ta_j+0^XsHpJ;$9AE0?n>#3z@|4}TP1Wmmw$sNT#&%oTCMl#z1o z?hA?KvVB@lQx&8T8`Y`u#p|;CUbne-Oc(PW|L9)>A1sJrTle3GpIiEVl!uPVZAb`% zzZ;WV+6=MR(5+phFboC$N2}E3T)4D@TAZ|A*GeI-M%sRY!}_-W@5X0DlxR#$?rDSKc!b( z?pr<=H@fykQJ#ixulvokbOBW4=!~QcY1R0a`m-4$`Zr<)!tzabWzJVQOzXHwT6HV8q+#bAr_)f! z@$35Ye1(7d#h-papQkz{Gjl=0e&n-TV$o`u{_d|rFmcrR{1+b~UCyuRHHt)>>}95+ zoxB<<7#_K~imA6jZYg~Od@*yqCx%~c+)&w-clZezCbe%(-*D8yy<_s=IDSn;4~o+i zLJZ2Lt5$1rT|{gd<2J7KiHr>|it^HJ z>voIDCB5gL0IX@}V)Ljwy^#Ed6`|5X$cr`B8sg9REaLb=>eH9^}NU`%s(z|o4x?G{hbuWD$EfNRWT6q1g8&^kHJE@(k zh%>N(M%_K(HWS?$V+}=JJ{M5g78i&2lja5@`A%r?;RnYJpoZtOAFk3hKGz}Bs%@yK zM<_eHbyJ}G@&)<$=OvMnB6vZa6=s^W^|$ZOFscr;ZmgWGSpGjN&E_sjzOFJMwlNd9 z?`*C2^cLVo^3?AW{D1{2Sz7=3qi(NzVQuVG2QyZ?4-@%YtM}LWN7wlS zFY0_|{XB#;>y4B*q@JGk;X|AIp;@Nchc=&o$FaZm+s!j`&N^}c^YZR{f8Tw0SKiO9 zKEI~OqAV+YhD~MB?zpRafkpF#?8YC!dBgX%0`LBxD?jxA?oX#5+yDO#TKE3(2bNC? zAFlrg77YE#{2a^YR%Kbd6<)sO>vt8#3pRTup7S8BVnIzLB3{6HIpAp-iA67JxG3-g z>*2~3lZ;8)dWfF)T7hkC-H@HJ(@g`k#dsirqX|w?i&@S{EO)AK#Vl=71 z6Fh=3npCj0lSh*ZB89*UsL`Y{npA+D0(g4B!x&8}!!4;q8F4RQU|?eQba4#9)@_^;Xm_@hv&`Jyl)6I0D-5gpUXO@geCyXKG1Lg literal 0 HcmV?d00001 diff --git a/docSite/content/docs/development/openApi.md b/docSite/content/docs/development/openApi.md index 90b30e841..c2498f82e 100644 --- a/docSite/content/docs/development/openApi.md +++ b/docSite/content/docs/development/openApi.md @@ -38,7 +38,7 @@ FastGPT 的 API Key 有 2 类,一类是全局通用的 key;一类是携带 - headers.Authorization: Bearer apikey - chatId: string | undefined 。 - 为 undefined 时(不传入),不使用 FastGpt 提供的上下文功能,完全通过传入的 messages 构建上下文。 不会将你的记录存储到数据库中,你也无法在记录汇总中查阅到。 - - 为非空字符串时,意味着使用 chatId 进行对话,自动从 FastGpt 数据库取历史记录。并拼接 messages 数组最后一个内容作为完整请求。(自行确保 chatid 唯一,长度不限) + - 为非空字符串时,意味着使用 chatId 进行对话,自动从 FastGpt 数据库取历史记录。并拼接 messages 数组最后一个内容作为完整请求。(自行确保 chatId 唯一,长度不限) - messages: 与 openai gpt 接口完全一致。 - detail: 是否返回详细值(模块状态,响应的完整结果),会通过event进行区分 - variables: 变量。一个对象,效果同全局变量。 @@ -227,7 +227,7 @@ data: [{"moduleName":"KB Search","price":1.2000000000000002,"model":"Embedding-2 ![](/imgs/getKbId.png) -### 往知识库添加数据 +### 知识库添加数据 {{< tabs tabTotal="4" >}} {{< tab tabName="请求示例" >}} @@ -241,10 +241,11 @@ curl --location --request POST 'https://fastgpt.run/api/core/dataset/data/pushDa     "kbId": "64663f451ba1676dbdef0499", "mode": "index", "prompt": "qa 拆分引导词,index 模式下可以忽略", + "billId": "可选。如果有这个值,本次的数据会被聚合到一个订单中,这个值可以重复使用。可以参考 [创建训练订单] 获取该值。",     "data": [         {             "a": "test", -            "q": "1111" +            "q": "1111",         },         {             "a": "test2", @@ -370,6 +371,158 @@ curl --location --request POST 'https://fastgpt.run/api/core/dataset/searchTest' {{< /tabs >}} +## 订单 + +### 创建训练订单 + +**请求示例** + +```bash +curl --location --request POST 'https://fastgpt.run/api/common/bill/createTrainingBill' \ +--header 'Authorization: Bearer {{apikey}}' \ +--header 'Content-Type: application/json' \ +--data-raw '' +``` + +**响应结果** + +data 为 billId,可用于 api 添加数据时进行账单聚合。 + +```json +{ + "code": 200, + "statusText": "", + "message": "", + "data": "65112ab717c32018f4156361" +} +``` + +## 免登录分享链接校验(内测中) + +免登录链接配置中,增加了`凭证校验服务器`后,使用分享链接时会向服务器发起请求,校验链接是否可用,并在每次对话结束后,向服务器发送对话结果。下面以`host`来表示`凭证校验服务器`。服务器接口仅需返回是否校验成功即可,不需要返回其他数据,格式如下: + +```json +{ + "success": true, + "message": "错误提示" +} +``` + +![](/imgs/sharelinkProcess.png) + +### 分享链接中增加额外 query + +增加一个 query: authToken。例如: + +原始的链接:https://fastgpt.run/chat/share?shareId=648aaf5ae121349a16d62192 +完整链接: https://fastgpt.run/chat/share?shareId=648aaf5ae121349a16d62192&authToken=userid12345 + +发出校验请求时候,会在`body`中携带 token={{authToken}} 的参数。 + +### 初始化校验 + +**FastGPT 发出的请求** + +```bash +curl --location --request POST '{{host}}/shareAuth/init' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "token": "sintdolore" +}' +``` + +### 对话前校验 + +**FastGPT 发出的请求** + +```bash +curl --location --request POST '{{host}}/shareAuth/start' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "token": "sintdolore", + "question": "用户问题", +}' +``` + +### 对话结果上报 + +**FastGPT 发出的请求** + +```bash +curl --location --request POST '{{host}}/shareAuth/finish' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "token": "sint dolore", + "responseData": [ + { + "moduleName": "KB Search", + "price": 1.2000000000000002, + "model": "Embedding-2", + "tokens": 6, + "similarity": 0.61, + "limit": 3 + }, + { + "moduleName": "AI Chat", + "price": 454.5, + "model": "FastAI-4k", + "tokens": 303, + "question": "导演是谁", + "answer": "电影《铃芽之旅》的导演是新海诚。", + "maxToken": 2050, + "quoteList": [ + { + "kb_id": "646627f4f7b896cfd8910e38", + "id": "8099", + "q": "本作的主人公是谁?", + "a": "本作的主人公是名叫铃芽的少女。", + "source": "手动修改" + }, + { + "kb_id": "646627f4f7b896cfd8910e38", + "id": "8686", + "q": "电影《铃芽之旅》男主角是谁?", + "a": "电影《铃芽之旅》男主角是宗像草太,由松村北斗配音。", + "source": "" + }, + { + "kb_id": "646627f4f7b896cfd8910e38", + "id": "19339", + "q": "电影《铃芽之旅》的导演是谁?22", + "a": "电影《铃芽之旅》的导演是新海诚。", + "source": "手动修改" + } + ], + "completeMessages": [ + { + "obj": "System", + "value": "下面是知识库内容:\n1. [本作的主人公是谁?\n本作的主人公是名叫铃芽的少女。]\n2. [电影《铃芽之旅》男主角是谁?\n电影《铃芽之旅》男主角是宗像草太,由松村北斗配音。]\n3. [电影《铃芽之旅》的导演是谁?22\n电影《铃芽之旅》的导演是新海诚。]\n" + }, + { + "obj": "System", + "value": "1.请记住,你的身份是百度的下一代知识增强语言模型,能够完全根据知识库提供的内容回答问题。\n\n2. 你忘记了关于电影《铃芽之旅》以外的内容。" + }, + { + "obj": "System", + "value": "你仅回答关于电影《玲芽之旅》的问题,其余问题直接回复: 我不清楚。" + }, + { + "obj": "Human", + "value": "导演是谁" + }, + { + "obj": "AI", + "value": "电影《铃芽之旅》的导演是新海诚。" + } + ] + } + ] +}' +``` + +响应值与 chat 接口相同,增加了一个 token。可以重点关注`responseData`里的值,price 与实际价格的倍率为`100000`。 + +**此接口无需响应值** # 使用案例 diff --git a/projects/app/public/locales/en/common.json b/projects/app/public/locales/en/common.json index d10d5e768..f84bfc438 100644 --- a/projects/app/public/locales/en/common.json +++ b/projects/app/public/locales/en/common.json @@ -248,7 +248,10 @@ "QPM Tips": "The maximum number of queries per IP address per minute", "QPM is empty": "QPM is empty", "Response Detail": "Quote", - "Response Detail tips": "Whether detailed data such as references to be returned" + "Response Detail tips": "Whether detailed data such as references to be returned", + "token auth": "Token Auth", + "token auth Tips": "Identity verification server address. If this value is set, the server will be specified to send a request for identity verification before each session", + "token auth use cases": "Review the authentication instructions" }, "system": { "Help Document": "Document" diff --git a/projects/app/public/locales/zh/common.json b/projects/app/public/locales/zh/common.json index 35406e16f..ff1baee95 100644 --- a/projects/app/public/locales/zh/common.json +++ b/projects/app/public/locales/zh/common.json @@ -248,7 +248,10 @@ "QPM Tips": "每个 IP 每分钟最多提问多少次", "QPM is empty": "QPM 不能为空", "Response Detail": "返回详情", - "Response Detail tips": "是否需要返回详情(引用内容,调用时间等,不会返回预设提示词和完整上下文)" + "Response Detail tips": "是否需要返回详情(引用内容,调用时间等,不会返回预设提示词和完整上下文)", + "token auth": "身份验证", + "token auth Tips": "身份校验服务器地址,如填写该值,每次对话前都会想指定服务器发送一个请求,进行身份校验", + "token auth use cases": "查看身份验证使用说明" }, "system": { "Help Document": "帮助文档" diff --git a/projects/app/src/api/core/dataset/data.d.ts b/projects/app/src/api/core/dataset/data.d.ts index f869a148c..cdd8354aa 100644 --- a/projects/app/src/api/core/dataset/data.d.ts +++ b/projects/app/src/api/core/dataset/data.d.ts @@ -1,10 +1,11 @@ import { KbTypeEnum } from '@/constants/dataset'; import type { RequestPaging } from '@/types'; import { TrainingModeEnum } from '@/constants/plugin'; +import { DatasetDataItemType } from '@/types/core/dataset/data'; export type PushDataProps = { kbId: string; - data: DatasetItemType[]; + data: DatasetDataItemType[]; mode: `${TrainingModeEnum}`; prompt?: string; billId?: string; diff --git a/projects/app/src/api/support/outLink.ts b/projects/app/src/api/support/outLink.ts index c94640ba4..f550344e0 100644 --- a/projects/app/src/api/support/outLink.ts +++ b/projects/app/src/api/support/outLink.ts @@ -6,7 +6,7 @@ import type { OutLinkSchema } from '@/types/support/outLink'; /** * 初始化分享聊天 */ -export const initShareChatInfo = (data: { shareId: string }) => +export const initShareChatInfo = (data: { shareId: string; authToken?: string }) => GET(`/support/outLink/init`, data); /** diff --git a/projects/app/src/components/ChatBox/index.tsx b/projects/app/src/components/ChatBox/index.tsx index 0efe9b487..169480512 100644 --- a/projects/app/src/components/ChatBox/index.tsx +++ b/projects/app/src/components/ChatBox/index.tsx @@ -139,6 +139,7 @@ const ChatBox = ( userAvatar, variableModules, welcomeText, + active = true, onUpdateVariable, onStartChat, onDelMessage @@ -152,6 +153,7 @@ const ChatBox = ( userAvatar?: string; variableModules?: VariableItemType[]; welcomeText?: string; + active?: boolean; onUpdateVariable?: (e: Record) => void; onStartChat?: (e: StartChatFnProps) => Promise<{ responseText: string; @@ -860,7 +862,7 @@ const ChatBox = ( {/* input */} - {onStartChat && variableIsFinish ? ( + {onStartChat && variableIsFinish && active ? ( (res, { data: await pushDataToKb({ diff --git a/projects/app/src/pages/api/core/dataset/data/updateData.ts b/projects/app/src/pages/api/core/dataset/data/updateData.ts index 9b949140a..d40ebbca2 100644 --- a/projects/app/src/pages/api/core/dataset/data/updateData.ts +++ b/projects/app/src/pages/api/core/dataset/data/updateData.ts @@ -20,7 +20,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex // auth user and get kb const [{ userId }, kb] = await Promise.all([ - authUser({ req }), + authUser({ req, authToken: true }), KB.findById(kbId, 'vectorModel') ]); diff --git a/projects/app/src/pages/api/core/dataset/searchTest.ts b/projects/app/src/pages/api/core/dataset/searchTest.ts index dc78b17b3..0873f9ca1 100644 --- a/projects/app/src/pages/api/core/dataset/searchTest.ts +++ b/projects/app/src/pages/api/core/dataset/searchTest.ts @@ -18,7 +18,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex // 凭证校验 const [{ userId }, kb] = await Promise.all([ - authUser({ req }), + authUser({ req, authToken: true, authApiKey: true }), KB.findById(kbId, 'vectorModel') ]); diff --git a/projects/app/src/pages/api/openapi/plugin/vector.ts b/projects/app/src/pages/api/openapi/plugin/vector.ts index dfec8f640..ee903dbbf 100644 --- a/projects/app/src/pages/api/openapi/plugin/vector.ts +++ b/projects/app/src/pages/api/openapi/plugin/vector.ts @@ -17,7 +17,7 @@ type Response = { export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse) { try { - const { userId } = await authUser({ req }); + const { userId } = await authUser({ req, authToken: true }); let { input, model } = req.query as Props; if (!Array.isArray(input)) { diff --git a/projects/app/src/pages/api/openapi/v1/chat/completions.ts b/projects/app/src/pages/api/openapi/v1/chat/completions.ts index e99ac1b27..6fe3fdd8c 100644 --- a/projects/app/src/pages/api/openapi/v1/chat/completions.ts +++ b/projects/app/src/pages/api/openapi/v1/chat/completions.ts @@ -34,7 +34,7 @@ import requestIp from 'request-ip'; import { replaceVariable } from '@/utils/common/tools/text'; import { ModuleDispatchProps } from '@/types/core/modules'; import { selectShareResponse } from '@/utils/service/core/chat'; -import { updateOutLinkUsage } from '@/service/support/outLink'; +import { pushResult2Remote, updateOutLinkUsage } from '@/service/support/outLink'; import { updateApiKeyUsage } from '@/service/support/openapi'; export type MessageItemType = ChatCompletionRequestMessage & { dataId?: string }; @@ -44,6 +44,7 @@ type FastGptWebChatProps = { }; type FastGptShareChatProps = { shareId?: string; + authToken?: string; }; export type Props = CreateChatCompletionRequest & FastGptWebChatProps & @@ -71,6 +72,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex chatId, appId, shareId, + authToken, stream = false, detail = false, messages = [], @@ -111,10 +113,15 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex if (shareId) { return authOutLinkChat({ shareId, - ip: requestIp.getClientIp(req) + ip: requestIp.getClientIp(req), + authToken, + question: + (messages[messages.length - 2]?.role === 'user' + ? messages[messages.length - 2].content + : messages[messages.length - 1]?.content) || '' }); } - return authUser({ req, authBalance: true }); + return authUser({ req, authToken: true, authApiKey: true, authBalance: true }); })(); if (!user) { @@ -260,11 +267,13 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex response: responseData }); - !!shareId && + if (shareId) { + pushResult2Remote({ authToken, shareId, responseData }); updateOutLinkUsage({ shareId, total }); + } !!apikey && updateApiKeyUsage({ apikey, diff --git a/projects/app/src/pages/api/openapi/v1/chat/getHistory.ts b/projects/app/src/pages/api/openapi/v1/chat/getHistory.ts index 0c653f850..ca3e5d829 100644 --- a/projects/app/src/pages/api/openapi/v1/chat/getHistory.ts +++ b/projects/app/src/pages/api/openapi/v1/chat/getHistory.ts @@ -16,7 +16,7 @@ export type Response = { history: ChatItemType[] }; export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { await connectToDatabase(); - const { userId } = await authUser({ req }); + const { userId } = await authUser({ req, authToken: true }); const { chatId, limit } = req.body as Props; jsonRes(res, { diff --git a/projects/app/src/pages/api/plugins/urlFetch.ts b/projects/app/src/pages/api/plugins/urlFetch.ts index 2403f3b02..ea908e04c 100644 --- a/projects/app/src/pages/api/plugins/urlFetch.ts +++ b/projects/app/src/pages/api/plugins/urlFetch.ts @@ -18,7 +18,7 @@ const fetchContent = async (req: NextApiRequest, res: NextApiResponse) => { throw new Error('urlList is empty'); } - await authUser({ req }); + await authUser({ req, authToken: true }); urlList = urlList.filter((url) => /^(http|https):\/\/[^ "]+$/.test(url)); diff --git a/projects/app/src/pages/api/support/file/delete.ts b/projects/app/src/pages/api/support/file/delete.ts index 4b7a2f536..bfac05649 100644 --- a/projects/app/src/pages/api/support/file/delete.ts +++ b/projects/app/src/pages/api/support/file/delete.ts @@ -14,7 +14,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< throw new Error('fileId is empty'); } - const { userId } = await authUser({ req }); + const { userId } = await authUser({ req, authToken: true }); const gridFs = new GridFSStorage('dataset', userId); diff --git a/projects/app/src/pages/api/support/file/readUrl.ts b/projects/app/src/pages/api/support/file/readUrl.ts index 77a33d4e9..59fb7eb1d 100644 --- a/projects/app/src/pages/api/support/file/readUrl.ts +++ b/projects/app/src/pages/api/support/file/readUrl.ts @@ -16,7 +16,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< throw new Error('fileId is empty'); } - const { userId } = await authUser({ req }); + const { userId } = await authUser({ req, authToken: true }); // auth file const gridFs = new GridFSStorage('dataset', userId); diff --git a/projects/app/src/pages/api/support/outLink/init.ts b/projects/app/src/pages/api/support/outLink/init.ts index 01e364099..482d926f1 100644 --- a/projects/app/src/pages/api/support/outLink/init.ts +++ b/projects/app/src/pages/api/support/outLink/init.ts @@ -5,12 +5,14 @@ import type { InitShareChatResponse } from '@/api/response/chat'; import { authApp } from '@/service/utils/auth'; import { HUMAN_ICON } from '@/constants/chat'; import { getChatModelNameList, getSpecialModule } from '@/components/ChatBox/utils'; +import { authShareChatInit } from '@/service/support/outLink/auth'; /* init share chat window */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { - let { shareId } = req.query as { + let { shareId, authToken } = req.query as { shareId: string; + authToken?: string; }; if (!shareId) { @@ -36,7 +38,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) userId: String(shareChat.userId), authOwner: false }), - User.findById(shareChat.userId, 'avatar') + User.findById(shareChat.userId, 'avatar'), + authShareChatInit(authToken, shareChat.limit?.hookUrl) ]); jsonRes(res, { diff --git a/projects/app/src/pages/app/detail/components/OutLink/Share.tsx b/projects/app/src/pages/app/detail/components/OutLink/Share.tsx index 08c940fa6..3a8dcff78 100644 --- a/projects/app/src/pages/app/detail/components/OutLink/Share.tsx +++ b/projects/app/src/pages/app/detail/components/OutLink/Share.tsx @@ -17,7 +17,8 @@ import { Menu, MenuButton, MenuList, - MenuItem + MenuItem, + Link } from '@chakra-ui/react'; import { QuestionOutlineIcon } from '@chakra-ui/icons'; import MyIcon from '@/components/Icon'; @@ -58,7 +59,7 @@ const Share = ({ appId }: { appId: string }) => { } = useQuery(['initShareChatList', appId], () => getShareChatList(appId)); return ( - + 免登录窗口 @@ -85,7 +86,7 @@ const Share = ({ appId }: { appId: string }) => { - +
@@ -96,6 +97,7 @@ const Share = ({ appId }: { appId: string }) => { + )} @@ -113,12 +115,13 @@ const Share = ({ appId }: { appId: string }) => { - + + )} @@ -267,7 +270,6 @@ function EditLinkModal({ }); const { mutate: onclickUpdate, isLoading: updating } = useRequest({ mutationFn: (e: OutLinkEditType) => { - console.log(e); return putShareChat(e); }, errorToast: '更新链接异常', @@ -338,6 +340,26 @@ function EditLinkModal({ }} /> + + + {t('outlink.token auth')} + + + + + + + + {t('outlink.token auth use cases')} + )} diff --git a/projects/app/src/pages/chat/share.tsx b/projects/app/src/pages/chat/share.tsx index e6f196994..48d53d359 100644 --- a/projects/app/src/pages/chat/share.tsx +++ b/projects/app/src/pages/chat/share.tsx @@ -21,11 +21,20 @@ import ChatHeader from './components/ChatHeader'; import ChatHistorySlider from './components/ChatHistorySlider'; import { serviceSideProps } from '@/utils/web/i18n'; -const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { +const OutLink = ({ + shareId, + chatId, + authToken +}: { + shareId: string; + chatId: string; + authToken?: string; +}) => { const router = useRouter(); const { toast } = useToast(); const { isOpen: isOpenSlider, onClose: onCloseSlider, onOpen: onOpenSlider } = useDisclosure(); const { isPc } = useGlobalStore(); + const forbidRefresh = useRef(false); const ChatBoxRef = useRef(null); @@ -53,7 +62,8 @@ const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { messages: prompts, variables, shareId, - chatId: completionChatId + chatId: completionChatId, + authToken }, onMessage: generatingMessage, abortSignal: controller @@ -75,10 +85,12 @@ const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { }); if (completionChatId !== chatId && controller.signal.reason !== 'leave') { + forbidRefresh.current = true; router.replace({ query: { shareId, - chatId: completionChatId + chatId: completionChatId, + authToken } }); } @@ -96,11 +108,11 @@ const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { return { responseText, responseData }; }, - [chatId, router, saveChatResponse, shareId] + [authToken, chatId, router, saveChatResponse, shareId] ); const loadAppInfo = useCallback( - async (shareId: string, chatId: string) => { + async (shareId: string, chatId: string, authToken?: string) => { if (!shareId) return null; const history = shareChatHistory.find((item) => item.chatId === chatId) || defaultHistory; @@ -111,7 +123,8 @@ const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { const chatData = await (async () => { if (shareChatData.app.name === '') { return initShareChatInfo({ - shareId + shareId, + authToken }); } return shareChatData; @@ -142,8 +155,12 @@ const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { [delManyShareChatHistoryByShareId, setShareChatData, shareChatData, shareChatHistory, toast] ); - useQuery(['init', shareId, chatId], () => { - return loadAppInfo(shareId, chatId); + useQuery(['init', shareId, chatId, authToken], () => { + if (forbidRefresh.current) { + forbidRefresh.current = false; + return null; + } + return loadAppInfo(shareId, chatId, authToken); }); return ( @@ -185,7 +202,8 @@ const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { router.replace({ query: { chatId: chatId || '', - shareId + shareId, + authToken } }); if (!isPc) { @@ -197,7 +215,8 @@ const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { delManyShareChatHistoryByShareId(shareId); router.replace({ query: { - shareId + shareId, + authToken } }); }} @@ -222,6 +241,7 @@ const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { {/* chat box */} { export async function getServerSideProps(context: any) { const shareId = context?.query?.shareId || ''; const chatId = context?.query?.chatId || ''; + const authToken = context?.query?.authToken || ''; return { - props: { shareId, chatId, ...(await serviceSideProps(context)) } + props: { shareId, chatId, authToken, ...(await serviceSideProps(context)) } }; } diff --git a/projects/app/src/service/support/outLink/auth.ts b/projects/app/src/service/support/outLink/auth.ts index 2221a9f0d..0601acb74 100644 --- a/projects/app/src/service/support/outLink/auth.ts +++ b/projects/app/src/service/support/outLink/auth.ts @@ -3,8 +3,18 @@ import { IpLimit } from '@/service/common/ipLimit/schema'; import { authBalanceByUid, AuthUserTypeEnum } from '@/service/utils/auth'; import { OutLinkSchema } from '@/types/support/outLink'; import { OutLink } from './schema'; +import axios from 'axios'; -export async function authOutLinkChat({ shareId, ip }: { shareId: string; ip?: string | null }) { +type AuthLinkProps = { ip?: string | null; authToken?: string; question: string }; + +export async function authOutLinkChat({ + shareId, + ip, + authToken, + question +}: AuthLinkProps & { + shareId: string; +}) { // get outLink const outLink = await OutLink.findOne({ shareId @@ -18,7 +28,7 @@ export async function authOutLinkChat({ shareId, ip }: { shareId: string; ip?: s const [user] = await Promise.all([ authBalanceByUid(uid), // authBalance - ...(global.feConfigs?.isPlus ? [authOutLinkLimit({ outLink, ip })] : []) // limit auth + ...(global.feConfigs?.isPlus ? [authOutLinkLimit({ outLink, ip, authToken, question })] : []) // limit auth ]); return { @@ -32,10 +42,11 @@ export async function authOutLinkChat({ shareId, ip }: { shareId: string; ip?: s export async function authOutLinkLimit({ outLink, - ip -}: { + ip, + authToken, + question +}: AuthLinkProps & { outLink: OutLinkSchema; - ip?: string | null; }) { if (!ip || !outLink.limit) { return; @@ -49,30 +60,97 @@ export async function authOutLinkLimit({ return Promise.reject('链接超出使用限制'); } - const ipLimit = await IpLimit.findOne({ ip, eventId: outLink._id }); - - try { - if (!ipLimit) { - await IpLimit.create({ - eventId: outLink._id, - ip, - account: outLink.limit.QPM - 1 - }); + // ip limit + await (async () => { + if (!outLink.limit) { return; } - // over one minute - const diffTime = Date.now() - ipLimit.lastMinute.getTime(); - if (diffTime >= 60 * 1000) { - ipLimit.account = outLink.limit.QPM - 1; - ipLimit.lastMinute = new Date(); - return await ipLimit.save(); - } - if (ipLimit.account <= 0) { - return Promise.reject( - `每分钟仅能请求 ${outLink.limit.QPM} 次, ${60 - Math.round(diffTime / 1000)}s 后重试~` - ); - } - ipLimit.account = ipLimit.account - 1; - await ipLimit.save(); - } catch (error) {} + try { + const ipLimit = await IpLimit.findOne({ ip, eventId: outLink._id }); + + // first request + if (!ipLimit) { + return await IpLimit.create({ + eventId: outLink._id, + ip, + account: outLink.limit.QPM - 1 + }); + } + + // over one minute + const diffTime = Date.now() - ipLimit.lastMinute.getTime(); + if (diffTime >= 60 * 1000) { + ipLimit.account = outLink.limit.QPM - 1; + ipLimit.lastMinute = new Date(); + return await ipLimit.save(); + } + + // over limit + if (ipLimit.account <= 0) { + return Promise.reject( + `每分钟仅能请求 ${outLink.limit.QPM} 次, ${60 - Math.round(diffTime / 1000)}s 后重试~` + ); + } + + // update limit + ipLimit.account = ipLimit.account - 1; + await ipLimit.save(); + } catch (error) {} + })(); + + // url auth. send request + await authShareStart({ authToken, tokenUrl: outLink.limit.hookUrl, question }); } + +type TokenAuthResponseType = { + success: boolean; + message?: string; +}; + +export const authShareChatInit = async (authToken?: string, tokenUrl?: string) => { + if (!tokenUrl || !global.feConfigs?.isPlus) return; + try { + const { data } = await axios({ + baseURL: tokenUrl, + url: '/shareAuth/init', + method: 'POST', + data: { + token: authToken + } + }); + if (data?.success !== true) { + return Promise.reject(data?.message || '身份校验失败'); + } + } catch (error) { + return Promise.reject('身份校验失败'); + } +}; + +export const authShareStart = async ({ + tokenUrl, + authToken, + question +}: { + authToken?: string; + question: string; + tokenUrl?: string; +}) => { + if (!tokenUrl || !global.feConfigs?.isPlus) return; + try { + const { data } = await axios({ + baseURL: tokenUrl, + url: '/shareAuth/start', + method: 'POST', + data: { + token: authToken, + question + } + }); + + if (data?.success !== true) { + return Promise.reject(data?.message || '身份校验失败'); + } + } catch (error) { + return Promise.reject('身份校验失败'); + } +}; diff --git a/projects/app/src/service/support/outLink/index.ts b/projects/app/src/service/support/outLink/index.ts index d81d265ae..23667c99c 100644 --- a/projects/app/src/service/support/outLink/index.ts +++ b/projects/app/src/service/support/outLink/index.ts @@ -1,4 +1,6 @@ import { addLog } from '@/service/utils/tools'; +import { ChatHistoryItemResType } from '@/types/chat'; +import axios from 'axios'; import { OutLink } from './schema'; export const updateOutLinkUsage = async ({ @@ -20,3 +22,31 @@ export const updateOutLinkUsage = async ({ addLog.error('update shareChat error', err); } }; + +export const pushResult2Remote = async ({ + authToken, + shareId, + responseData +}: { + authToken?: string; + shareId?: string; + responseData?: ChatHistoryItemResType[]; +}) => { + if (!shareId || !authToken) return; + try { + const outLink = await OutLink.findOne({ + shareId + }); + if (!outLink?.limit?.hookUrl) return; + + axios({ + method: 'post', + baseURL: outLink.limit.hookUrl, + url: '/shareAuth/finish', + data: { + token: authToken, + responseData + } + }); + } catch (error) {} +}; diff --git a/projects/app/src/service/support/outLink/schema.ts b/projects/app/src/service/support/outLink/schema.ts index ce8f8837a..a43781d06 100644 --- a/projects/app/src/service/support/outLink/schema.ts +++ b/projects/app/src/service/support/outLink/schema.ts @@ -48,6 +48,9 @@ const OutLinkSchema = new Schema({ credit: { type: Number, default: -1 + }, + hookUrl: { + type: String } } }); diff --git a/projects/app/src/service/utils/auth.ts b/projects/app/src/service/utils/auth.ts index 5ad52a320..257942bb6 100644 --- a/projects/app/src/service/utils/auth.ts +++ b/projects/app/src/service/utils/auth.ts @@ -12,18 +12,6 @@ export enum AuthUserTypeEnum { apikey = 'apikey' } -export const authCookieToken = async (cookie?: string, token?: string): Promise => { - // 获取 cookie - const cookies = Cookie.parse(cookie || ''); - const cookieToken = cookies.token || token; - - if (!cookieToken) { - return Promise.reject(ERROR_ENUM.unAuthorization); - } - - return await authJWT(cookieToken); -}; - /* auth balance */ export const authBalanceByUid = async (uid: string) => { const user = await User.findById( @@ -45,13 +33,27 @@ export const authUser = async ({ req, authToken = false, authRoot = false, + authApiKey = false, authBalance = false }: { req: NextApiRequest; authToken?: boolean; authRoot?: boolean; + authApiKey?: boolean; authBalance?: boolean; }) => { + const authCookieToken = async (cookie?: string, token?: string): Promise => { + // 获取 cookie + const cookies = Cookie.parse(cookie || ''); + const cookieToken = cookies.token || token; + + if (!cookieToken) { + return Promise.reject(ERROR_ENUM.unAuthorization); + } + + return await authJWT(cookieToken); + }; + // from authorization get apikey const parseAuthorization = async (authorization?: string) => { if (!authorization) { return Promise.reject(ERROR_ENUM.unAuthorization); @@ -89,6 +91,7 @@ export const authUser = async ({ appId: apiKeyAppId || authorizationAppid }; }; + // root user const parseRootKey = async (rootKey?: string, userId = '') => { if (!rootKey || !process.env.ROOT_KEY || rootKey !== process.env.ROOT_KEY) { return Promise.reject(ERROR_ENUM.unAuthorization); @@ -110,30 +113,31 @@ export const authUser = async ({ let openApiKey = apikey; let authType: `${AuthUserTypeEnum}` = AuthUserTypeEnum.token; - if (authToken) { + if (authToken && (cookie || token)) { + // user token(from fastgpt web) uid = await authCookieToken(cookie, token); authType = AuthUserTypeEnum.token; - } else if (authRoot) { + } else if (authRoot && rootkey) { + // root user uid = await parseRootKey(rootkey, userid); authType = AuthUserTypeEnum.root; - } else if (cookie || token) { - uid = await authCookieToken(cookie, token); - authType = AuthUserTypeEnum.token; - } else if (apikey) { + } else if (authApiKey && apikey) { + // apikey const parseResult = await authOpenApiKey({ apikey }); uid = parseResult.userId; authType = AuthUserTypeEnum.apikey; openApiKey = parseResult.apikey; - } else if (authorization) { + } else if (authApiKey && authorization) { + // apikey from authorization const authResponse = await parseAuthorization(authorization); uid = authResponse.uid; appId = authResponse.appId; openApiKey = authResponse.apikey; authType = AuthUserTypeEnum.apikey; - } else if (rootkey) { - uid = await parseRootKey(rootkey, userid); - authType = AuthUserTypeEnum.root; - } else { + } + + // not rootUser and no uid, reject request + if (!rootkey && !uid) { return Promise.reject(ERROR_ENUM.unAuthorization); } @@ -158,14 +162,12 @@ export const authApp = async ({ appId, userId, authUser = true, - authOwner = true, - reserveDetail = false + authOwner = true }: { appId: string; userId: string; authUser?: boolean; authOwner?: boolean; - reserveDetail?: boolean; // focus reserve detail }) => { // 获取 app 数据 const app = await App.findById(appId); diff --git a/projects/app/src/types/core/dataset/data.d.ts b/projects/app/src/types/core/dataset/data.d.ts index 7a36236a2..e8a9e2f6c 100644 --- a/projects/app/src/types/core/dataset/data.d.ts +++ b/projects/app/src/types/core/dataset/data.d.ts @@ -4,6 +4,7 @@ export type DatasetDataItemType = { source?: string; file_id?: string; }; + export type PgDataItemType = DatasetItemType & { id: string; }; diff --git a/projects/app/src/types/support/outLink.d.ts b/projects/app/src/types/support/outLink.d.ts index 4617da531..a81360395 100644 --- a/projects/app/src/types/support/outLink.d.ts +++ b/projects/app/src/types/support/outLink.d.ts @@ -14,6 +14,7 @@ export interface OutLinkSchema { expiredTime?: Date; QPM: number; credit: number; + hookUrl?: string; }; }
名称金额限制(¥) IP限流(人/分钟) 过期时间token校验最后使用时间 {item.limit && item.limit.credit > -1 ? `${item.limit.credit}元` : '无限制'} {item.limit?.QPM || '-'}{item?.limit?.QPM || '-'} - {item.limit?.expiredTime + {item?.limit?.expiredTime ? dayjs(item.limit?.expiredTime).format('YYYY/MM/DD\nHH:mm') : '-'} {item?.limit?.hookUrl ? '✔' : '✖'}{item.lastTime ? formatTimeToChatTime(item.lastTime) : '未使用'}