PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/home/dna1981/public_html.1739406478.bak/wp-content/themes/astra/inc/core/
Upload File :
Current File : /home/dna1981/public_html.1739406478.bak/wp-content/themes/astra/inc/core/common-functions.php
<?php
/**
 * Functions for Astra Theme.
 *
 * @package     Astra
 * @link        https://wpastra.com/
 * @since       Astra 1.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Foreground Color
 */
if ( ! function_exists( 'astra_get_foreground_color' ) ) {

	/**
	 * Foreground Color
	 *
	 * @param  string $hex Color code in HEX format.
	 * @return string      Return foreground color depend on input HEX color.
	 */
	function astra_get_foreground_color( $hex ) {

		$hex = apply_filters( 'astra_before_foreground_color_generation', $hex );

		// bail early if color's not set.
		if ( 'transparent' == $hex || 'false' == $hex || '#' == $hex || empty( $hex ) ) {
			return 'transparent';
		}

		// Get clean hex code.
		$hex = str_replace( '#', '', $hex );

		if ( 3 == strlen( $hex ) ) {
			$hex = str_repeat( substr( $hex, 0, 1 ), 2 ) . str_repeat( substr( $hex, 1, 1 ), 2 ) . str_repeat( substr( $hex, 2, 1 ), 2 );
		}

		if ( strpos( $hex, 'rgba' ) !== false ) {

			$rgba = preg_replace( '/[^0-9,]/', '', $hex );
			$rgba = explode( ',', $rgba );

			$hex = sprintf( '#%02x%02x%02x', $rgba[0], $rgba[1], $rgba[2] );
		}

		// Return if non hex.
		if ( function_exists( 'ctype_xdigit' ) && is_callable( 'ctype_xdigit' ) ) {
			if ( ! ctype_xdigit( $hex ) ) {
				return $hex;
			}
		} else {
			if ( ! preg_match( '/^[a-f0-9]{2,}$/i', $hex ) ) {
				return $hex;
			}
		}

		// Get r, g & b codes from hex code.
		$r   = hexdec( substr( $hex, 0, 2 ) );
		$g   = hexdec( substr( $hex, 2, 2 ) );
		$b   = hexdec( substr( $hex, 4, 2 ) );
		$hex = ( ( $r * 299 ) + ( $g * 587 ) + ( $b * 114 ) ) / 1000;

		return 128 <= $hex ? '#000000' : '#ffffff';
	}
}

/**
 * Generate CSS
 */
if ( ! function_exists( 'astra_css' ) ) {

	/**
	 * Generate CSS
	 *
	 * @param  mixed  $value         CSS value.
	 * @param  string $css_property CSS property.
	 * @param  string $selector     CSS selector.
	 * @param  string $unit         CSS property unit.
	 * @return void               Echo generated CSS.
	 */
	function astra_css( $value = '', $css_property = '', $selector = '', $unit = '' ) {

		if ( $selector ) {
			if ( $css_property && $value ) {

				if ( '' != $unit ) {
					$value .= $unit;
				}

				$css  = $selector;
				$css .= '{';
				$css .= '	' . $css_property . ': ' . $value . ';';
				$css .= '}';

				echo $css; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			}
		}
	}
}

/**
 * Get Font Size value
 */
if ( ! function_exists( 'astra_responsive_font' ) ) {

	/**
	 * Get Font CSS value
	 *
	 * @param  array  $font    CSS value.
	 * @param  string $device  CSS device.
	 * @param  string $default Default value.
	 * @return mixed
	 */
	function astra_responsive_font( $font, $device = 'desktop', $default = '' ) {

		if ( isset( $font[ $device ] ) && isset( $font[ $device . '-unit' ] ) ) {
			if ( '' != $default ) {
				$font_size = astra_get_css_value( $font[ $device ], $font[ $device . '-unit' ], $default );
			} else {
				$font_size = astra_get_font_css_value( $font[ $device ], $font[ $device . '-unit' ] );
			}
		} elseif ( is_numeric( $font ) ) {
			$font_size = astra_get_css_value( $font );
		} else {
			$font_size = ( ! is_array( $font ) ) ? $font : '';
		}

		return $font_size;
	}
}

/**
 * Get Font Size value
 */
if ( ! function_exists( 'astra_get_font_css_value' ) ) {

	/**
	 * Get Font CSS value
	 *
	 * Syntax:
	 *
	 *  astra_get_font_css_value( VALUE, DEVICE, UNIT );
	 *
	 * E.g.
	 *
	 *  astra_get_css_value( VALUE, 'desktop', '%' );
	 *  astra_get_css_value( VALUE, 'tablet' );
	 *  astra_get_css_value( VALUE, 'mobile' );
	 *
	 * @param  mixed  $value        CSS value.
	 * @param  string $unit         CSS unit.
	 * @param  string $device       CSS device.
	 * @return mixed                CSS value depends on $unit & $device
	 */
	function astra_get_font_css_value( $value, $unit = 'px', $device = 'desktop' ) {

		// If value is empty then return blank.
		if ( '' == $value || ( 0 == $value && ! astra_zero_font_size_case() ) ) {
			return '';
		}

		$css_val = '';

		switch ( $unit ) {
			case 'em':
			case 'vw':
			case 'rem':
			case '%':
						$css_val = esc_attr( $value ) . $unit;
				break;

			case 'px':
				if ( is_numeric( $value ) || strpos( $value, 'px' ) ) {
					/**
					 * Filter to disable px to rem conversion.
					 *
					 * This filter allows developers to disable the automatic conversion of font sizes from `px` to `rem` when calculating CSS values.
					 *
					 * @param bool $disable_px_to_rem Whether to disable the px to rem conversion. Default false.
					 *
					 * @since 4.8.10
					 */
					$disable_px_to_rem = apply_filters( 'astra_disable_px_to_rem_conversion', false );

					if ( $disable_px_to_rem ) {
						$css_val = esc_attr( $value ) . $unit;
						break;
					}

					$value            = intval( $value );
					$fonts            = array();
					$body_font_size   = astra_get_option( 'font-size-body' );
					$fonts['desktop'] = ( isset( $body_font_size['desktop'] ) && '' != $body_font_size['desktop'] ) ? $body_font_size['desktop'] : 15;
					$fonts['tablet']  = ( isset( $body_font_size['tablet'] ) && '' != $body_font_size['tablet'] ) ? $body_font_size['tablet'] : $fonts['desktop'];
					$fonts['mobile']  = ( isset( $body_font_size['mobile'] ) && '' != $body_font_size['mobile'] ) ? $body_font_size['mobile'] : $fonts['tablet'];

					// Construct the CSS value with the provided unit.
					$css_val = esc_attr( $value ) . $unit . ';';
					// If the device unit is 'px' and the device font size is set, convert the value to 'rem'.
					if ( $body_font_size[ $device . '-unit' ] === 'px' && $fonts[ $device ] ) {
						$css_val .= 'font-size:' . ( esc_attr( $value ) / esc_attr( $fonts[ $device ] ) ) . 'rem';
					}
				} else {
					$css_val = esc_attr( $value );
				}
		}

		return $css_val;
	}
}

/**
 * Get Font family
 */
if ( ! function_exists( 'astra_get_font_family' ) ) {

	/**
	 * Get Font family
	 *
	 * Syntax:
	 *
	 *  astra_get_font_family( VALUE, DEFAULT );
	 *
	 * E.g.
	 *  astra_get_font_family( VALUE, '' );
	 *
	 * @since  1.0.19
	 *
	 * @param  string $value       CSS value.
	 * @return mixed               CSS value depends on $unit
	 */
	function astra_get_font_family( $value = '' ) {
		$system_fonts = Astra_Font_Families::get_system_fonts();
		if ( isset( $system_fonts[ $value ] ) && isset( $system_fonts[ $value ]['fallback'] ) ) {
			$value .= ',' . $system_fonts[ $value ]['fallback'];
		}

		return $value;
	}
}


/**
 * Get CSS value
 */
if ( ! function_exists( 'astra_get_css_value' ) ) {

	/**
	 * Get CSS value
	 *
	 * Syntax:
	 *
	 *  astra_get_css_value( VALUE, UNIT );
	 *
	 * E.g.
	 *
	 *  astra_get_css_value( VALUE, 'url' );
	 *  astra_get_css_value( VALUE, 'px' );
	 *  astra_get_css_value( VALUE, 'em' );
	 *
	 * @param  string $value        CSS value.
	 * @param  string $unit         CSS unit.
	 * @param  string $default      CSS default font.
	 * @return mixed               CSS value depends on $unit
	 */
	function astra_get_css_value( $value = '', $unit = 'px', $default = '' ) {

		if ( '' == $value && '' == $default ) {
			return $value;
		}

		$css_val = '';

		switch ( $unit ) {

			case 'font':
				if ( 'inherit' != $value ) {
					$value   = astra_get_font_family( $value );
					$css_val = $value;
				} elseif ( '' != $default ) {
					$css_val = $default;
				} else {
					$css_val = '';
				}
				break;

			case 'px':
			case '%':
				if ( 'inherit' === strtolower( $value ) || 'inherit' === strtolower( $default ) ) {
					return $value;
				}

				$value   = ( '' != $value ) ? $value : $default;
				$css_val = esc_attr( $value ) . $unit;
				break;

			case 'url':
				$css_val = $unit . '(' . esc_url( $value ) . ')';
				break;

			default:
				$value = ( '' != $value ) ? $value : $default;
				if ( '' != $value ) {
					$css_val = esc_attr( $value ) . $unit;
				}
		}

		return $css_val;
	}
}

/**
 * Adjust the background obj.
 */
if ( ! function_exists( 'astra_get_background_obj' ) ) {

	/**
	 * Adjust Brightness
	 *
	 * @param  array $bg_obj   Color code in HEX.
	 *
	 * @return array         Color code in HEX.
	 */
	function astra_get_background_obj( $bg_obj ) {

		$gen_bg_css = array();

		$bg_img   = isset( $bg_obj['background-image'] ) ? $bg_obj['background-image'] : '';
		$bg_color = isset( $bg_obj['background-color'] ) ? $bg_obj['background-color'] : '';
		$bg_type  = isset( $bg_obj['background-type'] ) ? $bg_obj['background-type'] : '';

		if ( '' !== $bg_type ) {
			switch ( $bg_type ) {
				case 'color':
					if ( '' !== $bg_img && '' !== $bg_color ) {
						$gen_bg_css['background-image'] = 'linear-gradient(to right, ' . $bg_color . ', ' . $bg_color . '), url(' . $bg_img . ');';
					} elseif ( '' === $bg_img ) {
						$gen_bg_css['background-color'] = $bg_color . ';';
					}
					break;

				case 'image':
					$overlay_type    = isset( $bg_obj['overlay-type'] ) ? $bg_obj['overlay-type'] : 'none';
					$overlay_color   = isset( $bg_obj['overlay-color'] ) ? $bg_obj['overlay-color'] : '';
					$overlay_opacity = isset( $bg_obj['overlay-opacity'] ) ? $bg_obj['overlay-opacity'] : '';
					$overlay_grad    = isset( $bg_obj['overlay-gradient'] ) ? $bg_obj['overlay-gradient'] : '';
					if ( '' !== $bg_img ) {
						if ( 'none' !== $overlay_type ) {
							if ( 'classic' === $overlay_type && '' !== $overlay_color ) {
								$updated_overlay_color = $overlay_color;

								// Compatibility of overlay color opacity to HEX & VAR colors.
								if ( '' !== $overlay_opacity ) {
									$is_linked_with_gcp = 'var' === substr( $overlay_color, 0, 3 );

									if ( $is_linked_with_gcp ) {
										$astra_gcp_instance    = new Astra_Global_Palette();
										$updated_overlay_color = $astra_gcp_instance->get_color_by_palette_variable( $overlay_color );
									}

									if ( '#' === $updated_overlay_color[0] ) {
										$updated_overlay_color = astra_hex_to_rgba( $updated_overlay_color, $overlay_opacity );
									}
								}

								$gen_bg_css['background-image'] = 'linear-gradient(to right, ' . $updated_overlay_color . ', ' . $updated_overlay_color . '), url(' . $bg_img . ');';
							} elseif ( 'gradient' === $overlay_type && '' !== $overlay_grad ) {
								$gen_bg_css['background-image'] = $overlay_grad . ', url(' . $bg_img . ');';
							} else {
								$gen_bg_css['background-image'] = 'url(' . $bg_img . ');';
							}
						} else {
							$gen_bg_css['background-image'] = 'url(' . $bg_img . ');';
						}
					}
					break;

				case 'gradient':
					if ( isset( $bg_color ) ) {
						$gen_bg_css['background-image'] = $bg_color . ';';
					}
					break;

				default:
					break;
			}
		} elseif ( '' !== $bg_color ) {
			$gen_bg_css['background-color'] = $bg_color . ';';
		}

		if ( '' !== $bg_img ) {
			if ( isset( $bg_obj['background-repeat'] ) ) {
				$gen_bg_css['background-repeat'] = esc_attr( $bg_obj['background-repeat'] );
			}

			if ( isset( $bg_obj['background-position'] ) ) {
				$gen_bg_css['background-position'] = esc_attr( $bg_obj['background-position'] );
			}

			if ( isset( $bg_obj['background-size'] ) ) {
				$gen_bg_css['background-size'] = esc_attr( $bg_obj['background-size'] );
			}

			if ( isset( $bg_obj['background-attachment'] ) ) {
				$gen_bg_css['background-attachment'] = esc_attr( $bg_obj['background-attachment'] );
			}
		}

		return $gen_bg_css;
	}
}

/**
 * Parse CSS
 */
if ( ! function_exists( 'astra_parse_css' ) ) {

	/**
	 * Parse CSS
	 *
	 * @param  array $css_output Array of CSS.
	 * @param  mixed $min_media  Min Media breakpoint.
	 * @param  mixed $max_media  Max Media breakpoint.
	 * @return string             Generated CSS.
	 */
	function astra_parse_css( $css_output = array(), $min_media = '', $max_media = '' ) {

		$parse_css = '';
		if ( is_array( $css_output ) && count( $css_output ) > 0 ) {

			foreach ( $css_output as $selector => $properties ) {

				if ( null === $properties ) {
					break;
				}

				if ( ! count( $properties ) ) {
					continue;
				}

				$temp_parse_css   = $selector . '{';
				$properties_added = 0;

				foreach ( $properties as $property => $value ) {
					// to ignore if the value is empty with just !important appended.
					if ( ( '' == $value && 0 !== $value ) || '!important' === $value ) {
						continue;
					}

					$properties_added++;
					$temp_parse_css .= $property . ':' . $value . ';';
				}

				$temp_parse_css .= '}';

				if ( $properties_added > 0 ) {
					$parse_css .= $temp_parse_css;
				}
			}

			if ( '' != $parse_css && ( '' !== $min_media || '' !== $max_media ) ) {

				$media_css       = '@media ';
				$min_media_css   = '';
				$max_media_css   = '';
				$media_separator = '';

				if ( '' !== $min_media ) {
					$min_media_css = '(min-width:' . $min_media . 'px)';
				}
				if ( '' !== $max_media ) {
					$max_media_css = '(max-width:' . $max_media . 'px)';
				}
				if ( '' !== $min_media && '' !== $max_media ) {
					$media_separator = ' and ';
				}

				$media_css .= $min_media_css . $media_separator . $max_media_css . '{' . $parse_css . '}';

				return $media_css;
			}
		}

		return $parse_css;
	}
}

/**
 * Return theme options from astra-settings option key.
 */
if ( ! function_exists( 'astra_get_options' ) ) {

	/**
	 * Retrieve Astra theme options array.
	 *
	 * @return array The theme options array.
	 *
	 * @since 4.8.9
	 */
	function astra_get_options() {
		// Ensure we're not interfering during WordPress installation.
		if ( wp_installing() ) {
			return [];
		}

		/**
		 * Filter to bypass the cached Astra options.
		 *
		 * Example usage:
		 *     add_filter( 'astra_get_options_nocache', '__return_true' );
		 *
		 * @since 4.8.9
		 * @return bool Whether to bypass the cache. Default is false.
		 */
		if ( apply_filters( 'astra_get_options_nocache', false ) ) {
			$astra_options = get_option( ASTRA_THEME_SETTINGS );
		} else {
			// Use a static variable to cache the options for this request.
			static $cached_astra_options = null;

			// Fetch the options once and cache them in the static variable.
			if ( is_null( $cached_astra_options ) || is_customize_preview() ) {
				$cached_astra_options = Astra_Theme_Options::get_astra_options();
			}

			$astra_options = $cached_astra_options;
		}

		/**
		 * Filter the options array for Astra Settings.
		 *
		 * @since 4.8.9
		 * @return array The theme options array.
		 */
		return apply_filters( 'astra_get_options', $astra_options );
	}
}

/**
 * Return Theme option.
 */
if ( ! function_exists( 'astra_get_option' ) ) {

	/**
	 * Return Theme options.
	 *
	 * @param  string $option       Option key.
	 * @param  mixed  $default      Option default value.
	 * @param  string $deprecated   Option default value.
	 * @return mixed               Return option value.
	 */
	function astra_get_option( $option, $default = '', $deprecated = '' ) {

		if ( '' != $deprecated ) {
			$default = $deprecated;
		}

		$theme_options = Astra_Theme_Options::get_options();

		/**
		 * Filter the options array for Astra Settings.
		 *
		 * @since  1.0.20
		 * @var Array
		 */
		$theme_options = apply_filters( 'astra_get_option_array', $theme_options, $option, $default );

		$value = ( isset( $theme_options[ $option ] ) && '' !== $theme_options[ $option ] ) ? $theme_options[ $option ] : $default;

		/**
		 * Dynamic filter astra_get_option_$option.
		 * $option is the name of the Astra Setting, Refer Astra_Theme_Options::defaults() for option names from the theme.
		 *
		 * @since  1.0.20
		 * @var Mixed.
		 */
		return apply_filters( "astra_get_option_{$option}", $value, $option, $default );
	}
}

/**
 * Return translated theme option.
 */
if ( ! function_exists( 'astra_get_i18n_option' ) ) {

	/**
	 * Returns translated string for strings saved in Astra settings.
	 *
	 * This function retrieves a theme option value and checks if it needs translation.
	 * If the option's translation is needed, it looks it up based on the provided context.
	 * If the translation is not available, it returns the default value.
	 *
	 * Usage examples:
	 * - Retrieve translated theme option with a context description:
	 *      $value = astra_get_i18n_option( 'astra-option-key', esc_html_x( '%astra%', 'Context Description', 'astra-addon' ) );
	 *
	 * - Retrieve translated theme option with a different context:
	 *      $value = astra_get_i18n_option( 'astra-option-key', _x( '%astra%', 'Context Description', 'astra-addon' ) );
	 *
	 * @param  string $option       Option key.
	 * @param  string $translated   Default translation flag.
	 * @param  mixed  $default      Option default value.
	 * @param  string $deprecated   Option default value.
	 *
	 * @return string Return option value.
	 *
	 * @since 4.8.1
	 */
	function astra_get_i18n_option( $option, $translated, $default = '', $deprecated = '' ) {
		// #%astra%# is for TranslatePress compatibility.
		$is_translated = '%astra%' !== $translated && ! strpos( $translated, '#%astra%#' );
		return $is_translated ? $translated : astra_get_option( $option, $default, $deprecated );
	}
}

/**
 * Return translated string.
 */
if ( ! function_exists( 'astra_get_i18n_string' ) ) {

	/**
	 * Returns translated string.
	 *
	 * This function checks if string has translation.
	 * If the translation is not available, it returns the default value.
	 *
	 * Usage examples:
	 * - Retrieve translated theme option with a context description:
	 *      $value = astra_get_i18n_string( $default, esc_html_x( '%astra%', 'Context Description', 'astra-addon' ) );
	 *
	 * - Retrieve translated theme option with a different context:
	 *      $value = astra_get_i18n_string( $default, _x( '%astra%', 'Context Description', 'astra-addon' ) );
	 *
	 * @param  string $default      Default string value.
	 * @param  string $translated   Default translation flag.
	 *
	 * @return string Return string value.
	 *
	 * @since 4.8.1
	 */
	function astra_get_i18n_string( $default, $translated ) {
		// #%astra%# is for TranslatePress compatibility.
		$is_translated = '%astra%' !== $translated && ! strpos( $translated, '#%astra%#' );
		return $is_translated ? $translated : $default;
	}
}

if ( ! function_exists( 'astra_update_option' ) ) {

	/**
	 * Update Theme options.
	 *
	 * @param  string $option option key.
	 * @param  Mixed  $value  option value.
	 * @return void
	 */
	function astra_update_option( $option, $value ) {

		do_action( "astra_before_update_option_{$option}", $value, $option );

		// Get all customizer options.
		$theme_options = get_option( ASTRA_THEME_SETTINGS );

		// Update value in options array.
		if ( ! is_array( $theme_options ) ) {
			$theme_options = array();
		}
		$theme_options[ $option ] = $value;

		update_option( ASTRA_THEME_SETTINGS, $theme_options );

		do_action( "astra_after_update_option_{$option}", $value, $option );
	}
}

if ( ! function_exists( 'astra_delete_option' ) ) {

	/**
	 * Update Theme options.
	 *
	 * @param  string $option option key.
	 * @return void
	 */
	function astra_delete_option( $option ) {

		do_action( "astra_before_delete_option_{$option}", $option );

		// Get all customizer options.
		$theme_options = get_option( ASTRA_THEME_SETTINGS );

		// Update value in options array.
		unset( $theme_options[ $option ] );

		update_option( ASTRA_THEME_SETTINGS, $theme_options );

		do_action( "astra_after_delete_option_{$option}", $option );
	}
}

/**
 * Return Theme options from postmeta.
 */
if ( ! function_exists( 'astra_get_option_meta' ) ) {

	/**
	 * Return Theme options from postmeta.
	 *
	 * @param  string  $option_id Option ID.
	 * @param  string  $default   Option default value.
	 * @param  boolean $only_meta Get only meta value.
	 * @param  string  $extension Is value from extension.
	 * @param  string  $post_id   Get value from specific post by post ID.
	 * @return Mixed             Return option value.
	 */
	function astra_get_option_meta( $option_id, $default = '', $only_meta = false, $extension = '', $post_id = '' ) {

		$post_id = ( '' != $post_id ) ? $post_id : astra_get_post_id();

		$value = astra_get_option( $option_id, $default );

		// Get value from option 'post-meta'.
		if ( is_singular() || ( is_home() && ! is_front_page() ) ) {

			$value = get_post_meta( $post_id, $option_id, true );

			if ( empty( $value ) || 'default' == $value ) {

				if ( true === $only_meta ) {
					return false;
				}

				$value = astra_get_option( $option_id, $default );
			}
		}

		/**
		 * Dynamic filter astra_get_option_meta_$option.
		 * $option_id is the name of the Astra Meta Setting.
		 *
		 * @since  1.0.20
		 * @var Mixed.
		 */
		return apply_filters( "astra_get_option_meta_{$option_id}", $value, $default, $default );
	}
}

/**
 * Helper function to get the current post id.
 */
if ( ! function_exists( 'astra_get_post_id' ) ) {

	/**
	 * Get post ID.
	 *
	 * @param  string $post_id_override Get override post ID.
	 * @return number                   Post ID.
	 */
	function astra_get_post_id( $post_id_override = '' ) {

		if ( null == Astra_Theme_Options::$post_id ) {
			global $post;

			$post_id = 0;

			if ( is_home() ) {
				$post_id = get_option( 'page_for_posts' );
			} elseif ( function_exists( 'is_shop' ) && is_shop() && function_exists( 'wc_get_page_id' ) ) {
				$post_id = wc_get_page_id( 'shop' );
			} elseif ( is_archive() ) {
				global $wp_query;
				$post_id = $wp_query->get_queried_object_id();
			} elseif ( isset( $post->ID ) && ! is_search() && ! is_category() ) {
				$post_id = $post->ID;
			}

			Astra_Theme_Options::$post_id = $post_id;
		}

		return apply_filters( 'astra_get_post_id', Astra_Theme_Options::$post_id, $post_id_override );
	}
}


/**
 * Display classes for primary div
 */
if ( ! function_exists( 'astra_primary_class' ) ) {

	/**
	 * Display classes for primary div
	 *
	 * @param string|array $class One or more classes to add to the class list.
	 * @return void        Echo classes.
	 */
	function astra_primary_class( $class = '' ) {

		// Separates classes with a single space, collates classes for body element.
		echo 'class="' . esc_attr( join( ' ', astra_get_primary_class( $class ) ) ) . '"';
	}
}

/**
 * Retrieve the classes for the primary element as an array.
 */
if ( ! function_exists( 'astra_get_primary_class' ) ) {

	/**
	 * Retrieve the classes for the primary element as an array.
	 *
	 * @param string|array $class One or more classes to add to the class list.
	 * @return array        Return array of classes.
	 */
	function astra_get_primary_class( $class = '' ) {

		// array of class names.
		$classes = array();

		// default class for content area.
		$classes[] = 'content-area';

		// primary base class.
		$classes[] = 'primary';

		if ( ! empty( $class ) ) {
			if ( ! is_array( $class ) ) {
				$class = preg_split( '#\s+#', $class );
			}
			$classes = array_merge( $classes, $class );
		} else {

			// Ensure that we always coerce class to being an array.
			$class = array();
		}

		// Filter primary div class names.
		$classes = apply_filters( 'astra_primary_class', $classes, $class );

		$classes = array_map( 'sanitize_html_class', $classes );

		return array_unique( $classes );
	}
}

/**
 * Display classes for secondary div
 */
if ( ! function_exists( 'astra_secondary_class' ) ) {

	/**
	 * Retrieve the classes for the secondary element as an array.
	 *
	 * @param string|array $class One or more classes to add to the class list.
	 * @return void        echo classes.
	 */
	function astra_secondary_class( $class = '' ) {

		// Separates classes with a single space, collates classes for body element.
		echo 'class="' . esc_attr( join( ' ', astra_get_secondary_class( $class ) ) ) . '"';
	}
}

/**
 * Retrieve the classes for the secondary element as an array.
 */
if ( ! function_exists( 'astra_get_secondary_class' ) ) {

	/**
	 * Retrieve the classes for the secondary element as an array.
	 *
	 * @param string|array $class One or more classes to add to the class list.
	 * @return array        Return array of classes.
	 */
	function astra_get_secondary_class( $class = '' ) {

		// array of class names.
		$classes = array();

		// default class from widget area.
		$classes[] = 'widget-area';

		// secondary base class.
		$classes[] = 'secondary';

		if ( ! empty( $class ) ) {
			if ( ! is_array( $class ) ) {
				$class = preg_split( '#\s+#', $class );
			}
			$classes = array_merge( $classes, $class );
		} else {

			// Ensure that we always coerce class to being an array.
			$class = array();
		}

		// Filter secondary div class names.
		$classes = apply_filters( 'astra_secondary_class', $classes, $class );

		$classes = array_map( 'sanitize_html_class', $classes );

		return array_unique( $classes );
	}
}

/**
 * Get post format
 */
if ( ! function_exists( 'astra_get_post_format' ) ) {

	/**
	 * Get post format
	 *
	 * @param  string $post_format_override Override post formate.
	 * @return string                       Return post format.
	 */
	function astra_get_post_format( $post_format_override = '' ) {

		if ( ( is_home() ) || is_archive() ) {
			$post_format = 'blog';
		} else {
			$post_format = get_post_format();
		}

		return apply_filters( 'astra_get_post_format', $post_format, $post_format_override );
	}
}

/**
 * Wrapper function for get_the_title() for blog post.
 */
if ( ! function_exists( 'astra_the_post_title' ) ) {

	/**
	 * Wrapper function for get_the_title() for blog post.
	 *
	 * Displays title only if the page title bar is disabled.
	 *
	 * @since 1.0.15
	 * @param string $before Optional. Content to prepend to the title.
	 * @param string $after  Optional. Content to append to the title.
	 * @param int    $post_id Optional, default to 0. Post id.
	 * @param bool   $echo   Optional, default to true.Whether to display or return.
	 * @return string|void String if $echo parameter is false.
	 */
	function astra_the_post_title( $before = '', $after = '', $post_id = 0, $echo = true ) {

		$enabled = apply_filters( 'astra_the_post_title_enabled', true );
		if ( $enabled ) {

			$title  = astra_get_the_title( $post_id );
			$before = apply_filters( 'astra_the_post_title_before', $before );
			$after  = apply_filters( 'astra_the_post_title_after', $after );

			// This will work same as `the_title` function but with Custom Title if exits.
			if ( $echo ) {
				echo $before . $title . $after; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			} else {
				return $before . $title . $after;
			}
		}
	}
}

if ( ! function_exists( 'astra_the_search_page_title' ) ) {
	/**
	 * Function to get the search page custom title.
	 *
	 * @param string $before Optional. Content to prepend to the title.
	 * @param string $after  Optional. Content to append to the title.
	 * @param bool   $echo   Optional, default to true.Whether to display or return.
	 *
	 * @return string Returns search page custom title.
	 *
	 * @since 4.8.4
	 */
	function astra_the_search_page_title( $before = '', $after = '', $echo = false ) {
		$title = apply_filters(
			'astra_the_search_page_title',
			sprintf(
				/* translators: 1: search title, 2: search string */
				'%1$s %2$s',
				astra_get_i18n_option( 'section-search-page-title-custom-title', _x( '%astra%', 'Search Page Title: Heading - Text', 'astra' ) ),
				'<span>' . get_search_query() . '</span>'
			)
		);

		if ( $echo ) {
			echo $before . $title . $after; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		} else {
			return $before . $title . $after;
		}
	}
}

/**
 * Wrapper function for the_title()
 */
if ( ! function_exists( 'astra_the_title' ) ) {

	/**
	 * Wrapper function for the_title()
	 *
	 * Displays title only if the page title bar is disabled.
	 *
	 * @param string $before Optional. Content to prepend to the title.
	 * @param string $after  Optional. Content to append to the title.
	 * @param int    $post_id Optional, default to 0. Post id.
	 * @param bool   $echo   Optional, default to true.Whether to display or return.
	 * @return string|void String if $echo parameter is false.
	 */
	function astra_the_title( $before = '', $after = '', $post_id = 0, $echo = true ) {

		$title             = '';
		$post_type         = astra_get_post_type();
		$blog_post_title   = astra_get_option( 'ast-dynamic-archive-' . $post_type . '-structure', array( 'ast-dynamic-archive-' . $post_type . '-title', 'ast-dynamic-archive-' . $post_type . '-description' ) );
		$single_post_title = astra_get_option( 'ast-dynamic-single-' . $post_type . '-structure', 'page' === $post_type ? array( 'ast-dynamic-single-' . $post_type . '-image', 'ast-dynamic-single-' . $post_type . '-title' ) : array( 'ast-dynamic-single-' . $post_type . '-title', 'ast-dynamic-single-' . $post_type . '-meta' ) );

		if ( ( ! is_singular() && ( in_array( 'ast-dynamic-archive-' . $post_type . '-title', $blog_post_title ) || in_array( 'ast-dynamic-archive-' . $post_type . '-meta', $blog_post_title ) ) )
			|| ( is_singular() && ( in_array( 'ast-dynamic-single-' . $post_type . '-title', $single_post_title ) || in_array( 'ast-dynamic-single-' . $post_type . '-meta', $single_post_title ) ) )
		) {
			if ( apply_filters( 'astra_the_title_enabled', true ) ) {

				$title  = astra_get_the_title( $post_id );
				$before = apply_filters( 'astra_the_title_before', $before );
				$after  = apply_filters( 'astra_the_title_after', $after );

				$title = $before . $title . $after;
			}
		}

		// This will work same as `the_title` function but with Custom Title if exits.
		if ( $echo ) {
			echo $title; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		} else {
			return $title;
		}
	}
}

/**
 * Wrapper function for get_the_title()
 */
if ( ! function_exists( 'astra_get_the_title' ) ) {

	/**
	 * Wrapper function for get_the_title()
	 *
	 * Return title for Title Bar and Normal Title.
	 *
	 * @param int  $post_id Optional, default to 0. Post id.
	 * @param bool $echo   Optional, default to false. Whether to display or return.
	 * @return string|void String if $echo parameter is false.
	 */
	function astra_get_the_title( $post_id = 0, $echo = false ) {

		$title = '';
		if ( $post_id || is_singular() ) {
			$title = get_the_title( $post_id );
		} else {
			if ( is_front_page() && is_home() ) {
				// Default homepage.
				$title = apply_filters( 'astra_the_default_home_page_title', esc_html__( 'Home', 'astra' ) );
			} elseif ( is_home() ) {
				// blog page.
				$title = apply_filters( 'astra_the_blog_home_page_title', get_the_title( get_option( 'page_for_posts', true ) ) );
			} elseif ( is_404() ) {
				// for 404 page - title always display.
				$title = apply_filters( 'astra_the_404_page_title', esc_html__( 'This page doesn\'t seem to exist.', 'astra' ) );

				// for search page - title always display.
			} elseif ( is_search() ) {

				$title = astra_the_search_page_title();

			} elseif ( class_exists( 'WooCommerce' ) && is_shop() ) {

				$title = woocommerce_page_title( false );

			} elseif ( is_archive() ) {

				$title = get_the_archive_title();

			}
		}

		$title = apply_filters( 'astra_the_title', $title, $post_id );

		// This will work same as `get_the_title` function but with Custom Title if exits.
		if ( $echo ) {
			echo $title; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		} else {
			return $title;
		}
	}
}

/**
 * Don't apply direct new layouts to legacy users.
 *
 * @since 4.0.0
 * @return boolean false if it is an existing user , true if not.
 */
function astra_use_dynamic_blog_layouts() {
	$astra_settings = astra_get_options();
	return apply_filters( 'astra_get_option_dynamic_blog_layouts', isset( $astra_settings['dynamic-blog-layouts'] ) ? $astra_settings['dynamic-blog-layouts'] : true );
}

/**
 * Get taxonomy archive banner for layout 1.
 *
 * @since 4.0.0
 */
function astra_get_taxonomy_banner_legacy_layout() {
	$post_type        = astra_get_post_type();
	$banner_structure = is_search() ? astra_get_option( 'section-search-page-title-structure' ) : astra_get_option( 'ast-dynamic-archive-' . $post_type . '-structure', array( 'ast-dynamic-archive-' . $post_type . '-title', 'ast-dynamic-archive-' . $post_type . '-description' ) );

	if ( empty( $banner_structure ) ) {
		return;
	}

	?>
		<section class="ast-archive-description">
			<?php
			foreach ( $banner_structure as $metaval ) {
				$meta_key = 'archive-' . astra_get_last_meta_word( $metaval );
				switch ( $meta_key ) {
					case 'archive-title':
						do_action( 'astra_before_archive_title' );
						if ( is_search() ) {
							astra_the_search_page_title( '<h1 class="page-title ast-archive-title">', '</h1>', true );
						} else {
							add_filter( 'get_the_archive_title_prefix', '__return_empty_string' );
							the_archive_title( '<h1 class="page-title ast-archive-title">', '</h1>' );
							remove_filter( 'get_the_archive_title_prefix', '__return_empty_string' );
						}
						do_action( 'astra_after_archive_title' );
						break;
					case 'archive-breadcrumb':
						if ( ! is_author() ) {
							do_action( 'astra_before_archive_breadcrumb' );
							echo astra_get_breadcrumb(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
							do_action( 'astra_after_archive_breadcrumb' );
						}
						break;
					case 'archive-description':
						do_action( 'astra_before_archive_description' );
						if ( is_search() ) {
							$title = have_posts()
								? astra_get_i18n_option( 'section-search-page-title-found-custom-description', _x( '%astra%', 'Search Page Custom `When Results Found` Text', 'astra' ) )
								: astra_get_i18n_option( 'section-search-page-title-not-found-custom-description', _x( '%astra%', 'Search Page Custom `When Results Not Found` Text', 'astra' ) );
							echo wp_kses_post( wpautop( $title ) );
						} else {
							echo wp_kses_post( wpautop( get_the_archive_description() ) );
						}
						do_action( 'astra_after_archive_description' );
						break;
				}
			}
			?>
		</section>
	<?php
}

/**
 * Archive Page Title
 */
if ( ! function_exists( 'astra_archive_page_info' ) ) {

	/**
	 * Wrapper function for the_title()
	 *
	 * Displays title only if the page title bar is disabled.
	 */
	function astra_archive_page_info() {

		if ( apply_filters( 'astra_the_title_enabled', true ) ) {

			// Author.
			if ( is_author() ) {
				$author_name        = get_the_author() ? esc_attr( strval( get_the_author() ) ) : '';
				$author_name_html   = ( true === astra_check_is_structural_setup() && $author_name ) ? __( 'Author name: ', 'astra' ) . $author_name : $author_name;
				$author_description = get_the_author_meta( 'description' );
				/** @psalm-suppress RedundantConditionGivenDocblockType */
				?>

				<section class="ast-author-box ast-archive-description">
					<div class="ast-author-bio">
						<?php do_action( 'astra_before_archive_title' ); ?>
						<h1 class='page-title ast-archive-title'><?php echo esc_html( apply_filters( 'astra_author_page_title', $author_name_html ) ); ?></h1>
						<?php do_action( 'astra_after_archive_title' ); ?>
						<p><?php echo wp_kses_post( $author_description ); ?></p>
						<?php do_action( 'astra_after_archive_description' ); ?>
					</div>
					<div class="ast-author-avatar">
						<?php echo get_avatar( get_the_author_meta( 'email' ), 120 ); ?>
					</div>
				</section>

				<?php

			} else {
				$taxonomy_banner_content = astra_get_taxonomy_banner_legacy_layout();
				echo wp_kses_post( $taxonomy_banner_content );
			}
		}
	}

	add_action( 'astra_archive_header', 'astra_archive_page_info' );
}

/**
 * Adjust the HEX color brightness
 */
if ( ! function_exists( 'astra_adjust_brightness' ) ) {

	/**
	 * Adjust Brightness
	 *
	 * @param  string $hex   Color code in HEX.
	 * @param  number $steps brightness value.
	 * @param  string $type  brightness is reverse or default.
	 * @return string        Color code in HEX.
	 */
	function astra_adjust_brightness( $hex, $steps, $type ) {

		// Get rgb vars.
		$hex = str_replace( '#', '', $hex );

		// Return if non hex.
		if ( function_exists( 'ctype_xdigit' ) && is_callable( 'ctype_xdigit' ) ) {
			if ( ! ctype_xdigit( $hex ) ) {
				return $hex;
			}
		} else {
			if ( ! preg_match( '/^[a-f0-9]{2,}$/i', $hex ) ) {
				return $hex;
			}
		}

		$shortcode_atts = array(
			'r' => hexdec( substr( $hex, 0, 2 ) ),
			'g' => hexdec( substr( $hex, 2, 2 ) ),
			'b' => hexdec( substr( $hex, 4, 2 ) ),
		);

		// Should we darken the color?
		if ( 'reverse' == $type && $shortcode_atts['r'] + $shortcode_atts['g'] + $shortcode_atts['b'] > 382 ) {
			$steps = -$steps;
		} elseif ( 'darken' == $type ) {
			$steps = -$steps;
		}

		// Build the new color.
		$steps = max( -255, min( 255, $steps ) );

		$shortcode_atts['r'] = max( 0, min( 255, $shortcode_atts['r'] + $steps ) );
		$shortcode_atts['g'] = max( 0, min( 255, $shortcode_atts['g'] + $steps ) );
		$shortcode_atts['b'] = max( 0, min( 255, $shortcode_atts['b'] + $steps ) );

		$r_hex = str_pad( dechex( $shortcode_atts['r'] ), 2, '0', STR_PAD_LEFT );
		$g_hex = str_pad( dechex( $shortcode_atts['g'] ), 2, '0', STR_PAD_LEFT );
		$b_hex = str_pad( dechex( $shortcode_atts['b'] ), 2, '0', STR_PAD_LEFT );

		return '#' . $r_hex . $g_hex . $b_hex;
	}
} // End if.

/**
 * Convert colors from HEX to RGBA
 */
if ( ! function_exists( 'astra_hex_to_rgba' ) ) :

	/**
	 * Convert colors from HEX to RGBA
	 *
	 * @param  string $color   Color code in HEX.
	 * @param  mixed  $opacity Color code opacity.
	 * @return string           Color code in RGB or RGBA.
	 */
	function astra_hex_to_rgba( $color, $opacity = false ) {

		$default = 'rgb(0,0,0)';

		// Return default if no color provided.
		if ( empty( $color ) ) {
			return $default;
		}

		// Sanitize $color if "#" is provided.
		if ( '#' == $color[0] ) {
			$color = substr( $color, 1 );
		}

		// Check if color has 6 or 3 characters and get values.
		if ( 6 == strlen( $color ) ) {
			$hex = array( $color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5] );
		} elseif ( 3 == strlen( $color ) ) {
			$hex = array( $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] );
		} else {
			return $default;
		}

		// Convert HEX to RGB.
		$rgb = array_map( 'hexdec', $hex );

		// Check if opacity is set(RGBA or RGB).
		if ( $opacity ) {
			if ( 1 < abs( $opacity ) ) {
				$opacity = 1.0;
			}
			$output = 'rgba(' . implode( ',', $rgb ) . ',' . $opacity . ')';
		} else {
			$output = 'rgb(' . implode( ',', $rgb ) . ')';
		}

		// Return RGB(a) color string.
		return $output;
	}

endif;


if ( ! function_exists( 'astra_enable_page_builder_compatibility' ) ) :

	/**
	 * Allow filter to enable/disable page builder compatibility.
	 *
	 * @see  https://wpastra.com/docs/recommended-settings-beaver-builder-astra/
	 * @see  https://wpastra.com/docs/recommended-settings-for-elementor/
	 *
	 * @since  1.2.2
	 * @return  bool True - If the page builder compatibility is enabled. False - IF the page builder compatibility is disabled.
	 */
	function astra_enable_page_builder_compatibility() {
		return apply_filters( 'astra_enable_page_builder_compatibility', true );
	}

endif;


if ( ! function_exists( 'astra_get_pro_url' ) ) :
	/**
	 * Returns an URL with utm tags
	 * the admin settings page.
	 *
	 * @param string $path     Path for the Website URL.
	 * @param string $source   UMM source.
	 * @param string $medium   UTM medium.
	 * @param string $campaign UTM campaign.
	 * @return mixed
	 */
	function astra_get_pro_url( $path, $source = '', $medium = '', $campaign = '' ) {
		$url           = esc_url( ASTRA_WEBSITE_BASE_URL . $path );
		$astra_pro_url = trailingslashit( $url );

		// Set up our URL if we have a source.
		if ( ! empty( $source ) ) {
			$astra_pro_url = add_query_arg( 'utm_source', sanitize_text_field( $source ), $astra_pro_url );
		}

		// Modify the utm_source parameter using the UTM ready link function to include tracking information.
		if ( is_callable( '\BSF_UTM_Analytics\Inc\Utils::get_utm_ready_link' ) ) {
			$astra_pro_url = \BSF_UTM_Analytics\Inc\Utils::get_utm_ready_link( $astra_pro_url, 'astra' );
		}

		// Set up our URL if we have a medium.
		if ( ! empty( $medium ) ) {
			$astra_pro_url = add_query_arg( 'utm_medium', sanitize_text_field( $medium ), $astra_pro_url );
		}

		// Set up our URL if we have a campaign.
		if ( ! empty( $campaign ) ) {
			$astra_pro_url = add_query_arg( 'utm_campaign', sanitize_text_field( $campaign ), $astra_pro_url );
		}

		$astra_pro_url = apply_filters( 'astra_get_pro_url', $astra_pro_url, $url );
		$astra_pro_url = remove_query_arg( 'bsf', $astra_pro_url );

		$ref = get_option( 'astra_partner_url_param', '' );
		if ( ! empty( $ref ) ) {
			$astra_pro_url = add_query_arg( 'bsf', sanitize_text_field( $ref ), $astra_pro_url );
		}

		return $astra_pro_url;
	}

endif;


/**
 * Search Form
 */
if ( ! function_exists( 'astra_get_search_form' ) ) :
	/**
	 * Display search form.
	 *
	 * @param bool $echo Default to echo and not return the form.
	 * @return string|void String when $echo is false.
	 */
	function astra_get_search_form( $echo = true ) {

		$form = get_search_form(
			array(
				'input_placeholder' => apply_filters( 'astra_search_field_placeholder', esc_attr_x( 'Search...', 'placeholder', 'astra' ) ),
				'data_attributes'   => apply_filters( 'astra_search_field_toggle_data_attrs', '' ),
				'input_value'       => get_search_query(),
				'show_input_submit' => false,
			)
		);

		/**
		 * Filters the HTML output of the search form.
		 *
		 * @param string $form The search form HTML output.
		 */
		$result = apply_filters( 'astra_get_search_form', $form );

		if ( null === $result ) {
			$result = $form;
		}

		if ( $echo ) {
			echo $result; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		} else {
			return $result;
		}
	}

endif;

/**
 * Check if we're being delivered AMP
 *
 * @return bool
 */
function astra_is_amp_endpoint() {
	return function_exists( 'is_amp_endpoint' ) && is_amp_endpoint();
}

/*
 * Get Responsive Spacing
 */
if ( ! function_exists( 'astra_responsive_spacing' ) ) {

	/**
	 * Get Spacing value
	 *
	 * @param  array  $option    CSS value.
	 * @param  string $side  top | bottom | left | right.
	 * @param  string $device  CSS device.
	 * @param  string $default Default value.
	 * @param  string $prefix Prefix value.
	 * @return mixed
	 */
	function astra_responsive_spacing( $option, $side = '', $device = 'desktop', $default = '', $prefix = '' ) {

		if ( isset( $option[ $device ][ $side ] ) && isset( $option[ $device . '-unit' ] ) ) {
			$spacing = astra_get_css_value( $option[ $device ][ $side ], $option[ $device . '-unit' ], $default );
		} elseif ( is_numeric( $option ) ) {
			$spacing = astra_get_css_value( $option );
		} else {
			$spacing = ( ! is_array( $option ) ) ? $option : '';
		}

		if ( '' !== $prefix && '' !== $spacing ) {
			return $prefix . $spacing;
		}
		return $spacing;
	}
}

/**
 * Get the tablet breakpoint value.
 *
 * @param mixed $min min.
 * @param mixed $max max.
 *
 * @since 2.4.0
 *
 * @return number $breakpoint.
 */
function astra_get_tablet_breakpoint( $min = '', $max = '' ) {

	$update_breakpoint = astra_get_option( 'can-update-theme-tablet-breakpoint', true );

	// Change default for new users.
	$default = ( true === $update_breakpoint ) ? 921 : 768;

	$header_breakpoint = apply_filters( 'astra_tablet_breakpoint', $default );

	if ( '' !== $min ) {
		$header_breakpoint = $header_breakpoint - $min;
	} elseif ( '' !== $max ) {
		$header_breakpoint = $header_breakpoint + $max;
	}

	return absint( $header_breakpoint );
}

/**
 * Get the mobile breakpoint value.
 *
 * @param mixed $min min.
 * @param mixed $max max.
 *
 * @since 2.4.0
 *
 * @return number header_breakpoint.
 */
function astra_get_mobile_breakpoint( $min = '', $max = '' ) {

	$header_breakpoint = apply_filters( 'astra_mobile_breakpoint', 544 );

	if ( '' !== $min ) {
		$header_breakpoint = $header_breakpoint - $min;
	} elseif ( '' !== $max ) {
		$header_breakpoint = $header_breakpoint + $max;
	}

	return absint( $header_breakpoint );
}

/*
 * Apply CSS for the element
 */
if ( ! function_exists( 'astra_color_responsive_css' ) ) {

	/**
	 * Astra Responsive Colors
	 *
	 * @param  array  $setting      Responsive colors.
	 * @param  string $css_property CSS property.
	 * @param  string $selector     CSS selector.
	 * @return string               Dynamic responsive CSS.
	 */
	function astra_color_responsive_css( $setting, $css_property, $selector ) {
		$css = '';
		if ( isset( $setting['desktop'] ) && ! empty( $setting['desktop'] ) ) {
			$css .= $selector . '{' . $css_property . ':' . esc_attr( $setting['desktop'] ) . ';}';
		}
		if ( isset( $setting['tablet'] ) && ! empty( $setting['tablet'] ) ) {
			$css .= '@media (max-width:' . astra_get_tablet_breakpoint() . 'px) {' . $selector . '{' . $css_property . ':' . esc_attr( $setting['tablet'] ) . ';} }';
		}
		if ( isset( $setting['mobile'] ) && ! empty( $setting['mobile'] ) ) {
			$css .= '@media (max-width:' . astra_get_mobile_breakpoint() . 'px) {' . $selector . '{' . $css_property . ':' . esc_attr( $setting['mobile'] ) . ';} }';
		}
		return $css;
	}
}

if ( ! function_exists( 'astra_check_is_bb_themer_layout' ) ) :

	/**
	 * Check if layout is bb themer's layout
	 */
	function astra_check_is_bb_themer_layout() {

		$is_layout = false;

		$post_type = get_post_type();
		$post_id   = get_the_ID();

		if ( 'fl-theme-layout' === $post_type && $post_id ) {

			$is_layout = true;
		}

		return $is_layout;
	}

endif;


if ( ! function_exists( 'astra_is_white_labelled' ) ) :

	/**
	 * Check if white label option is enabled in astra pro plugin
	 */
	function astra_is_white_labelled() {

		if ( is_callable( 'Astra_Ext_White_Label_Markup::show_branding' ) && ! Astra_Ext_White_Label_Markup::show_branding() ) {
			return apply_filters( 'astra_is_white_labelled', true );
		}

		return apply_filters( 'astra_is_white_labelled', false );
	}

endif;

/**
 * Get the value for font-display property.
 *
 * @since 1.8.6
 * @return string
 */
function astra_get_fonts_display_property() {
	return apply_filters( 'astra_fonts_display_property', 'fallback' );
}

/**
 * Generate Responsive Background Color CSS.
 *
 * @param array  $bg_obj_res array of background object.
 * @param string $device CSS for which device.
 * @return array
 */
function astra_get_responsive_background_obj( $bg_obj_res, $device ) {

	$gen_bg_css = array();

	if ( ! is_array( $bg_obj_res ) ) {
		return;
	}

	$bg_obj      = $bg_obj_res[ $device ];
	$bg_img      = isset( $bg_obj['background-image'] ) ? $bg_obj['background-image'] : '';
	$bg_tab_img  = isset( $bg_obj_res['tablet']['background-image'] ) ? $bg_obj_res['tablet']['background-image'] : '';
	$bg_desk_img = isset( $bg_obj_res['desktop']['background-image'] ) ? $bg_obj_res['desktop']['background-image'] : '';
	$bg_color    = isset( $bg_obj['background-color'] ) ? $bg_obj['background-color'] : '';
	$tablet_css  = ( isset( $bg_obj_res['tablet']['background-image'] ) && $bg_obj_res['tablet']['background-image'] ) ? true : false;
	$desktop_css = ( isset( $bg_obj_res['desktop']['background-image'] ) && $bg_obj_res['desktop']['background-image'] ) ? true : false;

	$bg_type = ( isset( $bg_obj['background-type'] ) && $bg_obj['background-type'] ) ? $bg_obj['background-type'] : '';

	if ( '' !== $bg_type ) {
		switch ( $bg_type ) {
			case 'color':
				if ( '' !== $bg_img && '' !== $bg_color ) {
					$gen_bg_css['background-image'] = 'linear-gradient(to right, ' . $bg_color . ', ' . $bg_color . '), url(' . $bg_img . ')';
				} elseif ( 'mobile' === $device ) {
					if ( $desktop_css ) {
						$gen_bg_css['background-image'] = 'linear-gradient(to right, ' . $bg_color . ', ' . $bg_color . '), url(' . $bg_desk_img . ')';
					} elseif ( $tablet_css ) {
						$gen_bg_css['background-image'] = 'linear-gradient(to right, ' . $bg_color . ', ' . $bg_color . '), url(' . $bg_tab_img . ')';
					} else {
						if ( '' !== $bg_color ) {
							$gen_bg_css['background-color'] = $bg_color;
							$gen_bg_css['background-image'] = 'none';
						}
					}
				} elseif ( 'tablet' === $device ) {
					if ( $desktop_css ) {
						$gen_bg_css['background-image'] = 'linear-gradient(to right, ' . $bg_color . ', ' . $bg_color . '), url(' . $bg_desk_img . ')';
					} else {
						if ( '' !== $bg_color ) {
							$gen_bg_css['background-color'] = $bg_color;
							$gen_bg_css['background-image'] = 'none';
						}
					}
				} elseif ( '' === $bg_img ) {
					$gen_bg_css['background-color'] = $bg_color;
					$gen_bg_css['background-image'] = 'none';
				}
				break;

			case 'image':
				/** @psalm-suppress PossiblyUndefinedStringArrayOffset */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
				$overlay_type = isset( $bg_obj['overlay-type'] ) ? $bg_obj['overlay-type'] : 'none';
				/** @psalm-suppress PossiblyUndefinedStringArrayOffset */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
				$overlay_color = isset( $bg_obj['overlay-color'] ) ? $bg_obj['overlay-color'] : '';
				/** @psalm-suppress PossiblyUndefinedStringArrayOffset */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
				$overlay_grad = isset( $bg_obj['overlay-gradient'] ) ? $bg_obj['overlay-gradient'] : '';
				/** @psalm-suppress PossiblyUndefinedStringArrayOffset */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
				$overlay_opacity = isset( $bg_obj['overlay-opacity'] ) ? $bg_obj['overlay-opacity'] : '';
				/** @psalm-suppress PossiblyUndefinedStringArrayOffset */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort

				if ( '' !== $bg_img ) {
					if ( 'none' !== $overlay_type ) {
						if ( 'classic' === $overlay_type && '' !== $overlay_color ) {
							$updated_overlay_color = $overlay_color;

							// Compatibility of overlay color opacity to HEX & VAR colors.
							if ( '' !== $overlay_opacity ) {
								$is_linked_with_gcp = 'var' === substr( $overlay_color, 0, 3 );

								if ( $is_linked_with_gcp ) {
									$astra_gcp_instance    = new Astra_Global_Palette();
									$updated_overlay_color = $astra_gcp_instance->get_color_by_palette_variable( $overlay_color );
								}

								if ( '#' === $updated_overlay_color[0] ) {
									$updated_overlay_color = astra_hex_to_rgba( $updated_overlay_color, $overlay_opacity );
								}
							}

							$gen_bg_css['background-image'] = 'linear-gradient(to right, ' . $updated_overlay_color . ', ' . $updated_overlay_color . '), url(' . $bg_img . ')';
						} elseif ( 'gradient' === $overlay_type && '' !== $overlay_grad ) {
							$gen_bg_css['background-image'] = $overlay_grad . ', url(' . $bg_img . ')';
						} else {
							$gen_bg_css['background-image'] = 'url(' . $bg_img . ')';
						}
					} else {
						$gen_bg_css['background-image'] = 'url(' . $bg_img . ')';
					}
				}
				break;

			case 'gradient':
				if ( isset( $bg_color ) ) {
					$gen_bg_css['background-image'] = $bg_color;
				}
				break;

			default:
				break;
		}
	} elseif ( '' !== $bg_color ) {
		$gen_bg_css['background-color'] = $bg_color;
	}

	if ( '' !== $bg_img ) {
		if ( isset( $bg_obj['background-repeat'] ) ) {
			$gen_bg_css['background-repeat'] = esc_attr( $bg_obj['background-repeat'] );
		}

		if ( isset( $bg_obj['background-position'] ) ) {
			$gen_bg_css['background-position'] = esc_attr( $bg_obj['background-position'] );
		}

		if ( isset( $bg_obj['background-size'] ) ) {
			$gen_bg_css['background-size'] = esc_attr( $bg_obj['background-size'] );
		}

		if ( isset( $bg_obj['background-attachment'] ) ) {
			$gen_bg_css['background-attachment'] = esc_attr( $bg_obj['background-attachment'] );
		}
	}

	return $gen_bg_css;
}

/**
 * Common function to check is pagination is enabled on current page.
 *
 * @since 3.0.1
 * @return boolean
 */
function astra_check_pagination_enabled() {
	global  $wp_query;

	return ( $wp_query->max_num_pages > 1 && apply_filters( 'astra_pagination_enabled', true ) );
}

/**
 * Verify is current post comments are enabled or not for applying dynamic CSS.
 *
 * @since 3.0.1
 * @return boolean
 */
function astra_check_current_post_comment_enabled() {
	return ( is_singular() && comments_open() );
}

/**
 * Dont apply zero size to existing user.
 *
 * @since 3.6.9
 * @return boolean false if it is an existing user , true if not.
 */
function astra_zero_font_size_case() {
	$astra_settings = astra_get_options();
	return apply_filters( 'astra_zero_font_size_case', isset( $astra_settings['astra-zero-font-size-case-css'] ) ? false : true );
}

/**
 * Check the WordPress version.
 *
 * @since  2.5.4
 * @param string $version   WordPress version to compare with the current version.
 * @param mixed  $compare   Comparison value i.e > or < etc.
 * @return bool|null            True/False based on the  $version and $compare value.
 */
function astra_wp_version_compare( $version, $compare ) {
	return version_compare( get_bloginfo( 'version' ), $version, $compare );
}

/**
 * Check if existing setup is live with old block editor compatibilities.
 *
 * @return bool true|false.
 */
function astra_block_based_legacy_setup() {
	$astra_settings = astra_get_options();
	return ( isset( $astra_settings['blocks-legacy-setup'] ) && isset( $astra_settings['wp-blocks-ui'] ) && 'legacy' === $astra_settings['wp-blocks-ui'] ) ? true : false;
}

/**
 * Check is new structural things are updated.
 *
 * @return bool true|false.
 */
function astra_check_is_structural_setup() {
	$astra_settings = astra_get_options();
	return apply_filters( 'astra_get_option_customizer-default-layout-update', isset( $astra_settings['customizer-default-layout-update'] ) ? false : true ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
}

/**
 * Check if the user is old sidebar user.
 *
 * @since 3.9.4
 * @return bool true|false.
 */
function astra_check_old_sidebar_user() {
	$astra_settings = astra_get_options();
	return apply_filters( 'astra_old_global_sidebar_defaults', isset( $astra_settings['astra-old-global-sidebar-default'] ) ? false : true );
}

/**
 * Check if user is old for hiding/showing password icon field for login my-account form.
 *
 * @since 3.9.2
 * @return bool true|false.
 */
function astra_load_woocommerce_login_form_password_icon() {
	$astra_settings = astra_get_options();
	return apply_filters( 'astra_get_option_woo-show-password-icon', isset( $astra_settings['woo-show-password-icon'] ) ? false : true ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
}

/**
 * Function to add narrow width properties in the frontend.
 *
 * @since 4.0.0
 * @param string $location container layout for single-post, archives, pages, page meta.
 * @param string $narrow_container_max_width  dynamic container width in px.
 * @return string Parsed CSS based on $location and $narrow_container_max_width.
 */
function astra_narrow_container_width( $location, $narrow_container_max_width ) {

	if ( 'narrow-container' === $location ) {

		$narrow_container_css = array(
			'.ast-narrow-container .site-content > .ast-container' => array(
				'max-width' => astra_get_css_value( $narrow_container_max_width, 'px' ),
			),
		);

		// Remove Sidebar for Narrow Width Container Layout.
		if ( 'narrow-container' === astra_get_content_layout() ) {
			add_filter(
				'astra_page_layout',
				function() { // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewClosure.Found
					return 'no-sidebar';
				}
			);
		}

		return astra_parse_css( $narrow_container_css, astra_get_tablet_breakpoint( '', 1 ) );

	} else {
		return '';
	}
}

/**
 * Function which will return the Sidebar Layout to determine default body classes for Editor.
 *
 * @since 4.2.0
 * @param string $post_type Post Type.
 * @return string Sidebar Layout.
 */
function astra_get_sidebar_layout_for_editor( $post_type ) {

	$sidebar_layout = astra_get_option( 'single-' . $post_type . '-sidebar-layout' );

	if ( 'default' === $sidebar_layout ) {
		$sidebar_layout = astra_get_option( 'site-sidebar-layout' );
	}

	return $sidebar_layout;
}

/**
 * Gets the SVG for the duotone filter definition.
 *
 * @since 4.2.2
 *
 * @param string $filter_id The ID of the filter.
 * @param array  $color    An array of color strings.
 * @return string An SVG with a duotone filter definition.
 */
function astra_get_filter_svg( $filter_id, $color ) {

	$duotone_values = array(
		'r' => array(),
		'g' => array(),
		'b' => array(),
		'a' => array(),
	);

	/** @psalm-suppress PossiblyUndefinedStringArrayOffset */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
	$duotone_values['r'][] = $color['r'] / 255;
			/** @psalm-suppress PossiblyUndefinedStringArrayOffset */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
			$duotone_values['g'][] = $color['g'] / 255;
			/** @psalm-suppress PossiblyUndefinedStringArrayOffset */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
			$duotone_values['b'][] = $color['b'] / 255;
			/** @psalm-suppress PossiblyUndefinedStringArrayOffset */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
			$duotone_values['a'][] = $color['a'];
	ob_start();

	?>

	<svg
		xmlns="http://www.w3.org/2000/svg"
		viewBox="0 0 0 0"
		width="0"
		height="0"
		focusable="false"
		role="none"
		style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;"
	>
		<defs>
			<filter id="<?php echo esc_attr( $filter_id ); ?>">
				<feColorMatrix
					color-interpolation-filters="sRGB"
					type="matrix"
					values="
						.299 .587 .114 0 0
						.299 .587 .114 0 0
						.299 .587 .114 0 0
						.299 .587 .114 0 0
					"
				/>
				<feComponentTransfer color-interpolation-filters="sRGB" >
					<feFuncR type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['r'] ) ); ?> <?php echo esc_attr( implode( ' ', $duotone_values['r'] ) ); ?>" />
					<feFuncG type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['g'] ) ); ?> <?php echo esc_attr( implode( ' ', $duotone_values['g'] ) ); ?>" />
					<feFuncB type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['b'] ) ); ?> <?php echo esc_attr( implode( ' ', $duotone_values['b'] ) ); ?>" />
					<feFuncA type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['a'] ) ); ?> <?php echo esc_attr( implode( ' ', $duotone_values['a'] ) ); ?>" />
				</feComponentTransfer>
				<feComposite in2="SourceGraphic" operator="in" />
			</filter>
		</defs>
	</svg>

	<?php

	$svg = ob_get_clean();

	// Clean up the whitespace.
	$svg = preg_replace( "/[\r\n\t ]+/", ' ', $svg );
	$svg = str_replace( '> <', '><', $svg );
	$svg = trim( $svg );

	return $svg;
}

/**
 * Converts HEX to RGB.
 *
 * @since 4.2.2
 *
 * @param string $hex Hex color.
 * @return array split version of rgb.
 */
function astra_hex_to_rgb( $hex ) {
	// @codingStandardsIgnoreStart
	/**
	 * @psalm-suppress PossiblyNullArrayAccess
	 */
	list($r, $g, $b) = sscanf( $hex, '#%02x%02x%02x' );

	// @codingStandardsIgnoreEnd
	return array(
		'r' => $r,
		'g' => $g,
		'b' => $b,
		'a' => 1,
	);
}

/**
 * Converts RGBA to split array RGBA.
 *
 * @since 4.2.2
 *
 * @param string $rgba RGBA value.
 * @return array split version of rgba.
 */
function astra_split_rgba( $rgba ) {
	// Remove the "rgba(" and ")" from the input string.
	$rgba = str_replace( array( 'rgba(', ')' ), '', $rgba );

	// Split the RGBA values by comma.
	$values = explode( ',', $rgba );

	// Convert each value from string to integer.
	$r = intval( $values[0] );
	$g = intval( $values[1] );
	$b = intval( $values[2] );
	$a = floatval( $values[3] );

	// Create the split RGBA string.
	return array(
		'r' => $r,
		'g' => $g,
		'b' => $b,
		'a' => $a,
	);
}

/**
 * Render svg mask.
 *
 * @since 4.2.2
 *
 * @param string $id id.
 * @param string $filter_name filter name.
 * @param string $color color.
 * @return mixed masked svg,
 */
function astra_render_svg_mask( $id, $filter_name, $color ) {

	if ( 0 === strpos( $color, 'var(--' ) ) {
		$agp = new Astra_Global_Palette();
		/** @psalm-suppress UndefinedFunction  */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
		$svg_color = astra_hex_to_rgb( $agp->get_color_by_palette_variable( $color ) );
	} elseif ( preg_match( '/^#[a-f0-9]{6}$/i', $color ) ) {
		/** @psalm-suppress UndefinedFunction  */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
		$svg_color = astra_hex_to_rgb( $color );
	} else {
		/** @psalm-suppress UndefinedFunction  */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
		$svg_color = astra_split_rgba( $color );
	}

	/** @psalm-suppress UndefinedFunction  */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
	echo astra_get_filter_svg( $id, apply_filters( 'astra_' . $filter_name, $svg_color ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}

/**
 * Returns an array of logo svg icons.
 *
 * @return array
 * @since 4.7.0
 */
function astra_get_logo_svg_icons_array() {
	static $ast_all_svg_icons = array();

	if ( $ast_all_svg_icons ) {
		return $ast_all_svg_icons;
	}

	$icons_dir = ASTRA_THEME_DIR . 'assets/svg/logo-svg-icons';

	for ( $i = 0; $i < 4; $i++ ) {
		$file = "{$icons_dir}/icons-v6-{$i}.php";

		if ( file_exists( $file ) ) {
			$icons = include_once $file;

			foreach ( $icons as &$icon ) {
				$fallback            = isset( $icon['svg']['solid'] ) ? $icon['svg']['solid'] : array();
				$icon_brand_or_solid = isset( $icon['svg']['brands'] ) ? $icon['svg']['brands'] : $fallback;
				$path                = isset( $icon_brand_or_solid['path'] ) ? $icon_brand_or_solid['path'] : '';
				$width               = isset( $icon_brand_or_solid['width'] ) ? $icon_brand_or_solid['width'] : '';
				$height              = isset( $icon_brand_or_solid['height'] ) ? $icon_brand_or_solid['height'] : '';
				$view                = (bool) $width && (bool) $height ? "0 0 {$width} {$height}" : null;

				if ( $path && $view ) {
					ob_start();
					?>
				<svg xmlns="http://www.w3.org/2000/svg" viewBox= "<?php echo esc_attr( $view ); ?>"><path d="<?php echo esc_attr( $path ); ?>"></path></svg>
					<?php
					$icon['rendered'] = trim( ob_get_clean() );
				}
			}

			$ast_all_svg_icons = array_merge( $ast_all_svg_icons, $icons );
		}
	}

	return $ast_all_svg_icons;
}

/**
 * Retrieve the post type for the current page based on category, tag, or custom taxonomy archives.
 *
 * @return string The detected post type.
 *
 * @since 4.8.4
 */
function astra_get_post_type() {
	$post_type = get_post_type();

	// If post type not found check for taxonomy archives.
	if ( ! $post_type ) {
		// Get the queried object (category, tag, or custom taxonomy).
		$queried_object = get_queried_object();

		if ( is_category() || is_tag() || is_tax() ) {
			$taxonomy   = $queried_object->taxonomy ?? '';
			$post_types = get_post_types();
			
			// Loop through all post types to see which ones support the current taxonomy.
			foreach ( $post_types as $type ) {
				if ( in_array( $taxonomy, get_object_taxonomies( $type ) ) ) {
					// If a custom post type matches the taxonomy, assign it.
					$post_type = $type;
					break;
				}
			}
		}
	}

	/**
	 * Filter the detected post type before returning.
	 *
	 * @param string $post_type The detected post type.
	 */
	return apply_filters( 'astra_get_post_type', strval( $post_type ) );
}

/**
 * Get Astra's upgrade URL based on org or woo package version.
 *
 * @param string $type Type of upgrade URL.
 * @since 4.8.4
 * @return string Upgrade URL.
 */
function astra_get_upgrade_url( $type = 'pro' ) {
	/** @psalm-suppress TypeDoesNotContainType */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
	if ( ! ASTRA_THEME_ORG_VERSION ) {
		/** @psalm-suppress TypeDoesNotContainType */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
		return 'https://woo.com/products/astra-pro/';
	}

	switch ( $type ) {
		case 'pricing':
			$upgrade_url = astra_get_pro_url( '/pricing/', 'free-theme', 'customizer', 'main-cta' );
			break;
		case 'dashboard':
			$upgrade_url = astra_get_pro_url( '/pricing/', 'free-theme', 'dashboard', 'upgrade' );
			break;
		case 'customizer':
			$upgrade_url = astra_get_pro_url( '/pricing/', 'free-theme', 'dashboard', 'upgrade' );
			break;
		default:
			$upgrade_url = astra_get_pro_url( '/pro/', 'free-theme', 'dashboard', 'upgrade-now' );
			break;
	}

	return $upgrade_url;
}