PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/lib/node_modules/npm/node_modules/minimatch/dist/commonjs
Viewing File: /usr/lib/node_modules/npm/node_modules/minimatch/dist/commonjs/index.js
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.unescape = exports.escape = exports.AST = exports.Minimatch = exports.match = exports.makeRe = exports.braceExpand = exports.defaults = exports.filter = exports.GLOBSTAR = exports.sep = exports.minimatch = void 0; const brace_expansion_1 = require("@isaacs/brace-expansion"); const assert_valid_pattern_js_1 = require("./assert-valid-pattern.js"); const ast_js_1 = require("./ast.js"); const escape_js_1 = require("./escape.js"); const unescape_js_1 = require("./unescape.js"); const minimatch = (p, pattern, options = {}) => { (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); // shortcut: comments match nothing. if (!options.nocomment && pattern.charAt(0) === '#') { return false; } return new Minimatch(pattern, options).match(p); }; exports.minimatch = minimatch; // Optimized checking for the most common glob patterns. const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/; const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext); const starDotExtTestDot = (ext) => (f) => f.endsWith(ext); const starDotExtTestNocase = (ext) => { ext = ext.toLowerCase(); return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext); }; const starDotExtTestNocaseDot = (ext) => { ext = ext.toLowerCase(); return (f) => f.toLowerCase().endsWith(ext); }; const starDotStarRE = /^\*+\.\*+$/; const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.'); const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.'); const dotStarRE = /^\.\*+$/; const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.'); const starRE = /^\*+$/; const starTest = (f) => f.length !== 0 && !f.startsWith('.'); const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..'; const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/; const qmarksTestNocase = ([$0, ext = '']) => { const noext = qmarksTestNoExt([$0]); if (!ext) return noext; ext = ext.toLowerCase(); return (f) => noext(f) && f.toLowerCase().endsWith(ext); }; const qmarksTestNocaseDot = ([$0, ext = '']) => { const noext = qmarksTestNoExtDot([$0]); if (!ext) return noext; ext = ext.toLowerCase(); return (f) => noext(f) && f.toLowerCase().endsWith(ext); }; const qmarksTestDot = ([$0, ext = '']) => { const noext = qmarksTestNoExtDot([$0]); return !ext ? noext : (f) => noext(f) && f.endsWith(ext); }; const qmarksTest = ([$0, ext = '']) => { const noext = qmarksTestNoExt([$0]); return !ext ? noext : (f) => noext(f) && f.endsWith(ext); }; const qmarksTestNoExt = ([$0]) => { const len = $0.length; return (f) => f.length === len && !f.startsWith('.'); }; const qmarksTestNoExtDot = ([$0]) => { const len = $0.length; return (f) => f.length === len && f !== '.' && f !== '..'; }; /* c8 ignore start */ const defaultPlatform = (typeof process === 'object' && process ? (typeof process.env === 'object' && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__) || process.platform : 'posix'); const path = { win32: { sep: '\\' }, posix: { sep: '/' }, }; /* c8 ignore stop */ exports.sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep; exports.minimatch.sep = exports.sep; exports.GLOBSTAR = Symbol('globstar **'); exports.minimatch.GLOBSTAR = exports.GLOBSTAR; // any single thing other than / // don't need to escape / when using new RegExp() const qmark = '[^/]'; // * => any number of characters const star = qmark + '*?'; // ** when dots are allowed. Anything goes, except .. and . // not (^ or / followed by one or two dots followed by $ or /), // followed by anything, any number of times. const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?'; // not a ^ or / followed by a dot, // followed by anything, any number of times. const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?'; const filter = (pattern, options = {}) => (p) => (0, exports.minimatch)(p, pattern, options); exports.filter = filter; exports.minimatch.filter = exports.filter; const ext = (a, b = {}) => Object.assign({}, a, b); const defaults = (def) => { if (!def || typeof def !== 'object' || !Object.keys(def).length) { return exports.minimatch; } const orig = exports.minimatch; const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options)); return Object.assign(m, { Minimatch: class Minimatch extends orig.Minimatch { constructor(pattern, options = {}) { super(pattern, ext(def, options)); } static defaults(options) { return orig.defaults(ext(def, options)).Minimatch; } }, AST: class AST extends orig.AST { /* c8 ignore start */ constructor(type, parent, options = {}) { super(type, parent, ext(def, options)); } /* c8 ignore stop */ static fromGlob(pattern, options = {}) { return orig.AST.fromGlob(pattern, ext(def, options)); } }, unescape: (s, options = {}) => orig.unescape(s, ext(def, options)), escape: (s, options = {}) => orig.escape(s, ext(def, options)), filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)), defaults: (options) => orig.defaults(ext(def, options)), makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)), braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)), match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)), sep: orig.sep, GLOBSTAR: exports.GLOBSTAR, }); }; exports.defaults = defaults; exports.minimatch.defaults = exports.defaults; // Brace expansion: // a{b,c}d -> abd acd // a{b,}c -> abc ac // a{0..3}d -> a0d a1d a2d a3d // a{b,c{d,e}f}g -> abg acdfg acefg // a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg // // Invalid sets are not expanded. // a{2..}b -> a{2..}b // a{b}c -> a{b}c const braceExpand = (pattern, options = {}) => { (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); // Thanks to Yeting Li <https://github.com/yetingli> for // improving this regexp to avoid a ReDOS vulnerability. if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { // shortcut. no need to expand. return [pattern]; } return (0, brace_expansion_1.expand)(pattern); }; exports.braceExpand = braceExpand; exports.minimatch.braceExpand = exports.braceExpand; // parse a component of the expanded set. // At this point, no pattern may contain "/" in it // so we're going to return a 2d array, where each entry is the full // pattern, split on '/', and then turned into a regular expression. // A regexp is made at the end which joins each array with an // escaped /, and another full one which joins each regexp with |. // // Following the lead of Bash 4.1, note that "**" only has special meaning // when it is the *only* thing in a path portion. Otherwise, any series // of * is equivalent to a single *. Globstar behavior is enabled by // default, and can be disabled by setting options.noglobstar. const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); exports.makeRe = makeRe; exports.minimatch.makeRe = exports.makeRe; const match = (list, pattern, options = {}) => { const mm = new Minimatch(pattern, options); list = list.filter(f => mm.match(f)); if (mm.options.nonull && !list.length) { list.push(pattern); } return list; }; exports.match = match; exports.minimatch.match = exports.match; // replace stuff like \* with * const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/; const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); class Minimatch { options; set; pattern; windowsPathsNoEscape; nonegate; negate; comment; empty; preserveMultipleSlashes; partial; globSet; globParts; nocase; isWindows; platform; windowsNoMagicRoot; regexp; constructor(pattern, options = {}) { (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); options = options || {}; this.options = options; this.pattern = pattern; this.platform = options.platform || defaultPlatform; this.isWindows = this.platform === 'win32'; this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || options.allowWindowsEscape === false; if (this.windowsPathsNoEscape) { this.pattern = this.pattern.replace(/\\/g, '/'); } this.preserveMultipleSlashes = !!options.preserveMultipleSlashes; this.regexp = null; this.negate = false; this.nonegate = !!options.nonegate; this.comment = false; this.empty = false; this.partial = !!options.partial; this.nocase = !!this.options.nocase; this.windowsNoMagicRoot = options.windowsNoMagicRoot !== undefined ? options.windowsNoMagicRoot : !!(this.isWindows && this.nocase); this.globSet = []; this.globParts = []; this.set = []; // make the set of regexps etc. this.make(); } hasMagic() { if (this.options.magicalBraces && this.set.length > 1) { return true; } for (const pattern of this.set) { for (const part of pattern) { if (typeof part !== 'string') return true; } } return false; } debug(..._) { } make() { const pattern = this.pattern; const options = this.options; // empty patterns and comments match nothing. if (!options.nocomment && pattern.charAt(0) === '#') { this.comment = true; return; } if (!pattern) { this.empty = true; return; } // step 1: figure out negation, etc. this.parseNegate(); // step 2: expand braces this.globSet = [...new Set(this.braceExpand())]; if (options.debug) { this.debug = (...args) => console.error(...args); } this.debug(this.pattern, this.globSet); // step 3: now we have a set, so turn each one into a series of // path-portion matching patterns. // These will be regexps, except in the case of "**", which is // set to the GLOBSTAR object for globstar behavior, // and will not contain any / characters // // First, we preprocess to make the glob pattern sets a bit simpler // and deduped. There are some perf-killing patterns that can cause // problems with a glob walk, but we can simplify them down a bit. const rawGlobParts = this.globSet.map(s => this.slashSplit(s)); this.globParts = this.preprocess(rawGlobParts); this.debug(this.pattern, this.globParts); // glob --> regexps let set = this.globParts.map((s, _, __) => { if (this.isWindows && this.windowsNoMagicRoot) { // check if it's a drive or unc path. const isUNC = s[0] === '' && s[1] === '' && (s[2] === '?' || !globMagic.test(s[2])) && !globMagic.test(s[3]); const isDrive = /^[a-z]:/i.test(s[0]); if (isUNC) { return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]; } else if (isDrive) { return [s[0], ...s.slice(1).map(ss => this.parse(ss))]; } } return s.map(ss => this.parse(ss)); }); this.debug(this.pattern, set); // filter out everything that didn't compile properly. this.set = set.filter(s => s.indexOf(false) === -1); // do not treat the ? in UNC paths as magic if (this.isWindows) { for (let i = 0; i < this.set.length; i++) { const p = this.set[i]; if (p[0] === '' && p[1] === '' && this.globParts[i][2] === '?' && typeof p[3] === 'string' && /^[a-z]:$/i.test(p[3])) { p[2] = '?'; } } } this.debug(this.pattern, this.set); } // various transforms to equivalent pattern sets that are // faster to process in a filesystem walk. The goal is to // eliminate what we can, and push all ** patterns as far // to the right as possible, even if it increases the number // of patterns that we have to process. preprocess(globParts) { // if we're not in globstar mode, then turn all ** into * if (this.options.noglobstar) { for (let i = 0; i < globParts.length; i++) { for (let j = 0; j < globParts[i].length; j++) { if (globParts[i][j] === '**') { globParts[i][j] = '*'; } } } } const { optimizationLevel = 1 } = this.options; if (optimizationLevel >= 2) { // aggressive optimization for the purpose of fs walking globParts = this.firstPhasePreProcess(globParts); globParts = this.secondPhasePreProcess(globParts); } else if (optimizationLevel >= 1) { // just basic optimizations to remove some .. parts globParts = this.levelOneOptimize(globParts); } else { // just collapse multiple ** portions into one globParts = this.adjascentGlobstarOptimize(globParts); } return globParts; } // just get rid of adjascent ** portions adjascentGlobstarOptimize(globParts) { return globParts.map(parts => { let gs = -1; while (-1 !== (gs = parts.indexOf('**', gs + 1))) { let i = gs; while (parts[i + 1] === '**') { i++; } if (i !== gs) { parts.splice(gs, i - gs); } } return parts; }); } // get rid of adjascent ** and resolve .. portions levelOneOptimize(globParts) { return globParts.map(parts => { parts = parts.reduce((set, part) => { const prev = set[set.length - 1]; if (part === '**' && prev === '**') { return set; } if (part === '..') { if (prev && prev !== '..' && prev !== '.' && prev !== '**') { set.pop(); return set; } } set.push(part); return set; }, []); return parts.length === 0 ? [''] : parts; }); } levelTwoFileOptimize(parts) { if (!Array.isArray(parts)) { parts = this.slashSplit(parts); } let didSomething = false; do { didSomething = false; // <pre>/<e>/<rest> -> <pre>/<rest> if (!this.preserveMultipleSlashes) { for (let i = 1; i < parts.length - 1; i++) { const p = parts[i]; // don't squeeze out UNC patterns if (i === 1 && p === '' && parts[0] === '') continue; if (p === '.' || p === '') { didSomething = true; parts.splice(i, 1); i--; } } if (parts[0] === '.' && parts.length === 2 && (parts[1] === '.' || parts[1] === '')) { didSomething = true; parts.pop(); } } // <pre>/<p>/../<rest> -> <pre>/<rest> let dd = 0; while (-1 !== (dd = parts.indexOf('..', dd + 1))) { const p = parts[dd - 1]; if (p && p !== '.' && p !== '..' && p !== '**') { didSomething = true; parts.splice(dd - 1, 2); dd -= 2; } } } while (didSomething); return parts.length === 0 ? [''] : parts; } // First phase: single-pattern processing // <pre> is 1 or more portions // <rest> is 1 or more portions // <p> is any portion other than ., .., '', or ** // <e> is . or '' // // **/.. is *brutal* for filesystem walking performance, because // it effectively resets the recursive walk each time it occurs, // and ** cannot be reduced out by a .. pattern part like a regexp // or most strings (other than .., ., and '') can be. // // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>} // <pre>/<e>/<rest> -> <pre>/<rest> // <pre>/<p>/../<rest> -> <pre>/<rest> // **/**/<rest> -> **/<rest> // // **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow // this WOULD be allowed if ** did follow symlinks, or * didn't firstPhasePreProcess(globParts) { let didSomething = false; do { didSomething = false; // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>} for (let parts of globParts) { let gs = -1; while (-1 !== (gs = parts.indexOf('**', gs + 1))) { let gss = gs; while (parts[gss + 1] === '**') { // <pre>/**/**/<rest> -> <pre>/**/<rest> gss++; } // eg, if gs is 2 and gss is 4, that means we have 3 ** // parts, and can remove 2 of them. if (gss > gs) { parts.splice(gs + 1, gss - gs); } let next = parts[gs + 1]; const p = parts[gs + 2]; const p2 = parts[gs + 3]; if (next !== '..') continue; if (!p || p === '.' || p === '..' || !p2 || p2 === '.' || p2 === '..') { continue; } didSomething = true; // edit parts in place, and push the new one parts.splice(gs, 1); const other = parts.slice(0); other[gs] = '**'; globParts.push(other); gs--; } // <pre>/<e>/<rest> -> <pre>/<rest> if (!this.preserveMultipleSlashes) { for (let i = 1; i < parts.length - 1; i++) { const p = parts[i]; // don't squeeze out UNC patterns if (i === 1 && p === '' && parts[0] === '') continue; if (p === '.' || p === '') { didSomething = true; parts.splice(i, 1); i--; } } if (parts[0] === '.' && parts.length === 2 && (parts[1] === '.' || parts[1] === '')) { didSomething = true; parts.pop(); } } // <pre>/<p>/../<rest> -> <pre>/<rest> let dd = 0; while (-1 !== (dd = parts.indexOf('..', dd + 1))) { const p = parts[dd - 1]; if (p && p !== '.' && p !== '..' && p !== '**') { didSomething = true; const needDot = dd === 1 && parts[dd + 1] === '**'; const splin = needDot ? ['.'] : []; parts.splice(dd - 1, 2, ...splin); if (parts.length === 0) parts.push(''); dd -= 2; } } } } while (didSomething); return globParts; } // second phase: multi-pattern dedupes // {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest> // {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest> // {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest> // // {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest> // ^-- not valid because ** doens't follow symlinks secondPhasePreProcess(globParts) { for (let i = 0; i < globParts.length - 1; i++) { for (let j = i + 1; j < globParts.length; j++) { const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes); if (matched) { globParts[i] = []; globParts[j] = matched; break; } } } return globParts.filter(gs => gs.length); } partsMatch(a, b, emptyGSMatch = false) { let ai = 0; let bi = 0; let result = []; let which = ''; while (ai < a.length && bi < b.length) { if (a[ai] === b[bi]) { result.push(which === 'b' ? b[bi] : a[ai]); ai++; bi++; } else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) { result.push(a[ai]); ai++; } else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) { result.push(b[bi]); bi++; } else if (a[ai] === '*' && b[bi] && (this.options.dot || !b[bi].startsWith('.')) && b[bi] !== '**') { if (which === 'b') return false; which = 'a'; result.push(a[ai]); ai++; bi++; } else if (b[bi] === '*' && a[ai] && (this.options.dot || !a[ai].startsWith('.')) && a[ai] !== '**') { if (which === 'a') return false; which = 'b'; result.push(b[bi]); ai++; bi++; } else { return false; } } // if we fall out of the loop, it means they two are identical // as long as their lengths match return a.length === b.length && result; } parseNegate() { if (this.nonegate) return; const pattern = this.pattern; let negate = false; let negateOffset = 0; for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) { negate = !negate; negateOffset++; } if (negateOffset) this.pattern = pattern.slice(negateOffset); this.negate = negate; } // set partial to true to test if, for example, // "/a/b" matches the start of "/*/b/*/d" // Partial means, if you run out of file before you run // out of pattern, then that's fine, as long as all // the parts match. matchOne(file, pattern, partial = false) { const options = this.options; // UNC paths like //?/X:/... can match X:/... and vice versa // Drive letters in absolute drive or unc paths are always compared // case-insensitively. if (this.isWindows) { const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]); const fileUNC = !fileDrive && file[0] === '' && file[1] === '' && file[2] === '?' && /^[a-z]:$/i.test(file[3]); const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]); const patternUNC = !patternDrive && pattern[0] === '' && pattern[1] === '' && pattern[2] === '?' && typeof pattern[3] === 'string' && /^[a-z]:$/i.test(pattern[3]); const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined; const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined; if (typeof fdi === 'number' && typeof pdi === 'number') { const [fd, pd] = [file[fdi], pattern[pdi]]; if (fd.toLowerCase() === pd.toLowerCase()) { pattern[pdi] = fd; if (pdi > fdi) { pattern = pattern.slice(pdi); } else if (fdi > pdi) { file = file.slice(fdi); } } } } // resolve and reduce . and .. portions in the file as well. // don't need to do the second phase, because it's only one string[] const { optimizationLevel = 1 } = this.options; if (optimizationLevel >= 2) { file = this.levelTwoFileOptimize(file); } this.debug('matchOne', this, { file, pattern }); this.debug('matchOne', file.length, pattern.length); for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { this.debug('matchOne loop'); var p = pattern[pi]; var f = file[fi]; this.debug(pattern, p, f); // should be impossible. // some invalid regexp stuff in the set. /* c8 ignore start */ if (p === false) { return false; } /* c8 ignore stop */ if (p === exports.GLOBSTAR) { this.debug('GLOBSTAR', [pattern, p, f]); // "**" // a/**/b/**/c would match the following: // a/b/x/y/z/c // a/x/y/z/b/c // a/b/x/b/x/c // a/b/c // To do this, take the rest of the pattern after // the **, and see if it would match the file remainder. // If so, return success. // If not, the ** "swallows" a segment, and try again. // This is recursively awful. // // a/**/b/**/c matching a/b/x/y/z/c // - a matches a // - doublestar // - matchOne(b/x/y/z/c, b/**/c) // - b matches b // - doublestar // - matchOne(x/y/z/c, c) -> no // - matchOne(y/z/c, c) -> no // - matchOne(z/c, c) -> no // - matchOne(c, c) yes, hit var fr = fi; var pr = pi + 1; if (pr === pl) { this.debug('** at the end'); // a ** at the end will just swallow the rest. // We have found a match. // however, it will not swallow /.x, unless // options.dot is set. // . and .. are *never* matched by **, for explosively // exponential reasons. for (; fi < fl; fi++) { if (file[fi] === '.' || file[fi] === '..' || (!options.dot && file[fi].charAt(0) === '.')) return false; } return true; } // ok, let's see if we can swallow whatever we can. while (fr < fl) { var swallowee = file[fr]; this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); // XXX remove this slice. Just pass the start index. if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { this.debug('globstar found match!', fr, fl, swallowee); // found a match. return true; } else { // can't swallow "." or ".." ever. // can only swallow ".foo" when explicitly asked. if (swallowee === '.' || swallowee === '..' || (!options.dot && swallowee.charAt(0) === '.')) { this.debug('dot detected!', file, fr, pattern, pr); break; } // ** swallows a segment, and continue. this.debug('globstar swallow a segment, and continue'); fr++; } } // no match was found. // However, in partial mode, we can't say this is necessarily over. /* c8 ignore start */ if (partial) { // ran out of file this.debug('\n>>> no match, partial?', file, fr, pattern, pr); if (fr === fl) { return true; } } /* c8 ignore stop */ return false; } // something other than ** // non-magic patterns just have to match exactly // patterns with magic have been turned into regexps. let hit; if (typeof p === 'string') { hit = f === p; this.debug('string match', p, f, hit); } else { hit = p.test(f); this.debug('pattern match', p, f, hit); } if (!hit) return false; } // Note: ending in / means that we'll get a final "" // at the end of the pattern. This can only match a // corresponding "" at the end of the file. // If the file ends in /, then it can only match a // a pattern that ends in /, unless the pattern just // doesn't have any more for it. But, a/b/ should *not* // match "a/b/*", even though "" matches against the // [^/]*? pattern, except in partial mode, where it might // simply not be reached yet. // However, a/b/ should still satisfy a/* // now either we fell off the end of the pattern, or we're done. if (fi === fl && pi === pl) { // ran out of pattern and filename at the same time. // an exact hit! return true; } else if (fi === fl) { // ran out of file, but still had pattern left. // this is ok if we're doing the match as part of // a glob fs traversal. return partial; } else if (pi === pl) { // ran out of pattern, still have file left. // this is only acceptable if we're on the very last // empty segment of a file with a trailing slash. // a/* should match a/b/ return fi === fl - 1 && file[fi] === ''; /* c8 ignore start */ } else { // should be unreachable. throw new Error('wtf?'); } /* c8 ignore stop */ } braceExpand() { return (0, exports.braceExpand)(this.pattern, this.options); } parse(pattern) { (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); const options = this.options; // shortcuts if (pattern === '**') return exports.GLOBSTAR; if (pattern === '') return ''; // far and away, the most common glob pattern parts are // *, *.*, and *.<ext> Add a fast check method for those. let m; let fastTest = null; if ((m = pattern.match(starRE))) { fastTest = options.dot ? starTestDot : starTest; } else if ((m = pattern.match(starDotExtRE))) { fastTest = (options.nocase ? options.dot ? starDotExtTestNocaseDot : starDotExtTestNocase : options.dot ? starDotExtTestDot : starDotExtTest)(m[1]); } else if ((m = pattern.match(qmarksRE))) { fastTest = (options.nocase ? options.dot ? qmarksTestNocaseDot : qmarksTestNocase : options.dot ? qmarksTestDot : qmarksTest)(m); } else if ((m = pattern.match(starDotStarRE))) { fastTest = options.dot ? starDotStarTestDot : starDotStarTest; } else if ((m = pattern.match(dotStarRE))) { fastTest = dotStarTest; } const re = ast_js_1.AST.fromGlob(pattern, this.options).toMMPattern(); if (fastTest && typeof re === 'object') { // Avoids overriding in frozen environments Reflect.defineProperty(re, 'test', { value: fastTest }); } return re; } makeRe() { if (this.regexp || this.regexp === false) return this.regexp; // at this point, this.set is a 2d array of partial // pattern strings, or "**". // // It's better to use .match(). This function shouldn't // be used, really, but it's pretty convenient sometimes, // when you just want to work with a regex. const set = this.set; if (!set.length) { this.regexp = false; return this.regexp; } const options = this.options; const twoStar = options.noglobstar ? star : options.dot ? twoStarDot : twoStarNoDot; const flags = new Set(options.nocase ? ['i'] : []); // regexpify non-globstar patterns // if ** is only item, then we just do one twoStar // if ** is first, and there are more, prepend (\/|twoStar\/)? to next // if ** is last, append (\/twoStar|) to previous // if ** is in the middle, append (\/|\/twoStar\/) to previous // then filter out GLOBSTAR symbols let re = set .map(pattern => { const pp = pattern.map(p => { if (p instanceof RegExp) { for (const f of p.flags.split('')) flags.add(f); } return typeof p === 'string' ? regExpEscape(p) : p === exports.GLOBSTAR ? exports.GLOBSTAR : p._src; }); pp.forEach((p, i) => { const next = pp[i + 1]; const prev = pp[i - 1]; if (p !== exports.GLOBSTAR || prev === exports.GLOBSTAR) { return; } if (prev === undefined) { if (next !== undefined && next !== exports.GLOBSTAR) { pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next; } else { pp[i] = twoStar; } } else if (next === undefined) { pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + ')?'; } else if (next !== exports.GLOBSTAR) { pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next; pp[i + 1] = exports.GLOBSTAR; } }); const filtered = pp.filter(p => p !== exports.GLOBSTAR); // For partial matches, we need to make the pattern match // any prefix of the full path. We do this by generating // alternative patterns that match progressively longer prefixes. if (this.partial && filtered.length >= 1) { const prefixes = []; for (let i = 1; i <= filtered.length; i++) { prefixes.push(filtered.slice(0, i).join('/')); } return '(?:' + prefixes.join('|') + ')'; } return filtered.join('/'); }) .join('|'); // need to wrap in parens if we had more than one thing with |, // otherwise only the first will be anchored to ^ and the last to $ const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', '']; // must match entire pattern // ending in a * or ** will make it less strict. re = '^' + open + re + close + '$'; // In partial mode, '/' should always match as it's a valid prefix for any pattern if (this.partial) { re = '^(?:\\/|' + open + re.slice(1, -1) + close + ')$'; } // can match anything, as long as it's not this. if (this.negate) re = '^(?!' + re + ').+$'; try { this.regexp = new RegExp(re, [...flags].join('')); /* c8 ignore start */ } catch (ex) { // should be impossible this.regexp = false; } /* c8 ignore stop */ return this.regexp; } slashSplit(p) { // if p starts with // on windows, we preserve that // so that UNC paths aren't broken. Otherwise, any number of // / characters are coalesced into one, unless // preserveMultipleSlashes is set to true. if (this.preserveMultipleSlashes) { return p.split('/'); } else if (this.isWindows && /^\/\/[^\/]+/.test(p)) { // add an extra '' for the one we lose return ['', ...p.split(/\/+/)]; } else { return p.split(/\/+/); } } match(f, partial = this.partial) { this.debug('match', f, this.pattern); // short-circuit in the case of busted things. // comments, etc. if (this.comment) { return false; } if (this.empty) { return f === ''; } if (f === '/' && partial) { return true; } const options = this.options; // windows: need to use /, not \ if (this.isWindows) { f = f.split('\\').join('/'); } // treat the test path as a set of pathparts. const ff = this.slashSplit(f); this.debug(this.pattern, 'split', ff); // just ONE of the pattern sets in this.set needs to match // in order for it to be valid. If negating, then just one // match means that we have failed. // Either way, return on the first hit. const set = this.set; this.debug(this.pattern, 'set', set); // Find the basename of the path by looking for the last non-empty segment let filename = ff[ff.length - 1]; if (!filename) { for (let i = ff.length - 2; !filename && i >= 0; i--) { filename = ff[i]; } } for (let i = 0; i < set.length; i++) { const pattern = set[i]; let file = ff; if (options.matchBase && pattern.length === 1) { file = [filename]; } const hit = this.matchOne(file, pattern, partial); if (hit) { if (options.flipNegate) { return true; } return !this.negate; } } // didn't get any hits. this is success if it's a negative // pattern, failure otherwise. if (options.flipNegate) { return false; } return this.negate; } static defaults(def) { return exports.minimatch.defaults(def).Minimatch; } } exports.Minimatch = Minimatch; /* c8 ignore start */ var ast_js_2 = require("./ast.js"); Object.defineProperty(exports, "AST", { enumerable: true, get: function () { return ast_js_2.AST; } }); var escape_js_2 = require("./escape.js"); Object.defineProperty(exports, "escape", { enumerable: true, get: function () { return escape_js_2.escape; } }); var unescape_js_2 = require("./unescape.js"); Object.defineProperty(exports, "unescape", { enumerable: true, get: function () { return unescape_js_2.unescape; } }); /* c8 ignore stop */ exports.minimatch.AST = ast_js_1.AST; exports.minimatch.Minimatch = Minimatch; exports.minimatch.escape = escape_js_1.escape; exports.minimatch.unescape = unescape_js_1.unescape; //# sourceMappingURL=index.js.map