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/htlwork.com/www/dev/aippt/vendor/nesbot/carbon/src/Carbon/
Upload File :
Current File : /home/htlwork.com/www/dev/aippt/vendor/nesbot/carbon/src/Carbon/Factory.php
<?php

declare(strict_types=1);

/**
 * This file is part of the Carbon package.
 *
 * (c) Brian Nesbitt <brian@nesbot.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Carbon;

use Closure;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
use InvalidArgumentException;
use ReflectionMethod;
use RuntimeException;
use Symfony\Contracts\Translation\TranslatorInterface;
use Throwable;

/**
 * A factory to generate Carbon instances with common settings.
 *
 * <autodoc generated by `composer phpdoc`>
 *
 * @method bool                canBeCreatedFromFormat(?string $date, string $format)                                                                                Checks if the (date)time string is in a given format and valid to create a
 *                                                                                                                                                                  new instance.
 * @method ?Carbon             create($year = 0, $month = 1, $day = 1, $hour = 0, $minute = 0, $second = 0, $timezone = null)                                       Create a new Carbon instance from a specific date and time.
 *                                                                                                                                                                  If any of $year, $month or $day are set to null their now() values will
 *                                                                                                                                                                  be used.
 *                                                                                                                                                                  If $hour is null it will be set to its now() value and the default
 *                                                                                                                                                                  values for $minute and $second will be their now() values.
 *                                                                                                                                                                  If $hour is not null then the default values for $minute and $second
 *                                                                                                                                                                  will be 0.
 * @method Carbon              createFromDate($year = null, $month = null, $day = null, $timezone = null)                                                           Create a Carbon instance from just a date. The time portion is set to now.
 * @method ?Carbon             createFromFormat($format, $time, $timezone = null)                                                                                   Create a Carbon instance from a specific format.
 * @method ?Carbon             createFromIsoFormat(string $format, string $time, $timezone = null, ?string $locale = 'en', ?TranslatorInterface $translator = null) Create a Carbon instance from a specific ISO format (same replacements as ->isoFormat()).
 * @method ?Carbon             createFromLocaleFormat(string $format, string $locale, string $time, $timezone = null)                                               Create a Carbon instance from a specific format and a string in a given language.
 * @method ?Carbon             createFromLocaleIsoFormat(string $format, string $locale, string $time, $timezone = null)                                            Create a Carbon instance from a specific ISO format and a string in a given language.
 * @method Carbon              createFromTime($hour = 0, $minute = 0, $second = 0, $timezone = null)                                                                Create a Carbon instance from just a time. The date portion is set to today.
 * @method Carbon              createFromTimeString(string $time, DateTimeZone|string|int|null $timezone = null)                                                    Create a Carbon instance from a time string. The date portion is set to today.
 * @method Carbon              createFromTimestamp(string|int|float $timestamp, DateTimeZone|string|int|null $timezone = null)                                      Create a Carbon instance from a timestamp and set the timezone (UTC by default).
 *                                                                                                                                                                  Timestamp input can be given as int, float or a string containing one or more numbers.
 * @method Carbon              createFromTimestampMs(string|int|float $timestamp, DateTimeZone|string|int|null $timezone = null)                                    Create a Carbon instance from a timestamp in milliseconds.
 *                                                                                                                                                                  Timestamp input can be given as int, float or a string containing one or more numbers.
 * @method Carbon              createFromTimestampMsUTC($timestamp)                                                                                                 Create a Carbon instance from a timestamp in milliseconds.
 *                                                                                                                                                                  Timestamp input can be given as int, float or a string containing one or more numbers.
 * @method Carbon              createFromTimestampUTC(string|int|float $timestamp)                                                                                  Create a Carbon instance from a timestamp keeping the timezone to UTC.
 *                                                                                                                                                                  Timestamp input can be given as int, float or a string containing one or more numbers.
 * @method Carbon              createMidnightDate($year = null, $month = null, $day = null, $timezone = null)                                                       Create a Carbon instance from just a date. The time portion is set to midnight.
 * @method ?Carbon             createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $timezone = null)                 Create a new safe Carbon instance from a specific date and time.
 *                                                                                                                                                                  If any of $year, $month or $day are set to null their now() values will
 *                                                                                                                                                                  be used.
 *                                                                                                                                                                  If $hour is null it will be set to its now() value and the default
 *                                                                                                                                                                  values for $minute and $second will be their now() values.
 *                                                                                                                                                                  If $hour is not null then the default values for $minute and $second
 *                                                                                                                                                                  will be 0.
 *                                                                                                                                                                  If one of the set values is not valid, an InvalidDateException
 *                                                                                                                                                                  will be thrown.
 * @method Carbon              createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $timezone = null)   Create a new Carbon instance from a specific date and time using strict validation.
 * @method mixed               executeWithLocale(string $locale, callable $func)                                                                                    Set the current locale to the given, execute the passed function, reset the locale to previous one,
 *                                                                                                                                                                  then return the result of the closure (or null if the closure was void).
 * @method Carbon              fromSerialized($value)                                                                                                               Create an instance from a serialized string.
 * @method array               getAvailableLocales()                                                                                                                Returns the list of internally available locales and already loaded custom locales.
 *                                                                                                                                                                  (It will ignore custom translator dynamic loading.)
 * @method Language[]          getAvailableLocalesInfo()                                                                                                            Returns list of Language object for each available locale. This object allow you to get the ISO name, native
 *                                                                                                                                                                  name, region and variant of the locale.
 * @method array               getDays()                                                                                                                            Get the days of the week.
 * @method ?string             getFallbackLocale()                                                                                                                  Get the fallback locale.
 * @method array               getFormatsToIsoReplacements()                                                                                                        List of replacements from date() format to isoFormat().
 * @method array               getIsoUnits()                                                                                                                        Returns list of locale units for ISO formatting.
 * @method array|false         getLastErrors()                                                                                                                      {@inheritdoc}
 * @method string              getLocale()                                                                                                                          Get the current translator locale.
 * @method int                 getMidDayAt()                                                                                                                        get midday/noon hour
 * @method string              getTimeFormatByPrecision(string $unitPrecision)                                                                                      Return a format from H:i to H:i:s.u according to given unit precision.
 * @method string|Closure|null getTranslationMessageWith($translator, string $key, ?string $locale = null, ?string $default = null)                                 Returns raw translation message for a given key.
 * @method int                 getWeekEndsAt(?string $locale = null)                                                                                                Get the last day of week.
 * @method int                 getWeekStartsAt(?string $locale = null)                                                                                              Get the first day of week.
 * @method bool                hasRelativeKeywords(?string $time)                                                                                                   Determine if a time string will produce a relative date.
 * @method Carbon              instance(DateTimeInterface $date)                                                                                                    Create a Carbon instance from a DateTime one.
 * @method bool                isImmutable()                                                                                                                        Returns true if the current class/instance is immutable.
 * @method bool                isModifiableUnit($unit)                                                                                                              Returns true if a property can be changed via setter.
 * @method bool                isMutable()                                                                                                                          Returns true if the current class/instance is mutable.
 * @method bool                localeHasDiffOneDayWords(string $locale)                                                                                             Returns true if the given locale is internally supported and has words for 1-day diff (just now, yesterday, tomorrow).
 *                                                                                                                                                                  Support is considered enabled if the 3 words are translated in the given locale.
 * @method bool                localeHasDiffSyntax(string $locale)                                                                                                  Returns true if the given locale is internally supported and has diff syntax support (ago, from now, before, after).
 *                                                                                                                                                                  Support is considered enabled if the 4 sentences are translated in the given locale.
 * @method bool                localeHasDiffTwoDayWords(string $locale)                                                                                             Returns true if the given locale is internally supported and has words for 2-days diff (before yesterday, after tomorrow).
 *                                                                                                                                                                  Support is considered enabled if the 2 words are translated in the given locale.
 * @method bool                localeHasPeriodSyntax($locale)                                                                                                       Returns true if the given locale is internally supported and has period syntax support (X times, every X, from X, to X).
 *                                                                                                                                                                  Support is considered enabled if the 4 sentences are translated in the given locale.
 * @method bool                localeHasShortUnits(string $locale)                                                                                                  Returns true if the given locale is internally supported and has short-units support.
 *                                                                                                                                                                  Support is considered enabled if either year, day or hour has a short variant translated.
 * @method ?Carbon             make($var, DateTimeZone|string|null $timezone = null)                                                                                Make a Carbon instance from given variable if possible.
 *                                                                                                                                                                  Always return a new instance. Parse only strings and only these likely to be dates (skip intervals
 *                                                                                                                                                                  and recurrences). Throw an exception for invalid format, but otherwise return null.
 * @method void                mixin(object|string $mixin)                                                                                                          Mix another object into the class.
 * @method Carbon              now(DateTimeZone|string|int|null $timezone = null)                                                                                   Get a Carbon instance for the current date and time.
 * @method Carbon              parse(DateTimeInterface|WeekDay|Month|string|int|float|null $time, DateTimeZone|string|int|null $timezone = null)                    Create a carbon instance from a string.
 *                                                                                                                                                                  This is an alias for the constructor that allows better fluent syntax
 *                                                                                                                                                                  as it allows you to do Carbon::parse('Monday next week')->fn() rather
 *                                                                                                                                                                  than (new Carbon('Monday next week'))->fn().
 * @method Carbon              parseFromLocale(string $time, ?string $locale = null, DateTimeZone|string|int|null $timezone = null)                                 Create a carbon instance from a localized string (in French, Japanese, Arabic, etc.).
 * @method string              pluralUnit(string $unit)                                                                                                             Returns standardized plural of a given singular/plural unit name (in English).
 * @method ?Carbon             rawCreateFromFormat(string $format, string $time, $timezone = null)                                                                  Create a Carbon instance from a specific format.
 * @method Carbon              rawParse(DateTimeInterface|WeekDay|Month|string|int|float|null $time, DateTimeZone|string|int|null $timezone = null)                 Create a carbon instance from a string.
 *                                                                                                                                                                  This is an alias for the constructor that allows better fluent syntax
 *                                                                                                                                                                  as it allows you to do Carbon::parse('Monday next week')->fn() rather
 *                                                                                                                                                                  than (new Carbon('Monday next week'))->fn().
 * @method void                setFallbackLocale(string $locale)                                                                                                    Set the fallback locale.
 * @method void                setLocale(string $locale)                                                                                                            Set the current translator locale and indicate if the source locale file exists.
 *                                                                                                                                                                  Pass 'auto' as locale to use the closest language to the current LC_TIME locale.
 * @method void                setMidDayAt($hour)                                                                                                                   @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
 *                                                                                                                                                                              You should rather consider mid-day is always 12pm, then if you need to test if it's an other
 *                                                                                                                                                                              hour, test it explicitly:
 *                                                                                                                                                                                  $date->format('G') == 13
 *                                                                                                                                                                              or to set explicitly to a given hour:
 *                                                                                                                                                                                  $date->setTime(13, 0, 0, 0)
 *                                                                                                                                                                  Set midday/noon hour
 * @method string              singularUnit(string $unit)                                                                                                           Returns standardized singular of a given singular/plural unit name (in English).
 * @method void                sleep(int|float $seconds)
 * @method Carbon              today(DateTimeZone|string|int|null $timezone = null)                                                                                 Create a Carbon instance for today.
 * @method Carbon              tomorrow(DateTimeZone|string|int|null $timezone = null)                                                                              Create a Carbon instance for tomorrow.
 * @method string              translateTimeString(string $timeString, ?string $from = null, ?string $to = null, int $mode = CarbonInterface::TRANSLATE_ALL)        Translate a time string from a locale to an other.
 * @method string              translateWith(TranslatorInterface $translator, string $key, array $parameters = [], $number = null)                                  Translate using translation string or callback available.
 * @method Carbon              yesterday(DateTimeZone|string|int|null $timezone = null)                                                                             Create a Carbon instance for yesterday.
 *
 * </autodoc>
 */
class Factory
{
    protected string $className = Carbon::class;

    protected array $settings = [];

    /**
     * A test Carbon instance to be returned when now instances are created.
     */
    protected Closure|CarbonInterface|null $testNow = null;

    /**
     * The timezone to restore to when clearing the time mock.
     */
    protected ?string $testDefaultTimezone = null;

    /**
     * Is true when test-now is generated by a closure and timezone should be taken on the fly from it.
     */
    protected bool $useTimezoneFromTestNow = false;

    /**
     * Default translator.
     */
    protected TranslatorInterface $translator;

    /**
     * Days of weekend.
     */
    protected array $weekendDays = [
        CarbonInterface::SATURDAY,
        CarbonInterface::SUNDAY,
    ];

    /**
     * Format regex patterns.
     *
     * @var array<string, string>
     */
    protected array $regexFormats = [
        'd' => '(3[01]|[12][0-9]|0[1-9])',
        'D' => '(Sun|Mon|Tue|Wed|Thu|Fri|Sat)',
        'j' => '([123][0-9]|[1-9])',
        'l' => '([a-zA-Z]{2,})',
        'N' => '([1-7])',
        'S' => '(st|nd|rd|th)',
        'w' => '([0-6])',
        'z' => '(36[0-5]|3[0-5][0-9]|[12][0-9]{2}|[1-9]?[0-9])',
        'W' => '(5[012]|[1-4][0-9]|0?[1-9])',
        'F' => '([a-zA-Z]{2,})',
        'm' => '(1[012]|0[1-9])',
        'M' => '([a-zA-Z]{3})',
        'n' => '(1[012]|[1-9])',
        't' => '(2[89]|3[01])',
        'L' => '(0|1)',
        'o' => '([1-9][0-9]{0,4})',
        'Y' => '([1-9]?[0-9]{4})',
        'y' => '([0-9]{2})',
        'a' => '(am|pm)',
        'A' => '(AM|PM)',
        'B' => '([0-9]{3})',
        'g' => '(1[012]|[1-9])',
        'G' => '(2[0-3]|1?[0-9])',
        'h' => '(1[012]|0[1-9])',
        'H' => '(2[0-3]|[01][0-9])',
        'i' => '([0-5][0-9])',
        's' => '([0-5][0-9])',
        'u' => '([0-9]{1,6})',
        'v' => '([0-9]{1,3})',
        'e' => '([a-zA-Z]{1,5})|([a-zA-Z]*\\/[a-zA-Z]*)',
        'I' => '(0|1)',
        'O' => '([+-](1[0123]|0[0-9])[0134][05])',
        'P' => '([+-](1[0123]|0[0-9]):[0134][05])',
        'p' => '(Z|[+-](1[0123]|0[0-9]):[0134][05])',
        'T' => '([a-zA-Z]{1,5})',
        'Z' => '(-?[1-5]?[0-9]{1,4})',
        'U' => '([0-9]*)',

        // The formats below are combinations of the above formats.
        'c' => '(([1-9]?[0-9]{4})-(1[012]|0[1-9])-(3[01]|[12][0-9]|0[1-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])[+-](1[012]|0[0-9]):([0134][05]))', // Y-m-dTH:i:sP
        'r' => '(([a-zA-Z]{3}), ([123][0-9]|0[1-9]) ([a-zA-Z]{3}) ([1-9]?[0-9]{4}) (2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]) [+-](1[012]|0[0-9])([0134][05]))', // D, d M Y H:i:s O
    ];

    /**
     * Format modifiers (such as available in createFromFormat) regex patterns.
     *
     * @var array
     */
    protected array $regexFormatModifiers = [
        '*' => '.+',
        ' ' => '[   ]',
        '#' => '[;:\\/.,()-]',
        '?' => '([^a]|[a])',
        '!' => '',
        '|' => '',
        '+' => '',
    ];

    public function __construct(array $settings = [], ?string $className = null)
    {
        if ($className) {
            $this->className = $className;
        }

        $this->settings = $settings;
    }

    public function getClassName(): string
    {
        return $this->className;
    }

    public function setClassName(string $className): self
    {
        $this->className = $className;

        return $this;
    }

    public function className(?string $className = null): self|string
    {
        return $className === null ? $this->getClassName() : $this->setClassName($className);
    }

    public function getSettings(): array
    {
        return $this->settings;
    }

    public function setSettings(array $settings): self
    {
        $this->settings = $settings;

        return $this;
    }

    public function settings(?array $settings = null): self|array
    {
        return $settings === null ? $this->getSettings() : $this->setSettings($settings);
    }

    public function mergeSettings(array $settings): self
    {
        $this->settings = array_merge($this->settings, $settings);

        return $this;
    }

    public function setHumanDiffOptions(int $humanDiffOptions): void
    {
        $this->mergeSettings([
            'humanDiffOptions' => $humanDiffOptions,
        ]);
    }

    public function enableHumanDiffOption($humanDiffOption): void
    {
        $this->setHumanDiffOptions($this->getHumanDiffOptions() | $humanDiffOption);
    }

    public function disableHumanDiffOption(int $humanDiffOption): void
    {
        $this->setHumanDiffOptions($this->getHumanDiffOptions() & ~$humanDiffOption);
    }

    public function getHumanDiffOptions(): int
    {
        return (int) ($this->getSettings()['humanDiffOptions'] ?? 0);
    }

    /**
     * Register a custom macro.
     *
     * Pass null macro to remove it.
     *
     * @example
     * ```
     * $userSettings = [
     *   'locale' => 'pt',
     *   'timezone' => 'America/Sao_Paulo',
     * ];
     * $factory->macro('userFormat', function () use ($userSettings) {
     *   return $this->copy()->locale($userSettings['locale'])->tz($userSettings['timezone'])->calendar();
     * });
     * echo $factory->yesterday()->hours(11)->userFormat();
     * ```
     */
    public function macro(string $name, ?callable $macro): void
    {
        $macros = $this->getSettings()['macros'] ?? [];
        $macros[$name] = $macro;

        $this->mergeSettings([
            'macros' => $macros,
        ]);
    }

    /**
     * Remove all macros and generic macros.
     */
    public function resetMacros(): void
    {
        $this->mergeSettings([
            'macros' => null,
            'genericMacros' => null,
        ]);
    }

    /**
     * Register a custom macro.
     *
     * @param callable $macro
     * @param int      $priority marco with higher priority is tried first
     *
     * @return void
     */
    public function genericMacro(callable $macro, int $priority = 0): void
    {
        $genericMacros = $this->getSettings()['genericMacros'] ?? [];

        if (!isset($genericMacros[$priority])) {
            $genericMacros[$priority] = [];
            krsort($genericMacros, SORT_NUMERIC);
        }

        $genericMacros[$priority][] = $macro;

        $this->mergeSettings([
            'genericMacros' => $genericMacros,
        ]);
    }

    /**
     * Checks if macro is registered globally.
     */
    public function hasMacro(string $name): bool
    {
        return isset($this->getSettings()['macros'][$name]);
    }

    /**
     * Get the raw callable macro registered globally for a given name.
     */
    public function getMacro(string $name): ?callable
    {
        return $this->getSettings()['macros'][$name] ?? null;
    }

    /**
     * Set the default translator instance to use.
     */
    public function setTranslator(TranslatorInterface $translator): void
    {
        $this->translator = $translator;
    }

    /**
     * Initialize the default translator instance if necessary.
     */
    public function getTranslator(): TranslatorInterface
    {
        return $this->translator ??= Translator::get();
    }

    /**
     * Reset the format used to the default when type juggling a Carbon instance to a string
     *
     * @return void
     */
    public function resetToStringFormat(): void
    {
        $this->setToStringFormat(null);
    }

    /**
     * Set the default format used when type juggling a Carbon instance to a string.
     */
    public function setToStringFormat(string|Closure|null $format): void
    {
        $this->mergeSettings([
            'toStringFormat' => $format,
        ]);
    }

    /**
     * JSON serialize all Carbon instances using the given callback.
     */
    public function serializeUsing(string|callable|null $format): void
    {
        $this->mergeSettings([
            'toJsonFormat' => $format,
        ]);
    }

    /**
     * Enable the strict mode (or disable with passing false).
     */
    public function useStrictMode(bool $strictModeEnabled = true): void
    {
        $this->mergeSettings([
            'strictMode' => $strictModeEnabled,
        ]);
    }

    /**
     * Returns true if the strict mode is globally in use, false else.
     * (It can be overridden in specific instances.)
     */
    public function isStrictModeEnabled(): bool
    {
        return $this->getSettings()['strictMode'] ?? true;
    }

    /**
     * Indicates if months should be calculated with overflow.
     */
    public function useMonthsOverflow(bool $monthsOverflow = true): void
    {
        $this->mergeSettings([
            'monthOverflow' => $monthsOverflow,
        ]);
    }

    /**
     * Reset the month overflow behavior.
     */
    public function resetMonthsOverflow(): void
    {
        $this->useMonthsOverflow();
    }

    /**
     * Get the month overflow global behavior (can be overridden in specific instances).
     */
    public function shouldOverflowMonths(): bool
    {
        return $this->getSettings()['monthOverflow'] ?? true;
    }

    /**
     * Indicates if years should be calculated with overflow.
     */
    public function useYearsOverflow(bool $yearsOverflow = true): void
    {
        $this->mergeSettings([
            'yearOverflow' => $yearsOverflow,
        ]);
    }

    /**
     * Reset the month overflow behavior.
     */
    public function resetYearsOverflow(): void
    {
        $this->useYearsOverflow();
    }

    /**
     * Get the month overflow global behavior (can be overridden in specific instances).
     */
    public function shouldOverflowYears(): bool
    {
        return $this->getSettings()['yearOverflow'] ?? true;
    }

    /**
     * Get weekend days
     *
     * @return array
     */
    public function getWeekendDays(): array
    {
        return $this->weekendDays;
    }

    /**
     * Set weekend days
     */
    public function setWeekendDays(array $days): void
    {
        $this->weekendDays = $days;
    }

    /**
     * Checks if the (date)time string is in a given format.
     *
     * @example
     * ```
     * Carbon::hasFormat('11:12:45', 'h:i:s'); // true
     * Carbon::hasFormat('13:12:45', 'h:i:s'); // false
     * ```
     */
    public function hasFormat(string $date, string $format): bool
    {
        // createFromFormat() is known to handle edge cases silently.
        // E.g. "1975-5-1" (Y-n-j) will still be parsed correctly when "Y-m-d" is supplied as the format.
        // To ensure we're really testing against our desired format, perform an additional regex validation.

        return $this->matchFormatPattern($date, preg_quote($format, '/'), $this->regexFormats);
    }

    /**
     * Checks if the (date)time string is in a given format.
     *
     * @example
     * ```
     * Carbon::hasFormatWithModifiers('31/08/2015', 'd#m#Y'); // true
     * Carbon::hasFormatWithModifiers('31/08/2015', 'm#d#Y'); // false
     * ```
     */
    public function hasFormatWithModifiers(string $date, string $format): bool
    {
        return $this->matchFormatPattern($date, $format, array_merge($this->regexFormats, $this->regexFormatModifiers));
    }

    /**
     * Set a Carbon instance (real or mock) to be returned when a "now"
     * instance is created.  The provided instance will be returned
     * specifically under the following conditions:
     *   - A call to the static now() method, ex. Carbon::now()
     *   - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null)
     *   - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now')
     *   - When a string containing the desired time is passed to Carbon::parse().
     *
     * Note the timezone parameter was left out of the examples above and
     * has no affect as the mock value will be returned regardless of its value.
     *
     * Only the moment is mocked with setTestNow(), the timezone will still be the one passed
     * as parameter of date_default_timezone_get() as a fallback (see setTestNowAndTimezone()).
     *
     * To clear the test instance call this method using the default
     * parameter of null.
     *
     * /!\ Use this method for unit tests only.
     *
     * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance
     */
    public function setTestNow(mixed $testNow = null): void
    {
        $this->useTimezoneFromTestNow = false;
        $this->testNow = $testNow instanceof self || $testNow instanceof Closure
            ? $testNow
            : $this->make($testNow);
    }

    /**
     * Set a Carbon instance (real or mock) to be returned when a "now"
     * instance is created.  The provided instance will be returned
     * specifically under the following conditions:
     *   - A call to the static now() method, ex. Carbon::now()
     *   - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null)
     *   - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now')
     *   - When a string containing the desired time is passed to Carbon::parse().
     *
     * It will also align default timezone (e.g. call date_default_timezone_set()) with
     * the second argument or if null, with the timezone of the given date object.
     *
     * To clear the test instance call this method using the default
     * parameter of null.
     *
     * /!\ Use this method for unit tests only.
     *
     * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance
     */
    public function setTestNowAndTimezone(mixed $testNow = null, $timezone = null): void
    {
        if ($testNow) {
            $this->testDefaultTimezone ??= date_default_timezone_get();
        }

        $useDateInstanceTimezone = $testNow instanceof DateTimeInterface;

        if ($useDateInstanceTimezone) {
            $this->setDefaultTimezone($testNow->getTimezone()->getName(), $testNow);
        }

        $this->setTestNow($testNow);
        $this->useTimezoneFromTestNow = ($timezone === null && $testNow instanceof Closure);

        if (!$useDateInstanceTimezone) {
            $now = $this->getMockedTestNow(\func_num_args() === 1 ? null : $timezone);
            $this->setDefaultTimezone($now?->tzName ?? $this->testDefaultTimezone ?? 'UTC', $now);
        }

        if (!$testNow) {
            $this->testDefaultTimezone = null;
        }
    }

    /**
     * Temporarily sets a static date to be used within the callback.
     * Using setTestNow to set the date, executing the callback, then
     * clearing the test instance.
     *
     * /!\ Use this method for unit tests only.
     *
     * @template T
     *
     * @param DateTimeInterface|Closure|static|string|false|null $testNow  real or mock Carbon instance
     * @param Closure(): T                                       $callback
     *
     * @return T
     */
    public function withTestNow(mixed $testNow, callable $callback): mixed
    {
        $this->setTestNow($testNow);

        try {
            $result = $callback();
        } finally {
            $this->setTestNow();
        }

        return $result;
    }

    /**
     * Get the Carbon instance (real or mock) to be returned when a "now"
     * instance is created.
     *
     * @return Closure|CarbonInterface|null the current instance used for testing
     */
    public function getTestNow(): Closure|CarbonInterface|null
    {
        if ($this->testNow === null) {
            $factory = FactoryImmutable::getDefaultInstance();

            if ($factory !== $this) {
                return $factory->getTestNow();
            }
        }

        return $this->testNow;
    }

    public function handleTestNowClosure(
        Closure|CarbonInterface|null $testNow,
        DateTimeZone|string|int|null $timezone = null,
    ): ?CarbonInterface {
        if ($testNow instanceof Closure) {
            $callback = Callback::fromClosure($testNow);
            $realNow = new DateTimeImmutable('now');
            $testNow = $testNow($callback->prepareParameter($this->parse(
                $realNow->format('Y-m-d H:i:s.u'),
                $timezone ?? $realNow->getTimezone(),
            )));

            if ($testNow !== null && !($testNow instanceof DateTimeInterface)) {
                $function = $callback->getReflectionFunction();
                $type = \is_object($testNow) ? $testNow::class : \gettype($testNow);

                throw new RuntimeException(
                    'The test closure defined in '.$function->getFileName().
                    ' at line '.$function->getStartLine().' returned '.$type.
                    '; expected '.CarbonInterface::class.'|null',
                );
            }

            if (!($testNow instanceof CarbonInterface)) {
                $timezone ??= $this->useTimezoneFromTestNow ? $testNow->getTimezone() : null;
                $testNow = $this->__call('instance', [$testNow, $timezone]);
            }
        }

        return $testNow;
    }

    /**
     * Determine if there is a valid test instance set. A valid test instance
     * is anything that is not null.
     *
     * @return bool true if there is a test instance, otherwise false
     */
    public function hasTestNow(): bool
    {
        return $this->getTestNow() !== null;
    }

    public function withTimeZone(DateTimeZone|string|int|null $timezone): static
    {
        $factory = clone $this;
        $factory->settings['timezone'] = $timezone;

        return $factory;
    }

    public function __call(string $name, array $arguments): mixed
    {
        $method = new ReflectionMethod($this->className, $name);
        $settings = $this->settings;

        if ($settings && isset($settings['timezone'])) {
            $timezoneParameters = array_filter($method->getParameters(), function ($parameter) {
                return \in_array($parameter->getName(), ['tz', 'timezone'], true);
            });
            $timezoneSetting = $settings['timezone'];

            if (isset($arguments[0]) && \in_array($name, ['instance', 'make', 'create', 'parse'], true)) {
                if ($arguments[0] instanceof DateTimeInterface) {
                    $settings['innerTimezone'] = $settings['timezone'];
                } elseif (\is_string($arguments[0]) && date_parse($arguments[0])['is_localtime']) {
                    unset($settings['timezone'], $settings['innerTimezone']);
                }
            }

            if (\count($timezoneParameters)) {
                $index = key($timezoneParameters);

                if (!isset($arguments[$index])) {
                    array_splice($arguments, key($timezoneParameters), 0, [$timezoneSetting]);
                }

                unset($settings['timezone']);
            }
        }

        $clock = FactoryImmutable::getCurrentClock();
        FactoryImmutable::setCurrentClock($this);

        try {
            $result = $this->className::$name(...$arguments);
        } finally {
            FactoryImmutable::setCurrentClock($clock);
        }

        if (isset($this->translator)) {
            $settings['translator'] = $this->translator;
        }

        return $result instanceof CarbonInterface && !empty($settings)
            ? $result->settings($settings)
            : $result;
    }

    /**
     * Get the mocked date passed in setTestNow() and if it's a Closure, execute it.
     */
    protected function getMockedTestNow(DateTimeZone|string|int|null $timezone): ?CarbonInterface
    {
        $testNow = $this->handleTestNowClosure($this->getTestNow());

        if ($testNow instanceof CarbonInterface) {
            $testNow = $testNow->avoidMutation();

            if ($timezone !== null) {
                return $testNow->setTimezone($timezone);
            }
        }

        return $testNow;
    }

    /**
     * Checks if the (date)time string is in a given format with
     * given list of pattern replacements.
     *
     * @example
     * ```
     * Carbon::hasFormat('11:12:45', 'h:i:s'); // true
     * Carbon::hasFormat('13:12:45', 'h:i:s'); // false
     * ```
     *
     * @param string $date
     * @param string $format
     * @param array  $replacements
     *
     * @return bool
     */
    private function matchFormatPattern(string $date, string $format, array $replacements): bool
    {
        // Preg quote, but remove escaped backslashes since we'll deal with escaped characters in the format string.
        $regex = str_replace('\\\\', '\\', $format);
        // Replace not-escaped letters
        $regex = preg_replace_callback(
            '/(?<!\\\\)((?:\\\\{2})*)(['.implode('', array_keys($replacements)).'])/',
            static fn ($match) => $match[1].strtr($match[2], $replacements),
            $regex,
        );
        // Replace escaped letters by the letter itself
        $regex = preg_replace('/(?<!\\\\)((?:\\\\{2})*)\\\\(\w)/', '$1$2', $regex);
        // Escape not escaped slashes
        $regex = preg_replace('#(?<!\\\\)((?:\\\\{2})*)/#', '$1\\/', $regex);

        return (bool) @preg_match('/^'.$regex.'$/', $date);
    }

    private function setDefaultTimezone(string $timezone, ?DateTimeInterface $date = null): void
    {
        $previous = null;
        $success = false;

        try {
            $success = date_default_timezone_set($timezone);
        } catch (Throwable $exception) {
            $previous = $exception;
        }

        if (!$success) {
            $suggestion = @CarbonTimeZone::create($timezone)->toRegionName($date);

            throw new InvalidArgumentException(
                "Timezone ID '$timezone' is invalid".
                ($suggestion && $suggestion !== $timezone ? ", did you mean '$suggestion'?" : '.')."\n".
                "It must be one of the IDs from DateTimeZone::listIdentifiers(),\n".
                'For the record, hours/minutes offset are relevant only for a particular moment, '.
                'but not as a default timezone.',
                0,
                $previous
            );
        }
    }
}