JFIF     "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777"H !1AQ"2aqB#R3b$Cr4Ss%Tt&c$!1AQ"a#2B ? }XuAo)8^ IƟ`vUp9jY0Ǧ w)E허2jU`SEKw5]kSno!]:?jc\غV7/9N+{t#8zd/޲3F/=ź3GNquV"/4:{z%ۣI'D@ %88^f}VV)S_2ed^Mx"͟?UC62Q%чmO͓ cq0rŖJ\Õ_Sݶ'|G.q޾D U]nP%EF>˲E"d&'f2s6H]4w IS˶4VbaQ+9]XtNx:M0JNxϙ⟟"{nr;|{%vo\z-wc,*|k}-m55o4W9ؓw߱Yzk .=/oϡȴ^9ҧʹamtQԬZ]4?egjrQ}+)MleE]MPEn!`IK2RUEwVIoͷcp;lśe7΄uN ;rПV8|e\׹9Y-V_G.)XԢOv<;_"ڜ]ߙEr݊'K{KuBJ}KI}24|"v)/ʻo5)6-Tjd7.C]Q&lU,Yk1P4~UKZs|$kX6+屷CUq+N(jlGrpG&UB3#k3\9qfg7O8Kim(AJOO~C#e`i0wĦij$cWh<dtQߺ"NOtG+ZǪ]b5%]v5$)u|qZ柡s-rۖu$MKڎCmN_V'/1u,21pvlc>қeNnֺ|bkl=lǷNOʣlz*]»vȎ[)j[fs[]:s#m6Qt6*Q+`};ßj[F_jcv`r#w}|k<ڞ/r53N8>Kh q_-_??@enſEܥ\D\YAEo+ ޟd}IcY7+t{=ɩ>}i\\JfxzVdSzᔢ]Q^CJի\iceitMM5hڦg')^ et#ۯ"ÿfF->4iؤ2ݷ6#p6^-R̫gETj^I.kӽUp~D9[:/>h> \gJ|ۿؘ>ml9jMK =+*2i=0RiͶۗV{"u]IH`9J_˹KƼK$X-|=ve/ bjxw.9i%NqVJcFYKcTtO,F;%67vYb8֝qq0tUt=DvawsS~~Edzr^F-v{c++ݔ\|9Iy #nOavOY=3690Tcrilwa\˓m$?箵S6U c(.~R7suMhqcMOnKoc*ȣȩEd'J ܜk*_q}%M/7c.|;trddbsdcJev85̤iW Ę 8C# .딖e$sk80^\J众2)Nm~|Idj_ O+6ǻ#(MIz4Qo:օY,:q]̌"lK}{F]ζ)h>ʶ ^ue78_G#rqv$wkk[Q c+վ+ĸZΝFB]VzoiJRke&Kgom_7Wef_7,osJɽE%lzBt>mRs)v8'P0ֲtrOg4p_2`GlhYڦDF/ӚKmtm'P2kqU765fJY:y؊.ox%8V_ִ̌ܞjpqwЮQ;iUcNoOoٸcY w*4soӵkqf$?-jy~0{>?DaL8XL/ɞo+'8 {ʸxգj#Dy)wk̘e۩+%}~;ڼ5xek|y-%ڱ-ʜe:EEScÚ5z|r'&I&яF*F7|[nRF =(4ۖ@. n7@xx:N^8Bg%u/ny6&dR{?8U_Q6Z߯-oh.NR]} qi6~H(j7*uF&l&o8ts]/P89:jW*$w׹Ӌ FxpsCJi.7N q4WU_}7*M#qWiصnk'4ݍl*t^ c<'d:~͗enFQRz9v~ddoTZ̚k7X(wUswO̙fոҁՕ[$IAI>WW~ĪEѢNoeutYߑ-Eixιpxq{FnyfRrjqU᫤]>wPU8)Y-7Wbq㛋w:7ܣ].j%K:y4] %9$I%pT(󨪙VqiYٓ4y~5S/XTDZM2lȪ; S~Kx:(Mn0';-{*qV&|W3S+\֔a{R{s=lYmN9Fn&o'}Vi( ?*qV5ѼCNsM饏zߴ$^O69@ ,$y|jE;gW/u|M?3+ZՕN86յw%|QO㏏S\E#ddsgl+Scl3~~CԕQľ?5_ z߿t11OĶ0>oB9E/SOSk+b&Yn>$툧eg) "!܉(1 uBoJ)/t/,:=7M+1ܺ#CmS^Nz 6[u&]+|Dfj:uZ5-Z^TjMtm>cȳ NdT_,M#Ex;pt۴ͮ#!N iKl!zPծ~$1SiO} HI&g Bf)b%Ko̧kumEnص;V?j>nltOMVۆl>.WueYaw2+qK,?uHiqqSM}~gu3xbcWSy/Xc{%sZ]uaUM;7:cb5G97'7þյW,;$ܛyVjl޻y7S;o6gf.Tг[7/i1Z^rE cUF'P1-?%u&q{fw~27ޡ ^w$?SwP[=R3Y73 4x(Kk&rLȫMKn:RjcI?3Al`vض[POĖSYujj6v+-[xҵ=~zNN>\ɲQ/uufo*e6l;31붏.>w6=7#7dFDc%ƶTbd;2/=?Asr! ~ZSS~I"9y]Hn,ĊJ7S}cK"amCg3yP=RQɤW}t;-{F+v+RɔڎB?º{SV묖kۏmK~%.Q;OfEf_Y/F-V-MdD)m.ZՍ8Y*h[g/6ydmCc[rdfʾ䖗gd$^֍^ʅѻL|<[݉\߯RiJUo';œN?B smS ܹkس,mRE^ѣlJ&.ċ԰YO:޼f\Z'HCѯU[ʩ1ff4S-٥YxTIGLiыr }L)edׂ*l|ٚuoxӿnWkTbbVm zT_'"x5Vިxo1ج^Fq6Sd3ws'/ڞ6m?}1OsRGݝ+,~ڬ%^p1ef5c25vq~﹉ă[r-eq] 8+/ESj}?mUE.xYK3"oƔ^Y9I]I ޑ" &*4.Jâ}ټQbXKJ񽼀ncg`+riܭ_'Bֽp%bX'7cB}WPm|zHָLJhj~E>i~Z$297|_hyΕ&s}ZϷ *j]:v.HK<SP8`Pƣ)r ,}8Wk[ArHgn=о7:J]TTP>OOj J_KyB\Ԥrm嬷ȫr{ݙ5R(FRЪ6q}KLmR'eޖz6[YތesYYL5Tr7s\^rؙV͸컬j5d?yk'b S }kra^ߚRH)[sg.fLM\u= vJQ]rVkZuoN}#G?yjO%|i2fKoӰღC P_Ϳ6Zr{e/m$i}9 G2')YG9KY>|1ӫ +v+i;h\Q@˿Lӭn˖ 7ck>Vr.D0)hC<˄4"0[eԬݭe+l2s3ss oX]1r]+VK vI;mZ')R6e5=/i@]H^Z۬՝EW.jƆf{8mXMV~_̝z^VR}T63}}k3+k3:j1Phlpi{欍BȽ}6w73GtUZv>4eUj$ xz$$D/߇ߟI"uk̜aƪ*ke/F:dһ_PE1ݡkp(5ʏ-ɮ{Yllԧg!ܝ g]i-umεŸxOê^=PR ##XeMy%2L~󜺶Hm ݙ2t_ƶz7'\Z4T<"AM-&xaC]a5.huQ۫$cMμ|h;.J.o߸sE-zU{d];|YLSMvSEneNKr1B[]NeonNߪ$4̘FPrkxޱ=0lr7Q%=$KQ;0r*XKdGۃ*]w-npᬶ\tt4>Dc[Ouo3/)-WҴ xs71eԤm*ٖ웗H''.Cnmy]݊Kra[9)Y#2U6d7tf.[R.GdE>#O_.+-K`{KonR_ÕM/)?:F,Xo1ƽRmz8C]lD %(x+d2Ah+\CCLJ!D65x\ȼv)\Nrp*[YُfL*PyVΚuWA K4hyYdwihNIy#ub?4NDϐ'4 :nFe(o%ve@@xl-k%QƭRP&kεMŪ-Ys2u ]T!}8*TQnZ}v =~mԧyDM&8K>2|Bnugܷ.wvCs̼5F^ubES7ݢM&4Ź-~mKx1((sr!M5uy\q)oy|a)ˣ,A?w"T휳2\F}PR-<2%`~4Z5\W"(USkGpT(~Qj>ɰ쏳ǓSKKx's]nEf'.iݙL>Moƹk7ݭ[.г6lk<;?)#E]xFU7'>vF%R;t:Җs}NSBWX=Y8ث}~G)S^^ƽwR[)/Fm-ڞTK~˓Z]U;RQ=M/"NԝP[-Y9t_8V+}P?Ue{M/O&WWKvc#r'KM'p[±vtpRC/W|7K2Rfm;ljm%Z]^T[6}6iTC }L[uxg7(Z}. SRI)jҞzȶ쳢oYRw$ŷ"J\ǭw{u'R taF{;3hHB\RP(*ZQ]y;;k٥nWbGKv-V?NDҞkd9@z LJ}Kc9C*?V-*[*۸-0.|󲝳ߗZK#%_OFGF$kC$[NNJ7Yn[k~Xzc+Sʲuhsw^^4+nElbƮKD,}YLV=i=|p|_=b5mȵ(~,em#Xƥ.sVoEaWXc.lY uG\m';'*\ӆ}|˯UfQBvo}/"zw + qvMrQ[[AdU2ٽCGgjؖS~Ev%9">$_2Sߚ%ѽ7jX(t#21r{̬F]b()?r[Rı)W[O/6]XL9 vuLh-Ȃ9"'7f!Փ䮿Bf}[lag֧]?Pc#D9EmfK7o*})+n!]qIo^FrNVNo!Eƃd#OP?%ۋ(mPu93ۣ{}2&$%cZ߯LҚY);U afԶd,*'6_?B:R~}^̬~mJ+vC}Ѩe"MY+mi :s쥸;iJeYvBddeK|#5/mzR]F2 JHUU )/S{Ic$=: W)>} @0#URsR=w"L{+ɞ)d|*qq2>[nƨDۋ-G[6½J|{Ѿ4MwyG-Σ Ze{ug>2|'zΤ2%xՑ*<Q̥T')uLkjn(zF-JOR}wn~FV5zq2m'^VS=7Y^RdfeO)>EpX붚w*r*w˿^kڴ{J;K۔sRŶU]p\zn@dx6[+yeH[_m_/I&mv|M5&&-G"v۴^{vg8Y(K_~h0e AxfrzڬkhS/Vy1ϯdW3'͹}{'V-:MW(V/ͷ*E7s\EmEW}bUr'k,P{9?B֫ #[uNrB,wo^{fdF(5tRf.2J-/:~ t0M"d_/c^32*q]yLl^2[ݥZc*vtm213r'tSuM-Խ#o/HF+2VEpmǦޟS?Rs+t:u G8n,Ԛf,hY8SX*rKf>+cpruɬ=DMrXgϸ:~ɲ ~]'5'kElw\=ڞAG&')G9R\_̝1K;nPg&T(ի[^Jҟ"qoӸ.W}3mF>'$<\U6-~?x?B~{^xkpv-vlߣe빹j\(ښsuu6lH(qoaYt?x8}Ie '@b%TݲygV.+O9/W4MsCMuFjYzG.{ds.k(>G~K?ni-=R r}r ?s̥%l5Ϛ9IN6~۩RĢWNʾE[|nb.HY—קWkr1ҺշMNDp)^¸R:w;u1 12]T/Uiʹd%2OC2K*r5S]g凫5 UQ.ȫ– /i91njFkQxuJ1rn%XDžy?s˗վuMGƋ/m^J*RsF))uF,'l{=|nFm9:N\%u#tnXE->e2Y0PũjUȨEŭ|'eʹ[o{Ցms%CGg/}t|snzrvm\g}cÊ94Pvg'L}ّg궮ԱߢO^f.W-sT]M˔ېе<^Н'KuNn_Vl8*Kж^ xsuW51-ᅱFzƉT-kY/9wzDޯ/XlW)gypǚjDɨ~{ݤHCim.[>rqE_Uرx/>|L64%aj;fxӱF(K֓J9՞ -K> I_5Enn´&=Oc%o̟IJZF$۲5I9Wݚ n.WTuѲӏ[4U/9.2zX5\j3ĎEsMq4%9.d[7јc9eNa+sjE';%s#ɤ`ףS=WI쫢.Mv:j/[3:rTF_zt:.z%udW%]xܮVz$Vŗ49[^y.խN~M&mx+wGR~_4KC[ʻ:v>03߶v9x-Mȧ$c:lrCWjeg%ֹ_Nh՝Qɏj^ϛr^.>WhlE5yֵ6\W^确]*гc&^NI[oCDn.ߑ!,m&M_/'Mn$s\r^8|uSZZ1|LV<(zq׮xmٚZƏ%.Ԁs^2𱸒O#&,s[mײ9kޖCoSq&俙qxP.N] 2UǎsM2iN.f r[mcQZmFُE{#[TbҔ*sfaSrn^8N<\_'MarJ6 EQғ|F[S'[~q~kmn[_x?B f5Q١X=g(~[Cx}GO ĺo'e)~dq(Ot`sN=~heu ::m'Cjj>~5V柙cyQD%uqEc{[l^U O]b~eŦۑ'W3&' 2V.^D%G S6\wYNO$. O+^ŵG~haEs^=1*bICzFF4O#,Wu3허ekB\I'tWMߩOG3iFz{rgeM9g r] i3gk&u1r/1kVgR-ɿuF .^;3;?3큦bN̂r4ovMkڞ}[:,IVG<};*-2",>K%bK2Ƨ[w!)ˤ;d?4%Ul2ږec4#ōIw^R_/TFX+*FM[F|a'ߚ2SIMeVGn ~&Y Ym(?ԛ],=|сG4yjk"Q^~ԗ^c,qqrg^-:Uc[E8>>k|nS..LBIc>3i|ZEZXAqm nuOm<; X~mrK=~ ƱrSN<U!F΋WS/|t?K)zd} ,C"ovx?bբs3mX3桭X֖˦kFddhg}$ggSo5jL*NdJis$ EQ\v=0HxzyW~FT_Ƶccg,&=_V(%kq+_÷O'[_[Uڽv F $Ξ9n5EN/4Yy/%*} .jΔ`V_6\VͲohzfOgޯzpj}y}v:34WH;+x7ӻu<ݦ"mJ/=>eoD֣c4kXW-[}٬6;t[Na_• _5i5˗sٴ]+e;Joj㼶ۙyLumo5&F)F\ {(sm_M>gzcr)KU̠Ħ=VDd'h;-aŤ9KٰqQܫަazMp4bk9 UX.ͮ]KeS5Uq[¹X0ɦ6]roFjʧ2׏6/C6eQE5KӰmsFnIz&`z팡-ٯ.ixyك?c2//z6M4W[]_"?Õ[? Vfvӳq]I5(d|MʝzcC*mN>B2gD+><e:Gh %UkW%zJ8k_ˠ=KFRfw{sŖ^q\/{v[Ω}gLjT[t_ޕg6G~rkkMcSRKբ54?SAûO1o%[>5/R~CioNdNʛćh>f6H8c/<1xd[ŦCEk.9"ej?w&O6^ژR[vrQ.z㎩f6:V8}hi2z~ s-w]+|I9s_C~>-S&9ZFVLf7-d'pՠplJ#mm؎s(?Ʋ?/A%_sXuGNnR}_dq>1ʍ|У3]NXYZʷ/&ܛ彖LS? 6]"_t5qP5Kq]^m91jW暹U6-5WU澦M0˵f2ӪǮ.P~? _nEJTcTei)ٳrۣ%x %gs}7l9'tb~dXst# r?}Weaq>=+to)7،E*vn\e_,\NFxcivz]tM˼?Oԝ2Zrλs-ĺEtonIIfm/9^[^EBUjOnr6vI& l]%0")2䒶-+R*zyX<> -X9GUo^xYQ8ιvixٔa\t)hv}ьոVU~tK,=_wLLa?TYIo]$`N6cbi?#7;MRt<.~Q-mob\\g5췍 ڌ_?8nfJN/Y͢n3?_sϩ{HiְPo'yS??_jߡWi5q? MWȲ)8a]lLˏ--b[TXlΫRy;o5뜾$HW.mm?շG[Ƀ seo5Q}Le%*،«~uU{R$t\^%!weX:G('6WupTS&~8=jo?2_PϖE[nf6Tٯ;GLW)NM[o*\j%.gb|䭹noOX:1R)UTj74˓]D_bʝkzNI.9|^G`KeQ{mOjX/sR7evdgi7qm}ތW&4=~|YY)?7Oj}xXkF×4c.l?i|b[5Ή5j-[Y\z<茲Z$Ff&o;gErǩݦ̪/q[&[/9uuzi;PS^_/?]=ΕqK~ӛ5'NM[m_Ϲc'[oӯE#g߂vvGNRo϶o5Ǩ[ɉtov2~i<7iSȜN(G5+/ٛMTܣukj鷣/$1˒!Mxr\ߤs1ZuMQȌ^]c$CXrj#N/˦Ķ9]Nzê5zi;W,v!ŧD6zğ7uR5^MW}>igl2U2nXo{}_w]&vte\Z3 MEEe/ 2s㗼S_bIղTI}|[Ye/c]*̪9u/DmyNxSDgi `Z?.RFj۪'~.[KVb޺o濡to?E#[.^y=q4F8ڎ/GX\.YW!Z.ѕtt:?gYYyU%Uw~ri>ȦKhg,5/=>V?TrN4aWO,oӕ7-SRi*"dܽpuaVQÞd-#J2Nr:#``ѧWR-F?I-T -cOT2pr?þזgE\Ij~L9%EMoџUؙt8_eYΧWjU}e9y9z/#TT-2dLt3H=ڼcKb'"uIٓ'[[߱F~\2]r%C]^VCLjm[cJNryf}ջ.[DEoRՒb'>fVy_c6[K4Na5>{ɳaw/Uj.Զ_K~?IeJ7OQx3IgFc*جɊǽ-o3Ӭp / ]7V*ENܜ[r/tOJΉw*ʨ*JFN^.WZeLgUwKi/M9y8dkOᛊHxGĶM*&#h/U|6D(uFyE5hYxiSEVm^D|,ۿCj;<*ouOkYpΔ2{x-L] !k2ا#IM'a7:M}M1Y儭Mnk[/;4Uwkkɫ%aɔoXVV$m;2Z4i9:>\Yů= ?[{t6,~!c`Un+dW.gKyIB]l+3kض(\MZ\}>k\C~閹l[ů]VNtƸr몮X+U>v'nv{y7s[г̭9Ctvt% GqT8=wa(6\Rd柮YWv^Fd^\+緉,+=-^S"k:NVu o[_TIѝ椯bF/G㿏dΙ?T}K-T)W>s?3M)V*,;P\,}B u{rDexڥVFfw}47׋w}]Դ 1dmk1V%/'T:Fǒ_TEe[l/l/ٯc{Ƀ[~`zj⾥r}Vܪ{M8Qv]$mU]8J2MngcxY?鑞.9HjxSy.fS(|]MgcK2$(jRQ3XO|<f:Jq4& fw|$N )A8ת99 mFNM*Dϒ NoIa9i9y?:D⻧߇\7ɧ]mu"-˥5/w̨_ 7DK['[2"(%xzT\*GT"+<,yX.lEJrfo?.4N;l>jmZߣ5FdB3\r,t,./S]Q{tm5lӕT~A [fv7Iہc: ΪN7I]2(|o$NLW"#~Dͭ=v-Mv{-lqn{I3xn'6.=DƟܖަ~deQV;k2Ei\[bӴ1_]OhZl朠&t3xkei+c\'ZԪ'hK梿X@cTԫ#emIz6e^i?8 NBc̆f+MׇdC]YSd%lώ8-c7eι/}_con/no\핍~[WNReXMo+اn ?#Ͷ-AUFN1V4!y,{1a$S﹑;Ǚr"__[o) xk}7EI/riwؙ7mR}`|yrEVdo/B# uٳiNQKQkᑑ^d@/=ˑɒ768fsuor9=7ףܹճpMr-$1uySOZN?đrqզ9F q=.!T?ػ bf{¯q=$^:!ES߿ Fu\OS,8e^UוS^hF4BQƺȪw-kF39@X06 Fv=Q^|ƞ5}2tnmG_|Λ(|%](-5>KȁN$=6lq).12 V6m$ׇlOcҫܸ K{;ľ>+Q?Rx-Keu uMy$i B}G*h$Q -W[-&a"[i\}~Ek$<~c{MffS eS.#\^lMiytު]9S{u4 {DFޅSź}R ]R$y;r/P̙3niXMt;&!rxw\ZFmQ"w\L{^۔K&/gr:m=2%5bwE"^e[\$ɟPi!U_rdS2d?=[!(I.rC QZEim%}|YmzZ_ά<ۡLQM|` ybPȏ}?]Eu[`kҫgFb~F}Q8NP>5lӳ^-K%Q}$sx7SvnfTƸ|Kzd'_ⰽח$4L Y?qy32t j2e ȜrJ{mبhۍUU'p#8y'ѝ=i+Tĩo7WYyČkL5؝M=%"Nt}eXW)N.~sv5pɮ sSQ[+-/}kVk'FEɩ9SE&T=&\緵 --tf.9Ѳ4_##_ɱTFV؞~YTddS&s=䟚Fb1._5}~gM'p#,U hs--XG wtԹTi7M:GYK5'^W?C>_Gq/S&d| k_gO ӊiJeHU G_ Êg#),}-:5>V1emq}t}q?meKU:BqJeiPɗ#\$sI} Z生ƫoo=V=pVcUg"%wEm叡vIdhrȔ~F]p58_.,O|'Ɇ^L!c6OWӷ{x9?Fp?ceOuT+Uɵݹ&gx9i퓃sxGIm}_3Īr#:ԣ?4בc[jö#B7KʌWNo)=+c }YvP{lv^r+5Vxx_:~=̌Q}CTy+Wh鸚f$101뢊F[#--Y\i@l)W8/E>8nlj/ktOľ,q*[sE[]:?ZeQvŔɺ|j(Wx,LW=:S?κq%81c)jJvODLiW,{96vr-2}-EH,}%3k#l5gl~x__W Sڎ 8YJQvA=QIWju6-X9$kWЩCI4UWd'&O/Cf=Pi/#+>n$KYst܅y4ʷD^~%~myj,s_4Q}΍Cή;SW:h=Ff{.B/inȇo=-T͸OY2}hlK}.m7-z?,f-/^b\QWs/_͔/3In[6M;l ygؼ!WUË_)D9YL4_>f}ϵ3hV5Oѣ(l8?L4蹥[-Э=7V{&ʢPʼ*3cMz>u4@[oM gKS[jy"Lھzɵfx)GE`ֿ.=kJ>/iˢ[j-qץQC B@o V(ʯG?Bܻ\I>=K-].(vOE.5׮=/Pf^&$caY9{3މ%YOxZ~6Z;;ԗ.NJzş/YϖĜ%ѿO^tY$ν4|e}2ɶU9A؜h˺LrIm%J.|I]kG|DzU k4'(T\9߱^!z -:mW^ <= <^2*;Seq(6ªsHf5ʸO{Ilr~G uJY^k5X_y;5'59O@ƣ̶>pnCOvNwX4oUUf]Џe%MV9Xm9]x'Q=82z)c/~1\~LSow>ﺍƻUql~Sqo羘sk}VjG71kYؽ]b4qnMӡ; w@̇IL㿗[43)]=v*)EH'a񖳋ҎTkxuXGK& ZIR(M8?:ixJp-dmckpu*%N^-7E3='ceE&';_J'Mw𶥏Y9+d9+>!e_Sn|VX -TZu]Ģ/6\ckr /ޗ/z[y.N:*k$ }Yǭ}GUm^-%dm;K_#ctBsg2:8rz-VE|T w.}w9NEPGnoCe8/&3qT}MJ̙Mۗ~哳,-WI_Bsh+~͛vN{ZdYKݲkr%+lo*re-ه?:vYqFfCsqMXRķ{yqgrx.oǓ\xdڗ_ZC9WomX|KmV_%UJܷr$drȳL~MoKyYLic Jq<1$UuٯTד374s<ĕ96춉r9 pGc9=p^:)ZJb&VӝXٽ 0/X& ۳*_ԙƏ.5J 6<$$6B0d_d?hqd>XCe- wO@pg:.>$.Ϣ~L޲|,{-ɪ2.u/Ds-[ُiVIWK5M#Fܭ3?x.)ۣ,wJ)Ȳڣ-#fbdq&Tͧ8Q,YqQ)/R­?\k˔[p_+ogzP[6r^o}_kT}JiJ;<ivEH8wI@MOPʊ\#+$%PDF-1.7 GIF89;
ANDA PELER
Server IP : 182.253.108.180  /  Your IP : 3.141.200.103
Web Server : Apache
System : Linux sma1wiradesa.sch.id 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64
User : wijaya ( 1017)
PHP Version : 7.3.33-10+ubuntu18.04.1+deb.sury.org+1
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/share/usermin/authentic-theme/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /usr/share/usermin/authentic-theme/navigation-lib.pl
#
# Authentic Theme (https://github.com/authentic-theme/authentic-theme)
# Copyright Ilia Rostovtsev <ilia@virtualmin.com>
# Licensed under MIT (https://github.com/authentic-theme/authentic-theme/blob/master/LICENSE)
#
use strict;

our (%in, $root_directory, %gconfig, %gaccess, $base_remote_user, $remote_user, $theme_webprefix, $theme_server_webprefix,
     $xnav, %theme_text, %theme_config, $get_user_level, $http_x_url, $server_x_goto);

# Detects the state of navigation menu on initial load
# Returns navigation tab name and right page defaults
sub nav_detector
{
    # Get tab and dependent right page
    my $tab;
    my $page;

    # Get goto if the page been reloaded
    my $req_goto;
    if (!http_x_request()) {
        $req_goto = $server_x_goto;
    }

    my $prod    = get_product_name();
    my $mod_def = get_default_module();

    my $mod_rt_access = &webmin_user_is_admin();

    my $prd_cm           = "cloudmin";
    my $mod_cm           = "server-manager";
    my $mod_cm_available = foreign_available($mod_cm);
    my $mod_cm_access    = $get_user_level eq '4';

    my $prd_vm           = "virtualmin";
    my $mod_vm           = "virtual-server";
    my $mod_vm_available = foreign_available($mod_vm);
    my $mod_vm_access    = $get_user_level eq '2';

    my $prd_mb           = "webmail";
    my $mod_mb           = "mailbox";
    my $mod_mb_available = foreign_available($mod_mb);

    my $mod_um_access = $get_user_level eq '3';

    my $prd_db      = "dashboard";
    my $prd_db_mode = 0;

    my $page_index       = "index.cgi";
    my $page_sysinfo     = "sysinfo.cgi";
    my $page_sysinfo_def = "$theme_webprefix/$page_sysinfo";
    my $nav_def_tab      = $theme_config{"settings_right_default_tab_$prod"};

    # If we have goto substitute default
    if ($req_goto) {
        if ($req_goto =~ /\/$mod_cm\// ||
            $mod_cm_access)
        {
            $nav_def_tab = $prd_cm;
        } elsif ($req_goto =~ /\/$mod_vm\// ||
                 $mod_vm_access)
        {
            $nav_def_tab = $prd_vm;
        } elsif ($req_goto =~ /\/$mod_mb\//) {
            $nav_def_tab = $prd_mb;
        } else {
            $nav_def_tab = $prod;
        }

        # Page should be what was it reload on
        $page = $req_goto;

        # For modes with dashboard switch
        if ($page =~ /$page_sysinfo/ &&
            (   $mod_cm_access ||
                $mod_vm_access ||
                (!$mod_cm_available &&
                    !$mod_vm_available &&
                    !$mod_mb_available)))
        {
            $nav_def_tab = $prd_db;
        }
    }

    # If no goto and defaults not set
    else {

        # Validate if default goto is allowed for the given user
        $mod_def = undef
          if ($mod_def &&
              (!foreign_available($mod_def) ||
                !-r "$root_directory/$mod_def/$page_index"));

        if (!$nav_def_tab) {

            # Define default tab
            if ($mod_cm_available) {
                $nav_def_tab = $prd_cm;
            } elsif ($mod_vm_available) {
                $nav_def_tab = $prd_vm;
            } elsif ($mod_mb_available) {
                $nav_def_tab = $prd_mb;
            } else {
                $nav_def_tab = $prod;
            }
        }

        # If default set and if module available
        my $page_def = $theme_config{"settings_${prod}_default_module"};
        if (($nav_def_tab eq $prd_cm && !$mod_cm_available) ||
            ($nav_def_tab eq $prd_vm && !$mod_vm_available) ||
            ($nav_def_tab eq $prd_mb && !$mod_mb_available) ||
            ($nav_def_tab eq $prod   &&
                !$mod_cm_available &&
                !$mod_vm_available &&
                !$mod_mb_available &&
                !$page_def))
        {
            # Cloudmin mode
            if ($mod_cm_available && $mod_rt_access) {
                $nav_def_tab = $prd_cm;
            }

            # Virtualmin mode
            elsif ($mod_vm_available && $mod_rt_access) {
                $nav_def_tab = $prd_vm;
            }

            # This is the single product switch mode
            else {
                $nav_def_tab = $prd_db;
                $prd_db_mode = 1;
            }
        }

        # Check if specific single switch mode first
        if ($mod_cm_access || $mod_vm_access) {
            $nav_def_tab = $prd_vm;
        }

        # Check if real product is set
        elsif ($nav_def_tab eq '/') {
            $nav_def_tab = $prod;
        }

        # Define default page for Webmin/Usermin
        if ($nav_def_tab eq $prod || $nav_def_tab eq $prd_db) {
            if ($mod_def) {
                $page        = "$theme_webprefix/$mod_def/$page_index";
                $nav_def_tab = $prod;
            } else {

                # If default Webmin/Usermin module is actually set
                if ($page_def && $page_def ne $page_sysinfo) {
                    $page = "$theme_webprefix/$page_def";
                }

                # Define safe default
                else {
                    $page        = "$page_sysinfo_def";
                    $nav_def_tab = $prd_db if ($prd_db_mode);
                }
            }
        }

        # Define for modules
        else {
            my $type_cm = (($mod_cm_available && $nav_def_tab eq $prd_cm) || $mod_cm_access);
            my $type_vm = (($mod_vm_available && $nav_def_tab eq $prd_vm) || $mod_vm_access);
            my $prod_target =
              $type_cm ? $prd_cm :
              $type_vm ? $prd_vm :
              undef;

            if ($prod_target) {
                $page = $theme_config{"settings_right_${prod_target}_default"};
                if ($page eq $page_index) {
                    $page =
                      $type_cm ? "$theme_webprefix/$mod_cm/$page_index" :
                      $type_vm ? "$theme_webprefix/$mod_vm/$page_index" :
                      $page_sysinfo_def;
                }

                # If set to domain/server id, try using it
                elsif ($page =~ /^(\d+)$/) {
                    my $id_ = "$1";
                    my $id;
                    if ($id_ ||

                        # Cloudmin default server's id is '0'
                        $id_ eq '0')
                    {
                        if ($type_cm) {
                            $id = nav_cloudmin_server_available($id_, 'id');
                        } elsif ($type_vm) {
                            $id = nav_virtualmin_domain_available($id_, 'id');
                        }
                    }

                    # If current user has access to domain/server
                    if ($id ||

                        # Cloudmin default server's id is '0'
                        $id eq '0')
                    {
                        my $vm_file = $mod_vm_access ? 'view_domain.cgi' : 'summary_domain.cgi';
                        $page =
                          $type_cm ? "$theme_webprefix/$mod_cm/edit_serv.cgi?id=$id" :
                          $type_vm ? "$theme_webprefix/$mod_vm/$vm_file?dom=$id" :
                          $page_sysinfo_def;
                    }

                    # Fallback to default for user
                    else {
                        $page = $page_sysinfo_def;
                    }
                } else {

                    # If default page is not set assume dashboard
                    $page = $page_sysinfo_def;
                }
            }

            # If default page is not set assume dashboard
            else {
                $page = $page_sysinfo_def;
            }
        }

        # In case of Usermin
        if ($mod_um_access) {
            if ($nav_def_tab eq $prod) {
                $page = $mod_def eq $mod_mb ? $page_sysinfo_def : "$theme_webprefix/$mod_def/$page_index";
            } elsif ($nav_def_tab eq $prd_mb) {
                $page = "$theme_webprefix/$mod_mb/$page_index?id=INBOX";
            }
        }

        # For modes with dashboard switch
        if ($page =~ /$page_sysinfo/ &&
            (   $mod_cm_access ||
                $mod_vm_access ||
                (!$mod_cm_available &&
                    !$mod_vm_available &&
                    !$mod_mb_available)))
        {
            $nav_def_tab = $prd_db;
        }
    }

    # For modes with dashboard switch and various options presets
    if ($mod_cm_access || $mod_vm_access) {
        if ($page =~ /$page_sysinfo/) {
            $nav_def_tab = $prd_db;
        } elsif ($mod_cm_access) {
            $nav_def_tab = $prd_cm;
        } elsif ($mod_vm_access) {
            $nav_def_tab = $prd_vm;
        }
    }

    # Temporary patch to address older, existing user configuration
    $nav_def_tab = $prd_mb if ($nav_def_tab eq 'mail');

    # If Dashboard mode is set
    $nav_def_tab = "$1" eq $mod_vm ? $prd_vm : $prd_cm
        if ($page =~ /$page_sysinfo\?[\w]{3}\=($mod_vm|$mod_cm)/);

    # Return detected tab and page
    $tab  = $nav_def_tab;
    $page = $page;

    return ($tab, $page);
}

sub nav_webmin_menu
{
    my ($page) = @_;
    my $rv;
    $rv = nav_search();

    my @menus     = list_modules_webmin_menu();
    my $unused    = $theme_config{'settings_leftmenu_section_hide_unused_modules'} eq 'true';
    my $nomailbox = $theme_config{'settings_mail_ui'} ne 'false' ? 1 : 0;
    my $extra_links;

    foreach my $menu (@menus) {
        next if ($menu->{'id'} eq 'unused' && $unused);
        if ($menu->{'type'} eq 'cat') {
            $rv .= nav_cat($menu->{'id'}, $menu->{'desc'});
            $rv .= "<li class=\"sub-wrapper\"><ul class=\"sub\" style=\"display: none;\" id=\"$menu->{'id'}\">\n";
            foreach my $module (@{ $menu->{'members'} }) {
                next if ($module->{'id'} eq 'mailbox' && $nomailbox);
                $rv .= nav_cat_link("/$module->{'id'}/", $module->{'desc'});
            }
            $rv .= "</ul></li>\n";
        } elsif ($menu->{'type'} eq 'item' &&
                 $menu->{'desc'})
        {
            $rv .= nav_menu_link($menu->{'link'}, $menu->{'desc'}, 'fa-link');
        }
    }
    if (!$extra_links++) {
        if (&webmin_user_is_admin() || $theme_config{'settings_theme_config_admins_only_privileged'} ne 'true') {
            $rv .= nav_cat_link("/tconfig.cgi", $theme_text{'settings_right_theme_left_configuration_title'}, 'hidden');
        }
        if (&webmin_user_is_admin()) {
            $rv .=
              nav_cat_link("/settings-editor_read.cgi", $theme_text{'settings_right_theme_left_extensions_title'}, 'hidden');
            $rv .= nav_cat_link("/settings-logos.cgi", $theme_text{'settings_right_theme_left_logo_title'}, 'hidden');
            $rv .=
              nav_cat_link("/settings-backgrounds.cgi", $theme_text{'settings_right_theme_left_background_title'}, 'hidden');
        }
    }
    if (&foreign_available("webmin") &&
        $theme_config{'settings_leftmenu_section_hide_refresh_modules'} ne 'true')
    {
        $rv .= nav_menu_link('/webmin/refresh_modules.cgi', $theme_text{'left_refresh_modules'}, 'fa-refresh');
    }
    $rv .= nav_link_sysinfo($get_user_level eq '3');
    $rv .= nav_link_netdata();
    $rv .= nav_theme_links();
    $rv .= nav_links();
    $rv .= nav_menu_html_snippet();
    $rv .= nav_detect_page($page);
    $rv .= nav_detect_script();
    return $rv;
}

sub nav_virtualmin_menu
{
    my ($page) = @_;
    my $mod    = 'virtual-server';
    my $def    = nav_get_server_id($mod);
    my @menu   = list_combined_webmin_menu({ 'dom' => "$def" }, \%in, $mod);
    my $menu   = nav_list_combined_menu([$mod], \@menu, undef, undef, $page);
    my $rv     = $menu->{'before'};
    $rv .= nav_link_sysinfo(undef, $mod);
    $rv .= nav_link_sysstat();
    $rv .= $menu->{'after'}
      if ($menu->{'after'});
    $rv .= nav_theme_links();
    $rv .= nav_links($menu->{'mode'});
    $rv .= nav_menu_html_snippet();
    $rv .= nav_detect_page($page, 1);
    $rv .= nav_detect_script(1);
    return $rv;
}

sub nav_cloudmin_menu
{
    my ($page) = @_;
    my $mod    = 'server-manager';
    my $def    = nav_get_server_id($mod);
    my @menu   = list_combined_webmin_menu({ 'server' => "$def" }, \%in, $mod);
    my $menu   = nav_list_combined_menu([$mod], \@menu, undef, undef, $page);
    my $rv     = $menu->{'before'};
    $rv .= nav_link_sysinfo(undef, $mod);
    $rv .= nav_theme_links();
    $rv .= nav_links($menu->{'mode'});
    $rv .= nav_menu_html_snippet();
    $rv .= nav_detect_page($page);
    $rv .= nav_detect_script();
    return $rv;
}

sub nav_mailbox_menu
{
    my ($page)    = @_;
    my $mod       = 'mailbox';
    my $nofolders = $theme_config{'settings_mail_ui'} ne 'false' ? 1 : 0;
    my @menu      = list_combined_webmin_menu({ 'nofolders' => $nofolders });
    my $menu      = nav_list_combined_menu([$mod, 'changepass'], \@menu, undef, undef, $page);
    my $rv        = $menu->{'before'};
    $rv .= nav_menu_link("/uconfig.cgi?$mod", $theme_text{'theme_left_mail_prefs'}, 'fa-cog');
    $rv .= nav_link_sysinfo('user');
    $rv .= nav_theme_links();
    $rv .= nav_links();
    $rv .= nav_menu_html_snippet();
    $rv .= nav_detect_page($page);
    $rv .= nav_detect_script();
    return $rv;
}

sub nav_menu
{
    my ($tab_mode) = @_;
    my ($tab, $page) = nav_detector();
    my $rv;

    if ($tab eq 'cloudmin' ||
        $tab_mode eq 'cloudmin')
    {
        $rv = nav_cloudmin_menu($page);
    } elsif ($tab eq 'virtualmin' ||
             $tab_mode eq 'virtualmin')
    {
        $rv = nav_virtualmin_menu($page);
    } elsif ($tab eq 'webmail') {
        $rv = nav_mailbox_menu($page);
    } else {
        $rv = nav_webmin_menu($page);
    }
    return $rv;
}

sub nav_get_server_id
{
    my ($module) = @_;
    my $default;

    # Try to find default
    my $module_ =
      $module eq 'virtual-server' ? 'virtualmin' :
      $module eq 'server-manager' ? 'cloudmin' :
      $module;

    if ($theme_config{ 'settings_right_' . $module_ . '_default' } =~ /^(\d+)$/) {
        $default = "$1";
    }

    # If we have goto substitute default
    if ($server_x_goto =~ /\/$module\// &&
        ($server_x_goto =~ /dom=(\d+)/ || $server_x_goto =~ /id=(\d+)/))
    {
        my $id_ = "$1";
        if ($id_ =~ /^(\d+)$/) {
            $default = "$id_";
        }
    }
    return $default;
}

sub nav_set_last_id
{
    my ($link) = @_;
    if ($link && $link =~ /(id|dom)=(\d+)/) {
        return "vars.navigation.select.last='$2';";
    }
    return undef;
}

sub nav_detect_page
{
    my ($page, $set_last) = @_;
    my $rv;
    if ($page) {
        $page = quote_escape($page);
        $page =~ s/&amp;/&/g;
        my $last_id = $set_last ? nav_set_last_id($page) : undef;
        if ($last_id) {
            $last_id = "<script>$last_id</script>";
        }
        $rv .= "<li data-goto=\"$page\" class=\"hidden\">$last_id</li>\n";
    }
    return $rv;
}

sub nav_detect_script
{
    # Get goto hidden li element
    my ($set_last) = @_;
    my $rv;
    if ($server_x_goto) {
        my $link = quote_escape($server_x_goto);
        $link =~ s/&amp;/&/g;
        my $last_id = $set_last ? nav_set_last_id($link) : undef;
        $rv =
"<li data-script-goto><script>plugins.navigation.detect(\"$link\");plugins.navigation.detect(\"$link\", 1);\$(\"li[data-script-goto]\").remove();${last_id}</script></li>\n";
    }
    return $rv;
}

sub nav_menu_link
{
    my ($link, $text, $icon, $hidden, $after) = @_;
    my $external_link = ($link =~ /^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/)/);
    if ($icon !~ /\s+/) {
        $icon = "fa fa-fw $icon";
    }
    if ($after) {
        $after = " data-after";
    }
    if ($hidden) {
        $hidden = " hidden";
    }
    $link = "/$link" if (!$external_link && $link !~ /^\//);
    $link = ($external_link ? $link : "$theme_webprefix$link");
    return
"<li data-linked$after><a href=\"$link\" class=\"navigation_module_trigger$hidden\"><i class=\"$icon\"></i> <span>$text</span></a></li>\n";
}

sub nav_cat_link
{
    my ($link, $label, $hidden) = @_;
    my $rv;
    my $external_link = ($link =~ /^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/)/);
    $link = "/$link" if (!$external_link && $link !~ /^\//);
    $rv   = '<li data-linked' . ($hidden && ' class="hidden"') . '>' . "\n";
    $rv .= '<a' . ($hidden && ' data-parent-hidden') . ' href="' .
      ($external_link ? $link : "$theme_webprefix$link") . '"> ' . &filter_javascript($label) . '</a>' . "\n";
    $rv .= "</li>\n";
    return $rv;
}

sub nav_cat
{
    my ($c, $label) = @_;
    my %icon_table = ('webmin'            => 'fa-cog',
                      'usermin'           => 'fa-cog',
                      'settings'          => 'fa-cog',
                      'global_setting'    => 'fa-cog',
                      'cat_settings'      => 'fa-cog',
                      'system'            => 'fa2 fa2-system',
                      'cat_system'        => 'fa2 fa2-system',
                      'servers'           => 'fa2 fa2-server',
                      'other'             => 'fa2 fa2-tools',
                      'info'              => 'fa-info',
                      'hardware'          => 'fa2 fa2-disk',
                      'global_hardware'   => 'fa2 fa2-disk',
                      'global_storage'    => 'fa2 fa2-disk',
                      'cluster'           => 'fa2 fa2-cluster',
                      'global_cluster'    => 'fa-power-off',
                      'unused'            => 'fa-puzzle-piece',
                      'global_unused'     => 'fa-puzzle-piece',
                      'mail'              => 'fa2 fa2-email scaled1_5',
                      'global_mail'       => 'fa2 fa2-email scaled1_5',
                      'email'             => 'fa2 fa2-email scaled1_5',
                      'global_email'      => 'fa2 fa2-email scaled1_5',
                      'login'             => 'fa-user',
                      'global_login'      => 'fa-user',
                      'apps'              => 'fa2 fa2-server',
                      'global_apps'       => 'fa2 fa2-server',
                      'custom'            => 'fa2 fa2-system',
                      'global_custom'     => 'fa2 fa2-system',
                      'net'               => 'fa2 fa2-network',
                      'ip'                => 'fa2 fa2-network',
                      'global_ip'         => 'fa2 fa2-network',
                      'check'             => 'fa-user-md',
                      'global_check'      => 'fa-user-md',
                      'add'               => 'fa-plus',
                      'global_add'        => 'fa-plus',
                      'backup'            => 'fa-backup fa-1_15x',
                      'global_backup'     => 'fa-backup fa-1_15x',
                      'global_server',    => 'fa-cogs',
                      'cat_server',       => 'fa-cogs',
                      'global_system'     => 'fa-cogs',
                      'global_delete'     => 'fa-plug',
                      'cat_delete'        => 'fa-plug',
                      'global_logs'       => 'fa-file-text',
                      'cat_logs'          => 'fa-file-text',
                      'global_services'   => 'fa-puzzle-piece',
                      'cat_services'      => 'fa-puzzle-piece',
                      'cat_dns'           => 'fa2 fa2-dns scaled1_5',
                      'cat_dnsreg'        => 'fa2 fa2-domain scaled1_5',
                      'cat_mail'          => 'fa2 fa2-email-open scaled1_5',
                      'cat_web'           => 'fa2 fa2-web scaled1_5',
                      'create_new'        => 'fa-plus',
                      'create_add'        => 'fa-plus',
                      'create_create'     => 'fa-server-add',
                      'global_gce'        => 'fa-google',
                      'global_ec2'        => 'fa2 fa2-amazon scaled1_5',
                      'global_hosts'      => 'fa-globe',
                      'global_docker'     => 'fa2 fa2-docker margined-left--1 margined-right-1',
                      'global_virtualmin' => 'fa-virtualmin scaled1_5',
                      'global_owners'     => 'fa-users',
                      'global_monitor'    => 'fa2 fa2-system',
                      'global_settings'   => 'fa-cloud',
                      'cat_manage'        => 'fa2 fa2-tools',
                      'cat_res'           => 'fa-share-alt',
                      'global_admin'      => 'fa-key',
                      'cat_admin'         => 'fa-key',
                      'global_power'      => 'fa-power-off',
                      'cat_power'         => 'fa-power-off',
                      'cat_webmin'        => 'fa-webmin webmin-cat-menu',);

    my $icon = $icon_table{$c} || 'fa-link';
    if ($label) {
        my $rv;

        # Show link to close or open catgory
        $rv = "<li class=\"has-sub\">\n";
        $rv .= "<a data-has-sub-link href=\"#$c\">";
        $rv .= "<i class=\"fa $icon fa-fw\"></i> <span>@{[&filter_javascript($label)]}</span></a>\n";
        $rv .= '</li>' . "\n";
        return $rv;
    }
}

sub nav_search
{
    my $rv = "<li><br></li>";
    if (-r "$root_directory/webmin_search.cgi" && $gaccess{'webminsearch'}) {
        $rv = "<li class=\"menu-container search-form-container\">\n";
        $rv .= "<form id=\"webmin_search_form\" action=\"$theme_webprefix/webmin_search.cgi\" role=\"search\">\n";
        $rv .= "<div class=\"form-group\">\n";
        $rv .=
"<input type=\"text\" class=\"form-control sidebar-search\" name=\"search\" placeholder=\"$theme_text{'left_search'}\">\n";
        $rv .= "<i class=\"fa fa-search\"></i>\n";
        $rv .= "</div>\n";
        $rv .= "</form>\n</li>\n";
    }
    return $rv;
}

sub nav_link_sysinfo
{
    my ($user, $mod) = @_;
    $mod = "?mod=$mod" if ($mod);
    return
      nav_menu_link("/sysinfo.cgi$mod",
                    $user ? $theme_text{'body_header1'} : $theme_text{'theme_xhred_titles_dashboard'},
                    ($user ? 'fa-user-circle' : 'fa-dashboard'),
                    $theme_config{'settings_sysinfo_link_mini'} eq 'true', 1)
      if (dashboard_switch() ne '1');

}

sub nav_link_sysstat
{
    my $link;
    if (&webmin_user_is_admin()) {
        if (-d $root_directory . "/virtual-server/pro/timeplot") {
            $link = 'virtual-server/pro';
        } elsif (-d $root_directory . "/server-manager/timeplot") {
            $link = 'server-manager';
        }
        if ($link) {
            return nav_menu_link("/$link/history.cgi", $theme_text{'left_statistics'}, 'fa-area-chart', 0, 1);
        }
    }
}

sub nav_link_netdata
{
    my $link;
    if (&webmin_user_is_admin()) {
        if (has_command('netdata') &&
            $theme_config{'settings_leftmenu_netdata'} ne 'false')
        {
            ($theme_config{'settings_leftmenu_netdata_link'} ? ($link = $theme_config{'settings_leftmenu_netdata_link'}) :
               ($link = 'http://' . get_system_hostname() . ':19999'));
        }
        if ($link) {
            my $rv;
            $rv = "<li data-after class=\"leftmenu_netdata_link\">\n";
            $rv .= "<a target=\"_blank\" href=\"$link\" class=\"navigation_external_link leftmenu_netdata_link\">\n";
            $rv .= "<i class=\"fa fa-fw fa-line-chart\"></i> <span>$theme_text{'left_netdata'}</span>\n";
            $rv .= "</a></li>\n";
            return $rv;
        }
    }
}

sub nav_theme_links
{
    my $extra = $theme_config{'settings_leftmenu_custom_links'};
    my $rv    = "";
    if ($extra) {
        $extra = replace('\'', '"', un_urlize($extra, 1));
        if ($extra && $extra =~ m/"extra":/) {
            my ($extra) = $extra =~ /\{(?:\{.*\}|[^{])*\}/sg;
            my $extra_json = convert_from_json($extra);
            foreach my $e (@{ $extra_json->{'extra'} }) {
                if (length($e->{"link"}) && (!length($e->{"level"}) || string_contains($e->{"level"}, $get_user_level))) {
                    my $target = $e->{"target"};
                    if ($target) {
                        $target = " target=\"$target\"";
                    }
                    if ($e->{"port"}) {
                        my $host = $e->{"host"};
                        if (!$host) {
                            $host = get_env('http_host');
                            $host =~ s/:(\d+)$/:$e->{'port'}/;
                        } else {
                            $host .= ":$e->{'port'}";
                        }
                        my $proto = $e->{'protocol'} ? "$e->{'protocol'}://" : "//";
                        $e->{"link"} = "$proto$host$e->{'link'}";
                    }
                    my $type       = string_contains($e->{'link'}, '&#47;&#47') ? '' : 'data-linked';
                    my $type_class = $type ? "navigation_module_trigger"             : "navigation_external_link";
                    $rv .= '<li ' . $type . ' data-after><a ' . $target . ' href="' .
                      quote_escape($e->{"link"}, '"') . '" class="' . $type_class . '"><i class="fa fa-fw fa-' . $e->{"icon"} . '"></i> <span>';
                    utf8::encode($e->{'title'});
                    $rv .= $e->{'title'};
                    $rv .= '</span></a></li>';
                }
            }
        }
    }
    return $rv;
}

# Return HTML menu structure for given module
sub nav_list_combined_menu
{
    my ($modules, $items, $id, $group, $page) = @_;
    my ($nav_pos, $extra_links, $rv, $rv_after, $login_mode);

    my $gwp = sub {
        my ($link) = @_;

        # Link could but shouldn't end with just &
        $link =~ s/&amp;$//;

        if ($link) {
            if (!string_starts_with($link, "http") &&
                !string_starts_with($link, "ftp") &&
                !string_starts_with($link, "www") &&
                !string_starts_with($link, "../"))
            {
                $link = "/$link" if (!string_starts_with($link, "/"));
                $link = "$theme_webprefix$link"
                  if ($link !~ /^\Q$theme_webprefix\E/);
            }
        }
        return $link;
    };
    foreach my $item (@$items) {
        if ((grep {$_ eq $item->{'module'}} @{$modules}) || $group) {

            my $link = &$gwp($item->{'link'});
            my $icon;
            my $rv_after_local;

            if ($item->{'type'} eq 'item' &&
                $link !~ /virtual-server\/pro\/history\.cgi/)
            {

                # Define an icon for the link/accordion
                if ($link =~ /virtual-server\/index\.cgi/ ||
                    $link =~ /server-manager\/index\.cgi/)
                {
                    $icon = '<i class="fa fa-fw fa-tasks"></i>';
                } elsif ($link =~ /\/virtual-server\/edit_newvalidate\.cgi/ &&
                         !&webmin_user_is_admin())
                {
                    $icon = '<i class="fa fa-fw fa-user-md"></i>';
                } elsif ($link =~ /mailbox\/list_folders\.cgi/ ||
                         $link =~ /mailbox\/list_ifolders\.cgi/)
                {
                    $icon = '<i class="fa fa-fw fa-folder"></i>';
                } elsif ($link =~ /mailbox\/list_addresses\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-address-book"></i>';
                } elsif ($link =~ /filter\/edit_forward\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-share"></i>';
                } elsif ($link =~ /filter\/edit_auto\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-reply-all"></i>';
                } elsif ($link =~ /filter/) {
                    $icon = '<i class="fa fa-fw fa-filter"></i>';
                } elsif ($link =~ /mailbox\/edit_sig\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-pencil"></i>';
                } elsif ($link =~ /mailbox\/index\.cgi?id=/) {
                    $icon = '<i class="fa fa-fw fa-folder-o"></i>';
                } elsif ($link =~ /\/#demo_history$/) {
                    $icon           = '<i class="fa fa-fw fa-area-chart"></i>';
                    $rv_after_local = $link;
                }

                if ($get_user_level == 1) {
                    if ($link =~ /\/virtual-server\/edit_pass\.cgi/ &&
                        $link !~ /\/virtual-server\/edit_pass\.cgi\?/)
                    {
                        $icon = '<i class="fa fa-fw fa-key"></i>';
                    } elsif ($link =~ /\/virtual-server\/edit_newplan\.cgi/) {
                        $icon = '<i class="fa fa-fw fa-list"></i>';
                    } elsif ($link =~ /\/virtual-server\/edit_newresels\.cgi/) {
                        $icon = '<i class="fa fa-fw fa-cog"></i>';
                    } elsif ($link =~ /\/virtual-server\/bwgraph\.cgi/ && $id ne 'cat_logs') {
                        $icon = '<i class="fa fa-fw fa-line-chart"></i>';
                    }
                }

                if ($link =~ /\/virtual-server\/domain_form\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-server-add"></i>';

                } elsif ($link =~ /\/virtual-server\/edit_domain\.cgi/ ||
                         $link =~ /\/server-manager\/edit_serv\.cgi/)
                {
                    $icon = '<i class="fa fa-fw fa2 fa2-settings"></i>';
                } elsif ($link =~ /\/virtual-server\/view_domain\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-info-circle"></i>';

                } elsif ($link =~ /\/virtual-server\/list_users\.cgi/) {
                    $icon = '<i class="fa fa-fw fa2 fa2-users-cog"></i>';
                } elsif ($link =~ /\/virtual-server\/list_aliases\.cgi/ && $id ne 'cat_mail') {
                    $icon = '<i class="fa fa-fw fa2 fa2-maillist"></i>';
                } elsif ($link =~ /\/virtual-server\/list_databases\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-database"></i>';
                } elsif ($link =~ /\/virtual-server\/list_scripts\.cgi/ ||
                         $link =~ /\/server-manager\/mass_update_form\.cgi/)
                {
                    $icon = '<i class="fa fa-fw fa-update scaled1"></i>';
                } elsif ($link =~ /\/filemin\/index\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-file-manager scaled2"></i>';

                } elsif ($link =~ /\/xterm\/index\.cgi\?user/) {
                    $icon = '<i class="fa fa2 fa-fw fa2-terminal fa-1_10x margined-right--2"></i>';

                } elsif ($link =~ /\/virtual-server\/edit_html\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-globe"></i>';
                } elsif ($link =~ /\/server-manager\/edit_pass\.cgi/ ||
                         $link =~ /\/virtual-server\/edit_pass\.cgi$/ ||
                         $link =~ /\/changepass\/$/)
                {
                    $icon = '<i class="fa fa-fw fa-key"></i>';
                } elsif ($link =~ /\/server-manager\/save_serv\.cgi/ && $link =~ /recheck=1/) {
                    $icon = '<i class="fa fa-fw fa-exclamation-triangle"></i>';
                } elsif ($link =~ /\/server-manager\/create_form\.cgi/ && !$group) {
                    $icon = '<i class="fa fa-fw fa-server-add"></i>';
                } elsif ($link =~ /\/server-manager\/save_serv\.cgi/) {
                    if ($link =~ /refresh=1/) {
                        $icon = '<i class="fa fa-fw fa-refresh"></i>';
                    } elsif ($link =~ /regen=1/) {
                        $icon = '<i class="fa fa-fw fa-retweet"></i>';
                    }
                } elsif (
                        ($link =~ /^http:\/\// || $link =~ /^https:\/\// || $link =~ /^ftp:\/\// || $link =~ /^ftps:\/\//) &&
                        $link !~ /virtualmin\.com\/professional/)
                {
                    $icon = '<i class="fa fa-fw fa-external-link"></i>';
                } elsif ($link =~ /\.\.\/servers\/link\.cgi/) {
                    $icon = '<i class="fa fa-fw fa-webmin scaled1_5"></i>';
                }

                # Print Virtual Server Summary link
                my $print_server_summary = sub {
                    my ($dom_id) = @_;
                    return '<li data-linked><a target="page" class="navigation_module_trigger" href="' .
                      $theme_webprefix . '/virtual-server/summary_domain.cgi?dom=' .
                      $dom_id . '"><i class="fa fa-fw fa-info-circle"></i> <span>' .
                      $theme_text{'right_vm_server_summary'} . '</span></a></li>' . "\n";
                };
                if ((&webmin_user_is_admin() || $get_user_level eq '1') &&
                    $link =~ /\/virtual-server\/domain_form\.cgi/ &&
                    nav_virtualmin_domain_available_count())
                {
                    my $dom_id = $item->{'link'};
                    $dom_id =~ /gparent=(\d+)/;
                    $dom_id = $1;
                    if ($dom_id) {
                        $rv .= &$print_server_summary($dom_id);
                    }
                }

                # Set variable in case it hasn't been set before
                if (!length $link) {
                    $icon = undef;
                }

                my $rv_;
                $rv_ = '<li' . ($item->{'inactive'} ? " data-link-inactive" : "") . ' data-linked'
                  .
                  ( $item->{'target'} ? ' class="navigation_external"' :
                      ''
                  ) .
                  '>' . "\n";
                $rv_ .=
                  '<a ' .
                  ($link !~ /switch_user/ ? ' target="' . ($item->{'target'} ? '_blank' : 'page') . '" ' : '') . ' '
                  .
                  ( (!$group && !$item->{'target'}) ? "class=\"navigation_module_trigger\" " :
                      ''
                  ) .
                  'href="' . $link . '">' .
                  ($icon =~ /<i/ ? $icon : '') . ' <span>' . $item->{'desc'} . '</span></a>' . "\n";
                $rv_ .= '</li>' . "\n";
                $rv_ .= "\n";

                if ($rv_after_local) {
                    $rv_after .= $rv_;
                } else {
                    $rv .= $rv_;
                }

            } elsif ($item->{'type'} eq 'html') {
                if (trim(html_strip($item->{'html'}))) {
                    $rv .= '<li class="menu-container menu-status"><span class="badge"><i class="fa2 fa-fw fa2-pulsate"></i>' .
                      $item->{'html'} . '</span></li>';
                }
            } elsif ($item->{'type'} eq 'text' && $item->{'json'}) {
                    $login_mode =
"<span><strong>$theme_text{'theme_global_access_level'}</strong>:&nbsp;&nbsp;<em>@{[html_escape($item->{'json'}->{'level'})]}</em></span>";
            } elsif ($item->{'type'} eq 'text' && $item->{'desc'}) {
                if ($login_mode++ == 1) {
                    $login_mode =
"<span><strong>$theme_text{'theme_global_access_level'}</strong>:&nbsp;&nbsp;<em>@{[html_escape($item->{'desc'})]}</em></span>";
                }
            } elsif ($item->{'type'} eq 'cat') {
                $rv .= nav_cat($item->{'id'}, $item->{'desc'});
                $rv .= '<li class="sub-wrapper"><ul class="sub" style="display: none;" id="' . $item->{'id'} . '">' . "\n";
                my $menu = nav_list_combined_menu([$item->{'module'}], $item->{'members'}, $item->{'id'}, 'group');
                $rv .= $menu->{'before'};

                if (($item->{'id'} eq 'global_setting' || $item->{'id'} eq 'global_settings') &&
                    &webmin_user_is_admin() &&
                    !$extra_links++)
                {
                    $rv .=
                      nav_cat_link("/tconfig.cgi", $theme_text{'settings_right_theme_left_configuration_title'}, 'hidden');
                    $rv .= nav_cat_link("/settings-editor_read.cgi",
                                        $theme_text{'settings_right_theme_left_extensions_title'}, 'hidden');
                    $rv .=
                      nav_cat_link("/settings-logos.cgi", $theme_text{'settings_right_theme_left_logo_title'}, 'hidden');
                    $rv .= nav_cat_link("/settings-backgrounds.cgi",
                                        $theme_text{'theme_xhred_settings_right_theme_bgs_title'}, 'hidden');

                    if (check_pro_package('vm') eq '1' &&
                        $item->{'module'} eq 'virtual-server')
                    {
                        $rv .= nav_cat_link("/virtual-server/licence.cgi", $theme_text{'right_vlcheck'}, 1);
                    }

                    if (check_pro_package('cm') eq '1' &&
                        $item->{'module'} eq 'server-manager')
                    {
                        $rv .= nav_cat_link("/server-manager/licence.cgi", $theme_text{'right_slcheck'}, 1);
                    }

                } elsif (!&webmin_user_is_admin() &&
                         $theme_config{'settings_theme_config_admins_only_privileged'} ne 'true' &&
                         !$extra_links++)
                {
                    $rv .= nav_cat_link("/tconfig.cgi", $theme_text{'settings_right_theme_left_configuration_title'}, 1);
                }
                $rv .= "</ul></li>\n";
            } elsif ($item->{'type'} eq 'hr') {
                if ($nav_pos++ eq '1') {
                    $rv .= nav_search();
                }
            } elsif (($item->{'type'} eq 'menu' || $item->{'type'} eq 'input') &&
                     $item->{'module'} ne 'mailbox')
            {

                # For with an input of some kind
                if ($item->{'cgi'}) {
                    $rv .= "<li class=\"menu-container\"><form action='$item->{'cgi'}'>\n";
                } else {
                    $rv .= "<li class=\"menu-container\"><form>\n";
                }
                foreach my $h (@{ $item->{'hidden'} }) {
                    $rv .= ui_hidden(@$h);
                }

                $rv .= $item->{'desc'}, "\n";
                if ($item->{'type'} eq 'menu' || $item->{'type'} eq 'input') {
                    if ($item->{'name'} eq 'dname' && $item->{'module'} eq 'virtual-server') {

                        # Force select type
                        $item->{'name'}  = 'dom';
                        $item->{'value'} = $item->{'domid'};

                        # Regenerate data for select
                        $item->{'menu'} = [
                            map {
                                [$_->{'id'},
                                 virtual_server::shorten_domain_name($_),
                                 "title=\"" . virtual_server::show_domain_name($_) . "\""]
                              }
                              grep {virtual_server::can_edit_domain($_)}
                              sort {$a->{'dom'} cmp $b->{'dom'}} virtual_server::list_visible_domains()];
                    }
                    my $data_title =
                      $item->{'module'} eq 'virtual-server' ? $theme_text{'right_fdoms'} : $theme_text{'right_fvm2'};
                    my $select_width = ($theme_config{'settings_leftmenu_width'} - 11 * 2);
                    my $style        = "data-autocomplete-title=\"$data_title\" style=\"width:${select_width}px;\"";

                    # Build select menu
                    $rv .= ui_select($item->{'name'}, $item->{'value'}, $item->{'menu'}, 1, 0, 0, 0, $style);
                }
                $rv .= "</form></li>\n";
            }
        }
    }
    return { 'before' => $rv,
             'after'  => $rv_after,
             'mode'   => $login_mode };
}

# Returns a list of tiny square buttons for navigation menu
sub nav_links
{
    my ($login_mode) = @_;
    my $rv;
    $rv =
      '<li class="menu-container"><ul class="user-links"><li data-collapse-trigger-container data-linked' .
      get_button_tooltip('theme_xhred_tooltip_navigation_pinned', 'settings_hotkey_navigation', 'auto top') .
      ' class="user-link cursor-pointer' .
      ($theme_config{'settings_collapse_navigation_link'} eq 'false' && ' hidden') . '">';
    $rv .= '<span><i data-collapse-trigger="1" class="fa fa2 fa-fw fa2-collapse-left"></i></span>';
    $rv .= '</li>';

    if ($theme_config{'settings_sysinfo_link_mini'} eq 'true' &&
        dashboard_switch() ne '1')
    {
        $rv .= '<li data-linked' .
          get_button_tooltip('theme_xhred_titles_dashboard', 'settings_hotkey_sysinfo', 'auto top') . ' class="user-link">';
        $rv .=
          '<a class="menu-exclude-link sidebar_sysinfo_link" href="' .
          $theme_webprefix . '/sysinfo.cgi"><i class="fa fa-fw fa-' .
          ($get_user_level eq '3' ? 'user-circle' : 'dashboard') . '"></i></a>';
        $rv .= '</li>';
    }

    $rv .=
      '<li data-linked' .
      get_button_tooltip('theme_tooltip_night_mode', 'settings_hotkey_toggle_key_night_mode', 'auto top') .
      ' class="user-link palette-toggle cursor-pointer'
      .
      ( $theme_config{'settings_show_night_mode_link'} ne 'false' ? '' :
          ' hidden'
      ) .
      '">';
    $rv .= '<span><i class="fa fa-fw ' . (theme_night_mode() ? 'fa-sun' : 'fa-moon') . '"></i></span>';
    $rv .= '</li>';

    if ((foreign_available("xterm") && $theme_config{'settings_show_terminal_link'} ne 'false') ||
        (!foreign_available("xterm") && foreign_available("shell") && $theme_config{'settings_show_terminal_link2'} ne 'false'))
    {
        my $t = foreign_available("xterm") ? undef : '2';
        my $t_icons = !$t ? 'fa2 fa2-terminal' : 'fa fa-terminal';
        $rv .=
          '<li data-linked' .
          get_button_tooltip('theme_tooltip_terminal_link' . $t . '', 'settings_hotkey_shell' . $t . '', 'auto top') .
          ' class="user-link ported-console cursor-pointer">';
        $rv .= "<span><i class=\"$t_icons fa-fw\"></i></span>";
        $rv .= '</li>';
    }

    $rv .=
      '<li data-linked' . get_button_tooltip('left_favorites', 'settings_hotkey_favorites', 'auto top') .
      ' class="user-link favorites cursor-pointer' .
      ($theme_config{'settings_favorites'} ne 'false' ? '' : ' hidden') . '">';
    $rv .= '<span><i class="fa fa-fw fa-star"></i></span>';
    $rv .= '</li>';

    if ((&webmin_user_is_admin()  && $theme_config{'settings_theme_options_button'} ne 'false') ||
        (!&webmin_user_is_admin() &&
            $theme_config{'settings_theme_config_admins_only_privileged'} ne 'true' &&
            $theme_config{'settings_theme_options_button'} ne 'false'))
    {
        my $tooltip = get_button_tooltip('settings_title', 'settings_hotkey_open_module_config_privileged', 'auto top');
        $rv .= "<li $tooltip data-linked class=\"user-link theme-options cursor-pointer\">";
        $rv .= '<a class="menu-exclude-link" href="' . $theme_webprefix .
          '/tconfig.cgi" data-href="' . $theme_webprefix . '/tconfig.cgi"><i class="fa2 fa-fw fa2-palette"></i></a>';
        $rv .= '</li>';
    }

    if (&foreign_available("change-user") &&
        $theme_config{'settings_leftmenu_button_language'} eq 'true')
    {
        $rv .=
          '<li data-linked' . get_button_tooltip('theme_xhred_title_language_locale', undef, 'auto top') .
          ' class="user-link"><a class="menu-exclude-link" href="' .
          $theme_webprefix . '/change-user"><i class="fa fa-fw fa-globe"></i></a></li>';
    }

    my $foreign_acl = &foreign_available("acl");
    my $user_mode   = get_product_name() eq 'usermin';
    my $edit_user =
      ($foreign_acl ? ("<hr class='hr-no-margin hr-darker'>" . $theme_text{'theme_tooltip_edit_user'}) : undef);
    my $title_proc;
    if (!$user_mode && $login_mode && $login_mode !~ /^\d+$/) {
        $title_proc = $login_mode . $edit_user;
    } else {
        $title_proc =
          $foreign_acl ? $theme_text{'theme_tooltip_edit_user'} :
          ( get_product_name() eq 'usermin' ?
"<span><strong>$theme_text{'theme_global_access_level'}</strong>:&nbsp;&nbsp;<em>$theme_text{'theme_global_user_mode'}</em></span>"
            :
              undef);
    }
    my $user_title = get_button_tooltip($title_proc, undef, 'auto top', 1, undef, "aside");
    my $menu_elem_br;
    my $menu_width         = $theme_config{'settings_leftmenu_width'};
    my $button_width       = 26;
    my $button_margin      = 2;
    my $char_width         = 5.73;
    my $menu_lnk_colla     = $theme_config{'settings_collapse_navigation_link'} eq 'true';
    my $menu_lnk_dashb     = $theme_config{'settings_sysinfo_link_mini'} eq 'true';
    my $menu_lnk_night     = $theme_config{'settings_show_night_mode_link'} eq 'true';
    my $menu_lnk_favor     = $theme_config{'settings_favorites'} eq 'true';
    my $menu_lnk_themeconf = $theme_config{'settings_theme_options_button'} eq 'true';
    my $menu_lnk_lang      = $theme_config{'settings_leftmenu_button_language'} eq 'true';
    my $menu_lnk_refresh   = $theme_config{'settings_leftmenu_button_refresh'} eq 'true';
    my $menu_lnk_term      = $theme_config{'settings_show_terminal_link'} eq 'true' ||
      $theme_config{'settings_show_terminal_link2'} eq 'true';

    # Link buttons widths
    my $menu_width_needed = 0;
    foreach my $e (
                   ($menu_lnk_colla,
                    $menu_lnk_dashb,
                    $menu_lnk_night,
                    $menu_lnk_term,
                    $menu_lnk_favor,
                    $menu_lnk_themeconf,
                    $menu_lnk_lang,
                    $menu_lnk_refresh))
    {
        if ($e) {
            $menu_width_needed += ($button_width + $button_margin);
        }
    }

    # User button link
    $menu_width_needed += ($button_width + (4 * $button_margin)) + int($char_width * length($remote_user));

    # Logout button link
    $menu_width_needed += $button_width;

    # Servers index menu
    $menu_width_needed += $button_width * 2 if ($theme_server_webprefix);

    if ($menu_width - $menu_width_needed < $button_width - $button_margin) {
        $menu_elem_br = '<li class="flex-br"></li>';
    }
    my $cursor_def = !$foreign_acl ? ' cursor-default' : undef;
    $rv .= "$menu_elem_br<li $user_title class=\"user-link user-link-acl$cursor_def\">";
    if ($foreign_acl) {
        $rv .=
          '<a class="menu-exclude-link" data-href="' . $theme_webprefix . '/acl/edit_user.cgi" href="' .
          $theme_webprefix . '/acl/edit_user.cgi?user=' . (get_env('base_remote_user') eq "root" ? "root" : $remote_user) .
          '"><i class="fa2 fa-fw ' . get_user_icon() . '"></i>&nbsp;<span>' . $remote_user . '</span></a>';
    } else {
        $rv .=
          '<a class="menu-exclude-link cursor-default no-hover"><i class="fa2 fa-fw ' .
          get_user_icon() . '"></i>&nbsp;<span>' . $remote_user . '</span></a>';
    }
    $rv .= '</li>';

    my %miniserv;
    &get_miniserv_config(\%miniserv);

    if ($miniserv{'logout'} &&
        !get_env('ssl_user') &&
        get_env('http_user_agent') !~ /webmin/i)
    {
        my $tooltip = get_button_tooltip(($main::session_id ? 'theme_tooltip_logout' : 'theme_xhred_tooltip_switch_user'),
                                         'settings_hotkey_logout_dbl', 'auto top');
        $rv .= "<li $tooltip class=\"user-link __logout-link\">";
        if ($main::session_id) {
            $rv .=
              '<a data-nref class="menu-exclude-link" href="' .
              $theme_webprefix . '/session_login.cgi?logout=1"><i class="fa fa-fw fa-sign-out text-danger"></i></a>';
        } else {
            $rv .=
              '<a data-nref class="menu-exclude-link" href="' .
              $theme_webprefix . '/switch_user.cgi"><i class="fa fa-fw fa-exchange text-danger"></i></a>';
        }
        $rv .= '</li>';
    } else {
        if ($theme_server_webprefix) {
            my $master_link           = "$gconfig{'webprefix'}/servers/";
            my $tooltip_go_to_master  = get_button_tooltip('tooltip_back_to_servers_index_master', undef, 'auto top');
            my $tooltip_other_servers = get_button_tooltip('tooltip_list_other_servers',           undef, 'auto top');
            $rv .= "<li class=\"user-link servers-index-link\">";
            $rv .=
              '<a ' . $tooltip_go_to_master . ' data-nref class="menu-exclude-link" href="' .
              $master_link . '?' . $xnav . '"><i class="fa fa-fw fa2 fa2-server"></i></a>';
            $rv .= '
                <div data-http-webmin-servers="' .
              $master_link . '" ' . $tooltip_other_servers . ' class="popover-trigger hidden">
                    <a data-servers-index="popover">
                        <span class="popover-trigger-toggle" type="button" data-toggle="popover-trigger">
                            <span class="caret-" href="#">▼</span>
                        </span>
                    </a>
                </div>
            </li>';
        }
    }

    $rv .=
      '<li data-linked' .
      get_button_tooltip('theme_xhred_filemanager_context_refresh', 'settings_hotkey_reload', 'auto top') .
      ' class="user-link' . ($theme_config{'settings_leftmenu_button_refresh'} ne 'true' && ' hidden') .
'"><a class="menu-exclude-link" data-refresh="true" style="cursor: pointer"><i class="fa fa-fw fa-refresh"></i></a></li>';
    $rv .= '</ul></li>';
    $rv .= "\n";
    return $rv;
}

# XXX - needs further refactor
sub print_switch_webmin
{
    my ($tab)   = @_;
    my $prod    = get_product_name();
    my $checked = 0;
    if ($tab eq $prod) {
        $checked = 1;
    }

    print '<input class="dynamic" id="open_' . $prod . '" name="product-switcher" type="radio"' .
      ($checked ? " checked" : "") . '>
        <label'
      . get_button_tooltip(
                           (get_product_name() eq 'usermin' ? 'theme_xhred_titles_um' :
                              'theme_xhred_titles_wm'
                           ),
                           'settings_hotkey_toggle_key_' . get_product_name() . '',
                           'auto bottom'
      ) .
      ' for="open_' . get_product_name() . '">
                <i class="wbm-webmin wbm-sm"></i><span>'
      . (&get_product_name() eq 'webmin' ? $theme_text{'theme_xhred_titles_wm'} :
           $theme_text{'theme_xhred_titles_um'}
      ) .
      '</span></label>';
}

# XXX - needs further refactor
sub print_switch_dashboard
{
    my ($tab) = @_;
    my $checked = 0;
    if ($tab eq 'dashboard') {
        $checked = 1;
    }

    print '<input class="dynamic" id="open_dashboard" name="product-switcher" type="radio"' .
      ($checked ? " checked" : "") . '>
          <label'
      . get_button_tooltip('theme_xhred_titles_dashboard', 'settings_hotkey_sysinfo', 'auto right') .
      ' for="open_dashboard" style="padding-top: 1px;">
          <i class="fa fa-stack fa-dashboard"></i><span>'
      . $theme_text{'theme_xhred_titles_dashboard'} . '</span></label>';
}

# XXX - needs further refactor
sub print_switch_virtualmin
{
    my ($tab) = @_;
    my $checked = 0;
    if ($tab eq 'virtualmin') {
        $checked = 1;
    }

    print '<input class="dynamic" id="open_virtualmin" name="product-switcher" type="radio"' .
      ($checked ? " checked" : "") . '>
          <label'
      . get_button_tooltip('theme_xhred_titles_vm', 'settings_hotkey_toggle_key_virtualmin', 'auto right') .
      ' for="open_virtualmin">
          <i class="wbm-virtualmin wbm-sm"></i><span>'
      . $theme_text{'theme_xhred_titles_vm'} . '</span></label>';
}

# XXX - needs further refactor
sub print_switch_cloudmin
{
    my ($tab) = @_;
    my $checked = 0;
    if ($tab eq 'cloudmin') {
        $checked = 1;
    }

    print '<input class="dynamic" id="open_cloudmin" name="product-switcher" type="radio"' .
      ($checked ? " checked" : "") . '>
          <label'
      . get_button_tooltip('theme_xhred_titles_cm', 'settings_hotkey_toggle_key_cloudmin', 'auto right') .
      ' for="open_cloudmin">
          <i class="wbm-cloudmin wbm-sm"></i><span>'
      . $theme_text{'theme_xhred_titles_cm'} . '</span></label>';
}

# XXX - needs further refactor
sub print_switch_webmail
{
    my ($tab) = @_;
    my $checked = 0;
    if ($tab eq 'webmail') {
        $checked = 1;
    }

    print '<input class="dynamic" id="open_webmail" name="product-switcher" type="radio"' . ($checked ? " checked" : "") . '>
          <label'
      . get_button_tooltip('theme_xhred_titles_mail', 'settings_hotkey_toggle_key_webmail', 'auto right') .
      ' for="open_webmail">
          <i class="fa fa-stack fa-envelope"></i>
          <span>' . $theme_text{'theme_xhred_titles_mail'} . '</span></label>';
}

# XXX - needs further refactor
sub print_switch
{

    my ($t_var_switch_m, $t_var_product_m);

    if (&get_product_name() eq 'usermin' &&
        &foreign_available("mailbox"))
    {
        $t_var_switch_m  = '2';
        $t_var_product_m = '4';
    } elsif (!&foreign_available("virtual-server") && !&foreign_available("server-manager") ||
             &get_product_name() eq 'usermin' ||
             $get_user_level eq '2')
    {

        $t_var_switch_m  = '2';
        $t_var_product_m = '1';
    } elsif (&foreign_available("virtual-server") &&
             &foreign_available("server-manager"))
    {
        $t_var_switch_m  = '3';
        $t_var_product_m = '3';
    } elsif (&foreign_available("virtual-server") ||
             &foreign_available("server-manager") && (!&foreign_available("virtual-server") ||
                                                      !&foreign_available("server-manager")))
    {
        $t_var_switch_m  = '2';
        $t_var_product_m = '2';
    }

    my $o = ($theme_config{'settings_switch_rdisplay'} ne 'true' ? 'd' :
               'r');
    my ($tab, $page) = nav_detector();

    print '<div class="switch-toggle switch-' . $t_var_switch_m . ' switch-mins">';
    if ($t_var_product_m eq '1') {
        if ($o eq 'd') {
            if ($get_user_level eq '2') {
                print_switch_virtualmin($tab);
                print_switch_dashboard($tab);
            } else {
                print_switch_webmin($tab);
                print_switch_dashboard($tab);
            }
        } else {
            if ($get_user_level eq '2') {
                print_switch_dashboard($tab);
                print_switch_virtualmin($tab);
            } else {
                print_switch_dashboard($tab);
                print_switch_webmin($tab);
            }
        }
    }
    if ($t_var_product_m eq '2') {
        if ($get_user_level eq '4') {
            if ($o eq 'd') {
                print_switch_cloudmin($tab);
                print_switch_dashboard($tab);

            } else {
                print_switch_dashboard($tab);
                print_switch_cloudmin($tab);

            }
        } else {
            if ($o eq 'd') {
                print_switch_webmin($tab);
                &foreign_available("virtual-server") ? print_switch_virtualmin($tab) :
                  print_switch_cloudmin($tab);

            } else {
                &foreign_available("virtual-server") ? print_switch_virtualmin($tab) :
                  print_switch_cloudmin($tab);
                print_switch_webmin($tab);

            }
        }
    }
    if ($t_var_product_m eq '3') {
        if ($o eq 'd') {
            print_switch_webmin($tab);
            print_switch_virtualmin($tab);
            print_switch_cloudmin($tab);

        } else {
            print_switch_cloudmin($tab);
            print_switch_virtualmin($tab);
            print_switch_webmin($tab);

        }
    }
    if ($t_var_product_m eq '4') {

        if ($o eq 'd') {
            print_switch_webmail($tab);
            print_switch_webmin($tab);
        } else {
            print_switch_webmin($tab);
            print_switch_webmail($tab);
        }

    }
    print '<a></a>
            </div><div class="toggle-space"></div>';
}

# XXX - needs further refactor
sub dashboard_switch
{
    if ($get_user_level eq '2' ||
        $get_user_level eq '4' ||
        (!foreign_available("virtual-server") &&
            !foreign_available("server-manager") &&
            (get_product_name() ne 'usermin' || (get_product_name() eq 'usermin' && !foreign_available("mailbox")))))
    {
        return 1;
    } else {
        return 0;
    }
}

sub nav_virtualmin_domain_available
{
    my ($id, $type, $gkey) = @_;
    if (&foreign_available('virtual-server')) {
        &foreign_require("virtual-server", "virtual-server-lib.pl");
        foreach my $dom (&virtual_server::list_visible_domains()) {
            if ($id eq $dom->{$type}) {
                return $gkey ? $dom->{$gkey} : $dom->{$type};
            }
        }
    }
}

sub nav_virtualmin_domain_available_count
{
    if (&foreign_available('virtual-server')) {
        &foreign_require("virtual-server", "virtual-server-lib.pl");
        my %doms = virtual_server::list_visible_domains();
        return scalar(keys %doms);
    }
}

sub nav_cloudmin_server_available
{
    my ($id, $type, $gkey) = @_;
    if (&foreign_available('server-manager')) {
        &foreign_require("server-manager", "server-manager-lib.pl");
        foreach my $host (&server_manager::list_managed_servers()) {
            if ($id eq $host->{$type}) {
                return $gkey ? $host->{$gkey} : $host->{$type};
            }
        }
    }
}

sub nav_menu_html_snippet
{
    my $rv;
    my $html_snippet         = $theme_config{'settings_leftmenu_user_html'};
    my $html_snippet_limited = $theme_config{'settings_leftmenu_user_html_privileged'};
    $html_snippet = "<i class='fa2 fa-2x-force fa2-bug opacity-0_2'></i>"
        if (!$html_snippet && theme_debug_mode());
    $html_snippet =~ s/(<(\/|\s*)(html|head|meta|link|title|body).*?>)//g;

    if ($html_snippet_limited ne 'true' ||
        ($html_snippet_limited eq 'true' && &webmin_user_is_admin()))
    {
        $rv = '<li class="menu-container"><ul class="user-html"><li class="user-html-string">';
        $rv .= $html_snippet;
        $rv .= "</li></ul></li>";
    }
}

1;

Anon7 - 2022
SCDN GOK