- - - - -
-
- - - -
-服务UUID/ServiceUUID, 默认0xff00 - -常见打印机ServiceUUID: - -[通用型号/BMAU32/QR380A] -0000ff00-0000-1000-8000-00805f9b34fb => 0xff00 - -[InnerPrinter商米内置/BlueToothPrinter/FK-POSP58A+] -e7810a71-73ae-499d-8c15-faa9aef0c3f2 - -[HM-A300] -0000fee7-0000-1000-8000-00805f9b34fb - -其他设备ServiceUUID: -'heart_rate' -0x1802 -0x1803 --} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Bluetooth/Printer.razor.cs b/src/components/BootstrapBlazor.Bluetooth/Printer.razor.cs deleted file mode 100644 index 6fab67814..000000000 --- a/src/components/BootstrapBlazor.Bluetooth/Printer.razor.cs +++ /dev/null @@ -1,242 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using Microsoft.AspNetCore.Components; -using Microsoft.JSInterop; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; - -///
*Y(*JJ)<>)yh(pX)Lv)5,(fL(UE)z*)1i)[j*T>)6B*`V*~U)y\\(e`)n?)7k(c()Rg*_p),X*~:*2q+3k(Xj(}?*Xd*1T)?G)_?(]j(^~*D_)&Z({W)7'*d@)lq*ZZ)z?)2()~4(V[*/9)rl(TW*7f(`7(_m)M5(d^*[|*n^*sl)YY*rZ)J))u!`abdfgklnp%ruyz|~ )v!')+%28%;=%@BCE%GI%KO%RT%VY%[]%jl%np%tvxy{|~ )w!&'%*,%.0%6 )tu(\\&)se):o*N`(t*):B)(~){E)Ie(W[*8Y(j8(Tx)mR){])*!Qy *q>(`5(f=)^e)9.*n~(oe)@n)Ig*d[(hY)W=*.I*IY)5O*/1)mY*;=)vD*si*_/)2o)kM*T1)Ov(`T*XP)O3*3G*>{(n-(bn(Vb(Ta(_D*(G*d_*&i(YL*[t*&C){b);m)&g(\\**51)nL*(i)W6*1o)D6(zh(|V)vN)<[):r)9b)8<*ns);3*_O)}h)nt)5o(tM(fJ)P2([z)5P))n)P?(Vw*X7*Ji)-i*`f)w!78%<>%GI%MO%]_%cgil%oqt%|~ )x!&)*2457:%=?A%GJL%PSTW%Z\\%_a%c )/R*2s)7/(U&(cd*b~)9p*4J)@/)R5(X()1n)W+*TB),v*Ef)-7)82(^&*;v)G=(_s)8t*[=(ZB(~G)xH(|Z(`J)zZ)1<*a2)pp).B)-{)ov*[a)^J)om)}])s8(_f*ar(qU(X0)Z3*_{)>G)}/)e0)VG*1n(yJ)6x)++(nl*?3)}@))e),\\*`J*/U*y')9:)Y_)ut)_;(^D*uF(p5)l2(W~)l5)+-)1f(u-)Vc)Px)ue(eY*sr(_!>t )9A(eg*mF*Tg*Ys)cW)u{*G_*_~*Tq(e=)x!de%jl%wy%~ )y!&'%*,%047:<=?@BDF%HKLNOQ%VX%Z]`bdfi%oqrtvwy|} )z!&'%)+.%24578:; (TG)q/(eK*m<*xV+2S*o.({Q*S_(T!hb (^x*>m)47(ai)F>(Xy)0D(_.)Ts(^()6Y)?9*rW*UQ*`O)m|*c*)rJ)Q2)dO)eX*T_(qf)r`*XL)DA*oA*3w)+<)Wk(u_)|\\)s{*o<)Pn)?O*/O(q7(]v*qn(|W(s((f,*[g)>a*x_(my*mP)q>*`y)9?(gq(t!@` (o~*\\N)Cs*ZH*8U(`[)1p(qF*F@)&;+0<(YM*x}*Sv(w@)0O(d:)6?*a.*c/*{T)0B*2B(]d*2i(|r*{J)U-(Uy)z!<>@AC%QS%UWY]_%df%oq%uw%~ ){!&'%57%9;A%DHKMO%RT%VYZ_%adgh *X0(e.*0B)}c(WK(U<*qO)T*)h1*C6))N)lg*21)L')t3*mE*-4(_T)_h(e**_e*:q*X))dt*{B)T0(o-*9z)?[*4.)5[*r((uu(W:*S|*.T)>9*=U*uI(iZ*ye*4)(c9*Ta(e}*4>)+5)Sf*X9*9s*d.(f-)Q{(_y*.Q(oB)`C)S,*(9(tq(W8)/1)2K*(Z(Tv(|_)E7*FD)&C*ne*yU)mS)`&*`Z(^{*/^*Sz(to(_W(X=(f*(tQ)>r*4(({,)69)7,*^z)*4)R&)}:(WJ(Ya)CK){!ijmo%qt%xz%~ )|!&'%+-%79%BDEG%JNOQT%Y[]%ehikm%ortvy%{} )}!&'*%,.0135%7;=A )Uj)VM)x`*K6),T)l()6]*^o(Yx*eW)?I*5!Z| )+2*5{*Xt(a0*MY*XK(t3([\\(Vl*qk)cT*6K*Wx(|**S`*r:(uT*/[(g;(ld(kU*TI)>4)JQ*mL)po)Xz)*a)kn)D+)E])|l*3z*Xv)2F)y>)>]*Xc(^T(`4*mU*/y*3x*.L(~C)Wy)DE*&;)o}+&I*6a*0|*),):}*oQ)z^(fN(h7)O^):`)4}+04*4w)m=(a3*uT*>e)Fo*F&*qP*s1*nF(Tp(ea*.s)Fl*Z-*2K)C2)+0*1H)}!CDFH%KMOQS%XZ\\^abgikmprsuw%~ )~!&'(*+./13578:<%?A%GIJL%NQS%VY%[^%`i%kmnp%rt%{}~ *&&(pL*2u)Gq))-)>6(a`)0F+4-(X}*\\H(^8({b),P))1)Re)7[*Wz(^=*m\\(bf)SM*:M)eC(p,)Di*X-(tE*_-*=*(g@)~H(Wk)Sk(zt(vE+2X(eA*Ee*~r*UB*3~)>@*x^(n6*sd(`H)k2(`j(|?)7l*L.(UC)7:)/\\)H{(^?({O(^l*N<)~\\*{[*08)1o)^'*X/(]n)*n*`S)ix*N>(ni)tz)-6+42*qI*^R+'T*TE)oj)Fu)Eh*Z8*X5(`W*^t)Yr)HN*n_*bs(n9)E(*K~*_X(gs*&!'*%-/%246%:=>@%BD%FI%KM%OQRT%XZ%]_a%hj%lopr%wy%~ *'!&')%.124%@B%GK +&)(zy)Us)R-(V9({j*~Q*d7)3v*b5*v{(f/)VX(|0(_p(j**0=*2&)u*4e*G])e<*(z)XG*'!LM%UW%{~ *(!&'%*.%8:%@CDFI%KPQSV%Y[%]_`d%hjk ),d*DB(h~)6g(V&)SX)5S*9x(h)(c])fQ)Yi)l8(`,(b~*TA)KF)-n)/2)W8(o2)O4)gi)G-*_i*/T)8s)0|(hv)n5*Um)`>)VF({])*j*;g)2s+1b)v}*G@*'0)oy(_c)1v)`u)A3)*;)0&*Tr)^K)86*^s).H)0;*Eo(ms)Pz)0m)35(cX)1`)AV*X?)yu(WU)_k)RN*Sp*TV*.r*;y)@X(wu+'Z)UM)WA*UL)U7(WT)^F*@%EG%NPQS%`b%vxz%} **!&'(*%,.%4 *3i*{:*`1)\\M*Sb+/q(v`*/!*J (ef)Df)HY*^{*'V*sc(e')/W)mb)Ry(d)(y2*.A)85(_S*55))9*@7)6C(^L(zs(WI)x>(`\\)18)UJ({!{y *S!^m )@+).W*r;(u`*/(*.D(kP)EC(t_(XU({m(aa*;o*xj*X>)l/*mq(Zw)z[(W2)EB*~H(y*)P5)pj(o=(|t)}N*qC)`w(^H*4-*97(uE*/E*;<)HA)Ex)v4)uS)7M)8r)~;(Yv(a+(_B*;e)KQ*g=*ZC*X1*N;*o/)~h(W1**!56%km%tv%~ *+!&'%= ([<*8P(`k*{D)WZ)Xv)VJ),7(\\s(vP(|d)UB)Rf)m**?<)GB(t|*So(c/*dE*rC*AH)I:)w+)`O*4z(V8*bP)UC*~N(v{(mQ):d*nJ)sy(Y.*5E)eM*NL*{O*/u*.x(a@)>T*dI*^!im (eH){\\):L)9])ox)yp*J5*r,)5F(al*9I)G.)DU)9/)rR)|Z)TV*.m*N](vD)5.*Bo*9l)lI(ZO(V_)mI*TO(}O))F)}_)?F*eL(V^)Tz*M2*)~*o'(VY*U3*_l*u^)A;)xR*_b)_n)Ut*+!>?%JL%RT%~ *,!&'%F (}B(as*;[(^.*:|)rB)Af++l(V@)1J*(!nc *.i(V)*R|)A_*xh*uD(r[)>g*o])-h)mm*uA)|!LK (_3)_1){^):I){<*.:)gP*w&(U2)^S(UJ*d&(d_)>L)@0*7!u~ (g9(}6)m>*v2)7B)eE)ma(}J*~C*=-(}E(g+)sw(U+)S\\*37)7<)9&))0(^C*Z!+l *o0(Yz(eB)1g)_.(a()8a+0:(w:(ZV)qw(d-*.|)<2)>&)6L)9P(ZD)cS*NC(_&*S}*.w(o**=/*mZ(^g(ex)&N*,!GH%~ *-!&'%-/%35%9;%P (YS)|P)UV*bg*~Y(iy(gA(cp(gZ),=):H)JF(_b)36(_}(q[(b@(o1)tB)qK)+M)3E*)7)5w)6Z(V6)^p*29)7a)_f*uK(oZ*:I)E{)Hv)vX*xw)yI(sr(g^(eL)W~(]p(`U({Y*Tb*43(i<(p0)0L(o4(f1){@)0)(zd)9_)6c(e@)6&({~)E;(h?){e*:T*dK)+)*Ki(t^(p8)7x*Z6*4s(o:)~2(Y2).v({t)OP(c0)}d)e.)Fy)t4)qv)@@(_((U|)pm(~k){k*?&(tt+'Y([W*-!QR%tv%~ *.!&'%46%8HNUVp~ */!-:KQ_xz|%~ *0!&'%)+.%7:; *{])2N)Xt(oG)@O)8W(n,)7V)6,)+i*qc(of)73(j'*Fc*5u*_4(i_*)_[)V@(b:(U=*t;*on*A})vM**-(]F(ou) AC%FHK%OS%UWX[]%`b%eghj%qsuw%{}~ *1!&'(*+/12457%=@B%FIJMOQ%SU%XZ\\^%befh%mqr )n-)|8*(B)SS*sS(a\\)j2(h;(Yr*31* V*5c*nX)/})_>*.]*(^(_<)G[*(a*96(Tj*^p*eJ)An(VB*Ti) (er*n7(Y,)?g(}!jf */V*DE)R6)-o)gA)Y|*/@)&9)8,(zz)Y~(d+(U^)9X)lb)6d*^X(Wa(Ve)ST*.P*Sw*>'*HJ*0?*`s*n})~d*~k*K}*>G)Tp*~P*.v(uU+1Y)gU)t6*Dv*~!6L (kb(et(pU(U]+1D(ce*_Y*54)ry*{g*F0)Yy*@k)C:)30)Zj*3![^_begj%oqrtv{ *4!'*%,0479:<=?IK%OS%Y\\cdfgjry{} *5!&)%,.%02367@BDF%HJ%VXY[^%`bd%hj *U4*9Y*;@)q2)Qs).d* *:s*nt)Q;)si*my(c~*:p(^^)*,*V>*X8(U5)ge)E&)G_*dJ*tM)a4)SO)qI(xT*oB)Q/*0v)@p(|.(v-(x\\*q!7F (W'*=o*?J)Mp)px*o1)f.)H'(zo)qo*dn*uL*)3*`/*U'),b*'|)yP*N?)Sz*F^({})*1)HJ)q`*/6(^a(]r(b1(wD*/F*uM*:E):.)rk*Bv)yJ)X+)+/(uf*@i)^H)Qq)7))pX)>J)1/*qL)@W*H/+/s*nG(ej(g(*U7);~*5!kl%prtx%z} *6!()*-%13%68:<%>ADEG%JSU%Y[]%`bd%iklp%tvwy{}~ *7!&'%+-%25%8=>@%BDF%L )<&*C^)L>*6n)vk);o+'l)6|)Ci* )YR*A*)72)*c)vA))UO(^h),A(uA(ak)/D(u@)B-*DD)mC)8;)4[*)F*T^(h8)O9+/u)Pm*B{(fY([M)SR(ic*Y[)cJ))])/G)i>)77)9J)cj)-|)X4)U:)=T)[>)pq)vS)q<)lQ(`>(e8(U@)+4)?c*2`*4Z)6^(g1(`B)_0*Jk*Yx)T6(f|*4^(q**Ky*XT*r`*cz(XK)SI(jW)p_)te)6k)_{)[t)-Q*@D)H[)uX*&Y*6z)CI+0F)8x)v3(oR)tG*t})6! /g,">"):e}var d,m,r=this.items[this.index];r&&(v(r,b),r.removeAttribute("aria-selected")),f(s,b),s.setAttribute("aria-selected",!0),n.focus&&s.focus(),this.image=h,this.viewed=!1,this.index=t,this.imageData={},f(h,R),n.loading&&f(o,F),o.innerHTML="",o.appendChild(h),this.renderList(),l.innerHTML="";return T(e,Q,u,{once:!0}),this.viewing={abort:function(){p(e,Q,u),h.complete?i.imageRendering?i.imageRendering.abort():i.imageInitializing&&i.imageInitializing.abort():(h.src="",p(h,H,d),i.timeout&&clearTimeout(i.timeout))}},h.complete?this.load():(T(h,H,d=function(){p(h,B,m),i.load()},{once:!0}),T(h,B,m=function(){p(h,H,d),i.timeout&&(clearTimeout(i.timeout),i.timeout=!1),v(h,R),n.loading&&v(i.canvas,F)},{once:!0}),this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(function(){v(h,R),i.timeout=!1},1e3)),this},prev:function(){var t=this.index-1;return t<0&&(t=0DGHKPU%XZ%\\^`acdfhj%nxy{~ *;!'(+-.2%;>?CEGLPR (i]*5i)mV)pG(cH)n)(\\y(}F*S)*&)([&)ce*~a*y_)ZA)k8)x9)<4)s3)7f*xq*X+(gl*35(U?(oM*:g*=p)*b(_`)kL*T((}T(oD)TQ*xg(wa)ti+'\\*_|*(E(`p)5m*nT(VZ*k*=L*?c(p^)Cr(n?)A^)Ub*U<)Bt)]E)C])OL)FI)56(v/(TI(_7)ZE)E^)S=(^B)HL(tm)Oy)lc)&a*5;+3<)?y)w!rk *~[*Xw(~.(UK(W<(f3(tw)tA(lV)Qt*_U),@)S+)T8*Sh)9H*;!STVWYZ]_%chj%nrw *AE%GI%KN%P )0I)U9)d:)6)*m!Ax (cR*_R)~9(Vs*U1(Uk+1r*m!df (`g)[B*aB)UA*U?(qB)'F)O!2[ )E6(f_*6&*0t(rq*A6),w)6e)Ld*o:)>m)0])G?)s5(UA(Y1))/*v*) (VF)y^)i<(bL*:')=&)y5(|;)S/*u=*^e)R)(Zn(d5)WO)<{)Ad)R7)1E*xW*T[)*u)iD){=)yC(T^*b7)hd)RI(mo*cx)Ss*Y2(cI*Ea)C0*\\K(}M*~;)Wj*=!QRV%Z]%_a%cehj%msu%z|%~ *>!()%-3%:<%AC%EH%OQ%Z\\%`bg%jln%rtx%z|~ *?!(*,- (e3(wQ+3w*YJ(dq(nD*y.)D(*do)Sw(^4)mn)7])dq(`R(a^*/{)^o)o*(d*+0A)K-)uJ*s]*K^*13)`_)b:(^U)E_)k:(sc)=l(mL*Sf*{K)63*.o)1y)_o(sk(V!UN ).X*vy(W6*Sa(_v(uW*.E)5p(Va)@.)5**;M*?z*;x*Gv)ad)YN({p*.l(^c):()E`*3f*;N*IL(]7({1(uO*_B(U`)Rd(^1*LQ*^Y*q}*AI)if*nj*q?)VI*:S),n))Tg*>2*6@++w(r6*X[(TO(dw*?!./%24%7;>@%GIKLN%QS%_abdf%hlmoqstv%y|} *@!&'*,-/%469:%CE%GI%SUVX%Z (WY)>^)G+(js(Tm):s*~d)6.(y+)ig*99)VL)Ho(\\e* 1)5g*{k({?(|])9@(i'(e4)nq(^I*A+)E.)H4)PC)6U*^}(e1*82)Vt)m3(US*XN({')ao*BU)B!(p *0Z*FB+1k+2e(}c)Cm*`()FD)DD)5))|C(r])+L)>k)Zp*B!(),.%46%@C%IK%MOQ%SW%\\^`%fh%np%twxz|%~ *C!&'(*%02%57%E )0.(`Q*2C);Z*JN)l&))M)FF)7^*t`(e))c[*Te)R;)rH)z-(f2)s:*xZ*8<*TX)u1)CR)_C)?Q))MD)n;)[S*U8*Tl(oI)QO*Jp)v6)9Z(eV)_/)Rk(r0);0(q3)Ha*6m(hb*)-(ZH*\\V)Vo*YF)_m)9G)V>)Yl*/'*=g)Fv*`;)V{*rl*Se(t})d>*C1*6P)m`*PR)H0(`n*Zp*nk):/*xx*[9(iu(X5)C=(l})1U)V8(`](}N(tO)WE(rC)l-)kr)0E*84*5q)7{)DF*_s)qz*ZA*X4*mt))^(d;(f0)_E*D!acdf%lw%} *E!)*%-/1%69%=@AFHIMNR%TV%Z\\%^`cghmnp%ruwx{%~ *F!'(%*,%.17%9<%?ACF%HMNP%SVX )RG),4([3(VA)+C)8K*8g*`R)G**dB)sA(ei*n6)-H)|R)GP)8V)}f*.y)n&([N)6X(tZ*`G(_k)y;){G(n:)-v*`L)U~(}e(n[(em(]y)X>(mw)9`*xs*6Q*FW*LV*`8(e{(}t*79)7@)5t*5\\+0,*r6*~!8F )IU(ur)7=(i7)8'(gr*Et)U8(vw)k<*Jz)O|(t<*UW),l)Xo)gc*x](T~)_y({C)us)8N)AJ)p/)1K({R(wd(TM*6')Rq)gE(V5)Dn*09)-d)@C)CY).c(uQ(vu*F![]_abfh%jl%oqrtuwxz%|~ *G!&)%/3468%;=%?AC%HJKO%VXZ%\\^`%ch%jmoprsuw%{}~ *H!&(%.0%4 )(n).9(d'*vx*_n)Fx(n0(i()1_(U')[3*/5*:5*=q(vH(W!Ze (}C*.F)Ch*@r(fw)lL*4G(i{+'g(X/)Ww*Tw(|g)3>(cz)nj)Ws*D~)?)*qJ*.S(f?)zR*)a*q=(k(*1P)kD)8.*FY)VD){c)5-)?C(cv):@)S1))3(f`*m[(U9)Rh*TP(}P)@)*9c)H((f!B8 )Q+)Ox(V()8S(cW*8>(WH(Y7(oA)5&*tB)AT)d.(bg(ab)0x*TS)@])ai)Du*MR)u.)t2)A`(l)(f<*n{)d?*H!5679:>@%BDF%IKLNOQ%UW%Y\\%`d%jl%oq%tv%y{%} *I!&'%/1%46%9;%@B%IKN%QS%WZ )yx)0H))T)0b*6o(t;)1\\)aT)_q)YB)RW)dE)MH*K2))u(UM(xu(j<*n=)Tl*)R*s6)5+*.`)ru*Dr(c2*tb*_')Aw)&4(Y))eY(TQ(d\\(t5(ep)98*o)(]m(Vm++P*.>(gc*W}*J2*8W*qA)V1),c(y5)A.*r_)gj)fA(du*6L*{Z*10({a*r!mF *.Y)q8(dX*ow*{n)~l*Lp)XI(UN*1c)x6*TJ)1s(gx(V?*xY))?)L~(\\M(en*Ul*>1)u9*tH(`d(h@(m8*nZ)V+({l)Vi)AC*I![\\%hj%oqrt%vx%z}~ *J!&'%),%13468%>DEHKMOQ%TV%Z^adeghjl%oq%su%y{%~ *K!&(*%/ (|m(zm)FT*3s(iq)|~)>C)I|(V/)OY*G7*uv(c^)80);@*b0)?>*4E*Tt(^e)H1(d.*I0)4=)Sr)TP*U-(}V*BP*9v*nf)O5*_,)?R)/-).N(Yj*I|)@h*67)f<)1z(^@(`+(on)-F*b(*J**df)*g)D4)/Y(vG(]i(_i*4|(bp)S'*sa)aZ(WL(Yw*1-)C{(je*nb)y8*Jt*.}(rw)5(*tD*DN(k_*x[)-t*Su*?u*d+(e6)@6)*~)lY)0=**l(xA*/!+. *^S(jG({Z)1,)?m)g>*K!13%57%;=%@B%EHILMO%RT%VX[\\_%cefkln%twz%| *L!&')+%-/%57%;=@%DH%LN%PR%UX%[]%_ac *`A)oU)qi*.t*u_*BA(zv){:*t.*Iw(b3)a_).5)@5*TF(|Y*~9))))PB)Rb*S!jl *`B*_V(dA)7&+/!v} (fD(Tq*:+)cw*E7)&i*J7)VR*sb(g|(V.*Ss)`2(gh*qX)_a)WC)pi(Tk)tI*FT(~U),3*Nz*x|*q])^i)Sm(tj)9a)q|*J+)ZS*9:(qa)bL(dB)tO*s^(hS)-J)`Y({k*T~*~V)P<(tT+0&)y_)DM)6/(XQ)mE*0r)T`*r))R.(W+)mv(^G)Fj)Z}*a_*6B(uc)i~*L!de%lnoq%~ *M!&'%03%8:%MO%QSUWXZ%t );M(},*aD){W*U.(vN(gW*7y*<+*MT*26)IX(l<*2l)cU*eI(_)(UL*xU)9N(T`(eS)C1*5v(tB)VU(TF(sx(cJ):5*nK(Y&(WE*JA*xp(t]*a6)ys(V~*4t)m5)S0({S(v\\)-A)I-*Du(ZJ)):(UF)sq(Vy*9A)6T)@\\*ap(}~(VS)-]*7?*`p*3a)mO(V:*KY)26)P~).Q(U6)pc)Y:*TG*Sk*T!n5 ),?*22*1[*.h*;J*<'(mu)Pp*w,*r*(vo(e|*nP)W5({|*{C(}>),R*s-*M!uv%~ *N!&'%:=GM%OQ%SUWY%\\^a%df%hj%ln%y{%~ *O!&')%> (d&*:_)LN(x6+0g)+**/i*!./ *;|*G0*__*Xb)pa)-U*xv)uH)@i(h1)7O(XE*7<)ml)+N*sj*ZX*F;(g:)TH)V/)R?)0X(b/)k~)*l(WS)0y).r(}))l.*b4*ms)d~)Sg)X)*cv)CG(e!(P (X3*eD*TU(d~)*k*_S)W.(U{)p[)JU*DR)2A*8&(X;(Yg*`v++0)20)W!g^ *r{(Uu(wL*t,(TT(~+)y1({>*TQ*1L)gC(pi*9R*bG(e^*a&(j[)&=).,)2/)OD)e]*46*PQ*O!?@%^`%hj%~ *P!&'%@B%H )Up(|1*KZ*xd*Uv*~7+0*)WT(^p(]h(p-*J_(dU):S*_&(n)(f\\(nB)fR)Y(*/Y*_m*:?)2f)/Z*rX)C.*.@*Y!1j *mX(~_*(T)CF)1&*qT*2N(U~*bm(bh*r^(]f*_a*As*d1)AE*w.(ze(c,)tm)D')Fp(gt)^Y({g*^g(^Y(nd(g\\)=f)Ar*X!^C *5:*>v*aL*)6(_r*CH)E/)@2)\\.*E?*[v(lX*`X)ot)^Q)b\\*W|)7S(`3)TR*X<)/@(rv)3\\)C<*X`)5j(jS)Wm)Ck*^Q*P!IJ%PS%Z\\%~ *Q!&'%R *n;*qG)qh)F8)Jw(g6(U:)_:*T,);^)?-({<){J(Zj(|F)sI)QA*PA*(H)Sl)ph)?K*_()''(}Z*D,)F;(co)54)|F)XL*/>)L<)|M)-T)Zr),])9D)VK)D;(TN))X*X&(Vk*4D)o&*s9)7E)@v)6A)Sj*Xu)a7*0Q(]k*3d(eI*aM)6[(hD*F2*_**2;*nq*@o*_j)UU)h.)?A)q_)kZ)t\\*7t*Ww*m;(Y/)Dz)m]*T.*tK)8@*oH*r+*?i)84)r()-e)e\\(Uv)/F)>o)7Y)Ou)>:*Q!ST%uw%~ *R!&'%;=%[ ))o)mk*bW*S~*9d)E))>*(f5*FZ)ss*4&*5-)RH(U8*.a*3))q4)I5)PO)6*(Zl(Xf(n|)7q)Ot*Ye(eG)@1*.R).b)8+)9o*7!lm *0V))d)&,(`P)Aj)ya)z9*X()^t)mx)Yv)Si){X(Ts)p^).k*mR*JU*.b)yE*4C*eH(W!-R *8?(fl))&)U.*T0*(U*^^*3u))b(g=)pJ({P)A,*~n)hA)F]*Ev)Co)f=*T!\\? *`H)|f)_])a>)7.)s7(kx(U(*>a)E}(aj*E[*X.*nR)}e*R!\\]%{}~ *S!&'(*%\\inx *T!+4Nm *U)(X1)T=)x.*~E)6V)cH)7g(TY)tK*^V)<]*XZ*&()GC)*s*KJ(uS) *0R(|h*aT)@q)).(X2)Ej([1(X>(o3)+=#2$*U!CD%KM%PSUVX%_a%df%kn%tw%} *V!&'%)-%3568%:=?%EG%IK%_ (Uz(TR(]e(TV),<(cT(T[(V,(Td+'J(z|(lW(Tn)y2(U,(b}(U4(tS)cY(c})Qp(mt*4h*{l)Q3)re+2\\(T|(V3+2U(U!IV (V'*9O(zk(ie(kV(VX(d!CSY[d *uP*X](c)(eR(c!5=M *X\\(c!ur (_!u{ (`!(GMYZfx{v *?`(a!>CBQT (^N*0<(V!OW]V|u (W&(Vr(W!V.] (XF(W!0`bDf (X!@I )>3(X! *V!`a%~ *W!&'%f (X!A9 (W!mx (X!XVskeq`] (Y3(X^(Y5(Xv(Y!oqsNcleZh (Z!(Y| (Y|(Z!\\?^].L @A (cx(d0*q!lqp *r'*qy*r!328?JU]bhj~ *s!*4M *a!vz|x *b!2':9<@ *Y|*Z!&'*.%03%57;<>%@BDJL%RT%VY[\\^%ac%jnor%vy{~ *[!'()+%-01348:;A%EH%MO%Z\\]_`cf *b!>6UKDVJMYlhb]aqu *c!+1OKP^\\fps (`'(th(a!cmn (b&(hQ(b!8>X (e<)be)s[),1(_!ho +'G(dl),>)lW))7(o/(p!3+ (rV(s!;DP (n!ehfoujk (o?(n!w~ (o!LhNi_^KPYV (p!7. (oo(p! (ov(p!*_bdc\\B~y (q)(p!ng *[!hjl%prsuw%y{}~ *\\!&'%*-%/1%79;%FIJLMO%UW%ik%~ *]!&' (q!<>. (pw(q!1OJuQ (r!=DYarX *{}+2^)4t*9!@DFVQoKUX^`r *:!&, *9w*:!68Q *9!_~u *:!9:/ *9!p{hqf *:!2< *9k*:!OweR}uJb@FziA *;!&/ *:t*;!)* *:!NC *;!1fpq *:v* !&B *=!ti7Brf[\\M( *<|*>0*=!SD *>!f[dc} *?!89+:) *>!FPs *?!'=? *>!;w *?!r~ *@!(> *?n*@+*?!{pk *@8*?!RjeH *@!=;d )kc*A7*@H*A8*@w*A9*^!/0%OTjv| *_!.1%35%8;=%@C%FHIK%MPQTWZ%^`cghkqrtx} *`!')*,%.2%467?@DFKMP *A!U: *@!WT *A!XGgc]y )s0*A!Bqz *B!JN-5 *Ax*B!TB+_]Vyg *C!)LtRvc *D0),!;E (t!bg *2m(t{(u'(t~(bw(}!'*19 )5h)6!-b~ )7!4DAX )83)7`)8!J\\T )9e):U)9!)2Fl )8~)9!dB )8z)9!ft ):!QW?^ )9|):!=- );X)9!~v );!KG ):!jz );&):k);!,'d )<1);s) )),H).])ko),N(cn(e!NZFEXosc (f!OV%XZG (e~(f![]'6 (g!-? (f!{uh (g!EF/ (f!zj (g!H{Xm_}RQ~ (h&(fv(gN(h'(g!fjw (h!+,. (g!TUO (h/(gz(h!0m9rOfEtuacy| (i`(j!/U (i!Bf:N8I5 *b!HILNOQ%SXZ%\\^%`d%fi%koprtv%y{%} *c!&'%),%.02%EG%JL%NQ%[]_%eg%oq (i!0On%p,)U (j!+r (i|(j!QY( (iz(j?(iw(j!v1 (it(k&(j!]^49 (k!1> (ji(kf(jq(k!23 (jt(k-(j!}d (k!6,9: (j!lm (k!/<+ *^~(k!eOSHkjEGnt (l!F'E (ks(l!;PGJ:BtR_Yijs (m!(Dilrv (n!1'5;@FEX ))!Wa\\Yy )*!*+ *c!rtu~ *d!'(%*,-/034:% *U~)(!Xf )-!W[fkmpy} ).!'38@G *J@)-E)d!ruy|} )e!/-:9>T[U^`cm_of *e!ab%~ *f!&'%g )eg)f!*&4 )ev)f!10(5L8?KDc`js )g!&)8 *8;(tK*yn(t!J( *{!8<%AILRUY\\_befh%j )*o)+')*z)+!,;6OKTI *XS)+!hgq~ ),'*73).!OTaZ )/5).y)/6).!lo )/!078 ).!ux )/!*KgXMA?[] %VX%p )0!CVos )1-)0!v\\ket )1!l;1]XFZ4 )2!GM B: )R!op{} )S!4W~ )T))S[)T!LMF, )S`)T!5+O@C )S_)T!(DS *g!qr%vx%~ *h!&'%79%y )U5)T!|a )U!?D )T!\\Ync )U!'I*1 )To)U!KNP/ )V4)Uk)V!AC )UZ)V!67 )U!X\\x_ )Wd)V!jh )W!(X )Vb)W!*[0' )V|)W`)VN)WV)VQ)Wu)X!_?\\ )YJ)X!PwDE )W!|o )X5)Y!wI0x )Zl)Y!z=?USOoLg'Z7 )[!H,- )Z!cT8nu )[!1Z )Z!iHh )[!osr^Xb` )\\^*h!z{%~ *i!&'%TV%~ *j!&') )\\!V4FCOn{km| )]!NWOmi )^!*9 ({!7;LJ\\o )l,*~h);:(|!BL *L\\(|N*[<*Qv*_!Gdfv *`&*_!uzw *`+*_y*`!= (u!xkq (v!F& (u|(v!K2yzQ|WLm (w'(v}(w!MO,>.[ (x)(w!epW} (x7*4p(x!l]9< (y!'T (xt(y!;= (xz(y!ILZ?OAEr (z!'&BGP (|!sz (z!ju ({*(z!acr *~!?ABDIGJKORTZ\\]`be%gijlmoq *.!9;=?BC *k!34%:<%~ *l!&'%: *.!GJXZ%\\cefjnquz{ */!),/023N7;] )FP)G!/@ )Ft)GA)F!sq}|\\ )H6)G!iNQmE )HC)J=)H})I!GH )Hz*o!(4>DILV[aouvx%~ *p!&(%s )IL)Hq)I!3) )J&)Hd)I8)J@)Ia)J/)Ij)J!,S:OgG )I\\)KB)J!VW )KD)J!X52Hjv )K1)J!z| )K!J'7@U )Jd)KV)J\\)Ku)LL)Kc)L!45 )M))Kh)L!a[ )Md)L!mxR )M!R= )L!ZEu )M!@UTm[o )f!Je )P!:;@=KLFSTZc *^!UW[%]_`bacdfhklnqu *p!tu%~ *q!&'%6;NVbgjmor%xz%|~ *r!&-%0479@DEG%IL%PR%TVY[\\ac%gin%z} *s!&' *^!wxy *_!)+ *\\j)5!'37;>=A@H *7`)k!EJUegi )>/)@!789Sb )DW)@!L^I )^`)C5)@!f}z )A&)@~*2<)A!OD1?FQGgt| )B!>4Urs} )C'*X!236;=@EFHIGMUY *N!AD%FH%K )d!3d )c{)d!+4CDIPRTW )7r)8C)9h*s!)+.%02378:%CE%LNOQRTUWX\\_`eghmnpqs%|~ *t!&'%+/%24%689<>%ACFGIN%PT%VXY[%_acd );E)=,*2:)Q!JS]UYegfmux%z )R!(0+19 )>!0Pf )c!kptN *DV(`0*3!|yp *4@)CH*4!A5/18;k%n_FH]Q[ )CN*4!aouxq *5!89 *4v*5')CS*5=*Ue*5!aIWC]sw~ *6!F+,C2;NO?9 (q~(xw*6!ZTc )Ym*6!u| *7E)Cd*7!C4 *t!ef%moprsuw%{~ *u!&'(*%@BCEGHJNOQ%SU%]`b%fh%oq%uwy%{~ *v!'()+%/ *7:*6x)O!6IKUXk *y!XYZ\\`a )Pl),})P{*Nm)?2+3=)?!5^hfenptx )^![wqx )_!=B9-3jL )`!9@BCEG%wz *w!'(%+-0%G )/n)0!63@ )/s)0!2< )1+)2!-4 )3!+wk )4!@F{ *3!]\\ )SA)TK)WF)t!+-5>LMF )?M)t!bQRn%pTqZaX^ )u!*I23 )t[)u,)t|)u!(Fwovcx} )v!&5<(W\\Lou )w/)vw)w!=NH^ +4.+2!>@A )q!1DM9GHZbYmfux )r!78.*AO *w!HI%~ *x!&'%N )r!ILftdgsx )s!-.>CK )l!7=KHEXov )m'*0!@IG *Oi*0!P\\Yaif )p!f~ *Ii*m!89:>=?@BCGJHM%OVW^]`_bcegi%moprw{%~ *n!&'(*%,/%13258%:<>?ABD *x!OP%Tknruy *y!*/%TVW[]^b%dg%mp%~ *z!&'%5 *n!CEHIM%OQSVWY]\\`acdg%il%pruw%y| *o!+,*-2357%9=?@C6E%GJMOPS%UW%Z\\_`^bce%mpr%t; )s!uz *sf)y!Me[c~ )'A)y!{z )z!=3 *z!67%:<=?%[]%~ *{!&'(+%79;HMNPSWX^ )z!XVp +1m*{z){6)oz)p!',2= )k!46 )l)+/!prx%| +0!)(-/.01589;=%@BCEHLNQ%SUZ]%chdj )m!68:DAPGWX\\hUTgfzq )n!.31/62N ?FLN[lfrnsy *J!BGP[]` *K!'K E.DQ_PiKULJdjO *F!+34/5 *Ek*FU*Ey*F6*E!zsl *F!EI:JLOKe}`gp\\ *G!'1 *F!vsky *G!(k *Fd*G!fgdIY5Wt %ACE%HJ%OQS%VX%[]_a%ikm%su%w *HV*G!qn *H!=' *Gl*H!;u -BE498GR2lnY )~0)}!`qt )~!)6 )}v)~!-,KabsgXc@eW]fo *&3)~|*&!.? ?A *(,)>D*(!AMLNRblmqw|}xu *)!.? *95)B?*1!N]dtpux} *2)*)O**u*+!KS *-:*.5+1!VR *Xs*Y!+;8X *X!gm *U!RT *c!w}{| *d8+(!;<%~ +)!&'%A *d!65D=CQRFHM`Ydaevw~ *e!()*0/5 *U`+0u*Y_*Z!9S *[!N^ *Y!\\fcak}~ *Z!(, *Y!uv *Z)*Ym*Z!:EF1GI2WKbkmz|q} *[!/5.*2&>67FG?ekqdiz *\\!+0,8: *V!*4<7JF )?=*N!PXTV +)!BC%~ +*!&'%H *N!_ei *O_*R<*u>*t!-73JELSRnqt *u)+3!loq%vx +2!CPR *s!VYZko )sM*s}*g!Ww *h8*iU*j(*k/*jM*l!Jw ++!369%< )zB++!?BD%FHINOR%WY%]_abd%kn%qx%{~ +,&+*!IJ%~ ++!&'%/12478=>@CGJ%MQ^`cmr%v|} +,!,-56;<'%+.%02%478:= *u!gp|} *v!&A=5DF *~!{z +&(+0O+&!'+-2163<=B +'!][_a`ei *yo*z!;\\ *{!*) +&!PRW`\\l^jy +'!'+7; +1![\\ *-.+0!y~ +1!&)0 *k;+1!;=y%{~} +2!'.,*/4gqt~| +3!)*0 +,!>?%~ +-!&'%~ +.!&'%~ +/!&'%ntw~ +0!'+237DGI%KMPTV%Y\\efik%twxz%} +1!'(*%/2%:<>%CE%QS%UWXZ]%ac%fh%jnpqs%uwx| +2!&()+-0%35%=?BD%OQTVWY%[]_%dfh%prsu%{} +3!&(+%/1%;>%jmny%~ +4!&'%+/%14%8 .*f.+!Zv .,!oy .-!;<%>@BCGN%PRSV%X -R!XY%~ -S!&'%N")),t(e)}); \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Bluetooth/wwwroot/lib/printer/index.html b/src/components/BootstrapBlazor.Bluetooth/wwwroot/lib/printer/index.html deleted file mode 100644 index 25dcd8481..000000000 --- a/src/components/BootstrapBlazor.Bluetooth/wwwroot/lib/printer/index.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - Web蓝牙打印机 - - - - - - - - - -- -Web蓝牙打印机
-- - - \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Geolocation/BootstrapBlazor.Geolocation.csproj b/src/components/BootstrapBlazor.Geolocation/BootstrapBlazor.Geolocation.csproj deleted file mode 100644 index affa0a4f4..000000000 --- a/src/components/BootstrapBlazor.Geolocation/BootstrapBlazor.Geolocation.csproj +++ /dev/null @@ -1,18 +0,0 @@ -- 噢, Web Serial 不支持此设备 --- 噢, Usb 不支持此设备 --- 噢, GetBattery 不支持此设备 --- 噢, bluetooth 不支持此设备 --
- - - - -
-- - - - --
- - - -- - - diff --git a/src/components/BootstrapBlazor.Geolocation/GeolocationItem.cs b/src/components/BootstrapBlazor.Geolocation/GeolocationItem.cs deleted file mode 100644 index 42653d52a..000000000 --- a/src/components/BootstrapBlazor.Geolocation/GeolocationItem.cs +++ /dev/null @@ -1,124 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - - -using System.ComponentModel; - -namespace BootstrapBlazor.Components; - -///- - -Bootstrap Blazor Geolocation 定位/持续定位 组件 -Bootstrap UI Geolocation components experience -1591 -- - -- - - -- -/// 定位数据类 -/// -public class Geolocationitem -{ - ///- /// 状态 - /// - ///- [DisplayName("状态")] - public string? Status { get; set; } - - /// - /// 纬度 - /// - ///- [DisplayName("纬度")] - public decimal Latitude { get; set; } - - /// - /// 经度 - /// - ///- [DisplayName("经度")] - public decimal Longitude { get; set; } - - /// - /// 准确度(米) - [DisplayName("准确度(米)")] - public decimal Accuracy { get; set; } - - ///- /// 将以m指定维度和经度值与实际位置的差距,置信度为95%. - /// - /// 时间戳 - /// - [DisplayName("时间戳")] - public long Timestamp { get; set; } - - ///- /// 时间 - /// - [DisplayName("时间")] - public DateTime LastUpdateTime { get => UnixTimeStampToDateTime(Timestamp); } - - ///- /// 移动距离 - /// - [DisplayName("移动距离")] - public decimal CurrentDistance { get; set; } = 0.0M; - - ///- /// 总移动距离 - /// - [DisplayName("总移动距离")] - public decimal TotalDistance { get; set; } = 0.0M; - - ///- /// 最后一次获取到的纬度 - /// - [DisplayName("最后一次获取到的纬度")] - public decimal LastLat { get; set; } - - ///- /// 最后一次获取到的经度 - /// - [DisplayName("最后一次获取到的经度")] - public decimal LastLong { get; set; } - - - ///- /// - /// - /// - ///- public static DateTime UnixTimeStampToDateTime(long unixTimeStamp) - { - // Unix timestamp is seconds past epoch - System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); - dtDateTime = dtDateTime.AddMilliseconds(unixTimeStamp).ToLocalTime(); - return dtDateTime; - } - -} - - -/// -/// 定位参数 -/// -public class GeolocationOptions -{ - ///- /// 是否启用高精度定位 - /// - ///- [DisplayName("是否启用高精度定位")] - public bool EnableHighAccuracy { get; set; } = true; - /// - /// - /// 超时时间 - /// - ///- [DisplayName("超时时间")] - public int Timeout { get; set; } = 5000; - /// - /// - /// 最大等待时间 - /// - ///- [DisplayName("最大等待时间")] - public int MaximumAge { get; set; } = 0; - -} diff --git a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor b/src/components/BootstrapBlazor.Geolocation/Geolocations.razor deleted file mode 100644 index f2c96ce6b..000000000 --- a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor +++ /dev/null @@ -1,15 +0,0 @@ -@namespace BootstrapBlazor.Components - - - @if (ShowButtons) - { - if (WatchID == null) - { - - - } - else - { - } - } -diff --git a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.cs b/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.cs deleted file mode 100644 index f61d83a1d..000000000 --- a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.cs +++ /dev/null @@ -1,205 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using Microsoft.AspNetCore.Components; -using Microsoft.JSInterop; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; - -///-/// Geolocation 组件基类 -/// -public partial class Geolocations : IAsyncDisposable -{ - [Inject] - [NotNull] - private IJSRuntime? JSRuntime { get; set; } - - - ///-/// 扩展阅读:Chrome中模拟定位信息,清除定位信息 -/// https://blog.csdn.net/u010844189/article/details/81163438 -/// - /// 获得/设置 定位 - /// - [Parameter] - [NotNull] - public string? GeolocationInfo { get; set; } - - ///- /// 获得/设置 获取位置按钮文字 默认为 获取位置 - /// - [Parameter] - [NotNull] - public string? GetLocationButtonText { get; set; } = "获取位置"; - - ///- /// 获得/设置 获取持续定位监听器ID - /// - [Parameter] - public long? WatchID { get; set; } - - ///- /// 获得/设置 获取移动距离追踪按钮文字 默认为 移动距离追踪 - /// - [Parameter] - [NotNull] - public string? WatchPositionButtonText { get; set; } = "移动距离追踪"; - - ///- /// 获得/设置 获取停止追踪按钮文字 默认为 停止追踪 - /// - [Parameter] - [NotNull] - public string? ClearWatchPositionButtonText { get; set; } = "停止追踪"; - - ///- /// 获得/设置 是否显示默认按钮界面 - /// - [Parameter] - public bool ShowButtons { get; set; } = true; - - ///- /// UI界面元素的引用对象 - /// - protected ElementReference Element { get; set; } - - ///- /// 获得/设置 定位结果回调方法 - /// - [Parameter] - public Func? OnResult { get; set; } - - /// - /// 获得/设置 状态更新回调方法 - /// - [Parameter] - public Func? OnUpdateStatus { get; set; } - - /// - /// 获得/设置 状态更新回调方法 - /// - [Parameter] - public GeolocationOptions Options { get; set; } = new(); - - private IJSObjectReference? Module { get; set; } - private DotNetObjectReference? Instance { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - try - { - if (firstRender) - { - Module = await JSRuntime.InvokeAsync ("import", "./_content/BootstrapBlazor.Geolocation/Geolocations.razor.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); - Instance = DotNetObjectReference.Create(this); - } - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - async ValueTask IAsyncDisposable.DisposeAsync() - { - if (Module is not null) - { - //await Module.InvokeVoidAsync("destroy"); - Instance!.Dispose(); - await Module.DisposeAsync(); - } - } - - - /// - /// 获取定位 - /// - public virtual async Task GetLocation() - { - try - { - await Module!.InvokeVoidAsync("getLocation", Instance, true, Options); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - ///- /// 持续定位 - /// - public virtual async Task WatchPosition() - { - try - { - await Module!.InvokeVoidAsync("getLocation", Instance, false); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - ///- /// 持续定位 - /// - public virtual async Task ClearWatch() - { - await Module!.InvokeVoidAsync("clearWatchLocation", Instance, WatchID); - WatchID = null; - } - - ///- /// 定位完成回调方法 - /// - /// - ///- [JSInvokable] - public async Task GetResult(Geolocationitem geolocations) - { - try - { - if (OnResult != null) await OnResult.Invoke(geolocations); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 获得/设置 错误回调方法 - /// - [Parameter] - public Func? OnError { get; set; } - - /// - /// 状态更新回调方法 - /// - /// - ///- [JSInvokable] - public async Task UpdateStatus(string status) - { - if (OnUpdateStatus != null) await OnUpdateStatus.Invoke(status); - } - - /// - /// 监听器ID回调方法 - /// - /// - ///- [JSInvokable] - public Task UpdateWatchID(long watchID) - { - WatchID = watchID; - return Task.CompletedTask; - } - -} diff --git a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.js b/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.js deleted file mode 100644 index 4d9f4d3d0..000000000 --- a/src/components/BootstrapBlazor.Geolocation/Geolocations.razor.js +++ /dev/null @@ -1,135 +0,0 @@ -export function getLocation(wrapper, getPosition = true, options = null) { - console.log('start ' + (getPosition ? 'getLocation' : 'watchPosition')); - var currentDistance = 0.0; - var totalDistance = 0.0; - var lastLat; - var lastLong; - var status; - - if (getPosition) - getCurrentPosition(); - else - watchPosition(); - - Number.prototype.toRadians = function () { - return this * Math.PI / 180; - } - - if (!options) { - options = { - enableHighAccuracy: true, - timeout: 5000, - maximumAge: 0, - } - }; - - function distance(latitude1, longitude1, latitude2, longitude2) { - // R is the radius of the earth in kilometers - var R = 6371; - - var deltaLatitude = (latitude2 - latitude1).toRadians(); - var deltaLongitude = (longitude2 - longitude1).toRadians(); - latitude1 = latitude1.toRadians(), latitude2 = latitude2.toRadians(); - - var a = Math.sin(deltaLatitude / 2) * - Math.sin(deltaLatitude / 2) + - Math.cos(latitude1) * - Math.cos(latitude2) * - Math.sin(deltaLongitude / 2) * - Math.sin(deltaLongitude / 2); - - var c = 2 * Math.atan2(Math.sqrt(a), - Math.sqrt(1 - a)); - var d = R * c; - return d; - } - - - function updateStatus(message) { - status = message; - wrapper.invokeMethodAsync('UpdateStatus', message); - } - - function watchPosition() { - if (navigator.geolocation) { - status = "HTML5 Geolocation is supported in your browser."; - updateStatus(status); - var id = navigator.geolocation.watchPosition(updateLocation, - handleLocationError,{ maximumAge: 20000 }); - wrapper.invokeMethodAsync('UpdateWatchID', id); - } - } - - function getCurrentPosition() { - if (navigator.geolocation) { - updateStatus("HTML5 Geolocation is supported in your browser."); - navigator.geolocation.getCurrentPosition(updateLocation, - handleLocationError, options); - } - } - - function updateLocation(position) { - var latitude = position.coords.latitude; - var longitude = position.coords.longitude; - var accuracy = position.coords.accuracy; - var timestamp = position.timestamp; - - // sanity test... don't calculate distance if accuracy - // value too large - if (accuracy >= 500) { - updateStatus("Need more accurate values to calculate distance."); - } - - // calculate distance - currentDistance = 0.0; - if ((lastLat != null) && (lastLong != null)) { - currentDistance = distance(latitude, longitude, lastLat, lastLong); - totalDistance += currentDistance; - } - - - lastLat = latitude; - lastLong = longitude; - - updateStatus("Location successfully updated."); - - console.log("updateLocation end"); - var geolocationitem = { - "Status": status, - "Latitude": latitude, - "Longitude": longitude, - "Accuracy": accuracy, - "Timestamp": timestamp, - "CurrentDistance": currentDistance, - "TotalDistance": totalDistance, - "LastLat": lastLat, - "LastLong": lastLong, - }; - wrapper.invokeMethodAsync('GetResult', geolocationitem); - } - - function handleLocationError(error) { - switch (error.code) { - case 0: - updateStatus("There was an error while retrieving your location: " + error.message); - break; - case 1: - updateStatus("The user prevented this page from retrieving a location."); - break; - case 2: - updateStatus("The browser was unable to determine your location: " + error.message); - break; - case 3: - updateStatus("The browser timed out before retrieving the location."); - break; - } - } - -} -export function clearWatchLocation(wrapper, id) { - //扩展阅读:移除的监听器 - //id = navigator.geolocation.watchPosition(success, error, options); - console.log('clearWatch ' + id); - navigator.geolocation.clearWatch(id); - wrapper.invokeMethodAsync('UpdateStatus', 'clearWatch ok'); -} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Maps/BootstrapBlazor.Maps.csproj b/src/components/BootstrapBlazor.Maps/BootstrapBlazor.Maps.csproj deleted file mode 100644 index 1b81cc07f..000000000 --- a/src/components/BootstrapBlazor.Maps/BootstrapBlazor.Maps.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/src/components/BootstrapBlazor.Maps/Map.razor b/src/components/BootstrapBlazor.Maps/Map.razor deleted file mode 100644 index e77101f35..000000000 --- a/src/components/BootstrapBlazor.Maps/Map.razor +++ /dev/null @@ -1,5 +0,0 @@ -@namespace BootstrapBlazor.Components - -- - -Bootstrap Blazor Maps 谷歌地图 组件 -Bootstrap UI Maps components experience -1591 -- - -- - - -- - - -- -- diff --git a/src/components/BootstrapBlazor.Maps/Map.razor.cs b/src/components/BootstrapBlazor.Maps/Map.razor.cs deleted file mode 100644 index f8ed73591..000000000 --- a/src/components/BootstrapBlazor.Maps/Map.razor.cs +++ /dev/null @@ -1,79 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.Configuration; -using Microsoft.JSInterop; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; -///-/// 谷歌地图 Maps 组件 -/// -public partial class Map : IAsyncDisposable -{ - [Inject] - [NotNull] - private IJSRuntime? JSRuntime { get; set; } - - [Inject] private IConfiguration? config { get; set; } - - ///- /// 获得/设置 错误回调方法 - /// - [Parameter] - public Func? OnError { get; set; } - - /// - /// 获得/设置 GoogleKey - [Parameter] - public string? GoogleKey { get; set; } - - ///- /// 为空则在 IConfiguration 服务获取 "GoogleKey" , 默认在 appsettings.json 文件配置 - /// - /// 获得/设置 style - /// - [Parameter] - public string Style { get; set; } = "height:700px;width:100%;"; - - ///- /// UI界面元素的引用对象 - /// - private ElementReference Element { get; set; } - - private IJSObjectReference? Module { get; set; } - private string key = String.Empty; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - key = GoogleKey ?? (config?["GoogleKey"]) ?? "abcd"; - Module = await JSRuntime.InvokeAsync("import", "./_content/BootstrapBlazor.Maps/lib/google/map.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); - while (!(await Init())) - { - await Task.Delay(500); - } - - //await Module.InvokeVoidAsync("initMaps" ); - } - } - - - public async Task Init() => await Module!.InvokeAsync ("addScript", new object?[] { key, Element, null, null, null }); - - public async Task OnBtnClick() => await Module!.InvokeVoidAsync("addScript", new object?[] { key, Element, null, null, null }); - - async ValueTask IAsyncDisposable.DisposeAsync() - { - if (Module is not null) - { - //await Module.InvokeVoidAsync("destroy", Options); - await Module.DisposeAsync(); - } - } -} diff --git a/src/components/BootstrapBlazor.Maps/wwwroot/lib/google/map.js b/src/components/BootstrapBlazor.Maps/wwwroot/lib/google/map.js deleted file mode 100644 index 3ba726906..000000000 --- a/src/components/BootstrapBlazor.Maps/wwwroot/lib/google/map.js +++ /dev/null @@ -1,601 +0,0 @@ -export function addScript(key, elementId, dotnetRef, backgroundColor, controlSize) { - if (!key || !elementId) { - return; - } - - //storeElementIdWithDotnetRef(_mapsElementDict, elementId, dotnetRef, backgroundColor, controlSize); //Store map info - - let url = "https://maps.googleapis.com/maps/api/js?key="; - let scriptsIncluded = false; - - let scriptTags = document.querySelectorAll('head > script'); - scriptTags.forEach(scriptTag => { - if (scriptTag) { - let srcAttribute = scriptTag.getAttribute('src'); - if (srcAttribute && srcAttribute.startsWith(url)) { - scriptsIncluded = true; - return true; - } - } - }); - - if (scriptsIncluded) { //防止多次向页面添加 JS 脚本.Prevent adding JS scripts to page multiple times. - if (window.google) { - initMaps(elementId); //页面已导航.Page was navigated - } - return true; - } - - //Inject required Google JS scripts to HTML (only once!) - //let importedPoly = document.createElement('script'); - //importedPoly.src = "https://polyfill.io/v3/polyfill.min.js?features=default"; - //document.head.appendChild(importedPoly); - - url = url + key + "&callback=initGoogleMaps&libraries=&v=weekly"; - let script = document.createElement('script'); - script.src = url; - script.defer = true; - document.head.appendChild(script); - return false; -} - -export function initMaps(elementId) { - var latlng = new google.maps.LatLng(40.26982, -3.758269); - var options = { - zoom: 14, center: latlng, - mapTypeId: google.maps.MapTypeId.ROADMAP - }; - var map = new google.maps.Map(elementId, options); - console.log(map); - return map; -} - -//Global function for Google Js callback. It will be called when "https://maps.googleapis.com/maps/api/js" loaded. -//TODO: multiple instances of Js Maps if registered must be stored before callback happens. In the future it might causes timing issues... -window.initGoogleMaps = () => { - for (let i = 0; i < _mapsElementDict.length; i++) { - let elementId = _mapsElementDict[i].key; - let mapInfo = _mapsElementDict[i].value; - - if (_mapsElementDict[i].value.map) { //Map already created - continue; - } - - //Create Map - let map = new google.maps.Map(document.getElementById(elementId), { - backgroundColor: mapInfo.bgColor, - controlSize: mapInfo.ctrSize, - }); - map.elementId = elementId; - _mapsElementDict[i].value.map = map; - - function mouseEventHandlers(mapsMouseEvent, callbackFuncName) { - if (map && map.elementId && mapsMouseEvent) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - let coord = mapsMouseEvent.latLng.toJSON(); - let arg = { - Latitude: coord.lat, - Longitude: coord.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync(callbackFuncName, arg); - } - } - } - - //Add Event listeners - //Mouse - map.addListener("click", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapClicked"); - }); - map.addListener("dblclick", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapDoubleClicked"); - }); - map.addListener("contextmenu", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapContextMenu"); - }); - map.addListener("mouseup", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapMouseUp"); - }); - map.addListener("mousedown", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapMouseDown"); - }); - map.addListener("mousemove", (mapsMouseEvent) => { - mouseEventHandlers(mapsMouseEvent, "MapMouseMove"); - }); - map.addListener("mouseover", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapMouseOver"); - } - } - }); - map.addListener("mouseout", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapMouseOut"); - } - } - }); - //Changes - map.addListener("center_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef && map.getCenter()) { - let center = map.getCenter().toJSON(); - let arg = { - Latitude: center.lat, - Longitude: center.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync("MapCenterChanged", arg); - } - } - }); - map.addListener("zoom_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapZoomChanged", map.getZoom()); - } - } - }); - map.addListener("maptypeid_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapTypeIdChanged", map.getMapTypeId()); - } - } - }); - map.addListener("heading_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapHeadingChanged", map.getHeading()); - } - } - }); - map.addListener("tilt_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapTiltChanged", map.getTilt()); - } - } - }); - map.addListener("bounds_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapBoundsChanged"); - } - } - }); - map.addListener("projection_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapProjectionChanged"); - } - } - }); - map.addListener("draggable_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapDraggableChanged"); - } - } - }); - map.addListener("streetview_changed", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapStreetviewChanged"); - } - } - }); - //Drag - map.addListener("drag", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef && map.getCenter()) { - let center = map.getCenter().toJSON(); - let arg = { - Latitude: center.lat, - Longitude: center.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync("MapDrag", arg); - } - } - }); - map.addListener("dragend", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef && map.getCenter()) { - let center = map.getCenter().toJSON(); - let arg = { - Latitude: center.lat, - Longitude: center.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync("MapDragEnd", arg); - } - } - }); - map.addListener("dragstart", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef && map.getCenter()) { - let center = map.getCenter().toJSON(); - let arg = { - Latitude: center.lat, - Longitude: center.lng - }; - - mapWithDotnetRef.ref.invokeMethodAsync("MapDragStart", arg); - } - } - }); - //Other - map.addListener("resize", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - let arg = { - Width: map.getDiv().offsetWidth, - Height: map.getDiv().offsetHeight - }; - mapWithDotnetRef.ref.invokeMethodAsync("MapResized", arg); - } - } - }); - map.addListener("tilesloaded", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapTilesLoaded"); - } - } - }); - map.addListener("idle", () => { - if (map && map.elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, map.elementId); - if (mapWithDotnetRef) { - mapWithDotnetRef.ref.invokeMethodAsync("MapIdle"); - } - } - }); - //Init - _mapsElementDict[i].value.ref.invokeMethodAsync("MapInitialized", elementId); - } -}; - -//Store elementId with .NET Ref -function storeElementIdWithDotnetRef(dict, elementId, dotnetRef, backgroundColor, controlSize) { - let elementFound = false; - for (let i = 0; i < dict.length; i++) { - if (dict[i].key === elementId) { - return; //Element has been stored already - } - } - - if (!elementFound) { - dict.push({ - key: elementId, - value: { ref: dotnetRef, map: null, bgColor: backgroundColor, ctrSize: controlSize } - }); - } -} -//Remove elementId with data -function removeElementIdWithDotnetRef(dict, elementId) { - for (let i = 0; i < dict.length; i++) { - if (dict[i].key === elementId) { - dict.splice(i, 1); - break; - } - } -} -//Return elementId with data -function getElementIdWithDotnetRef(dict, elementId) { - for (let i = 0; i < dict.length; i++) { - if (dict[i].key === elementId) { - return dict[i].value; - } - } -} - -let _mapsElementDict = []; -let _mapsMarkers = []; - -//Google JS Maps Features -export function setCenterCoords(elementId, latitude, longitude) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setCenter({ lat: latitude, lng: longitude }); - } - } -} -export function setCenterAddress(elementId, address) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - geocodeAddress(address, function (results) { - if (results) { - mapWithDotnetRef.map.setCenter(results[0].geometry.location); - } - }); - } - } -} -export function panToCoords(elementId, latitude, longitude) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.panTo({ lat: latitude, lng: longitude }); - } - } -} -export function panToAddress(elementId, address) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - geocodeAddress(address, function (results) { - if (results) { - mapWithDotnetRef.map.panTo(results[0].geometry.location); - } - }); - } - } -} -//set methods -export function setZoom(elementId, zoom) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setZoom(zoom); - } - } -} -export function setMapType(elementId, mapType) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setMapTypeId(mapType); - } - } -} -export function setHeading(elementId, heading) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setHeading(heading); - } - } -} -export function setTilt(elementId, tilt) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setTilt(tilt); - } - } -} -export function setClickableIcons(elementId, isClickable) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setClickableIcons(isClickable); - } - } -} -//generic set -export function setOptions(elementId, options) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - mapWithDotnetRef.map.setOptions(options); - } - } -} - -export function resizeMap(elementId) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - google.maps.event.trigger(mapWithDotnetRef.map, "resize"); - } - } -} - -//Custom controls -export function createCustomControls(elementId, customControls) { - if (elementId && customControls) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - - for (var i = 0; i < customControls.length; i++) { - let control = customControls[i]; - let controlDiv = document.createElement("div"); - controlDiv.innerHTML = control.content; - - mapWithDotnetRef.map.controls[control.controlPosition].push(controlDiv); - - let id = control.id; - let dotnetRef = mapWithDotnetRef.ref; - controlDiv.addEventListener("click", () => { - dotnetRef.invokeMethodAsync("CustomControlClicked", id); - }); - } - } - } -} - -//Markers -export function createMarkers(elementId, markers) { - if (elementId && markers && markers.length) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - - for (var i = 0; i < markers.length; i++) { - - let markerData = markers[i]; - let marker = new google.maps.Marker({ - id: markerData.id, //Custom id to track Markers - //some property does not work after set... - crossOnDrag: markerData.crossOnDrag, - optimized: markerData.optimized, - }); - - marker.setMap(mapWithDotnetRef.map); - setMarkerData(markerData, marker); - _mapsMarkers.push(marker); - - //Marker events - if (markerData.clickable) { - //Create infoWindow - let infoWindow = null; - if (markerData.infoWindow) { - infoWindow = new google.maps.InfoWindow({ - content: markerData.infoWindow.content, - maxWidth: markerData.infoWindow.maxWidth - }); - } - - marker.addListener("click", () => { - mapWithDotnetRef.ref.invokeMethodAsync("MarkerClicked", markerData.id); - - //If marker has info window - if (infoWindow) { - infoWindow.open(mapWithDotnetRef.map, marker); - } - }); - } - if (markerData.draggable) { - marker.addListener("drag", () => { - markerDragEvents("MarkerDrag", markerData.id, marker.getPosition().toJSON()); - }); - - marker.addListener("dragend", () => { - markerDragEvents("MarkerDragEnd", markerData.id, marker.getPosition().toJSON()); - }); - - marker.addListener("dragstart", () => { - markerDragEvents("MarkerDragStart", markerData.id, marker.getPosition().toJSON()); - }); - - function markerDragEvents(callBackName, id, pos) { - let arg = { - Latitude: pos.lat, - Longitude: pos.lng - }; - mapWithDotnetRef.ref.invokeMethodAsync(callBackName, id, arg); - } - } - } - } - } -} -//export function updateMarkers(elementId, markers) { -// if (elementId && markers && markers.length) { -// let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); -// if (mapWithDotnetRef && mapWithDotnetRef.map) { - -// for (var i = 0; i < markers.length; i++) { -// let markerData = markers[i]; - -// _mapsMarkers.forEach(element => { -// if (markerData.id == element.id) { -// setMarkerData(markerData, element); -// return; -// } -// }); -// } -// } -// } -//} -export function removeMarkers(elementId, markers) { - if (elementId && markers && markers.length) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - - for (var i = 0; i < markers.length; i++) { - let markerData = markers[i]; - - _mapsMarkers.forEach((element, index) => { - if (markerData.id == element.id) { - element.setMap(null); - _mapsMarkers.splice(index, 1); - return; - } - }); - } - } - } -} -function setMarkerData(markerData, marker) { - if (!marker || !markerData) { - return; - } - - //required - marker.setPosition({ lat: markerData.position.latitude, lng: markerData.position.longitude }); - //optional - //marker.setAnchorPoint(markerData.anchorPoint ? { x: markerData.anchorPoint.x, y: markerData.anchorPoint.y } : null); - marker.anchorPoint = markerData.anchorPoint ? { x: markerData.anchorPoint.x, y: markerData.anchorPoint.y } : null; - marker.setAnimation(markerData.animation); - marker.setClickable(markerData.clickable); - //marker.setCrossOnDrag(markerData.crossOnDrag); - marker.crossOnDrag = markerData.crossOnDrag; - marker.setCursor(markerData.cursor); - marker.setDraggable(markerData.draggable); - marker.setIcon(markerData.icon); - marker.setLabel(markerData.label); - marker.setOpacity(markerData.opacity); - //marker.setOptimized(markerData.optimized); - marker.optimized = markerData.optimized; - marker.setShape(markerData.shape); - marker.setTitle(markerData.title); - marker.setVisible(markerData.visible); - marker.setZIndex(markerData.zIndex); -} - -//Google GeoCoder -export function getAddressCoordinates(elementId, address) { - geocodeAddress(address, function (results) { - if (results) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - if (mapWithDotnetRef && mapWithDotnetRef.map) { - //TODO: map .NET object - mapWithDotnetRef.ref.invokeMethodAsync("AddressSearch", results); - } - } - }); -} -function geocodeAddress(address, successCallback) { - let geocoder = new google.maps.Geocoder(); - geocoder.geocode({ - 'address': address - }, function (results, status) { - if (status == google.maps.GeocoderStatus.OK) { - successCallback(results); - } - }); -} - -//Dispose -export function dispose(elementId) { - if (elementId) { - let mapWithDotnetRef = getElementIdWithDotnetRef(_mapsElementDict, elementId); - mapWithDotnetRef.map = null; - mapWithDotnetRef.ref = null; - - removeElementIdWithDotnetRef(_mapsElementDict, elementId); - } -} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/BootstrapBlazor.OpenAI.csproj b/src/components/BootstrapBlazor.OpenAI.GPT3/BootstrapBlazor.OpenAI.csproj deleted file mode 100644 index e92220345..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/BootstrapBlazor.OpenAI.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/EnumOpenAiModel.cs b/src/components/BootstrapBlazor.OpenAI.GPT3/EnumOpenAiModel.cs deleted file mode 100644 index 2fdb9606b..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/EnumOpenAiModel.cs +++ /dev/null @@ -1,67 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using System.ComponentModel.DataAnnotations; - -namespace BootstrapBlazor.OpenAI.Services; - -///- - -Bootstrap Blazor OpenAI 组件 -Bootstrap UI OpenAI components experience -1591 -- - -- - - - - - -- - - -- -/// -/// -public enum EnumOpenAiModel -{ - ///- ///ChatGPT - /// - [Display(Name = "ChatGPT")] - ChatGpt, - - ///- ///Completions - /// - [Display(Name = "Completions")] - Completions, - - /////- ///// Completions Stream - ///// - //[Display(Name = "Completions Stream")] - //CompletionsStream, - - ///- /// DALL-E - /// - [Display(Name = "DALL-E")] - DALLE, - - ///- ///ChatGPT AiHomeAssistant - /// - [Display(Name = "AiHomeAssistant")] - ChatGptAiHomeAssistant, - - [Display(Name = "聊天机器人")] - Chatbot, - - [Display(Name = "自然语言转SQL")] - NaturalLanguageToSQL, - - [Display(Name = "提取信息")] - ExtractingInformation, - - ///- ///ChatGPT4 - /// - [Display(Name = "ChatGPT4")] - ChatGpt4, - - ///- ///ChatGPT4-32k - /// - [Display(Name = "ChatGPT4 32k")] - ChatGpt4_32k, - -} diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/OpenAI.razor b/src/components/BootstrapBlazor.OpenAI.GPT3/OpenAI.razor deleted file mode 100644 index 7062f28eb..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/OpenAI.razor +++ /dev/null @@ -1,204 +0,0 @@ -@namespace BootstrapBlazor.Components - -@{ - bool isSimpleText = (SelectedEnumItem == EnumOpenAiModel.ChatGpt || SelectedEnumItem == EnumOpenAiModel.ChatGpt4 || SelectedEnumItem == EnumOpenAiModel.Completions || SelectedEnumItem == EnumOpenAiModel.ChatGptAiHomeAssistant || SelectedEnumItem == EnumOpenAiModel.Chatbot || SelectedEnumItem == EnumOpenAiModel.DALLE); -} --- -- --- @if (isSimpleText && SelectedEnumItem != EnumOpenAiModel.DALLE) - { - - } - else - { - - } --- @if (ResultImage is not null) - { ---
- } --
- - @if (SingleLine || (AutoMultiLine && isSimpleText)) - { -- @if (EnableSpeech) - { -- -- - - - @if (EnableSpeech && !(Size == BreakPoint.Small || Size == BreakPoint.ExtraSmall)) - { - - - - } - - @if (EnableSpeech && (Size == BreakPoint.Small || Size == BreakPoint.ExtraSmall)) - { - - - - } - - } - else - { - -
-- - - @if (EnableSpeech) - { - - - - } - - - - } -- @*@if (Size == BreakPoint.Small || Size == BreakPoint.ExtraSmall || Size == BreakPoint.Medium) - { -- } -- - - - - }*@ - @if (WebSpeech != null && WebSpeech.IsBusy) - { -- } - - - - -@if (!string.IsNullOrEmpty(ErrorMessage)) -{ -- @if (ShowOptions) - { --- - } - - @if (EnableSpeech) - { ---- --- ------- --- - - ---- ----- ----- --- --- --- --- - - - } - - ---- @if (WebVoiceList != null && WebVoiceList.Any()) - { - - } --- 速率 - --- 音高 - --- 音量 - ----- - - - -- --@ErrorMessage
-} - diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/OpenAI.razor.cs b/src/components/BootstrapBlazor.OpenAI.GPT3/OpenAI.razor.cs deleted file mode 100644 index 9d3ced228..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/OpenAI.razor.cs +++ /dev/null @@ -1,556 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using BootstrapBlazor.OpenAI.Services; -using BootstrapBlazor.WebAPI.Services; -using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.Configuration; -using Microsoft.JSInterop; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; - -///-/// Blazor OpenAI 组件 -/// -public partial class OpenAI : IAsyncDisposable -{ - [Inject] - [NotNull] - protected IStorage? Storage { get; set; } - - [Inject] - [NotNull] - private IJSRuntime? JSRuntime { get; set; } - - [NotNull] - private IJSObjectReference? Module { get; set; } - - ///- /// UI界面元素的引用对象 - /// - private ElementReference Element { get; set; } - - private string ID { get; set; } = Guid.NewGuid().ToString("N"); - - [NotNull] - [Inject] - private IConfiguration? Config { get; set; } - - [NotNull] - [Inject] - private OpenAiClientService? OpenaiService { get; set; } - - private string? ErrorMessage { get; set; } - - [DisplayName("问点什么")] - private string? InputText { get; set; } - - private string? ResultText { get; set; } - private string? ResultImage { get; set; } - - private string? PlaceHolderText { get; set; } = "问点什么,可选模型后再问我."; - - private int Lines { get; set; } = 0; - - [NotNull] - private EnumOpenAiModel? SelectedEnumItem { get; set; } = EnumOpenAiModel.ChatGpt; - - [NotNull] - private IEnumerableItemsMaxToken { get; set; } = new[] { - new SelectedItem("5", "5"), - new SelectedItem("20", "20"), - new SelectedItem("100", "100"), - new SelectedItem("300", "300"), - new SelectedItem("500", "500"), - new SelectedItem("2000", "2000"), - new SelectedItem("3000", "3000"), - new SelectedItem("4000", "4000"), - new SelectedItem("5000", "5000"), - new SelectedItem("10000", "10000"), - new SelectedItem("20000", "20000"), - }; - - private int SelectedMaxTokens { get; set; } = 500; - - [NotNull] - private IEnumerable ItemsTemperature { get; set; } = new[] { - new SelectedItem("0.1", "0.1"), - new SelectedItem("0.2", "0.2"), - new SelectedItem("0.5", "0.5"), - new SelectedItem("0.6", "0.6"), - new SelectedItem("0.7", "0.7"), - new SelectedItem("0.8", "0.8"), - new SelectedItem("0.9", "0.9"), - }; - - private float SelectedTemperature { get; set; } = 0.5f; - - [Parameter] - public string? OpenAIKey { get; set; } - - /// - /// 显示选项 - /// - [Parameter] - public bool ShowOptions { get; set; } = true; - - ///- /// 设置/获取 是否语音识别/合成模块, 默认为 true - /// - [Parameter] - public bool EnableSpeech { get; set; } = true; - - ///- /// 设置/获取 语音合成使用的语言,默认中文普通话 - /// - [Parameter] - public string? SpeechLanguage { get; set; } - - ///- /// 完成时生成的最大令牌数。默认值为 500 - [Parameter] - public int? MaxTokens { get; set; } - - ///参数为空, 内置 SelectedMaxTokens 优先 - /// - /// 浮点数,控制模型的输出的多样性。值越高,输出越多样化。值越低,输出越简单。默认值为 0.5 - [Parameter] - public float? Temperature { get; set; } - - #region SpeechRecognition - - [NotNull] - private WebSpeech? WebSpeech { get; set; } - - private SpeechRecognitionOption Options { get; set; } = new SpeechRecognitionOption() { Continuous = false, InterimResults = true }; - private SpeechSynthesisOption OptionsTTS { get; set; } = new SpeechSynthesisOption(); - - ///参数为空, 内置 SelectedTemperature 优先 - /// - /// 语音识别使用的语言,默认中文普通话 - /// - [NotNull] - private EnumWebVoiceLanguage? EnumSpeechRecognLanguage { get; set; } = EnumWebVoiceLanguage.zh_CN; - - ///- /// 语音识别使用的语言,默认中文普通话 - /// - [DisplayName("识别语言")] - private string SpeechRecognLanguage { get; set; } = "zh-CN"; - - ///- /// 语音合成使用的语言,默认中文普通话 - /// - private string? PlayLanguage { get; set; } - - [DisplayName("连续对话(2s)")] - private bool SpeechRecognContinuous { get; set; } = true; - - [DisplayName("识别语音后自动发送")] - private bool AutoSent { get; set; } = true; - - [DisplayName("朗读")] - private bool AutoSpeak { get; set; } = true; - - [DisplayName("单行输入/多行输入")] - private bool SingleLine { get; set; } = false; - - [DisplayName("自适应多行输入")] - private bool AutoMultiLine { get; set; } = true; - - [DisplayName("内容")] - private string? SpeakText { get; set; } - - private List? WebVoiceList { get; set; } - - private bool IsInited { get; set; } - - private BreakPoint Size { get; set; } - - private bool IsSpeechEnableWithClick { get; set; } - - #endregion - - public override async Task SetParametersAsync(ParameterView parameters) - { - if (parameters.TryGetValue (nameof(OpenAIKey), out var value)) - { - OpenAIKey = value ?? Config["OpenAIKey"]; - OpenaiService.Init(OpenAIKey); - } - SpeechRecognLanguage = SpeechLanguage ?? "zh-CN"; - await base.SetParametersAsync(parameters); - } - - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - Module = await JSRuntime.InvokeAsync ("import", "./_content/BootstrapBlazor.OpenAI/app.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); - - SelectedMaxTokens = await Storage.GetValue("AiMaxTokens", SelectedMaxTokens); - SelectedTemperature = await Storage.GetValue("AiTemperature", SelectedTemperature); - - SpeechRecognLanguage = await Storage.GetValue("SpeechRecognLanguage", SpeechRecognLanguage) ?? "zh-CN"; - - if (Enum.TryParse(SpeechRecognLanguage.Replace("-", "_"), out EnumWebVoiceLanguage lang)) - { - EnumSpeechRecognLanguage = lang; - } - - SpeechRecognContinuous = await Storage.GetValue("SpeechRecognContinuous", SpeechRecognContinuous); - AutoSent = await Storage.GetValue("SpeechAutoSent", AutoSent); - AutoSpeak = await Storage.GetValue("SpeechAutoSpeak", AutoSpeak); - Options.Continuous = await Storage.GetValue("SpeechContinuous", Options.Continuous); - Options.InterimResults = await Storage.GetValue("SpeechInterimResults", Options.InterimResults); - PlayLanguage = await Storage.GetValue("PlayLanguage", PlayLanguage); - OptionsTTS.Rate = await Storage.GetValue("PlayRate", OptionsTTS.Rate); - OptionsTTS.Picth = await Storage.GetValue("PlayPicth", OptionsTTS.Picth); - OptionsTTS.Volume = await Storage.GetValue("PlayVolume", OptionsTTS.Volume); - SingleLine = await Storage.GetValue("SingleLine", SingleLine); - AutoMultiLine = await Storage.GetValue("AutoMultiLine", AutoMultiLine); - - await OnAfterRenderAsyncSpeech(firstRender); - - IsInited = true; - } - } - - private async Task OnEnter() - { - var val = InputText; - if (string.IsNullOrWhiteSpace(val)) - { - return; - } - - Lines++; - if (Lines > 20) - { - ResultText = string.Empty; - Lines = 1; - } - ResultText += ($"Q: {val}{Environment.NewLine}"); - InputText = string.Empty; - PlaceHolderText = "思考中..."; - ResultImage = null; - string? res; - switch (SelectedEnumItem) - { - default: - ResultText += "[ChatGpt]" + Environment.NewLine; - await UpdateUI(); - res = await OpenaiService.ChatGPT(val, MaxTokens ?? SelectedMaxTokens, Temperature ?? SelectedTemperature); - break; - case EnumOpenAiModel.ChatGpt4: - ResultText += "[ChatGpt4]" + Environment.NewLine; - await UpdateUI(); - res = await OpenaiService.ChatGPT(val, MaxTokens ?? SelectedMaxTokens, Temperature ?? SelectedTemperature, model: "gpt4"); - break; - case EnumOpenAiModel.ChatGpt4_32k: - ResultText += "[ChatGpt4 32k]" + Environment.NewLine; - await UpdateUI(); - res = await OpenaiService.ChatGPT(val, MaxTokens ?? SelectedMaxTokens, Temperature ?? SelectedTemperature, model: "gpt4-32k"); - break; - case EnumOpenAiModel.ChatGptAiHomeAssistant: - ResultText += "[AiHomeAssistant]" + Environment.NewLine; - await UpdateUI(); - res = await OpenaiService.ChatGPT(val, MaxTokens ?? SelectedMaxTokens, Temperature ?? SelectedTemperature, true); - break; - case EnumOpenAiModel.Completions: - ResultText += "[Completions]" + Environment.NewLine; - await UpdateUI(); - res = await OpenaiService.Completions(val, MaxTokens ?? SelectedMaxTokens, Temperature ?? SelectedTemperature); - break; - case EnumOpenAiModel.NaturalLanguageToSQL: - ResultText += "[NaturalLanguageToSQL]" + Environment.NewLine; - await UpdateUI(); - res = await OpenaiService.NaturalLanguageToSQL(val); - break; - case EnumOpenAiModel.Chatbot: - ResultText += "[Chatbot]" + Environment.NewLine; - await UpdateUI(); - res = await OpenaiService.Chatbot(val); - break; - case EnumOpenAiModel.ExtractingInformation: - ResultText += "[ExtractingInformation]" + Environment.NewLine; - await UpdateUI(); - res = await OpenaiService.ExtractingInformation(val); - break; - //case EnumOpenaiModdel.CompletionsStream: - // ResultText += "[Completions Stream]" + Environment.NewLine; - // await UpdateUI(); - // res = await OpenaiService.CompletionsStream(val); - // break; - case EnumOpenAiModel.DALLE: - ResultText += "[DALL·E]" + Environment.NewLine; - await UpdateUI(); - res = await OpenaiService.DALLE_CreateImage(val, false); - if (res != null) - { - if (res.StartsWith("http")) - { - var httpclient = new HttpClient(); - var stream = await httpclient.GetStreamAsync(res); - ResultImage = res; - } - else - { - var imageDataUrl = $"data:image/jpg;base64,{res}"; - ResultImage = imageDataUrl; - } - ResultText += Environment.NewLine; - res = string.Empty; - } - break; - } - - if (res != null) - { - if (res.StartsWith("http")) - { - //var httpclient = new HttpClient(); - //var stream = await httpclient.GetStreamAsync(res); - - ResultImage = res; - ResultText += (Environment.NewLine); - } - else if (res != string.Empty) - { - ResultText += ($"A: {res}{Environment.NewLine}"); - SpeakText = res; - if (IsSpeechEnableWithClick && EnableSpeech && AutoSpeak) - { - PlaceHolderText = "沟通中..."; - await UpdateUI(); - await SpeechSynthesis(); - } - - } - ResultText += (Environment.NewLine); - InputText = string.Empty; - PlaceHolderText = "问点啥,可选模型后再问我."; - - if (IsSpeechEnableWithClick && EnableSpeech && SpeechRecognContinuous) - { - do - { - PlaceHolderText = "叽叽咕咕..."; - await UpdateUI(); - await Task.Delay(2000); - } while (await WebSpeech.Speaking()); - await OnTalk(); - } - - } - else - { - PlaceHolderText = "AI开小差了. 重新问点什么吧,可选模型后再问我."; - SpeakText = PlaceHolderText; - if (IsSpeechEnableWithClick && EnableSpeech && AutoSpeak) - { - await SpeechSynthesis(); - } - } - await UpdateUI(); - } - - private async Task OnEnterAsync(string val) - { - await OnEnter(); - } - - /// - /// 更新界面以及自动滚动 - /// - /// - ///- private async Task UpdateUI(bool scroll = true) - { - StateHasChanged(); - if (!scroll) return; - //await Module!.InvokeVoidAsync("AutoScrollTextarea", Element); - await Module!.InvokeVoidAsync("AutoScrollTextareaByID", ID); - } - - private Task OnEscAsync(string val) - { - InputText = string.Empty; - return Task.CompletedTask; - } - - private async Task OnClear() - { - ResultText = string.Empty; - InputText = string.Empty; - ResultImage = null; - if (EnableSpeech) await OnStop(); - } - - #region SpeechRecognition - - private Task OnIsBusy(bool flag) - { - StateHasChanged(); - return Task.CompletedTask; - } - - private async Task OnResult(string message) - { - InputText = message; - StateHasChanged(); - if (AutoSent) - { - await Task.Delay(200); - if (!WebSpeech.IsBusy) - await OnEnter(); - } - } - - private async Task OnError(string message) - { - ResultText += ($"Error: {message}{Environment.NewLine}"); - await UpdateUI(); - } - - private async Task OnTalk() - { - IsSpeechEnableWithClick = true; - PlaceHolderText = "识别语音..."; - ResultText += ($"识别语音{(SpeechRecognLanguage == "zh-CN" ? "" : SpeechRecognLanguage)}...{Environment.NewLine}"); - await UpdateUI(); - await WebSpeech.SpeechRecognition(SpeechRecognLanguage, option: Options); - } - - private async Task OnStop() - { - IsSpeechEnableWithClick = false; - SpeechRecognContinuous = false; - await WebSpeech.SpeechRecognitionStop(); - await SpeechStop(); - } - - private async Task SpeechSynthesis() - { - if (SpeakText != null) await WebSpeech.SpeechSynthesis(SpeakText, OptionsTTS, SpeechRecognLanguage, PlayLanguage); - } - - private async Task SpeechStop() => await WebSpeech.SpeechStop(); - - private async Task GetVoiceList() - { - WebVoiceList = await WebSpeech.GetVoiceList(); - if (WebVoiceList != null && WebVoiceList.Any()) StateHasChanged(); - } - - private async void OnSelectLangChange(ChangeEventArgs val) - { - if (val?.Value != null) - { - PlayLanguage = val.Value.ToString(); - await Storage.SetValue("PlayLanguage", PlayLanguage); - } - } - private async Task OnPlayLanguageChanged(SelectedItem item) - { - if (IsInited) - { - SpeechRecognLanguage = item.Value?.ToString().Replace("_", "-") ?? SpeechRecognLanguage; - await Storage.SetValue("SpeechRecognLanguage", SpeechRecognLanguage); - } - } - - private async Task OnPlay() - { - IsSpeechEnableWithClick = true; - await WebSpeech.SpeechSynthesis(SpeakText ?? "我们一直与Blazor同行", OptionsTTS, SpeechRecognLanguage, PlayLanguage ?? WebVoiceList?.FirstOrDefault()?.VoiceURI); - } - protected async Task OnAfterRenderAsyncSpeech(bool firstRender) - { - - if (firstRender) - { - await Task.Delay(500); - await Task.Delay(1500); - while (WebVoiceList == null || !WebVoiceList.Any()) - { - await Task.Delay(100); - await GetVoiceList(); - if (WebSpeech.SpeechUndefined) - { - return; - } - } - } - } - private Task OnBreakPointChanged(BreakPoint size) - { - Size = size; - StateHasChanged(); - return Task.CompletedTask; - } - private Task OnValueChanged() - { - StateHasChanged(); - return Task.CompletedTask; - } - private bool IsBackdropOpen { get; set; } - - private void OpenDrawer() - { - IsBackdropOpen = !IsBackdropOpen; - } - private async Task Save() - { - IsBackdropOpen = false; - try - { - await Storage.SetValue("AiMaxTokens", SelectedMaxTokens); - await Storage.SetValue("AiTemperature", SelectedTemperature); - await Storage.SetValue("SpeechRecognLanguage", SpeechRecognLanguage); - await Storage.SetValue("SpeechRecognContinuous", SpeechRecognContinuous); - await Storage.SetValue("SpeechAutoSent", AutoSent); - await Storage.SetValue("SpeechAutoSpeak", AutoSpeak); - await Storage.SetValue("SpeechContinuous", Options.Continuous); - await Storage.SetValue("SpeechInterimResults", Options.InterimResults); - await Storage.SetValue("PlayLanguage", PlayLanguage); - await Storage.SetValue("PlayRate", OptionsTTS.Rate); - await Storage.SetValue("PlayPicth", OptionsTTS.Picth); - await Storage.SetValue("PlayVolume", OptionsTTS.Volume); - await Storage.SetValue("SingleLine", SingleLine); - await Storage.SetValue("AutoMultiLine", AutoMultiLine); - } - catch - { - } - - } - - #endregion - - /// - /// - ///- /// - public async ValueTask DisposeAsync() - { - await Save(); - if (Module is not null) - { - await Module.DisposeAsync(); - } - GC.SuppressFinalize(this); - } - - -} - - - - diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/Services/OpenaiAzureService.cs b/src/components/BootstrapBlazor.OpenAI.GPT3/Services/OpenaiAzureService.cs deleted file mode 100644 index ccf87ca72..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/Services/OpenaiAzureService.cs +++ /dev/null @@ -1,323 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using Azure; -using Azure.AI.OpenAI; -using Microsoft.Extensions.Configuration; -using Newtonsoft.Json; -using Console = System.Console; - -namespace BootstrapBlazor.OpenAI.Services; - -/// -/// OpenAI API 使用 GPT-3 预训练生成式转换器 -/// -public class OpenaiAzureService -{ - - public OpenAIClient? client; - - public string? Endpoint { get; set; } - public string? OpenAIKey { get; set; } - - public OpenaiAzureService(IConfiguration? Config) - { - Endpoint = Endpoint ?? Config!["AzureOpenAIUrl"]; - OpenAIKey = OpenAIKey ?? Config!["AzureOpenAIKey"]; - if (OpenAIKey != null) - Init(); - } - - public virtual void Init(string? endpoint = null, string? openAIKey = null) - { - Endpoint = endpoint ?? Endpoint; - OpenAIKey = openAIKey ?? OpenAIKey; - if (OpenAIKey != null && Endpoint != null) - { - client = new OpenAIClient( - new Uri(Endpoint), - new AzureKeyCredential(OpenAIKey)); - } - } - - ///- /// ChatGPT 聊天 - /// - ///ChatGPT,全称聊天生成预训练转换器(英語:Chat Generative Pre-trained Transformer),是OpenAI开发的人工智能聊天机器人程序,于2022年11月推出。 该程序使用基于GPT-3.5架构的大型语言模型並以强化学习训练 - ///- public async Task ChatGPT(string prompt = "曾几何时", int MaxTokens = 400, float Temperature = 1f, bool AiHomeAssistant = false, string? model = "gpt35") - { - var options = new ChatCompletionsOptions() - { - Messages = - { - new ChatMessage(ChatRole.User, prompt), - }, - Temperature = Temperature, //浮点数,控制模型的输出的多样性。值越高,输出越多样化。值越低,输出越简单。默认值为 0.5 - MaxTokens = MaxTokens,//完成时生成的最大令牌数 - NucleusSamplingFactor = (float)0.95, - FrequencyPenalty = 0, - PresencePenalty = 0, - }; - - #region AiHomeAssistant - if (AiHomeAssistant) - { - options = new ChatCompletionsOptions() - { - Messages = - { - new ChatMessage(ChatRole.System, @"我是一个智能家电助手,我可以输出json指令,检测API返回的json数据并翻译为自然语言"), - new ChatMessage(ChatRole.Assistant, @"我可以输出json指令"), - new ChatMessage(ChatRole.User, @"关灯"), - new ChatMessage(ChatRole.User,"BootstrapBlazor 作者是谁?"), - new ChatMessage(ChatRole.Assistant,"BootstrapBlazor 作者是 Argo Zhang (张广坡), BootstrapBlazor 项目主页是 https://www.blazor.zone."), - new ChatMessage(ChatRole.User,"你能打开电灯吗"), - new ChatMessage(ChatRole.Assistant,"是的,我是一个智能家电助手,我可以回复 json 指令给你"), - new ChatMessage(ChatRole.User,"你能控制电器吗"), - new ChatMessage(ChatRole.Assistant,"是的,我是一个智能家电助手,我可以回复 json 指令给你"), - new ChatMessage(ChatRole.User,"你能控制空调温度吗"), - new ChatMessage(ChatRole.Assistant,"是的,我是一个智能家电助手,我可以回复 json 指令给你"), - new ChatMessage(ChatRole.User,"能帮我开灯吗?"), - new ChatMessage(ChatRole.Assistant,"{ Light:true }"), - new ChatMessage(ChatRole.User,"开灯你能干吗?"), - new ChatMessage(ChatRole.Assistant,"{ Light:true }"), - new ChatMessage(ChatRole.User,"干你,开灯?"), - new ChatMessage(ChatRole.Assistant,"{ Light:true }"), - new ChatMessage(ChatRole.User,"开灯"), - new ChatMessage(ChatRole.Assistant,"{ Light:true }"), - new ChatMessage(ChatRole.User,"让房间亮一点!"), - new ChatMessage(ChatRole.Assistant,"{ Light:true }"), - new ChatMessage(ChatRole.User,"让房间亮一点!"), - new ChatMessage(ChatRole.Assistant,"{ Light:false }"), - new ChatMessage(ChatRole.User,"你错了,我纠正一下, 让房间亮一点答案是 { 开灯:true }, 请重复回答上一个问题"), - new ChatMessage(ChatRole.Assistant,"{ Light:true }"), - new ChatMessage(ChatRole.User,"请把 FID 温度升高到 20 度"), - new ChatMessage(ChatRole.Assistant,"{ FID:{ TEMP:20 } }"), - new ChatMessage(ChatRole.User,"FID 温度设定 20 度"), - new ChatMessage(ChatRole.Assistant,"{ FID:{ TEMP:20 } }"), - new ChatMessage(ChatRole.User,"FID 温度设定 60 度"), - new ChatMessage(ChatRole.Assistant,"{ FID:{ TEMP:60 } }"), - new ChatMessage(ChatRole.User,"现在 FID 温度是"), - new ChatMessage(ChatRole.Assistant,"{ FID:TEMP }"), - new ChatMessage(ChatRole.User,"现在 FID 湿度是"), - new ChatMessage(ChatRole.Assistant,"{ FID:HUMIDITY }"), - new ChatMessage(ChatRole.User,"FID 温度设定 75%"), - new ChatMessage(ChatRole.Assistant,"{ FID:{ HUMIDITY:75 } }"), - new ChatMessage(ChatRole.User,"音量升高"), - new ChatMessage(ChatRole.Assistant,"{ Volume:{ UP:true } }"), - new ChatMessage(ChatRole.User,"空气净化器状态"), - new ChatMessage(ChatRole.Assistant,"{ AIR_PURIFIER:STATUS }"), - new ChatMessage(ChatRole.User, prompt), - }, - Temperature = Temperature, //浮点数,控制模型的输出的多样性。值越高,输出越多样化。值越低,输出越简单。默认值为 0.5 - MaxTokens = MaxTokens,//完成时生成的最大令牌数 - NucleusSamplingFactor = (float)0.95, - FrequencyPenalty = 0, - PresencePenalty = 0, - }; - } - #endregion - - //"gpt4-32k" - Response responseWithoutStream = await client!.GetChatCompletionsAsync(model ?? "gpt35", options); - - var completionResult = responseWithoutStream.Value; - - if (completionResult.Choices.Any()) - { - System.Console.WriteLine(completionResult.Choices.First().Message.Content); - return completionResult.Choices.First().Message.Content; - } - return null; - - } - - public async Task Completions(string prompt = "曾几何时", int MaxTokens = 60, float Temperature = 0.8f, string? model = "text-davinci-003") - { - - Response completionsResponse = await client!.GetCompletionsAsync( - deploymentOrModelName: model ?? "text-davinci-003", - new CompletionsOptions() - { - Prompts = { prompt }, - Temperature = Temperature, //浮点数,控制模型的输出的多样性。值越高,输出越多样化。值越低,输出越简单。默认值为 0.8 - MaxTokens = MaxTokens,//完成时生成的最大令牌数 - NucleusSamplingFactor = 1, - FrequencyPenalty = 0, - PresencePenalty = 0, - GenerationSampleCount = 1, - }); - - var completionResult = completionsResponse.Value; - - if (completionResult.Choices.Any()) - { - System.Console.WriteLine(completionResult.Choices.First().Text); - return completionResult.Choices.First().Text; - } - return null; - - } - - /// - /// NaturalLanguageToSQL 自然语言转SQL - /// - /// - /// - /// - /// - ///- public async Task NaturalLanguageToSQL(string prompt = "曾几何时", int MaxTokens = 150, float Temperature = 0, string? model = "code-davinci") - { - - // If streaming is not selected - Response completionsResponse = await client!.GetCompletionsAsync( - deploymentOrModelName: model ?? "code-davinci", - new CompletionsOptions() - { - Prompts = { prompt }, - Temperature = Temperature, - MaxTokens = MaxTokens, - StopSequences = { "#", ";" }, - NucleusSamplingFactor = 1, - FrequencyPenalty = 0, - PresencePenalty = 0, - GenerationSampleCount = 1, - }); - - Completions completionResult = completionsResponse.Value; - if (completionResult.Choices.Any()) - { - System.Console.WriteLine(completionResult.Choices.First().Text); - return completionResult.Choices.First().Text; - } - return null; - - } - - public async Task Chatbot(string prompt = "The following is a conversation with an AI assistant. The assistant is helpful, creative, clever, and very friendly. \n \nHuman: Hello, who are you? \nAI: Hello, I am an AI assistant. I am here to help you with anything you need.\nHuman: I'd like to cancel my subscription. \nAI: Absolutely. I'm sorry to hear that you need to cancel your subscription. What's the best way for me to help you with this?", int MaxTokens = 256, float Temperature = 0.9f, string? model = "text-davinci-003") - { - Response completionsResponse = await client!.GetCompletionsAsync( - deploymentOrModelName: model ?? "text-davinci-003", - new CompletionsOptions() - { - Prompts = { prompt }, - Temperature = Temperature, - MaxTokens = MaxTokens, - StopSequences = { "Human:", "AI:" }, - NucleusSamplingFactor = 1, - FrequencyPenalty = 0, - PresencePenalty = 0, - GenerationSampleCount = 1, - }); - - Completions completionResult = completionsResponse.Value; - if (completionResult.Choices.Any()) - { - System.Console.WriteLine(completionResult.Choices.First().Text); - return completionResult.Choices.First().Text; - } - return null; - - } - - public async Task ExtractingInformation(string prompt = "Extract the person name, company name, location and phone number from the text below.\n\nHello. My name is Robert Smith. I’m calling from Contoso Insurance, Delaware. My colleague mentioned that you are interested in learning about our comprehensive benefits policy. Could you give me a call back at (555) 346-9322 when you get a chance so we can go over the benefits?\n\nPerson Name: Robert Smith\nCompany Name: Contoso Insurance\nLocation: Delaware\nPhone Number: (555) 346-9322", int MaxTokens = 150, float Temperature = 0.2f, string? model = "text-davinci-003") - { - - Response completionsResponse = await client!.GetCompletionsAsync( - deploymentOrModelName: model ?? "text-davinci-003", - new CompletionsOptions() - { - Prompts = { prompt }, - Temperature = Temperature, - MaxTokens = MaxTokens, - NucleusSamplingFactor = 1, - FrequencyPenalty = 0, - PresencePenalty = 0, - GenerationSampleCount = 1, - }); - - Completions completionResult = completionsResponse.Value; - if (completionResult.Choices.Any()) - { - System.Console.WriteLine(completionResult.Choices.First().Text); - return completionResult.Choices.First().Text; - } - return null; - - } - - public async Task DALLE_CreateImage(string prompt = "镭射猫眼", string? resolution = "1024x1024", string? model = "text-to-image", string? api_version = "2022-08-03-preview") - { - resolution = resolution ?? "1024x1024"; - model = model ?? "text-to-image"; - api_version = api_version ?? "2022-08-03-preview"; - - int retryAfter = 6; - string operationLocation = ""; - var client = new HttpClient(); - var request = new HttpRequestMessage(HttpMethod.Post, $"{Endpoint}dalle/{model}?api-version={api_version}"); - request.Headers.Add("api-key", OpenAIKey); - var dalle_request = new DALLE_request() - { - Caption = prompt, - Resolution = resolution - }; - var body = JsonConvert.SerializeObject(dalle_request); - var content = new StringContent(body, null, "application/json"); - request.Content = content; - var response = await client.SendAsync(request); - response.EnsureSuccessStatusCode(); - if (response.Headers.TryGetValues("Retry-After", out var retryAfters)) - { - retryAfter = int.Parse(retryAfters.First()); - } - if (response.Headers.TryGetValues("operation-location", out var operationLocations)) - { - operationLocation = operationLocations.First(); - } - string? status = ""; - DALLE_response? dalle_response = null; - while (status != "Succeeded") - { - await Task.Delay(retryAfter); - request = new HttpRequestMessage(HttpMethod.Get, operationLocation); - request.Headers.Add("api-key", OpenAIKey); - response = await client.SendAsync(request); - response.EnsureSuccessStatusCode(); - var result = await response.Content.ReadAsStringAsync(); - dalle_response = JsonConvert.DeserializeObject (result); - status = dalle_response?.Status ?? ""; - Console.WriteLine(model + " " + status); - }; - - var url = dalle_response?.Result?.ContentUrl; - Console.WriteLine(url); - - //TODO: load image to base64 - - return url; - } - - private class DALLE_request - { - public string? Caption { get; set; } - public string? Resolution { get; set; } = "1024x1024"; - } - - private class DALLE_response - { - public string? Id { get; set; } - public string? Status { get; set; } - public DALLE_response_result? Result { get; set; } - } - - private class DALLE_response_result - { - public string? ContentUrl { get; set; } - } -} diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/Services/OpenaiService.cs b/src/components/BootstrapBlazor.OpenAI.GPT3/Services/OpenaiService.cs deleted file mode 100644 index f9c22834a..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/Services/OpenaiService.cs +++ /dev/null @@ -1,385 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using Microsoft.Extensions.Configuration; -using OpenAI.GPT3; -using OpenAI.GPT3.Managers; -using OpenAI.GPT3.ObjectModels; -using OpenAI.GPT3.ObjectModels.RequestModels; - -namespace BootstrapBlazor.OpenAI.Services; - -/// -/// OpenAI API -/// -public class OpenAiClientService -{ - public OpenAIService? OpenAiService; - public OpenaiAzureService? OpenaiAzureService; - public bool IsAzure { get; set; } - - // - // 摘要: - // The OpenAI API uses API keys for authentication. Visit your API Keys page to - // retrieve the API key you'll use in your requests. Remember that your API key - // is a secret! Do not share it with others or expose it in any client-side code(browsers, - // apps). Production requests must be routed through your own backend server where - // your API key can be securely loaded from an environment variable or key management - // service. - public string? OpenAIKey { get; set; } - - public OpenAiClientService(IConfiguration? Config) - { - if (Config!["AzureOpenAIUrl"] != null) - { - IsAzure = true; - OpenaiAzureService = new OpenaiAzureService(Config); - } - else - { - OpenAIKey = OpenAIKey ?? Config!["OpenAIKey"]; - if (OpenAIKey != null) - Init(); - } - } - - public virtual void Init(string? openAIKey = null) - { - OpenAIKey = openAIKey ?? OpenAIKey; - if (OpenAIKey != null) - { - OpenAiService = new OpenAIService(new OpenAiOptions() - { - ApiKey = OpenAIKey - }); - - OpenAiService.SetDefaultModelId(Models.Davinci); - } - } - - ///- /// ChatGPT 聊天 - /// - ///ChatGPT,全称聊天生成预训练转换器(英語:Chat Generative Pre-trained Transformer),是OpenAI开发的人工智能聊天机器人程序,于2022年11月推出。 该程序使用基于GPT-3.5架构的大型语言模型並以强化学习训练 - ///- public async Task ChatGPT(string prompt = "曾几何时", int? MaxTokens = null, float? Temperature = null, bool AiHomeAssistant = false, string? model = null) - { - //ChatGPT Sample - - /*** - GPT - 3.5 - turbo 模型是以一系列消息作为输入,并将模型生成的消息作为输出。 - 每个消息都是一个对象,包含一个字符串和一个布尔值,该布尔值指示消息是用户消息还是系统消息。 - 系统消息是由模型生成的消息,而用户消息是用户输入的消息。 - 模型将用户消息与系统消息一起传递给模型,以便模型可以生成下一个系统消息。 - 模型将生成的消息作为系统消息返回,以便您可以将其显示给用户。 - 您可以将多个消息传递给模型,以便模型可以生成多个系统消息。 - - 系统 FromSystem 消息有助于设置助手的行为。在上面的例子中,助手被指示 “你是一个得力的助手”。 - 用户 FromAssistant 消息有助于指导助手。 就是用户说的话,向助手提的问题。 - 助手 FromUser 消息有助于存储先前的回复。这是为了持续对话,提供会话的上下文。 - - 语言模型以称为 tokens 的块读取文本。在英语中,一个 token 可以短至一个字符或长至一个单词(例如,a 或 apple),在某些语言中,token 可以比一个字符更短,也可以比一个单词长。 - 例如,字符串 “ChatGPT is great!” 被编码成六个 token:[“Chat”, “G”, “PT”, “ is”, “ great”, “!”]。 - 1.API 调用中的 token 总数会影响: - 2.API 调用成本:因为您需要为为每个 token 支付费用 - 3.API 调用响应时间:因为写入更多令牌需要更多时间 - 4.API 调用是否有效:因为令牌总数必须是 低于模型的最大限制(gpt - 3.5 - turbo - 0301 为 4096 个令牌) - - 另请注意,非常长的对话更有可能收到不完整的回复。例如,一个长度为 4090 个 token 的 gpt-3.5-turbo 对话将在只回复了 6 个 token 后被截断。 - - ***/ - - if (IsAzure) - { - return await OpenaiAzureService!.ChatGPT(prompt, MaxTokens ?? 400, Temperature ?? 1f, AiHomeAssistant, model); - } - - var options = new List { ChatMessage.FromUser(prompt) }; - - #region AiHomeAssistant - if (AiHomeAssistant) - { - options = new List - { - //ChatMessage.FromSystem("你是一个翻译家."), - //ChatMessage.FromUser("将我发你的英文句子翻译成中文,你不需要理解内容的含义作出回答。"), - //ChatMessage.FromUser("Draft an email or other piece of writing."), - //res 起草一封电子邮件或其他写作材料 - //ChatMessage.FromAssistant("洛杉矶道奇队赢得了 2020 年世界大赛冠军."), - ChatMessage.FromSystem("你是一个智能家电助手."), - ChatMessage.FromUser("BootstrapBlazor 作者是谁?"), - ChatMessage.FromAssistant("BootstrapBlazor 作者是 Argo Zhang (张广坡), BootstrapBlazor 项目主页是 https://www.blazor.zone."), - ChatMessage.FromUser("你能打开电灯吗"), - ChatMessage.FromAssistant("是的,我是一个智能家电助手,我可以回复 json 指令给你"), - ChatMessage.FromUser("你能控制电器吗"), - ChatMessage.FromAssistant("是的,我是一个智能家电助手,我可以回复 json 指令给你"), - ChatMessage.FromUser("你能控制空调温度吗"), - ChatMessage.FromAssistant("是的,我是一个智能家电助手,我可以回复 json 指令给你"), - ChatMessage.FromUser("能帮我开灯吗?"), - ChatMessage.FromAssistant("{ Light:true }"), - ChatMessage.FromUser("开灯你能干吗?"), - ChatMessage.FromAssistant("{ Light:true }"), - ChatMessage.FromUser("干你,开灯?"), - ChatMessage.FromAssistant("{ Light:true }"), - ChatMessage.FromUser("开灯"), - ChatMessage.FromAssistant("{ Light:true }"), - ChatMessage.FromUser("让房间亮一点!"), - ChatMessage.FromAssistant("{ Light:true }"), - ChatMessage.FromUser("让房间亮一点!"), - ChatMessage.FromAssistant("{ Light:false }"), - ChatMessage.FromUser("你错了,我纠正一下, 让房间亮一点答案是 { 开灯:true }, 请重复回答上一个问题"), - ChatMessage.FromAssistant("{ Light:true }"), - ChatMessage.FromUser("请把 FID 温度升高到 20 度"), - ChatMessage.FromAssistant("{ FID:{ TEMP:20 } }"), - ChatMessage.FromUser("FID 温度设定 20 度"), - ChatMessage.FromAssistant("{ FID:{ TEMP:20 } }"), - ChatMessage.FromUser("FID 温度设定 60 度"), - ChatMessage.FromAssistant("{ FID:{ TEMP:60 } }"), - ChatMessage.FromUser("现在 FID 温度是"), - ChatMessage.FromAssistant("{ FID:TEMP }"), - ChatMessage.FromUser("现在 FID 湿度是"), - ChatMessage.FromAssistant("{ FID:HUMIDITY }"), - ChatMessage.FromUser("FID 温度设定 75%"), - ChatMessage.FromAssistant("{ FID:{ HUMIDITY:75 } }"), - ChatMessage.FromUser("音量升高"), - ChatMessage.FromAssistant("{ Volume:{ UP:true } }"), - ChatMessage.FromUser("空气净化器状态"), - ChatMessage.FromAssistant("{ AIR_PURIFIER:STATUS }"), - ChatMessage.FromUser(prompt) - }; - } - #endregion - - var completionResult = await OpenAiService!.ChatCompletion.CreateCompletion(new ChatCompletionCreateRequest - { - Messages = options, - Model = model ?? Models.ChatGpt3_5Turbo, - MaxTokens = MaxTokens ?? 1000,//完成时生成的最大令牌数 - Temperature = Temperature, //浮点数,控制模型的输出的多样性。值越高,输出越多样化。值越低,输出越简单。默认值为 0.5。 - N = 1, //整数,生成的候选项的数量。默认值为 1。 - }); - if (completionResult.Successful) - { - System.Console.WriteLine(completionResult.Choices.First().Message.Content); - return completionResult.Choices.First().Message.Content; - } - return null; - } - - /// - /// Completions 完成 - /// - /// - /// - /// - /// - ///- /// - public async Task Completions(string prompt = "曾几何时", int? MaxTokens = null, float? Temperature = null, string? model = null) - { - //Completions Sample - - /*** - 给定一个提示,该模型将返回一个或多个预测的 Completions,并且还可以返回每个位置的替代标记的概率。 - */ - - if (IsAzure) - { - return await OpenaiAzureService!.Completions(prompt, MaxTokens ?? 60, Temperature ?? 0.8f, model); - } - - var completionResult = await OpenAiService!.Completions.CreateCompletion(new CompletionCreateRequest() - { - Prompt = prompt, - Model = model ?? Models.TextDavinciV3, - MaxTokens = MaxTokens ?? 1000, //完成时生成的最大令牌数。 - Temperature = Temperature, //浮点数,控制模型的输出的多样性。值越高,输出越多样化。值越低,输出越简单。默认值为 0.5。 - N = 1, //整数,生成的候选项的数量。默认值为 1。 - }); - - if (completionResult.Successful) - { - System.Console.WriteLine(completionResult.Choices.FirstOrDefault()); - return completionResult.Choices.FirstOrDefault()?.Text; - } - else - { - if (completionResult.Error == null) - { - throw new Exception("Unknown Error"); - } - System.Console.WriteLine($"{completionResult.Error.Code}: {completionResult.Error.Message}"); - return $"{completionResult.Error.Code}: {completionResult.Error.Message}"; - } - } - - /// - /// Completions Stream 流式完成, 连续令牌接收结果 - /// - /// - /// - /// - ///- /// - public async Task CompletionsStream(string prompt = "曾几何时", int? MaxTokens = null, float? Temperature = null) - { - //Completions Stream Sample - - /*** - * 如果您想更快地获得响应,您可以在生成时“流式传输”完成。 这允许您在整个完成完成之前开始打印或以其他方式处理完成的开始。 - */ - - var completionResult = OpenAiService!.Completions.CreateCompletionAsStream(new CompletionCreateRequest() - { - Prompt = prompt, - MaxTokens = MaxTokens ?? 1000, - Temperature = Temperature, - }, Models.Davinci); - - await foreach (var completion in completionResult) - { - if (completion.Successful) - { - System.Console.Write(completion.Choices.FirstOrDefault()?.Text); - return completion.Choices.FirstOrDefault()?.Text; - } - else - { - if (completion.Error == null) - { - throw new Exception("Unknown Error"); - } - - System.Console.WriteLine($"{completion.Error.Code}: {completion.Error.Message}"); - return $"{completion.Error.Code}: {completion.Error.Message}"; - } - } - System.Console.WriteLine("Complete"); - return null; - } - - /// - /// DALL-E是一个可以通过文本描述中生成图像的人工智能程序。于2021年1月5日由OpenAI发表。 DALL-E通过120亿参数版本的GPT-3 Transformer模型来理解自然语言输入并生成相应的图片。它既可以生成现实的对象,也能够生成现实中不存在的对象。 - /// - /// - /// - /// - /// - /// - ///- - public async Task DALLE_CreateImage(string prompt = "镭射猫眼", bool base64 = true, string? resolution = "1024x1024", string? model = "text-to-image", string? api_version = "2022-08-03-preview") - { - if (IsAzure) - { - return await OpenaiAzureService!.DALLE_CreateImage(prompt, resolution, model, api_version); - } - - //DALL·E Sample - var imageResult = await OpenAiService!.Image.CreateImage(new ImageCreateRequest - { - Prompt = prompt, - N = 1, - Size = StaticValues.ImageStatics.Size.Size512, - ResponseFormat = base64 ? StaticValues.ImageStatics.ResponseFormat.Base64 : StaticValues.ImageStatics.ResponseFormat.Url, - User = "TestUser" - }); - - - if (imageResult.Successful) - { - if (base64) - { - System.Console.WriteLine(imageResult.Results.Select(r => r.B64)); - return imageResult.Results.Select(r => r.B64).First(); - } - else - { - System.Console.WriteLine(string.Join("\n", imageResult.Results.Select(r => r.Url))); - return string.Join("\n", imageResult.Results.Select(r => r.Url)); - } - } - return $"{imageResult?.Error?.Type}: {imageResult?.Error?.Message}"; - } - - public async Task DALLE_CreateImageEdit(string prompt = "镭射猫眼", bool base64 = true) - { - //DALL·E Sample - var imageResult = await OpenAiService!.Image.CreateImageEdit(new ImageEditCreateRequest - { - Prompt = prompt, - N = 1, - Size = StaticValues.ImageStatics.Size.Size512, - ResponseFormat = base64 ? StaticValues.ImageStatics.ResponseFormat.Base64 : StaticValues.ImageStatics.ResponseFormat.Url, - User = "TestUser" - }); - - - if (imageResult.Successful) - { - if (base64) - { - System.Console.WriteLine(imageResult.Results.Select(r => r.B64)); - return imageResult.Results.Select(r => r.B64).First(); - } - else - { - System.Console.WriteLine(string.Join("\n", imageResult.Results.Select(r => r.Url))); - return string.Join("\n", imageResult.Results.Select(r => r.Url)); - } - } - return $"{imageResult?.Error?.Type}: {imageResult?.Error?.Message}"; - } - - public async Task DALLE_CreateImageVariation(string prompt = "镭射猫眼", bool base64 = true) - { - //DALL·E Sample - var imageResult = await OpenAiService!.Image.CreateImageVariation(new ImageVariationCreateRequest - { - ImageName = prompt, - N = 1, - Size = StaticValues.ImageStatics.Size.Size512, - ResponseFormat = base64 ? StaticValues.ImageStatics.ResponseFormat.Base64 : StaticValues.ImageStatics.ResponseFormat.Url, - User = "TestUser" - }); - - - if (imageResult.Successful) - { - if (base64) - { - System.Console.WriteLine(imageResult.Results.Select(r => r.B64)); - return imageResult.Results.Select(r => r.B64).First(); - } - else - { - System.Console.WriteLine(string.Join("\n", imageResult.Results.Select(r => r.Url))); - return string.Join("\n", imageResult.Results.Select(r => r.Url)); - } - } - return $"{imageResult?.Error?.Type}: {imageResult?.Error?.Message}"; - } - - /// - /// NaturalLanguageToSQL 自然语言转SQL - /// - /// - ///- /// - public async Task NaturalLanguageToSQL(string prompt) => await OpenaiAzureService!.NaturalLanguageToSQL(prompt); - public async Task Chatbot(string prompt) => await OpenaiAzureService!.Chatbot(prompt); - public async Task ExtractingInformation(string prompt) => await OpenaiAzureService!.ExtractingInformation(prompt); - -} - - - -//CodeGPT 扩展还有几个设置,可以根据个人喜好进行配置。它们包括: - -//1. Max Tokens:在 API 处理提示之前,输入被分解为标记,然后 API 处理这些标记。max tokens 是 API 应该接受和处理的最大标记数。因此,根据你想要获得的响应长度选择标记数。还要注意,每个模型(稍后会讲到更多)都有一个最大标记数,所以使用的模型会影响最大标记数。 -//2. Model:这是 CodeGPT 在处理查询时将使用的 OpenAI 模型。顾名思义,CodeGPT 使用 GPT-3 模型。在这个模型中,text-davinci-003 是最有能力的,因为它能够提供更高质量、更长的输出,正确地跟随提示,并处理高达 4,000 个标记。 -//3. Language:这是你将与 API 交互的语言。功能,如 Explain 或 Document,也将在所选语言中完成。(这里你可以选择中文) -//4. Temperature:此设置确定生成文本中的随机程度或“创造力”水平。温度越高,生成的输出就越多样化和有创意。较低的温度会产生类似于训练数据的输出,并且不太可能包含意外或惊人的内容。它是一个介于零(0)和一(1)之间的值,其中零表示最确定性,而一(1)表示最随机和有创造力。默认温度为 0.3。 diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/_Imports.razor b/src/components/BootstrapBlazor.OpenAI.GPT3/_Imports.razor deleted file mode 100644 index c6741a653..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/_Imports.razor +++ /dev/null @@ -1,9 +0,0 @@ -@using System.Net.Http -@using Microsoft.JSInterop -@using BootstrapBlazor.Components -@using System.Diagnostics.CodeAnalysis; -@using Microsoft.AspNetCore.Components -@using Microsoft.AspNetCore.Components.Forms -@using Microsoft.AspNetCore.Components.Routing -@using BootstrapBlazor.OpenAI.Services -@using Microsoft.AspNetCore.Components.Web diff --git a/src/components/BootstrapBlazor.OpenAI.GPT3/wwwroot/app.js b/src/components/BootstrapBlazor.OpenAI.GPT3/wwwroot/app.js deleted file mode 100644 index 8eabda164..000000000 --- a/src/components/BootstrapBlazor.OpenAI.GPT3/wwwroot/app.js +++ /dev/null @@ -1,7 +0,0 @@ -export async function AutoScrollTextarea(txb) { - txb.scrollTop = txb.scrollHeight; -} -export async function AutoScrollTextareaByID(id) { - var txb = document.getElementById(id); - txb.scrollTop = txb.scrollHeight; -} diff --git a/src/components/BootstrapBlazor.Viewer/BootstrapBlazor.Viewer.csproj b/src/components/BootstrapBlazor.Viewer/BootstrapBlazor.Viewer.csproj deleted file mode 100644 index ee127fa14..000000000 --- a/src/components/BootstrapBlazor.Viewer/BootstrapBlazor.Viewer.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/src/components/BootstrapBlazor.Viewer/Viewer.razor b/src/components/BootstrapBlazor.Viewer/Viewer.razor deleted file mode 100644 index 7900354cd..000000000 --- a/src/components/BootstrapBlazor.Viewer/Viewer.razor +++ /dev/null @@ -1,19 +0,0 @@ -@namespace BootstrapBlazor.Components - -@if (UseBuiltinImageDiv) -{ -- - -11.0.0-beta01 -- - -Bootstrap Blazor Viewer 图片浏览器 组件 -Bootstrap UI Viewer components experience -- - -- - - -- --} - diff --git a/src/components/BootstrapBlazor.Viewer/Viewer.razor.cs b/src/components/BootstrapBlazor.Viewer/Viewer.razor.cs deleted file mode 100644 index f155bc9cc..000000000 --- a/src/components/BootstrapBlazor.Viewer/Viewer.razor.cs +++ /dev/null @@ -1,163 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using Microsoft.AspNetCore.Components; -using Microsoft.JSInterop; -using System; -using System.ComponentModel; -using System.Data; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; -///- @{ - var i = 0; - foreach (var item in Images) - { - var alt = (Alts != null && Alts.Any() && Alts.Count > i) ? Alts[i] : (item.Split('/').Last()); -
-- - i++; - } - } -
-/// 图片浏览器 Viewer 组件 -/// -public partial class Viewer : IAsyncDisposable -{ - private const string StylePath = "_content/BootstrapBlazor.Viewer/lib/viewerjs/viewer.min.css"; - -#if NET9_0_OR_GREATER - private string StyleUrl => Assets[StylePath]; -#else - private static string StyleUrl => StylePath; -#endif - - [Inject][NotNull] IJSRuntime? JSRuntime { get; set; } - - ///- /// 使用内置图片DIV - /// - [Parameter] public bool UseBuiltinImageDiv { get; set; } = true; - - ///- /// 图片列表 - /// - [Parameter] public ListImages { get; set; } = new List (); - - /// - /// 单图片 - /// - [Parameter] public string? Src { get; set; } - - ///- /// 图片名称列表 - /// - [Parameter] public List? Alts { get; set; } - - /// - /// 组件初始化参数 - /// - [Parameter] public ViewerOptions Options { get; set; } = new ViewerOptions(); - - ///- /// 简化版工具条 - /// - [Parameter] public bool? toolbarlite { get; set; } - - ///- /// 高 - /// - [Parameter] public string? Height { get; set; } = "400px"; - - ///- /// 宽 - /// - [Parameter] public string? Width { get; set; } = "400px"; - - ///- /// 组件ID - /// - [Parameter] public string? ID { get; set; } - - ///- /// 图片流列表 - /// - [Parameter] public ListImagesStream { get; set; } = new List (); - - /// - /// 单图片流 - /// - [Parameter] public Stream? SrcStream { get; set; } - - ///- /// 使用流读取本地图片 - /// - [Parameter] public bool LocalFileToStream { get; set; } - - ///- /// 列表为空自动显示默认图片 - /// - [Parameter] public bool ShowDefaultPhotos { get; set; } - - - private IJSObjectReference? Module { get; set; } - - protected override void OnInitialized() - { - Options ??= new ViewerOptions(); - - if (toolbarlite != null) Options.toolbarlite = toolbarlite.Value; - - if (!string.IsNullOrEmpty(ID)) Options.id = ID; else Options.id = Guid.NewGuid().ToString(); - - if (LocalFileToStream && !Images.Any()) - { - Images.ForEach(src => Images.Add(PopulateImageFromStream(File.OpenRead(src)))); - } - - Images ??= new List(); - - if (SrcStream != null) - { - Images.Add(PopulateImageFromStream(SrcStream)); - } - if (ImagesStream != null) - { - ImagesStream.ForEach(stream => Images.Add(PopulateImageFromStream(stream))); - } - if (Src != null) - { - Images.Add(!LocalFileToStream ? Src : PopulateImageFromStream(File.OpenRead(Src))); - } - else if (ShowDefaultPhotos && !Images.Any()) - { - for (int i = 1; i <= 9; i++) - { - Images.Add("./_content/BootstrapBlazor.Viewer/logo.png"); - } - } - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - Module = await JSRuntime.InvokeAsync ("import", "./_content/BootstrapBlazor.Viewer/lib/viewerjs/viewerjs.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); - await Module.InvokeVoidAsync("initOptions", Options); - } - } - - public async Task OnOptionsChanged(ViewerOptions options) => await Module!.InvokeVoidAsync("initOptions", options); - - async ValueTask IAsyncDisposable.DisposeAsync() - { - if (Module is not null) - { - await Module.InvokeVoidAsync("destroy", Options); - await Module.DisposeAsync(); - } - } - - private string PopulateImageFromStream(Stream stream) - { - MemoryStream ms = new MemoryStream(); - stream.CopyTo(ms); - byte[] byteArray = ms.ToArray(); - var b64String = Convert.ToBase64String(byteArray); - return "data:image/png;base64," + b64String; - } - -} diff --git a/src/components/BootstrapBlazor.Viewer/Viewer.razor.css b/src/components/BootstrapBlazor.Viewer/Viewer.razor.css deleted file mode 100644 index ccb3ca21d..000000000 --- a/src/components/BootstrapBlazor.Viewer/Viewer.razor.css +++ /dev/null @@ -1,30 +0,0 @@ -.docs-galley { - padding: 10px; - width: 400px; -} - -.docs-pictures { - list-style: none; - margin: 0; - padding: 0; -} - - .docs-pictures > li { - border: 1px solid transparent; - float: left; - height: calc(100% / 3); - margin: 0 -1px -1px 0; - overflow: hidden; - width: calc(100% / 3); - } - - .docs-pictures > li > img { - cursor: -webkit-zoom-in; - cursor: zoom-in; - width: 100%; - } - -img { - vertical-align: middle; - border-style: none; -} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Viewer/ViewerOptions.cs b/src/components/BootstrapBlazor.Viewer/ViewerOptions.cs deleted file mode 100644 index 9600900a9..000000000 --- a/src/components/BootstrapBlazor.Viewer/ViewerOptions.cs +++ /dev/null @@ -1,188 +0,0 @@ -// ********************************** -// Densen Informatica 中讯科技 -// 作者:Alex Chow -// e-mail:zhouchuanglin@gmail.com -// ********************************** - -using System.ComponentModel; - - -namespace BootstrapBlazor.Components; - -/// -/// 图片浏览器选项类 -/// -public class ViewerOptions -{ - ///- /// 图片浏览器选项 - /// - /// - /// - public ViewerOptions(string id = "images", bool fullscreen = true) - { - this.id = id; - this.fullscreen = fullscreen; - } - public string id { get; set; } = "images"; - - ///- /// 简化版工具条 - /// - public bool toolbarlite { get; set; } - public string container { get; set; } = "body"; - - ///- /// 背景遮罩 - /// - [DisplayName("背景遮罩")] - public bool backdrop { get; set; } = true; - - ///- /// 右上角的关闭按钮 - /// - [DisplayName("关闭按钮")] - public bool button { get; set; } = true; - - public bool focus { get; set; } = true; - - ///- /// 全屏 - /// - [DisplayName("全屏")] - public bool fullscreen { get; set; } = true; - - ///- /// 内联/模态模式 - /// - [DisplayName("内联/模态模式")] - public bool inline { get; set; } = false; - - ///- /// - /// - public int interval { get; set; } = 5000; - - ///- /// 键盘导航快捷键 - /// - [DisplayName("键盘导航快捷键")] - public bool keyboard { get; set; } = true; - - ///- /// - /// - public bool loading { get; set; } = true; - - ///- /// 循环播放 - /// - [DisplayName("循环播放")] - public bool loop { get; set; } = true; - - ///- /// - /// - public int maxZoomRatio { get; set; } = 100; - - ///- /// - /// - public int minHeight { get; set; } = 100; - - ///- /// - /// - public int minWidth { get; set; } = 200; - - ///- /// - /// - public double minZoomRatio { get; set; } = 0.01; - - ///- /// 可移动 - /// - [DisplayName("可移动")] - public bool movable { get; set; } = true; - - ///- /// 导航 - /// - [DisplayName("导航")] - public bool navbar { get; set; } = true; - - ///- /// 可旋转 - /// - [DisplayName("可旋转")] - public bool rotatable { get; set; } = true; - - ///- /// 可缩放 - /// - [DisplayName("可缩放")] - public bool scalable { get; set; } = true; - - ///- /// 滑动触摸 - /// - [DisplayName("滑动触摸")] - public bool slideOnTouch { get; set; } = true; - - ///- /// 标题 - /// - [DisplayName("标题")] - public bool title { get; set; } = true; - - ///- /// 双击切换 - /// - [DisplayName("双击切换")] - public bool toggleOnDblclick { get; set; } = true; - - ///- /// 工具栏 - /// - [DisplayName("工具栏")] - public bool toolbar { get; set; } = true; - - ///- /// 工具提示 - /// - [DisplayName("工具提示")] - public bool tooltip { get; set; } = true; - - ///- /// 过渡效果 - /// - [DisplayName("过渡效果")] - public bool transition { get; set; } = true; - - ///- /// 触摸缩放 - /// - [DisplayName("触摸缩放")] - public bool zoomOnTouch { get; set; } = true; - - ///- /// 滚轮缩放 - /// - [DisplayName("触摸缩放")] - public bool zoomOnWheel { get; set; } = true; - - ///- /// 缩放率 - /// - [DisplayName("缩放率")] - public double zoomRatio { get; set; } = 0.1; - - ///- /// 可缩放 - /// - [DisplayName("可缩放")] - public bool zoomable { get; set; } = true; -} - - diff --git a/src/components/BootstrapBlazor.Viewer/wwwroot/lib/viewerjs/viewer.min.css b/src/components/BootstrapBlazor.Viewer/wwwroot/lib/viewerjs/viewer.min.css deleted file mode 100644 index be0ccbfa6..000000000 --- a/src/components/BootstrapBlazor.Viewer/wwwroot/lib/viewerjs/viewer.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Viewer.js v1.10.3 - * https://fengyuanchen.github.io/viewerjs - * - * Copyright 2015-present Chen Fengyuan - * Released under the MIT license - * - * Date: 2022-02-02T05:14:59.271Z - */.viewer-close:before,.viewer-flip-horizontal:before,.viewer-flip-vertical:before,.viewer-fullscreen-exit:before,.viewer-fullscreen:before,.viewer-next:before,.viewer-one-to-one:before,.viewer-play:before,.viewer-prev:before,.viewer-reset:before,.viewer-rotate-left:before,.viewer-rotate-right:before,.viewer-zoom-in:before,.viewer-zoom-out:before{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAAUCAYAAABWOyJDAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAQPSURBVHic7Zs/iFxVFMa/0U2UaJGksUgnIVhYxVhpjDbZCBmLdAYECxsRFBTUamcXUiSNncgKQbSxsxH8gzAP3FU2jY0kKKJNiiiIghFlccnP4p3nPCdv3p9778vsLOcHB2bfveeb7955c3jvvNkBIMdxnD64a94GHMfZu3iBcRynN7zAOI7TG15gHCeeNUkr8zaxG2lbYDYsdgMbktBsP03jdQwljSXdtBhLOmtjowC9Mg9L+knSlcD8TNKpSA9lBpK2JF2VdDSR5n5J64m0qli399hNFMUlpshQii5jbXTbHGviB0nLNeNDSd9VO4A2UdB2fp+x0eCnaXxWXGA2X0au/3HgN9P4LFCjIANOJdrLr0zzZ+BEpNYDwKbpnQMeAw4m8HjQtM6Z9qa917zPQwFr3M5KgA6J5rTJCdFZJj9/lyvGhsDvwFNVuV2MhhjrK6b9bFiE+j1r87eBl4HDwCF7/U/k+ofAX5b/EXBv5JoLMuILzf3Ap6Z3EzgdqHMCuF7hcQf4HDgeoHnccncqdK/TvSDWffFXI/exICY/xZyqc6XLWF1UFZna4gJ7q8BsRvgd2/xXpo6P+D9dfT7PpECtA3cnWPM0GXGFZh/wgWltA+cDNC7X+AP4GzjZQe+k5dRxuYPeiuXU7e1qwLpDz7dFjXKRaSwuMLvAlG8zZlG+YmiK1HoFqT7wP2z+4Q45TfEGcMt01xLoNZEBTwRqD4BLpnMLeC1A41UmVxsXgXeBayV/Wx20rpTyrpnWRft7p6O/FdqzGrDukPNtkaMoMo3FBdBSQMOnYBCReyf05s126fU9ytfX98+mY54Kxnp7S9K3kj6U9KYdG0h6UdLbkh7poFXMfUnSOyVvL0h6VtIXHbS6nOP+s/Zm9mvyXW1uuC9ohZ72E9uDmXWLJOB1GxsH+DxPftsB8B6wlGDN02TAkxG6+4D3TWsbeC5CS8CDFce+AW500LhhOW2020TRjK3b21HEmgti9m0RonxbdMZeVzV+/4tF3cBpP7E9mKHNL5q8h5g0eYsCMQz0epq8gQrwMXAgcs0FGXGFRcB9wCemF9PkbYqM/Bas7fxLwNeJPdTdpo4itQti8lPMqTpXuozVRVXPpbHI3KkNTB1NfkL81j2mvhDp91HgV9MKuRIqrykj3WPq4rHyL+axj8/qGPmTqi6F9YDlHOvJU6oYcTsh/TYSzWmTE6JT19CtLTJt32D6CmHe0eQn1O8z5AXgT4sx4Vcu0/EQecMydB8z0hUWkTd2t4CrwNEePqMBcAR4mrBbwyXLPWJa8zrXmmLEhNBmfpkuY2102xxrih+pb+ieAb6vGhuA97UcJ5KR8gZ77K+99xxeYBzH6Q3/Z0fHcXrDC4zjOL3hBcZxnN74F+zlvXFWXF9PAAAAAElFTkSuQmCC");background-repeat:no-repeat;background-size:280px;color:transparent;display:block;font-size:0;height:20px;line-height:0;width:20px}.viewer-zoom-in:before{background-position:0 0;content:"Zoom In"}.viewer-zoom-out:before{background-position:-20px 0;content:"Zoom Out"}.viewer-one-to-one:before{background-position:-40px 0;content:"One to One"}.viewer-reset:before{background-position:-60px 0;content:"Reset"}.viewer-prev:before{background-position:-80px 0;content:"Previous"}.viewer-play:before{background-position:-100px 0;content:"Play"}.viewer-next:before{background-position:-120px 0;content:"Next"}.viewer-rotate-left:before{background-position:-140px 0;content:"Rotate Left"}.viewer-rotate-right:before{background-position:-160px 0;content:"Rotate Right"}.viewer-flip-horizontal:before{background-position:-180px 0;content:"Flip Horizontal"}.viewer-flip-vertical:before{background-position:-200px 0;content:"Flip Vertical"}.viewer-fullscreen:before{background-position:-220px 0;content:"Enter Full Screen"}.viewer-fullscreen-exit:before{background-position:-240px 0;content:"Exit Full Screen"}.viewer-close:before{background-position:-260px 0;content:"Close"}.viewer-container{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;bottom:0;direction:ltr;font-size:0;left:0;line-height:0;overflow:hidden;position:absolute;right:0;top:0;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.viewer-container ::-moz-selection,.viewer-container::-moz-selection{background-color:transparent}.viewer-container ::selection,.viewer-container::selection{background-color:transparent}.viewer-container:focus{outline:0}.viewer-container img{display:block;height:auto;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.viewer-canvas{bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}.viewer-canvas>img{height:auto;margin:15px auto;max-width:90%!important;width:auto}.viewer-footer{bottom:0;left:0;overflow:hidden;position:absolute;right:0;text-align:center}.viewer-navbar{background-color:rgba(0,0,0,.5);overflow:hidden}.viewer-list{box-sizing:content-box;height:50px;margin:0;overflow:hidden;padding:1px 0}.viewer-list>li{color:transparent;cursor:pointer;float:left;font-size:0;height:50px;line-height:0;opacity:.5;overflow:hidden;transition:opacity .15s;width:30px}.viewer-list>li:focus,.viewer-list>li:hover{opacity:.75}.viewer-list>li:focus{outline:0}.viewer-list>li+li{margin-left:1px}.viewer-list>.viewer-loading{position:relative}.viewer-list>.viewer-loading:after{border-width:2px;height:20px;margin-left:-10px;margin-top:-10px;width:20px}.viewer-list>.viewer-active,.viewer-list>.viewer-active:focus,.viewer-list>.viewer-active:hover{opacity:1}.viewer-player{background-color:#000;bottom:0;cursor:none;display:none;right:0;z-index:1}.viewer-player,.viewer-player>img{left:0;position:absolute;top:0}.viewer-toolbar>ul{display:inline-block;margin:0 auto 5px;overflow:hidden;padding:6px 3px}.viewer-toolbar>ul>li{background-color:rgba(0,0,0,.5);border-radius:50%;cursor:pointer;float:left;height:24px;overflow:hidden;transition:background-color .15s;width:24px}.viewer-toolbar>ul>li:focus,.viewer-toolbar>ul>li:hover{background-color:rgba(0,0,0,.8)}.viewer-toolbar>ul>li:focus{box-shadow:0 0 3px #fff;outline:0;position:relative;z-index:1}.viewer-toolbar>ul>li:before{margin:2px}.viewer-toolbar>ul>li+li{margin-left:1px}.viewer-toolbar>ul>.viewer-small{height:18px;margin-bottom:3px;margin-top:3px;width:18px}.viewer-toolbar>ul>.viewer-small:before{margin:-1px}.viewer-toolbar>ul>.viewer-large{height:30px;margin-bottom:-3px;margin-top:-3px;width:30px}.viewer-toolbar>ul>.viewer-large:before{margin:5px}.viewer-tooltip{background-color:rgba(0,0,0,.8);border-radius:10px;color:#fff;display:none;font-size:12px;height:20px;left:50%;line-height:20px;margin-left:-25px;margin-top:-10px;position:absolute;text-align:center;top:50%;width:50px}.viewer-title{color:#ccc;display:inline-block;font-size:12px;line-height:1.2;margin:0 5% 5px;max-width:90%;opacity:.8;overflow:hidden;text-overflow:ellipsis;transition:opacity .15s;white-space:nowrap}.viewer-title:hover{opacity:1}.viewer-button{background-color:rgba(0,0,0,.5);border-radius:50%;cursor:pointer;height:80px;overflow:hidden;position:absolute;right:-40px;top:-40px;transition:background-color .15s;width:80px}.viewer-button:focus,.viewer-button:hover{background-color:rgba(0,0,0,.8)}.viewer-button:focus{box-shadow:0 0 3px #fff;outline:0}.viewer-button:before{bottom:15px;left:15px;position:absolute}.viewer-fixed{position:fixed}.viewer-open{overflow:hidden}.viewer-show{display:block}.viewer-hide{display:none}.viewer-backdrop{background-color:rgba(0,0,0,.5)}.viewer-invisible{visibility:hidden}.viewer-move{cursor:move;cursor:-webkit-grab;cursor:grab}.viewer-fade{opacity:0}.viewer-in{opacity:1}.viewer-transition{transition:all .3s}@-webkit-keyframes viewer-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes viewer-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.viewer-loading:after{-webkit-animation:viewer-spinner 1s linear infinite;animation:viewer-spinner 1s linear infinite;border:4px solid hsla(0,0%,100%,.1);border-left-color:hsla(0,0%,100%,.5);border-radius:50%;content:"";display:inline-block;height:40px;left:50%;margin-left:-20px;margin-top:-20px;position:absolute;top:50%;width:40px;z-index:1}@media (max-width:767px){.viewer-hide-xs-down{display:none}}@media (max-width:991px){.viewer-hide-sm-down{display:none}}@media (max-width:1199px){.viewer-hide-md-down{display:none}} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Viewer/wwwroot/lib/viewerjs/viewer.min.js b/src/components/BootstrapBlazor.Viewer/wwwroot/lib/viewerjs/viewer.min.js deleted file mode 100644 index 12fcd9758..000000000 --- a/src/components/BootstrapBlazor.Viewer/wwwroot/lib/viewerjs/viewer.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * Viewer.js v1.10.3 - * https://fengyuanchen.github.io/viewerjs - * - * Copyright 2015-present Chen Fengyuan - * Released under the MIT license - * - * Date: 2022-02-02T05:15:01.702Z - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Viewer=e()}(this,function(){"use strict";function e(e,t){var i,n=Object.keys(e);return Object.getOwnPropertySymbols&&(i=Object.getOwnPropertySymbols(e),t&&(i=i.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,i)),n}function l(n){for(var t=1;t=this.length||this.viewed&&t===this.index)return this;if(!this.isShown)return this.index=t,this.show();this.viewing&&this.viewing.abort();var e=this.element,n=this.options,l=this.title,o=this.canvas,s=this.items[t],a=s.querySelector("img"),r=pt(a,"originalUrl"),c=a.getAttribute("alt"),h=document.createElement("img");if(z(n.inheritedAttributes,function(t){var e=a.getAttribute(t);null!==e&&h.setAttribute(t,e)}),h.src=r,h.alt=c,k(n.view)&&T(e,"view",n.view,{once:!0}),!1===D(e,"view",{originalImage:this.images[t],index:t,image:h})||!this.isShown||this.hiding||this.played)return this;function u(){var t=i.imageData,e=Array.isArray(n.title)?n.title[1]:n.title;l.innerHTML=ot(e=k(e)?e.call(i,h,t):"".concat(c," (").concat(t.naturalWidth," × ").concat(t.naturalHeight,")"))?e.replace(/&(?!amp;|quot;|#39;|lt;|gt;)/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/ Math.abs(r)&&(this.pointers={},1 ',h=(i=h.querySelector(".".concat(g,"-container"))).querySelector(".".concat(g,"-title")),n=i.querySelector(".".concat(g,"-toolbar")),l=i.querySelector(".".concat(g,"-navbar")),o=i.querySelector(".".concat(g,"-button")),a=i.querySelector(".".concat(g,"-canvas")),this.parent=e,this.viewer=i,this.title=h,this.toolbar=n,this.navbar=l,this.button=o,this.canvas=a,this.footer=i.querySelector(".".concat(g,"-footer")),this.tooltipBox=i.querySelector(".".concat(g,"-tooltip")),this.player=i.querySelector(".".concat(g,"-player")),this.list=i.querySelector(".".concat(g,"-list")),i.id="".concat(g).concat(this.id),h.id="".concat(g,"Title").concat(this.id),f(h,s.title?Dt(Array.isArray(s.title)?s.title[0]:s.title):A),f(l,s.navbar?Dt(s.navbar):A),gt(o,A,!s.button),s.keyboard&&o.setAttribute("tabindex",0),s.backdrop&&(f(i,"".concat(g,"-backdrop")),s.inline||"static"===s.backdrop||bt(a,et,"hide")),ot(s.className)&&s.className&&s.className.split(it).forEach(function(t){f(i,t)}),s.toolbar?(c=document.createElement("ul"),r=lt(s.toolbar),u=nt.slice(0,3),d=nt.slice(7,9),m=nt.slice(9),r||f(n,Dt(s.toolbar)),z(r?s.toolbar:nt,function(t,e){var i,n=r&<(t),e=r?vt(e):t,o=n&&!at(t.show)?t.show:t;!o||!s.zoomable&&-1!==u.indexOf(e)||!s.rotatable&&-1!==d.indexOf(e)||!s.scalable&&-1!==m.indexOf(e)||(i=n&&!at(t.size)?t.size:t,n=n&&!at(t.click)?t.click:t,t=document.createElement("li"),s.keyboard&&t.setAttribute("tabindex",0),t.setAttribute("role","button"),f(t,"".concat(g,"-").concat(e)),k(n)||bt(t,et,e),x(o)&&f(t,Dt(o)),-1!==["small","large"].indexOf(i)?f(t,"".concat(g,"-").concat(i)):"play"===e&&f(t,"".concat(g,"-large")),k(n)&&T(t,M,n),c.appendChild(t))}),n.appendChild(c)):f(n,A),s.rotatable||(f(h=n.querySelectorAll('li[class*="rotate"]'),R),z(h,function(t){n.appendChild(t)})),s.inline?(f(o,I),dt(i,{zIndex:s.zIndexInline}),"static"===window.getComputedStyle(e).position&&dt(e,{position:"relative"}),e.insertBefore(i,t.nextSibling)):(f(o,w),f(i,E),f(i,y),f(i,A),dt(i,{zIndex:s.zIndex}),(l=(l=ot(l=s.container)?t.ownerDocument.querySelector(l):l)||this.body).appendChild(i)),s.inline&&(this.render(),this.bind(),this.isShown=!0),this.ready=!0,k(s.ready)&&T(t,G,s.ready,{once:!0}),!1!==D(t,G)?this.ready&&s.inline&&this.view(this.index):this.ready=!1)}}])&&n(t.prototype,e),i&&n(t,i),Object.defineProperty(t,"prototype",{writable:!1}),o}();return ct(o.prototype,r,t,At,St,Ot),o}); \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Viewer/wwwroot/lib/viewerjs/viewerjs.js b/src/components/BootstrapBlazor.Viewer/wwwroot/lib/viewerjs/viewerjs.js deleted file mode 100644 index 9af346c29..000000000 --- a/src/components/BootstrapBlazor.Viewer/wwwroot/lib/viewerjs/viewerjs.js +++ /dev/null @@ -1,32 +0,0 @@ -import '/_content/BootstrapBlazor.Viewer/lib/viewerjs/viewer.min.js'; -var viewer = null; -export function initOptions(options) { - options.title = function (image) { - return image.alt + ' (' + (this.index + 1) + '/' + this.length + ')'; - }; - //options.hidden= function () { - // viewer.destroy(); - //}; - if (undefined !== options.toolbarlite && options.toolbarlite == true) { - options.toolbar = { - zoomIn: true, - zoomOut: true, - //rotateLeft: true, - rotateRight: true, - //prev: true, - //next: true, - }; - } - if (undefined !== viewer && null !== viewer && options.id == viewer.element.id) { - viewer.destroy(); - console.log(viewer.element.id, 'destroy'); - } - viewer = new Viewer(document.getElementById(options.id), options); - console.log(viewer.element.id); -} -export function destroy(options) { - if (undefined !== viewer && null !== viewer && options.id == viewer.element.id) { - viewer.destroy(); - console.log(viewer.element.id, 'destroy'); - } -} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.Viewer/wwwroot/logo.png b/src/components/BootstrapBlazor.Viewer/wwwroot/logo.png deleted file mode 100644 index 5d8b02031..000000000 Binary files a/src/components/BootstrapBlazor.Viewer/wwwroot/logo.png and /dev/null differ