From 8358c34f2248484cac8d4d33da22298e25caa4cc Mon Sep 17 00:00:00 2001 From: mdillar_criteo Date: Tue, 5 May 2020 16:59:29 +0200 Subject: [PATCH 01/34] Added Nuvem as an Ecommerce platform --- src/apps.json | 8 ++++++++ src/icons/nuvem.png | Bin 0 -> 21831 bytes 2 files changed, 8 insertions(+) create mode 100644 src/icons/nuvem.png diff --git a/src/apps.json b/src/apps.json index 7b7865430..a1366db2f 100644 --- a/src/apps.json +++ b/src/apps.json @@ -7467,6 +7467,14 @@ "icon": "zeit.svg", "website": "https://zeit.co/now" }, + "Nuvem": { + "cats": [ + 6 + ], + "script": "(N|n)uvem", + "icon": "nuvem.png", + "website": "https://www.nuvemshop.com.br/" + }, "OWL Carousel": { "cats": [ 5 diff --git a/src/icons/nuvem.png b/src/icons/nuvem.png new file mode 100644 index 0000000000000000000000000000000000000000..5a8ddd3d4d6709cc38df0088bdff0e9fcf22874c GIT binary patch literal 21831 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

hH6l;zd&@@g qPOb6qasO|6{J-e(f9Cl-xtBCM?Up&)Qvw93k5vEGRH{|94EYZy6uRyJ literal 0 HcmV?d00001 From e95ca2dc7c6b27d9288e7311579c8839c55d3e5b Mon Sep 17 00:00:00 2001 From: mdillar_criteo Date: Wed, 6 May 2020 03:54:57 +0200 Subject: [PATCH 02/34] Added Powerboutique as an Ecommerce Platform --- src/apps.json | 8 ++++++++ src/icons/powerboutique.jpg | Bin 0 -> 39937 bytes 2 files changed, 8 insertions(+) create mode 100644 src/icons/powerboutique.jpg diff --git a/src/apps.json b/src/apps.json index 7b7865430..1a4c51ab4 100644 --- a/src/apps.json +++ b/src/apps.json @@ -8407,6 +8407,14 @@ "icon": "PostgreSQL.png", "website": "http://www.postgresql.org/" }, + "Powerboutique": { + "cats": [ + 6 + ], + "script": "powerboutique", + "icon": "powerboutique.jpg", + "website": "https://www.powerboutique.com/" + }, "Powergap": { "cats": [ 6 diff --git a/src/icons/powerboutique.jpg b/src/icons/powerboutique.jpg new file mode 100644 index 0000000000000000000000000000000000000000..61a3d6c8bbae4fc1c4985d5fc598ae6bb57968c2 GIT binary patch literal 39937 zcmeFZ2UHYIvoJhM&KU#*MRLwra#AGcBym|XEG$bFP{~<9a?X+kBr7Nqlpr~S5>%oA z2`UKuv!Fh{;okS2`O}s=B(myLx)6dS*^%PL}|Z8!DP_T_UP*h}KH*$2dh5LAN0D}Ai!jk;Ll7bQp{1TEP5+DFd z0|1PB0Dz4;^9u?J$oj?dAlA>c=Arruq*RdvN^tdC4MUhxgr@+Ka zsr$@ENEmTOW4%AbGs<1wURVi8DR=KMPDSBbdUvROQ!)~l*^r25m|hi3m#Rjt#}eS^VMAU19LFmaMNhWgEJb$Q;`cjMd%)q!NM zI!6%x8a@O*wwb5EjrVD{x$4_bZhOk4l{B)*SlTP}Z{;u*?d7KJd(E_(aW=5kNED

wKIrxv|DaAu*~OeO&vbLs|buK*mz>O)j5rAzqUtIV5zpzk|4Z14HKC;${pPl zn+}X^9`oD`)M|j&cj}Gr<^5Rs*d_znc*2BVCb80Iy*erX5Qj*lt`R<8J2uy{d%}14 zRijfhuTt9iz(;M9m$#X6KccPrxpT)5eC&`72DdNpDccB29pKnc(lgpzo35#wsM?_M z(?Y+%y0!!x>z|{AJ3z}{IKMig*=!KH7#LJGUb-J#8VDcm+!E?lTrIRf&_t`5Qez1P z8d>nn@%q$18FtP&1)L~LPl1?i?%;|^B%N7gQ>BXPfbZnjKztW37oNG{YkML_?RzeJ zo!N(uZ4na!$)jyPnq|yJZrJ5w62%dRuaAxkhE4%I>1f>8$4b5H{^9MXfX?{4FNkXt zDppKMI;pq=A>UgL*NC9wCweh+eMg_fGWNH&Xs91e-WS;366@%9*~9$U(_Qo2aMPo_ zd#^XIveo9$ zLVM)v#wpI$??I7eK{qkV0dDO=k6-B|qjefymn$xz%*Lv0q+kM~33=sW3%^ zUoJQWL{>Xmu5KA#o7k2qnBL`Vt2)~G&|TOh5?|r?()&nSRLJvV`Jm_VDNt0WR?(Ez zQNM@xrR}23gE2wHjJ0G@GVebd!o$$doMJyHDyuM$h3GtRTI?3}2sOJtc z@U9;o9ee*_rak-ej^9LtS+Mcu6Uz_NZ=v%lieU=P8jab(BOii``#0=&g9}f(UctZB zY<*m>T{qm%?6emgb(2;|c=gq-@#Dh0>6+UKe6qe+KkIT;pzBs3^aQ>~P$6l@cdf6a zwe@w(C39=2>3f6t_x>WylW)xRC+1Fp^rm6U@0k~5Q}$Q4O4-yl<9+n@5&Uf_#v&H% z#n%a5?JwuXzZvViNPlwhsoHDyvX1|2F_Y$sK+Db5GP=XLSNYGcKfEAP?Oa=s!0Waq z?jPsenHgMu7_2$0fe1DTDxcm@F7&F&(bRdcx=%Hm5HR2ASDmK)#?m?K$G(r7=gg-y z>2;3npmwj7Zbt+i2HT>A?aCnO2)n>Z6 z#<6tDljmi~{79=Khn4Z3 zfV;bU$b3YCA^*dVzU6UNo}GRt>27OG#Yy+UW%O*JJ01TILjGKDwN7VGKahR?>lRap zmmd&UP}RUd-JSvfF&)GdK)=XxjSjqxMKkn0r?H&TNYpnT?e{+#EBv8Pmli%uOnX*N z@{INgJd%Ka)D0j2;JYIn-H=*dNOvzJm_^++1KOTQJsUXO<%~ns4GDv}dAXtpC>V8C zbU~o<#Ajvo9DPw73XVur85H?kCJdoz?F!RZHr5AG=aroo&_=-Fc6ui?PPznUCSNm2zT=Y=@(F(itb3aU(ErVYlHZm(Y5!~ z_?=NixGDaXaYO!w+5P-$}v6mf_#wbv<2> zXLxO27dhSE?0DWVC=!lPvPN2?T5zVMw!OCJFZ)2jC}!}CQX5c**`15|r)u>^?awaGVXNd%gfV&$xz`(%;ZPn4u{#W-Ap$NL5P6}`&67K2(ceDRlgy0ti zrNSS0!e4k@M|+1q3HZMVpl-kUQL_g9!?_OU&JyS*o;y!yXETcRj7IdcQt%{u8#uQ& z!ZRFdrd~SZr1{4@`tDgC_v{EBAZMjO_Y#%xeohzAV9zwzKf_)J`0VUJiVJuI-9Ruw zeqstTGJj(P&+w+;@fVNC83twfKQU)AzkzuGoMXW0zfI`tDDuB0o&KND&iVo+8f+T? zIm@A(aL^@29nSLnC`1`EV>4GIBz#9 z3!q$TRB!Uza?bU+8~e#&v)r{N-I7?SJ(Y z@p76CNj zZm7P-MZ(>|Mcotj=QR$`1-uyk3zop{k55)oCHiHM${T+Pz zJNWc>@aga1)8E0T|8E4J&hP22fOl;Gpa=d@8@B*4AP>4saL{>z0StgP-~htNGsg)9 zxq}>J|AB)6Py~OdTf(z@#B<*a8{A+$tKoE+xXl5HbeH7gbMxf2Ms2e4LgB7_zSi!1 z0=)cufRwDSyEW7qhGejTfnJF;hBDd zuw|5$VUY5b^mTQ2g(0mOd|h4KJSBal8P9}Ef-nlr$H;KTf^?Qpf;^Pcm+flekMk+HiWI6q^^?6 z&$_^zG~>@k`S|$o`UvsD5%zon5)u-8{DORff;=DxkEfp-(%P5D&6DYu1SOa!6ybOl zmtsIk1Y<59|pF8LpomFlN<%7AvTw!iVPq1GFP|ZIR z>i%m(`*)Fl5dE8cHWZaURn!w^(6EMrF(PnJ{ttc_7_fp#Gol8KM?ipw zUqoMk9~?1BL2)jA0ZD%Tb5;$wt)rdaZ&qO*eqkO#3H@Ii_+0$pK>uO|EyflMg8fHk zTd1TR9N}sWw%5_s+8)N|9w!Wg0qdm+MDoudm#@C0Ls464eCq5=}4qCA4Upn$XSl2mo`L|VH+VX8{fj39>B z(a}~C>>(R*QBi9iF>!uT9+;T0D36VewJ47;6eb`F6@iM|iHrOyuLOsBp$zC(d0Vi& zikO&+fPk1VznCDusJMWDxQeKtypXblgc84kkc8;(y3fN0)-L}m8Q=u_s{?;YkOy1h z30j8d&*`UNZT}N;ag-6@S5oE|mXHt@6jxAG5a$;Y7ZH&cmgkpH5El?s6jzesL(MOc zk>MOVFU0^z6$=idY^q*!6-+!q$+zl0~_)BwlYXlhAN5T-E z(u{TpxGTfCWxKoCGa%tVGiPT0UyAg!_Wn!UzwHR||71r0_d4R|_&^=3-RxoDvckvs zzi-F?Y&!i@TmGvH&;M*t|9A}Pm#O_zQ_gJt+)(-c*@n+(f2=#dCIq;cp}^m(sLZd` z?(g&8J@9uA{M`e8_rTvh@OKaV|ELH4^21?n;9Zgr=w+X-5Ez4=ho!czmWryn@>#%u z;JUh_8ypSX2z3RYbU?Wx#wMl=*ss8iP+V|d7Tof*hI+bd=&7I{5&=Lrg#qQSpx~bg z3_2W4o$Vh1<2={385n*M{)cB$s5=7O(}ie*{6e;%M-9TEAnf9UbVuP)`&Se;&L|iS zwR1&*02Ksb)c!7o{W;8i#&ZtKpw;ks3@LE)jKKa6*yaxy z3GPLLynrIy-S2F7j)5J@!2kvl#2K!`d|Y5iB#$;29I-~&f}smncWXC4061?msuV!> zFTUUz`uyiW90mZ? zbAREO^TF6tC;&7K|Ir>Ql)d~BSaF0wc~KquJN-w7-<J`vt9@WPcSwGW8nE`BmQ3({6noj^x)Qo*})Jn(Bow=1g#8wAO;+6H(N)Pqsidt z_7C3v9}@nT#r}|h0?+Ll1jvg|018W9fMl2gK>siZV36Yj=r?mg3gq{=spA@gK|%m9 zy1aI7_aF??&yN3aKuZ9#Xr7K|4+sE?y7~-IFNF6w3kK?h2|g7=3{U_xz$JhQU6C`ff(Q(kOE`^c|b8x4%7hkKr`?d zcn0(W1HcF{3Csgaz&l_I_zWBXN8k$t*bqVpIfMps8NveLf(SyyAueA+wNW$OhyKqW7=c-V1{F+VwPeyV)kH8V!p#Xz{0|! z!eYY`!@7=Tg5`u2fEA0CgH?<56l)Y~6>A?G8=D533tJjn3)>nSi5-refn9~&i9Lq> z4*MGpKF(zvK^zqvQye#(yEv&h6*wI@V>oL#N4O-oEVz=mTDZ2jez*y^#kg&_!?^Eo zkMKzG*zlzB^zoeV?%<{4)!_BuE#U3q5f~N$t1iOTUgsg;egrS*d( z>PhND8U`9=8fThBnr50sS`1oFS{+&++FaTm+U<)J7q4D~UW~q2e{qfujgFH}mo9*= zh;EQ>pZ*g4HF|gY4EpEv+n1;=$z5`~bpKMvrH#wvmt`(HUcP_1^YSJGC4)SJ3qv|X zH^b*EbXTrl@w!rQ<<*rVMm9zR#=DHQjEhWoOyW#-O!t|(m_9RKX4YW7#azie$AZfu z&f>t5#?r^~m6eUvh&6(>nRT6wnoX6>pRJN@ft`?DmfeHBkbQy!i$k2lnInf|gcFTZ zgwugDi*uL@jZ2ivkt>I5lpB*O|kb9bkfJdIko2QaznU{)Jo%b$pGw(+}Wywk8v=I)+62A`atcBPvjiuE2!&LHf`wXyc7(ZvVZyn>Ga}?7 z8X^%QT_VS#VxkDq8qp0gW-%+VY_Vx^3UO`mSn(GUm=X#S!4i)pzDtTqA|>l3KV9Xy z>U_20>bex06iljEYE_z1+FH6mdP#;s#!4n%W=ZynthH>R?1~(doUL4`+?qUxypw#D z{6__T1%yJQ!dFE}#X!ZUO6W@0l%kbhDU&H1C}%3aR$)}JSE*F_d`;w9z_q8>F|Vs# zPrN>@O0No4Em!?~L+nQ2jczppH9fUVwH0+vb%c7G2AakVjbx1lO%_cz&1Nk?OI0gb zYf+m`+e5ou2TMm=CrjtOu7K_>-99~XJxjd`y#sv({RI7a19k&1gDyj2!<&ZXhF^`8 zjFOC&jQNZMjR#CHOtDQ3O-oJp&6Lej%--D;xfyagvo=$Pra<8<9A&*`hPmUEf&sf&?Itt*bJm20aTnVYj)H~bRZ7e4CFl3a93!;iY+{Ev2ic zw`4G9+{^fp>5w^@rI1ydO_v>&{WZrnXDnAPwGm`GXRBS7UGvY4pHFn_bie9R>v_?u()+wm zzOVCz^oz$YC11Aoi}yDVhz>LjiVQXmi3~Nq5`EP)EH>OSA~Di7DmB_MCOh_QTxq;_ zLUm$bQgd>2%3x|{`sVb~jP1<&tjp}qocG+({OtwIh3G|+#njhyuM6LBys2FhU3#*t zv^=eMbgZt}sJQ8#gu%&rVe{=i|{J+ry?0EOt4Jq%PSA`ZP$AR|(gduW380gu7?wgDv zc~!q;dp-!;JR`{LfPPN3(h(32WB?IhqPX&9TcLeff~H65(I~1U1&@yVi(8{HrM;~Z zs5~H^xZ%+Ig!RiLTgGkB-wQOa%zf!x)YBy>?8+1)^`JMyyHr8R*Yd(z$H4T$_sh6z z;y;F&R(^cw+Lfu@GvyhMIM7mjwG(J5)Mu>pdgZNw6ZfYAC=92KziT6<2%kGXKy;%^ z@NR<@%NjvS#4Ns%{ey@Go{ecW%$liHm6i0mONKQz=DT^3eNlc%YZrhouon^Y_y+cs z(ze`mk28`!Kbu!!7+}?7dIai;gr)>rB!y~6>q88Z#2_}cF0eQR2QBe zbi6R%`F@9l-t6Gk&Hb-a?KnR0_tW)nznQzW@$KWuUv1yDqj}O?##iEMwLN={wed(+ zZ!n`%xxT?ZUXoKd(rC(iWi{W(5Mr`_VQF?1tI(|MDs^VttGXCs?bhfE% zSCE1gKk-4{0qb?Ci& zs7rF=OuzcA+sA2F7kNIWopRYp`oP&}=&IMJLKO)a6}_)u5jP|LDt)XyDJ^#N0`ir? zy?fI!Dlfk=pX7tuVq7z+l^N>r@Q<#=t!VlfJI{t$nwqf?`h92rnPrZwp`h5neh}+7 znYZ^od44aWeG=TrL!9uH#$o$YtjOc-;4IJFWJZaO$eZ{gRkIH}IABG3xr$?xkL=i2 z8%&O8GYAY*w-@X`I`*`)me7yQrZK0zpRk8*2?mied2dL0R|d$c+NiUH=DBElR*-UM z;wbjaS9qkq;ZbVE<*5*<%9YCfQoHcVwEpZ#UWK6%`F5{(uBmJs=}}zCCg5c_B6jGa zugB=Si9FZdJc~fJ+>V{yUhku_;d>HeZwhih81ZKPGdu`<<@5(a+RDT9bWsLC>W1 zvWR}%x>O=8k)M1moYgy0WmNDx|LbkO1}m3)_!asOk_KmvIeaQV-3B`qjr-9x%q+H* zPx6!Z5-Vi3ziMa1&hFe;HLCFr)!A>J5xg_g$!aT>wG}D8$=A_vZO&g%H30iP7rhXM zX?TCIW|vD|?Aa#SCPf$KDe0L%z5ipZPl1Q7zAh!j4pW=F z@^zZ;V*}L>B-lkoX%E85%$wKfYlAAqxaY%VZg|&04H7AfdNQDf-LtYNR~Vvjm#&xt z??%ZL-K0WJT?#JF%Z0wrIB$ETaaQv3S5;^ibMR^xn0SQQa$ZrWFUDkfkspTFkG2=t zH02|`5(c{ta51nWKtca5DH0_{Oy{JvY@S_e{vF5Pxc`$LfPjm)Ah<4LVu0&47S_)N z{Orwr@QVXDq-5k2SNKUNsV-162ndSE$!jyS+!F#5HL3{G6)qVn~x}bRQatK*(|N8>z=opSXj~YgJ8C z>iu`;P1vPY3Rv{M3`{($fnuyAEh^ zQ&!XsmK~|D)<#KpdonU>TxVwQ?I-rWQ2gOqt*OT={>b_nH_i77E)5z+vpA!OCgXQd zqSOtYm*V&CtLxs)^w+keZmgEaqh8+asrl?|y0L}pG*Q0>7ejlzLuw{`A;w_j^0Fm; z0}rCcZfE8DD^h+t@9bLyFV*eV-PVFf$E4N#56WmuUN6j1SqQ(4A*u;!A^!i02+H8}$OkNyr3aUDH(s&p4s^##d8ZXD?#SV;_ZVE2e2AB@$ zW+NA=i{FrElazOrJ-s)spIPg!v+Q9!M4I~6=S@kY-=0!NknscEf@|b&Qx{$91)8b5 zD$7TuC>i=c(NKK1vDdt*jm?v-aaAH6PiRFRGHKJ3KMy~G4Y^dtkYl%Bc|DT!sS`RY zKV+B1xxDIpDezWAJQY=Hb~MYfqxyyppSK`82H%VGM7CI9g7TAq?Z;TaZCR2-D`T~6=Cl1lG`)C{W#Vc)D z7-A#2$CgUEqlMOI)_Fsu{{5rR_*fI!Z2M)Lh4>zUV}V1|ohBtkj;b#&ax?IjNhD(0 z2w_Xdi!Z~~Tvaw=1$JM)M~k6>3;d89y+yVi%)WitBG+oV&PvbAnkDkM|3)@bs8|+n zQB`Pw^H)P7!h5TjUiWw1ZP&br^k14eGu9Yhw9U3)G30YLU)W8jTWM!DcI_T?yz1IS zTCHB=JwLQxy$NL-xbddS`K`9$b&p$E{hzbwtrSuf0X>?dDAP~^IicGYRpDk0uIALY z`}*iYUr|Sot{${MyZ`1Ev$#%#TdmV-y3O+bS1#=v2kBl7Hec=Ny|`9Nj-PSMCE3VH z?+1vDw0Q@Y(Ll{Ve^fgH!#L9{-8-M_p*{6Ou0k)}cs_i7MYTx|b6vJsQ26vV`~r-0 zMkJ>3`6)1zv_zj*Z9q6AaLZ}b!=>A_BP0MCw=b;@9Ze{2UfmN6*`*XonlyL27eDjT zZ~mfne9vuuvTcAL^WA1(4z5H-@X!NQ6WdX*E3tEkM$5Eo(PX-P#=0{qPaU3i$LoGD z8c1=mCl5z=j?8>%)+a@^6dBdbIX${dTm685(`Bnc=BmDQp8HAu{XQ&A7m_C%A*N5C zc6ToI8xAy>m9Dx;<#9$(*-XTS5Z)BvCy`9nAEJKu%Jp0{jPCtZ9Zuw~Gip52PWl%N^H_o;uu%jUb4(ctSj+!+n!KDw#M9UHwH zBkTfkkE^QmZ+eA%cX4WMS0YL{GEgSbL%K@ERLQ1!=Hit>E#wUE@5Sl$=3LvD5w8`-W!%soj0>(9ml+@MS2 zmue{^=EL}iR%%vQ!8?+ToMtTD#FC6^e|_5Y!K&AXkFDzNLc7{8hS2ayXGNi7D!S&tieU{B1n)Gae-JU1+ni_pMO*f@C}hJT5N!O6mgMglSrhN&=BZer_D3b?9#EjKT; zULX06$vh#`C)n%4%Vt#*_XSO*t01z(I=515=D3xyNU~AqFv(t=*PK{*(LHsdW+A~~ zUi+bc9hb2%(FF@~SAJ@#wZsyexPr zwPbVoiEg#UO&YJKR!k>%ohnx4zN|Ag?3;gk1RJV^Cj`rpG)zhPYUr?&6$L6vc4GaIp z_IjjB^wav~fK!;vT+q#vGu78+WKw09eX*V)RR4ywJX>9r$Va%th*^HW$Yq(m&;55#Zq1$vF_)ipZ>ES-$8mAe+EUr)iF z?`W@BtsTSbeYqhrmGU-PS6f|7;?-4G?s5Md|AZitqv-W4=WVUv2T-@hB&Wjz+ijuN zlFz{poi`m;YNse3cl%hQy;y!v40o-2m>D{rrIP$UfSb-HhWAbQ=fxk(;x9%yU5D@M zC(r02Wy87p9S?)r^YlJ6dzEsBdQ5OHkS^K?DC!m7FDlmmA~!fFC^2xW%*dwU!*V#| z(#m2CNo`5@qczd?TPZ{w(yMfpEOOB{zH_`!4pcu<>B2vVzin4%yksO*v7+OUHY_;0 zryLXN<0R17->q|BcvG6lREBX|5Swmuq;fsSs1jjAs^asotMIbzFgS#R znO}FRzLH}+$D*>cn8$^nX>t8~#8l!fgn9Yn8a1gBM)UTEA3Z-1%PaJw_pbFVyyMX+ z)l=$vv7GzpR={)qlYTd?_XF{oyHju5mBPaUE!%q^nabXnP5vH^qpOyoc?u9$N7onK zE#8Q#zDC)WdQnI2`>VN^S~cGi;-WKqd(@%kLlj39rtQ1X=UV*3`1`B2Ud7V*rq481 zv$a#p8w*Bq+){{M)r-g8f{L0SD+SM#o$NIEpHOvFD%sZc91Rl_k&GBdj4^vrdL7nj z4dy0m7Vp{_>NYW6M6AXoC&{}kP*e2 z9`p3goy(Q`sg)wX81P`D?oG)K@!wKLxKHnNMwIxlCS0MFUG_yq49WOR912H+HVB39E~KG~zq||J^ zO;u1>-J5pxMrl)7t2JJMk<43VhY071Qq_fIQ}#I8F#3wFiR~0E;~^v3GWXV3r8o7k z43tI~oiaUfqMrx&<|WOW2#DDpDyFMDuu)kezX2YX5#i>9!;XwaeCXdR>egmOYzEYO zeF;ep&1ZsTDIH(=yA}yaE;*>?AFqDV4E-kJJa2L7a4iinLz6AQ#*#zf4LMS1{6bMN z-!5Ors&vmsh1_}N!?jL^rl4Wbuu3i*yk~4OOCmBzc(k*RE6J?fvn0mHhTFRuj&wTI zHGWGKS%sfW+*_aCA2PfnF)5F(zg+lHtN*=2&OPmKMFp*8%pd#R!MHLadq^Xv_D7P+RRI%FdzCYLuWCZvNL6zvQBM!fx`*zavME}v3P6y{-L zPq9ZC@!iB`F;R>UndaA|npbZI1CxB1gg8D_Q`!4*$0a<-7 zjmbw`Ds|~bsSE0h#}9glQ!7R?_BLjt`s}`_bxIFdbC08$a&N2b74DgRq_2JKaEsTY zu-8y#k3Mr!)-0<~Ld56^f40IBpgDH19(RF~+$^)ufkK9T-OVN#Mu-+wGBSGjG8;}? zP$LI|0kDgn;E14%{hR#(- zFK-t#U!EKByQ_6~URCybea7Y33r3${yP7QVesl&|Y*gMJNh8-~KvDwW2~}Rv%e_A05;zrnIc1+|Di--i&S6s2nLI;33USs28TNxJX`Kuyc)H zVKFPG&@D1LnrBu{8;B2699g_0th+kjI#}ZjG3LmWcE&*$iDlZv-Zk#(CC|}IjfphV zfOU-5H@jyTFMs!Zd#meMy-{{tcKKU%YCT~x<1T-{`jf85UtV??aE_+9EZpC21y;fx zu5P3y4$;RoMmjF8=^e{b)|*|uG?u^>gB=PU1;;%IF;kG6>t80Yf`%-;o zT=le+SEvh%WnArgFPT|o4M*!G&&DZqeoz zA2`7p!>S}%`vL0&udz45&m*Efj);McgO7)Y4@OSVAmH5FYA2oI_ z{|t&?$$~+V7p&VET4I;35+>Km?8LYV&#=5$aG%7$&}($}&=M0aoqsTpAf{R?3(y%f z#+MFp^gEOs`8GWl+DK-46~^Et#LAVw%gZ*zZ=hD@B97$JiznZX;!@J4yB>HSn3Z@#o$QQ>q2$3g!+NH$ZVJy=RH?n$xG+wjC)C5v zt|_AcF}|(xj)#utHnZ^Z)hnSQyOYRL$b0phj-wYYx>GG#IeJ{te;=Cnwt9r!-J$-9 zgocx8_QAX47t2X3VJ5yO<53Wl~ax8J2*D>{)^`pWM$ojJhI;hZJpNzkIfV<#zD zt;a!>&fYp|?v-prO39nOW14l5@hGP`ZC#ILJU9P|c1fLS%B9?I%I+B@;%&uTZ8aAt zr(;V#!!oo5W!n}RHPn_CidYCbEu&PD&4j{dE0V8p3d0mBHl55018eGbH!0kIIEI8- z8u1=^+r(txi#K98lbB>LXkjF84#4rq*e;efd%bBV^CXmPxGbP>H~NEo>Iwyii^^O0 z?aDFCJ^cMvM~$6fXU~rZJ}c?Tgf|nFQh39QeRNqF+{Xk+Jq<=IvoQ7|GOhD3CMQrg z;Y1DTN9mAbUb67ZZ~Dd=^+>QKlr#HNzA8Uyxyh?APPMRNYE>Iz&aVuurC)pVnFaJW z?&AJIB(D0hx3E!E#rmZ^S9e>KW#=M({w10 z`_B6H!1E> zoRiF5qTA|M!{qB=~{MaX{=C_JOOdm85yak*^!+Pp7S^6%o-Z}-oUOCwb z9pv9!zFEkWKlsE2X`-$E@%9ZVBb|fDr0KbtrjrRXPXAFo=S#^{P0O%F@Af^}IbF9?nLR}`v_&&=w$Jb2>f z(BjKMX)Hn(AJRvSfPBQeoLH;;q4M>*m*k=-!6U#6+JAqXkI6m|J3oc0Cp_I=V06*% z%gDIANRr3%Jvr@~mdqa7wio(z)w(p}TG>&2cLh&g5|iChqR`?Zs2m1ky0ZlEE7KP9 zv9wVJXYxGA|pVbr7JBZ1k-&6`vdJ_QRO- z(9%6vxno#jubNbGfAf(9a{ZN&bq5(s{U$jX<3JoQ|+P>KvHMWMc>f zXgj-7JH6Oy%@S3Fm1^824e>>`VrJ`h+r{ncEdv>Sw~uHPnZ`=GODEpMKH3>FI1H1~ z;0@Hw(O_XpP;-r9jjKpHuCX7k)kfb+tvr0#F~BOQhR!NjY2uU=&TyohKgD!I!B9Gq z(x=BRJ_QG{)wr%XZaq%pYY`B^L772Dzr3lUa8;>fs_`?^dLipc@xIT}u7w>-{Gw*L zOrR*=_ro;R=8%kdsfl6-KC9Bp{&l*3(H8aV_r>GM^}h{q_&#DCUwtG0e&u7!I1$}O zMUKIGqV2$V(_u>L!dSJb`7GNon5*tTKti8f~#Vtq+-#9)FMs zG3R2(lAayAjQ+?{Ke;lgHFI=vxpk1E1GC(@n=_f6JgZWfU;R$I&)d z)sx@UNF+4}A7F@AO?2<6iAquseaYa#p;gkHcWaq&sL69$)Xx^QsPKGW+)|>m)HI&4 zE7s(d;`nw-_(6gfbl~3Wb-Q_gC3yqM8AOrkgQ3cacWEZmLw$=L*Hd(w%+xAMYnjPs z?^HA-ajp@}t%_9^hI9|rR#Qtbo@CvcKdkGG{c$J_F046Ln#yTZid-)hVf6SB>-&A^ z%Nn@hhbF88dbfjkD#BWsGTY*Beb~9Vs6*Clv>Q`j!sX_htY~v9)sg(NoBoVzOW{IU z#$=br@eg}^)A{-EY_reL-p5#^EZ3xAy4Fn9n^CN^k;H5FZ>BDi+$@s!gd3UBNCqnC zX)h~P3h#c&7 z5?XeM|6=M`_UCSPfyFdQvye;7hS$uJE{i;Dn)6o+wqw7ym6REAnP+5lv$(9S@TJ!~ z+1i{z%Ehae$nFX+D*en$y4Zvdc9>`zc}wS9d&?!Io=s?Ey_G&%4Wo}D%UOFKKQMN4 z%lm;auf*_VsOm#|1;#IiH&q2h0&w3yqdKV)VT{mm-&oKwxo@IUqgNtw;vw!-+2y78 zQh1TyBsaywab3tHjrv5C;ypEU3hA&JY<@01+cA)ZXP08ayr$yos@U*a#VzB^n#vuQ zqAAP%fU#$kItn35Pg3;yU01em>L~3~H!W(avb=bo$)J9<{a~IbFi!H2Fi4B9HONj-PukkBo&{G!vg^8*a`Yz?s)5St`Ph5- z2$f2Yl3j!E0#S=T+s_*vGi~*4IRvhiY>mAAZsyte0xE)>GMpz;9Tf3dh^sb~W)&c( zSTA31pfkFWevtXmc$|#;WpvEcdR_62u_rxGT?ecsZE;6F1u(ZDY+^!lowz=rahBqe z8eEmEC?9ScNI*Dr=L%>>zx&wMm_wu%ZnW0%SiCLf1T*zQT?6rN!< zm9#0+;t%bBM$k;RSWMR2NX@zQy)Nb&`eqotT$yO6(iuxNr`v!)TFM`Au4I^(NRn~v z8^`s>LfhEIbF3|mDMtg-KWEKaguhdaOhDF`sTh4Le>vpOSBb;O&KPA&s-&d!QAs0F zW@=tGXizxiM{v|Q^B9J3TLFi`F47F$zDQ|w>2*`BLv(ulB#=kiLx5_-Vfvi0(9YR;v{ z+FvMzx<>`Ws2CdP>vwKBLY-+@7p{NkRpS$$XeoTRp0;XGA+WOV7lW~aOw(Iyrorim zy;eNJFbo$_=(6`9lg%Sm~6K+O5LTll;ge%yP95e4_ zAtFQ!t21)_aD#NlF>U_yos?9?uFXQmUJPY;%fsmEsifl^$|q0EB%)^1xSNjnHwCU# z-43jCnF_FZa8zDm`pi}`_T9ixGkoy_uNK*u``t_j)D zLnAqRHD+W9U8~UbT?13xwwcvMc-3kRzWnTi#Vam)8;t6D!v*ypp$}ASTut+j7<97& z-;cfueIA`TlW@T>hOm*-+=Da0^6p@1p2M?pyczBXZe+X>D^lgsz)-V4)8 zd2fWj?v_Uoto6j~&5M#znnSbr&7j9H>nl@)gxU+rYH>*!oa?GDmFf~_Bk-7Y{VNT{ zZb*4&FjCx|yw_qQ*)~%mFdU;BO0|YGAzb9y>LR}5Xeh7r9mBlogqVERLFr<`jp8Q4 zy9~GSy5b!oIqDgqTxEqq3qMqpJq+WzC$$EYmyCHfC&n(C`ysNvkExHH0=Ls6(pvg1 zp<6X_Bx3!5#y^oLdt4*tmP!WE{V!-{`Wc*3_Co(VU@>M?1HzOP8;)k1=mWv~6%$#N1%Q7~|7(Jv)1QVkBJj=^1{wQ$f7DEAmX z1tu+=gZ6JK6}RG5E|(jnm}iov^9qj}7&y>Rh3gcRK8+cm^yf~Wyp~z6SJJ(Fm9i02 zjF#EaM`R1ViTR^`S0v}>QMHJ`1eFr`&f05h&l4@p;y63Cqb}!!ixCOjCU%b^I}Ucu z7dR?x4TfVrl${RO>rlkqZ^Mo4@EYt?E5DA%A`mZ?ep~B-2xT2$RNbrZDq-%?9ddu& zC9iCR8kwl~$Y2LCu+;@bBYbg|PE~S| zTV3y5xZ=_8@{lMfF^TO-#`_mnu%J4eL@mk>^NX;Dj9f^4GAaTnUh2`z&T7;uRT`wn zioM;^7>|}paC_%sxDH2a9w~bqYiTQ9OWR2uew>X>Dv(`2CR^y41aQbHui}Ylei&FP zldT)gD>CFj8s9G7S8*l>&t9cUNGcOO*nipm{3IU(+cn+)ZKF?ruS~Xo{tEF^W9dyV@AKi^q zk`c@2AGkxQ6No+07)V_e(!3I8n9utrx9fNi> z+Iy|_eV3iKIe_igDWX~jMwE|>$Ug6yf3=BQ(ZrV zjQ7+kbPpzqv?_}FwALeQe|wAF8Pmwo^5{vjH}~HQ7p4(k1mWNf#eA82-6eScIAD%V z@+lj@o{jEk{jhoGCVp7H^CD6jRNgwx!^cPSW zJ!o$Dk!Zn@P(BUKNkw3+|C^#EcZ2mTur+#Z%$jv~Y-4P`b8|c(RUx%nD7Cj*UG^Sd zCC;*${5k1c4ul>grWh@qK*Rb@uY|bZ=Pa*5C*0x)YAJ$h9VK1Z>~8sqwpoDi0!@0$ zFV;CS=O8D`d2emAJ{$K7h+*B0qwn`~?@#Ep6zR1|wK_ktk_a(h0E|C1xX@U#;=gel zUrNtTFL(HBZBBX^iaFP7d*rQn;wUJ6jRM|9Z(%3gi}Apm&V{A~gQsFs2&ajEN|5PP z{sqtygT+|J@m_p4$G1ATIuJ?iO=c|YM2_v~vN zTLF2UpOo=7?APfY+bt*q=+zI2>-do}ytm-Eb1u(dk9@S2;n6caq3 zT=R+Vzy3zynYyW!$I%9{4YKK=q=3ULrIe_`D$6I2YWqcX4O``>Sy9lhE4^*&yq(No_i9)yL5l z1;%}JNvU>*HB4Y^ant#;i(*vZdWCkb_AP>LRhOY9i|<&>UqFj19_+?pdhRjg{`loc zdpP3Ry|7r6i&e2|#ip*EScbV(-qj#K!*UJ#geyn4L^6fK+D@=Vg1E=8nC{g<_XXYb zp=LYW`g4- zfMWXWU>%YgCiRQ zNqnEfu%W#=g4WT1jz$`qN#GKz_R!ogf3oA*HvW&W@f7X3jR;RnE`Md2)xokkl?Hx| zh)Qp8%(%ef336w$sd9)vxHXQ!G=UPwnAQ|G{S;meZRM(qzRnDRFSD^?K2>%W71KhF z{_L4~lEw8wXi~T}U)3=Q)8Y22SRVPqrx{BvI`pDnYt&!Jl#?0RKu^~4r>8jSuktM0 zF^%I>Mz4YnvjHmuH%6u5CU(aOyAt`4-%AQ{WR7Oa7nlMmxT(HZdzu3SqC958=hB^I zI-&-gId86f)J)&Pqh)NfbymmJ=`+r1fA8NKK%b1{0}ec`di{F;0m%Toj7&WO~f!5C3ZU{->_OIbVxoY23D#|{zdS11XzIAdz7K-YbrC%%k_!GTy*dxCtWmmo=`bZ*RrC6 z-mW`}5aUH{`dhZ-0NiwL3KrV#*4`dR8DS?;g&VM54p7e0^6os1uo9Vq{5%ubNxIri=7v3oP_yjeEJzVQZu@d=rx8M1bMDTR(O)GQe<_({h0a-l9h z>~e^-kC&{~47wpa7rfFppBXAU;^zW>)KMIljNz$J#H{g`E}L_#8Zu3yDR>4zcXf0&TZWU9*)1tZ#b1p=W^4_OtyGR_j+y3`n$Pwe^I*ytYOwhOEhJ67DI5 zs1bw_8hE2T-Ra11DRYP`EABtHbjhP5zA3__H}zVwna59FB%kR)8}S0;2es=k#{;pa zAS~=L>7}2!5T7u$(5Ok$rC1cuv?6sRb-YYKd5)Roy1!`MJ(xxxgSS{Q@|nyeh+@}x!$_ykx7mOvdbp%J~n6@ zWlrH(A>JvQ!>Uy{l!M1PwMBJTnztS-MNOn|razAksk#IxhgEO%DnH3o$e$;rY%yB*X7~^D!$n1Zw0iY9>6HtS{qb_8yxv7J-t1O<-1u4BcaC^Xd^!nqO|<>QZ@nTp*i1sk0c z6P@DqnSXU@#%5INL$WHb{8Hg4(I z=Ea?pEsdar8D1 z2@K>-=h^pY7!b%-D_Vff7uWr6^e~F+|45+=Y07qQ)SPo=CExgR`=TCoU*=I{)I11k z?y4NvV?{1DhJKked)e1y*pHUxEuTJu5D(?%jhpba8kb^t31zI*lV7Kw@S`EvZueBm zrZ7)e$ax#tG@8i5G+#xiVw+#f+N{{GtwR6sen_u~zyC0JZ~zcB_dmHk2sT$ze$Q3y zjN}eg;;}^e4zWdBo!-5Leh}l4LbR{uHqa zjk{v|9xg&GD198vb+})7Z0ToqAIISCDnNHOGizY#*LcaTc@{6KyDQQIOl`Np>X%|_ z4F~@P;7{)RAnl37Fxj{qZYhT?D%am70VVI$9Wd?Oiejxger>x@GY~5Sr!8;~-afNc z1LL?NtaW*wI&@eB8%;}Y+y;#Q>=D+)SmWz;er%aa$So0MWpy@=hxCGMzT6L!rSBnbomM*CC1&xg{y z%4o9NGRiJ&NeVb1l;PuMt3c$yNabBNW5ALp$yt)>{UjFj^s&JB~QqqQup z@09vmYl3w>>*8;}x7t$Fg1|5Xja^D%4j`k2)b?pbi#6-{yN0x}6Z8~)?Q3Da?-n*`Y<5mM2ReXmua25W3x1H3 zHmS`oREo*;1$25==Ma1|U`q%z1XEp1M*9u#a;>3$7u5JB9<@&(Kb58Cm`2;9xx!aN z(l7Phl#AhKJ2fUYGHCNV4%StTK)G0LAxthST)3Dcu+;cgg1AJw`Ce3wAqql(svN;n z?fYOpwN)1J3;*JC4l*S)ZEWTlfFxq2g6nw%k0hsgUwD7}^%b`+z(}CC0}CNCaItJu z?miO&Xb2(9roy$)JWeU`c`!|8Q9!z*Fg?5aRG+yyoyz}x`QR&xM5K(0bsn1!d$^7u^rDF7!`8)t57zT+Ze8#5V|~9bazT^hCPrh&zg?`p(Ur{yms!^x9sG zKP}w|pE=R;mji>*XLkC^W<~nN-eLjugK^yzN;)$y)OV4M5u0Hfh^q|KI=<_^SJgi6 z*)QE3?E7x8vC_#_Ogs`XnnFyXbdra6nk9JC@pa@se50hn<;ZqA zCUpOU+QR4SkdO!AlFH%=$*Fz-hQxEVS<%GQg<3B%;McT?OXl1YC|O_vLigeFmC z(Ny!&w!p(&%4nvlY>lKEUMv5TL}G0_Q$nb4Ej5;*;2CybmLJn8gar5Rtz|fgEQ~P; zZMn4VYFfDp036HTrhIisFfo5b5=*U+^R$GRE1+ihvai7J=aueSguUZP$I}zIm zhZ+Vjf~HMr)-nu(_8S3~e%(y<4?hXZq^r&mVVZjI;c{aZ_*yw5lpO*HXpF>)=G;9Z zoNbN0%=L2$dcrMa1rJ&0yDX}Zx6@zr%WL#LRK_fj`EK-Fku+a8@0pacPta z1*BOWGDDqp_AOg@BCt33EC)3Tfn){q6Uf$zq)|0DC53MDE-onk`tW5OI6mB$YY$~fcf^#;xWRldt1484cpF=j!XvsWCNq>ks z5yb5l%(;7e zV7|Ot%p-L{7oFjlF%4i?gvZdatg}l+z`*OybJXkRV8hArtiCXz1Ki<2*{&(Js#of7 zbaQTghA7jJ2#7ieBSq$qbmkv1<1lK&2?OmKsr1!K#b>yGNP#+K%3v(hHYUiKSc4)m zh!$ud4rI__ZY23U>?SYYp8OJI4+tyX#WV0u*EC$}$zs&_SQpzMSQU3*e;KPOVblG> zc+mN!s%YchSyODAdoJ+3v9G|HuJJN=MP??Er)v>LeV6#g=qw^VSO`u;6Ihq>mi2UE zkQB*4HZB37#xn#>L#Sk$D+aZQ|TF-{&Yc$Tc#S)WJc?*va27av7~!UY=+IBqQQxFb#0^w>{DQq>KzRThNj2RkUrVsT5ZTC~42-zTh37(K$uirPHP;|}o zq)LvK#H1fTm&&s2Vwm%XP9dpDZnB}rN6E&&a=P*Be+069m7{11&tLcnHa8!Zb8T9C zQRGa+CVgP~$cbruyK>IbBG0n5zb?toOP@io!13_TS~b~_D-H9+E0vxN-gbbFr+N}# z&K@v;f|m~T!_W~@u$ViHB&DsIx1=D-L7S~jo}Osq^=PZks1_S2;Of0^q42=$gI6jS zvaDemS-o^J*ujI?ojr4v3!+r*xSSO2Ktp_%Yv(^BvbJWn@?A~h39Rk(`LW_M`${zu ziKpOg3r0#i&Ko&qiU9v~c|8@LP4XqL$wH$o31{+L&h;t;rF?cY6w~QfnYEBB9Oci&E?=j9RP$_3a=KJyNGNO8HDkR zA0ySN_dq;CF%GPa>PNIp3Jg}&@OLUkW02X%-_nGeAv}+M)za1aT%*uMhcQ1*crJK@O<~7^}d$DzTq6QMc+(K30qMi{}uc_ZY%xaFq z6mJdYYCro(j5y>svoPsDfp{B?9){rLq%>jO3!ta+tyNq|Toj6|UjrK25Ryfv(g-GZ zR!010pT|f%*sny(0D-Z9-|#1|QETdp{qwv-;wkFXOx7=3+P(>DskY$vm8Y;v4{y{Z z_3;V-Y-T@^RdHjYwSw@R>3T<9%8pg5h&dxuQ;FTsZ>^l0B#Er2iD)d8R|uW?(aFnJ z2p5%%(~-9K%SPhQcZYCBx|Ox61Z+7N2DuEYb6~(5`SZT;zB&aVeB-Ij--wx`QI(=PqBAy+%CC;yp&bNZmi3%!h~OG+%Q=Oqn_zku(z;lfT+ z_gx8<&rcWHeMk~6de6U3#f)CAzu*)rh4UVt#&6Wt2X{`6d`bAB?P9VO|Atrh8}1zW z=&vj1$wpx9P1^JGfyVRmI99md7rUIN%dVF{p;y~*Qg4&@HjWveru-!?j9$+?|LKAM zr#ktHb^gEC|G^c210?-_Z=?Em7xIrx5&)zRc^yaoqhWZx!Fl)ZzW^1RUPk~NYxnDj zLjR84{BYb5HL!`I43j;zWHfMAm~{;h9MOl^Iw$*|q$R@OsK(%3O@TNNfv&qL|340@ds zfFOiv8C8Q$Br^!2-y=N_mG1o%YnL(3_U{>x4k_Dq)D?uY_S(aZ0QgLg7fKIZmHZ#6 z4?4JaiPZ}s*eK8tl!k7}kZDDThpfQ=pPd1V{!RFQum9~UK>3;nVFA6e62K$C!NViK z|IZ6vNsOquv8i4&AzYFW_oRGv^V*(7*#7{f{(&U1Ukf`#bBF667oP99_3k(PQ86-U zzdg&Z%}+$hpwsE(a1qo1;67X`8j$YesN>NQjcPWn;Sj#zZZOS7J7eRD+Hs-Kpr35y$(eF# z(IA8j5M9LqlVheis%$+WT?0_^buTzRC82ma5R8vBXRyR?rBHn*i!Vw}Q}Vq@aJRr~ zEZFh{e7;J7&-qZ8oF%DQVb=A~rUEqQAR!tT(yAs71E$hT(w1b;n&S+}@bE-1I5d)| z{7H_cq=!%X#0FSO{WhX-Jrq|RT7&9M5sen2Aeni>R{bu455AFi*~Hb)sMGPDU*_lt zd^pz`FF-1~L9r-UsJ)XoEUzGeryre+(`{)$x|xPxc@Qn5@D>d%S4JHn#t0p5T_apX zVf~bbj%0NQ&>c-m$5q>~as|XLv=68l;D?#o@48;A$f_^=eF=ViK`7!qUZgDc8cD<1Y7n+0~GnbcG|n{lWmD zzou7YK!K}1@8FkPU0XSuZIN?Km-syF-DEP`{koErP2Vv$(*(@ zV)Rpf(V&RlfSc0UL$BwpXh~}31pMuwb7UmdO^5Vh)MlS(gb-PF3iw}m?{Miq56zuY z=6gPKxN7?S1@LVB%jUgW@jrgA|IGM*W%IEArSrHT`Bb$%k~2G3=7~xF3-9-8#vP`o zH<71LS`zt4TSws5%Twq{a76(N@ss5&oY+;-hYI6h)$+v_;IFdcMYU=R2gMKNvRlDs zuV?Nr?(lGGrO)m?&;QCWR2w3;zgVzTzOp>NJQ76wQ4*9*)d*r8XQfPL^6}qWwvhbY z*H2K+Wk()Ld({sTVYuZH73c1JqdS#A*{(}g_xcf4z47@epM7!^IR$)2Djy=zPR#xS z%7Y`&5B8;jpz)%@Hp_Ny))+74I-%hnb^XM#_-z@yCRRQrW6#U749oiQ(IqjQjZvsw zEWL}ho=2|>j5JvFnfL8mu7ZB=K710T6D}ecj3@MydvshSN61Md*hfgGdzm=w%%*YX5qUzgK_U_9>lvKCHFT|M z)h9u(4SlZSg3&dkXnC%N-PIj*Bc3X8VTmt8<6nqgaNoN#PNdHc`Rs(!#BFV?l6ql{ z%f&nOv8IJ2o`djA`^6Z=z!-}Q?UONro%*zN;)@M8Li0#vjjQRNDE-(9)BKSn5A z5%0cyX($HAkM_680qNxX^SwFs>X^;15up!;^PRtWHfkks*o^|mLe3a^ICg+{btA7w zEPNTl6EqXEH!B4WaWk6Xa(MH=+7?Wk@$ZMhdh+9nkZdUUARx0@#Zo$JTi^Nf$GS`( zBg#%u1NVK=vG-Ozb7WKO=6lPne&Gqu5=@G!i$KjG{ zTTj$#lD+gx;ST%etJMZW?a8oTT1<;#P74JzxxEj8pHL6GH;?RRIyI(%aE72Oz$syc zgr=e07Kv0&xE|jpZ##8W*M+(`+-7u6J=>PZjQKK7Qe{bNgOaYzqG((f_aN_KdhoTS z<_&elvhZNP!3(6(F15kccEr5t~(oqX!0F3;*kOcnE&^N`2n&4{NletHJKdSL?oF6NEit~I1frt7W( z6T6SRvM!3eZGT3Uy)TD;or-U^i~D(3NiC}VOvQ5gh3$R&=hjRPZsB*}?|?u1z*dRp zDb{EtWxJ0U*qGlN-wwt`QXexH>qM#l(GY+lVl$qfsACBS^eF0;?Nz5^ zUWkTREC^JW>7`d9Qd@f3(rI?NYR~l6xF{LHt4qu1W~*qxs|wbWad_4v)zRgi^T$xkSsrn0>(i+cPZR>e zqDBycIjr&rzeo=W>$w)O%?wTHL*euyV!WlrMb~64V}TVKaHj_ra4Qu+hDP`{MsY6x z2+t}flFB%(FMtbbiH7g@P8Ipc+#I;|+g#u++w>QHbzDTP5AMDvJ|iSq@%Z~ zL?)JtS(S_l6KT<8`Fw|tU`%beJ;?BisqD zuIyloOv5Roy19j3^VH>-XP6_H(Rj?haW;} zVe-;3-gCk=?J}u%4HF%ixiR{i>ps#rHG<{=Zlq4QQwQyMmeT`e}OLwuF@0=$lC5jbQVHFfRz^_9q(p!xz+SV?!c(^_j5lI?ioSxFVn^hk%QxakqEDhL`c}BLdk{`tWX*RxZdWWlu48^ zbs9~Cv=&z)GFs42P9IWL1tgxR;dL3Xv$@EGbhpj8iz4#ZVTaM-95Jb%)AT>y%t5VG z(y%2lM>!toPQ2Wp`b;e%_G-VvT}8X2DvD>tF+{^ts_|fGW`;w|a4TQSTtv5oL<0v{ zwrvTGPKl0~_+eZOx;q5>YzF*Asv>;p-UBQH?-!{|!fcJm9nTN=8tC!`2WqwbtJ$wq z+#0!+8WAUyvxpP>fdcNoEv`gX;)qePeX1Si-JW;wQ+u6>EPZ06z|l;6l^)@@L+u>; zMT22^6n(V*?=t<6&3Bx=$G=)J9mfs1H+(+oaolYLsG?(ksK_^Pqlk>4kIY2h){>UY zbQnV?@oTQd=zv~XX>OZIiBMyD^}pVjcIw(&`1ovEvT%CF9JZq0k(W8v{`rR*0ggagGM)0-`qnr(6Un z`W#;IKoxRp?g8gfskA&}D8tZeHlDBmP^TlzxYt@;R$1y}6vgKh)aon^aF>NqwR|@w zML<>_&z)Vm5UH#Kfrz~;0Te~VGj(@m{2c$9Ur9(Xk}FR-8q2>bAHWs4@F|l4EK%O^~QcG+?#GZ zh>|Og<#QxCsWq=c_!UTwge*875A=eua1!?BZ@Fhs29c7nGR zfsNP5IAamshsmCJYv(ckaC(21VQse?1Fl!?{o9dYPG^bf?%}dh0U)CH3@Mj#^w{Dq zvUzn*A(6)Jb7X^!)SjGo-Dn_&jG}o>EZNq6Pkt7c*cTq-2XSJ^b1M&F zw!EH8r_E-hWpBkfh%yI^153{(!<| zzoa3Nq7RR$hlhKEA?NbEyS?#hKD^9zk|B;;Qr%!KXuQOFxf#&5V>^Tp&y72%%C4hg z9oX_%kRSqRHBiapwsYv+Db@k&lVUvYLVKz?)*oRt5g8 zHGI0(Pt7EjBz%!ZQE?uAOy&x*ENSwZ#9Y^`Y`0M0Yu{Qa6wtW$#`}kzGbs(IAJYtL z8;n$WNj+Gjy7m5DIo7|&6e zKaK?rDH1rzHnl5sY2Dw4f-LKS9((!631bN~Fmx&BUC$)CXGQ3NM4^2P9lKNbkPRe8 zAxnyJTyHB-TWlZgbCnr|E1v><5&y+5X*pbg5uModrl_Tgc6=j->@c~J1%y5&<^43X zIGDZ2nQ*Yy`5Mu3q5`r0v&)Y!5Gn}ny(BEKit`!w8ls7=h8pr5f^M2bM_CBLX}p2Y z+llea9@Opb#iUPTn`uJ$BfJ-T!00@?5RxzC91Yr{RT;4X_etVk>TQ1q)p({vzI z;Fwa60QaN8Wy+z>x>?&JE4WQy^eYRj^JA(hWRJ<^sK3MPuHIqP0SJ}dniF!gg*J=@@LqwCYtsD*(h#w$g-b)5}aHU@||z`CGYK@ zkXcs&YVu=zOlIvj+fL#+(7%A-!p~A|@Q*U%-pn!CiS4=cJ@4lc5RJ1Hm*=8(wTqz` z?A9ZFp$h3WDgc7-XhaefRxXG}A#FWCY#FXr4EtRtICIOIwoA@e)*x=hY7ep!_9k(` zWf3c9A&TqI%2#vIFefTuR`aiEt44)bS^EYO@r{x z30Q=0eo%|QHlNT$WWjU}J-P@gISLAQv_n7kM|m5X5FbB_cCW;83h6y`gb>kp(nss4 zda3J7cZ1%RU*|bKPZc7~TU9Yk`A;7QCKBFcN;lnN<=H3S%-;S&CN7(`k-C$@rF!OL&4$ z&pQZR#$}|$F5_8cpn{Rm>y}UpDFq^-tA2k)I^{Fk6RE8m02Y=2hLbvJvNWy zwrGX?tS6_aeLF@ruh`r!9x!*1hhe(H{hBr&Z2gwq5> zBF&hw1$*beFUs=z=ATfNQ7Mc`!Jb=BepCowp?th_dPWnh`rF%cuqezl?6UFwy@&?d z`?B90bsdevlD|K>AvS(>{0nfE1FYWt<_Sh``LSlScv1J73Ra0}`qTRtV7e_U8z# z4qP6ZCKxE4YXIbzMY;j#1*G2&+PXa7(>lU*7?U1Fq41KD*W%BAXxDz2QC~fTw_txM zQv4{Wr+WSf=~FH+N#l(C3m^g&_DWqlAxL-pqcR9iSI5Qq<8t&*P|Y`|Z|j*@;_GY|5ve0h{p?dcPwulTbE41a>u}hq&tXtzsV!dr z3pl)V( Date: Wed, 6 May 2020 04:03:27 +0200 Subject: [PATCH 03/34] Replaced "Nuvem" by "Nuvemshop" --- src/apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps.json b/src/apps.json index a1366db2f..828ec9a12 100644 --- a/src/apps.json +++ b/src/apps.json @@ -7467,7 +7467,7 @@ "icon": "zeit.svg", "website": "https://zeit.co/now" }, - "Nuvem": { + "Nuvemshop": { "cats": [ 6 ], From 559445ea7e0ef0707e3b32e5031fd988124f4a0c Mon Sep 17 00:00:00 2001 From: mdillar_criteo Date: Wed, 6 May 2020 04:13:42 +0200 Subject: [PATCH 04/34] Added html regex for Nuvemshop --- src/apps.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/apps.json b/src/apps.json index 828ec9a12..252b80518 100644 --- a/src/apps.json +++ b/src/apps.json @@ -7472,6 +7472,7 @@ 6 ], "script": "(N|n)uvem", + "html": " Date: Wed, 6 May 2020 17:07:01 +0700 Subject: [PATCH 05/34] feat: Add Jitsi --- src/apps.json | 8 ++++++++ src/icons/Jitsi.png | Bin 0 -> 5599 bytes 2 files changed, 8 insertions(+) create mode 100644 src/icons/Jitsi.png diff --git a/src/apps.json b/src/apps.json index 41f87971e..10795b483 100644 --- a/src/apps.json +++ b/src/apps.json @@ -5394,6 +5394,14 @@ "icon": "JET Enterprise.svg", "website": "http://www.jetecommerce.com.br/" }, + "Jitsi": { + "cats": [ + 52 + ], + "script": "lib-jitsi-meet.*\\.js", + "icon": "Jitsi.png", + "website": "https://jitsi.org" + }, "JS Charts": { "cats": [ 25 diff --git a/src/icons/Jitsi.png b/src/icons/Jitsi.png new file mode 100644 index 0000000000000000000000000000000000000000..cc5358aead4896e2e68a9324037e7c193795e369 GIT binary patch literal 5599 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 eSC(q Date: Wed, 6 May 2020 12:23:22 +0200 Subject: [PATCH 06/34] Added Heroku --- src/apps.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/apps.json b/src/apps.json index 41f87971e..7275b49ec 100644 --- a/src/apps.json +++ b/src/apps.json @@ -4814,6 +4814,19 @@ "script": "hellobar\\.js", "website": "http://hellobar.com" }, + "Heroku": { + "cats": [ + 62 + ], + "headers": { + "Via": "/[\d.-]+ vegur$" + }, + "implies": [ + "Amazon Web Services" + ], + "icon": "heroku.svg", + "website": "https://www.heroku.com/" + }, "Hexo": { "cats": [ 57 From ff5cd3d8d0d5c0c1f2d168b80fba49cdc27ed2ad Mon Sep 17 00:00:00 2001 From: Alexander Matzen Date: Wed, 6 May 2020 12:25:16 +0200 Subject: [PATCH 07/34] Added Heroku icon --- src/icons/heroku.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/icons/heroku.svg diff --git a/src/icons/heroku.svg b/src/icons/heroku.svg new file mode 100644 index 000000000..8d02649e6 --- /dev/null +++ b/src/icons/heroku.svg @@ -0,0 +1 @@ + \ No newline at end of file From ceeab409d601d5a210b0131a298cd28067123474 Mon Sep 17 00:00:00 2001 From: Vladislav Studenichnik Date: Thu, 7 May 2020 15:28:42 +0300 Subject: [PATCH 08/34] Update Swell logo --- src/icons/Swell.svg | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/icons/Swell.svg b/src/icons/Swell.svg index ae3cfb497..4b04290a9 100644 --- a/src/icons/Swell.svg +++ b/src/icons/Swell.svg @@ -1,14 +1,19 @@ - - - - + + + + + + + + From 8e6cb23b07d8db8a9d37beba2f9f5a71908ca8a1 Mon Sep 17 00:00:00 2001 From: Tobias Lins Date: Wed, 13 May 2020 12:15:38 +0200 Subject: [PATCH 09/34] Add splitbee analytics --- src/apps.json | 8 ++++++++ src/drivers/npm/npm-shrinkwrap.json | 2 +- src/icons/splitbee.svg | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/icons/splitbee.svg diff --git a/src/apps.json b/src/apps.json index 41f87971e..f98aef08a 100644 --- a/src/apps.json +++ b/src/apps.json @@ -9473,6 +9473,14 @@ }, "website": "http://www.spip.net" }, + "Splitbee": { + "cats": [ + 10 + ], + "icon": "splitbee.svg", + "script": "^https:\\/\\/cdn\\.splitbee\\.io\\/sb\\.js", + "website": "https://splitbee.io" + }, "SQL Buddy": { "cats": [ 3 diff --git a/src/drivers/npm/npm-shrinkwrap.json b/src/drivers/npm/npm-shrinkwrap.json index b7d31ac7c..1dd512a23 100644 --- a/src/drivers/npm/npm-shrinkwrap.json +++ b/src/drivers/npm/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "wappalyzer", - "version": "5.9.33", + "version": "5.9.34", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/icons/splitbee.svg b/src/icons/splitbee.svg new file mode 100644 index 000000000..eb8f78916 --- /dev/null +++ b/src/icons/splitbee.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + From b9355b169e185736ffacb2984af9105ec7ca3dfa Mon Sep 17 00:00:00 2001 From: Ian Trent Date: Sat, 16 May 2020 21:46:51 -0400 Subject: [PATCH 10/34] Add Tailwind CSS identifier --- src/apps.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/apps.json b/src/apps.json index 41f87971e..3eb07ee4d 100644 --- a/src/apps.json +++ b/src/apps.json @@ -10747,7 +10747,10 @@ "cats": [ 66 ], - "html": "]+?href=\"[^\"]+tailwindcss(?:\\.min)?\\.css", + "html": [ + "]+?href=\"[^\"]+tailwindcss(?:\\.min)?\\.css", + "[^>]*class=\"[^\"]*(?:sm:|md:|lg:|xl:)" + ], "icon": "tailwindcss.svg", "website": "https://tailwindcss.com/" }, From 1dc00388a2797196db92b94091e2421d599fe60a Mon Sep 17 00:00:00 2001 From: kingthorin Date: Thu, 21 May 2020 08:28:21 -0400 Subject: [PATCH 11/34] Add GitHub Action to validate apps.json against schema.json Signed-off-by: kingthorin --- .github/workflows/schema-check.yml | 32 +++++++ schema.json | 135 +++++++++++++++++++---------- 2 files changed, 123 insertions(+), 44 deletions(-) create mode 100644 .github/workflows/schema-check.yml diff --git a/.github/workflows/schema-check.yml b/.github/workflows/schema-check.yml new file mode 100644 index 000000000..ec10d3079 --- /dev/null +++ b/.github/workflows/schema-check.yml @@ -0,0 +1,32 @@ +name: JSON Schema Check + +on: + pull_request: + branches: + - master + paths: + - 'src/apps.json' + +jobs: + schema-check: + runs-on: ubuntu-latest + env: + CI: true + steps: + - name: Setup Action + uses: actions/checkout@v2 + - name: Setup Node + uses: actions/setup-node@v1 + with: + node-version: 13.x + - name: Install dependencies + run: npm install -g ajv-cli + - name: Run schema check + run: | + ajv validate -s schema.json -d src/apps.json +# - name: Upload list of broken links +# if: failure() && github.event_name == 'pull_request' +# uses: actions/upload-artifact@v1 +# with: +# name: broken-links +# path: brokenlinks.txt \ No newline at end of file diff --git a/schema.json b/schema.json index 45b52ac12..6ba762af5 100644 --- a/schema.json +++ b/schema.json @@ -2,18 +2,18 @@ "title": "Wappalyzer Schema", "type": "object", "additionalProperties": false, + "required": ["categories","apps"], "properties": { "$schema": { "type": "string" }, "categories": { "type": "object", - "required": true, + "minProperties": 64, "additionalProperties": false, "patternProperties": { "^[0-9]+$": { "type": "object", - "required": true, "properties": { "priority": { "type": "number" @@ -27,89 +27,136 @@ }, "apps": { "type": "object", - "required": true, "additionalProperties": { "additionalProperties": false, + "required": ["cats","website"], "properties": { "cats": { "type": "array", "items": { "type": "number" }, - "required": true + "minItems": 1 }, "cpe": { - "type": "string" + "type": "string", + "pattern": "^(?!\\s*$).+" }, "cookies": { "type": "object", - "additionalProperties": { - "type": "string" + "additionalProperties": false, + "patternProperties": { + "^.+$": { + }, + "additionalProperties": { + "type": "string" + } } }, "js": { "type": "object", - "additionalProperties": { - "type": "string" + "additionalProperties": false, + "patternProperties": { + "^.+$": { + }, + "additionalProperties": { + "type": "string" + } } }, "headers": { "type": "object", - "additionalProperties": { - "type": "string" + "additionalProperties": false, + "patternProperties": { + "^.+$": { + }, + "additionalProperties": { + "type": "string" + } } }, "html": { - "type": [ - "string", - "array" - ], - "items": { - "type": "string" - } + "oneOf": [ + { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?!\\s*$).+" + } + }, + { + "type": "string", + "pattern": "^(?!\\s*$).+" + } + ] }, "excludes": { - "type": [ - "string", - "array" - ], - "items": { - "type": "string" - } + "oneOf": [ + { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?!\\s*$).+" + } + }, + { + "type": "string", + "pattern": "^(?!\\s*$).+" + } + ] }, "implies": { - "type": [ - "string", - "array" - ], - "items": { - "type": "string" - } + "oneOf": [ + { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?!\\s*$).+" + } + }, + { + "type": "string", + "pattern": "^(?!\\s*$).+" + } + ] }, "meta": { "type": "object", - "additionalProperties": { - "type": "string" + "additionalProperties": false, + "patternProperties": { + "^.+$": { + }, + "additionalProperties": { + "type": "string" + } } }, "script": { - "type": [ - "string", - "array" - ], - "items": { - "type": "string" - } + "oneOf": [ + { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?!\\s*$).+" + } + }, + { + "type": "string", + "pattern": "^(?!\\s*$).+" + } + ] }, "url": { - "type": "string" + "type": "string", + "pattern": "^(?!\\s*$).+" }, "website": { "type": "string", - "required": true + "pattern": "^(?!\\s*$).+" }, "icon": { - "type": "string" + "type": "string", + "pattern": "^(?!\\s*$).+" } } } From 46865aa22ee9826aa877192281aca4dd68a7bedf Mon Sep 17 00:00:00 2001 From: kingthorin Date: Thu, 21 May 2020 08:32:50 -0400 Subject: [PATCH 12/34] Test --- src/apps.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/apps.json b/src/apps.json index 41f87971e..7d3f0472e 100644 --- a/src/apps.json +++ b/src/apps.json @@ -11961,6 +11961,9 @@ "cookie_name": "NivCMSPro" }, "icon": "nivsoft.png", + "js": { + "": "" + }, "headers": { "X-Powered-By": "NivCMS" }, From b6a003c97776ec141328ff19f46a154fcd32bfa8 Mon Sep 17 00:00:00 2001 From: kingthorin Date: Thu, 21 May 2020 08:35:23 -0400 Subject: [PATCH 13/34] Remove spurious property "env" on ClickFUnnels entry Signed-off-by: kingthorin --- src/apps.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/apps.json b/src/apps.json index 7d3f0472e..f1e05f66e 100644 --- a/src/apps.json +++ b/src/apps.json @@ -1608,7 +1608,6 @@ 32 ], "html": " Date: Thu, 21 May 2020 08:36:53 -0400 Subject: [PATCH 14/34] Cleanup action Signed-off-by: kingthorin --- .github/workflows/schema-check.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/schema-check.yml b/.github/workflows/schema-check.yml index ec10d3079..19da87a7c 100644 --- a/.github/workflows/schema-check.yml +++ b/.github/workflows/schema-check.yml @@ -24,9 +24,3 @@ jobs: - name: Run schema check run: | ajv validate -s schema.json -d src/apps.json -# - name: Upload list of broken links -# if: failure() && github.event_name == 'pull_request' -# uses: actions/upload-artifact@v1 -# with: -# name: broken-links -# path: brokenlinks.txt \ No newline at end of file From d7b83352427817ba1dd512b5acc6046966893756 Mon Sep 17 00:00:00 2001 From: kingthorin Date: Thu, 21 May 2020 08:39:10 -0400 Subject: [PATCH 15/34] Tabs not spaces in schema.json Signed-off-by: kingthorin --- schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema.json b/schema.json index 6ba762af5..428284fa1 100644 --- a/schema.json +++ b/schema.json @@ -9,7 +9,7 @@ }, "categories": { "type": "object", - "minProperties": 64, + "minProperties": 64, "additionalProperties": false, "patternProperties": { "^[0-9]+$": { From 3de0f31a9073fb908c62aa4419e888d4eb814075 Mon Sep 17 00:00:00 2001 From: kingthorin Date: Thu, 21 May 2020 09:04:09 -0400 Subject: [PATCH 16/34] Collect all errors & display additional context Signed-off-by: kingthorin --- .github/workflows/schema-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/schema-check.yml b/.github/workflows/schema-check.yml index 19da87a7c..5f2a0088d 100644 --- a/.github/workflows/schema-check.yml +++ b/.github/workflows/schema-check.yml @@ -23,4 +23,4 @@ jobs: run: npm install -g ajv-cli - name: Run schema check run: | - ajv validate -s schema.json -d src/apps.json + ajv validate -s schema.json -d src/apps.json --all-errors --error-data-path=property From f53d4520416bcd2caaab318741c7fe6739b1a3ed Mon Sep 17 00:00:00 2001 From: exploide Date: Thu, 21 May 2020 18:17:18 +0200 Subject: [PATCH 17/34] detect otrs version by X-Powered-By header --- src/apps.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/apps.json b/src/apps.json index 41f87971e..b010398a1 100644 --- a/src/apps.json +++ b/src/apps.json @@ -13468,6 +13468,9 @@ "cats": [ 13 ], + "headers": { + "X-Powered-By": "OTRS ([\\d.]+)\\;version:\\1" + }, "html": "\\;version:\\1" ], "icon": "NextGEN Gallery.png", - "implies": [ - "WordPress" - ], + "implies": "WordPress", "script": "/nextgen-gallery/js/", "website": "https://www.imagely.com/wordpress-gallery-plugin" }, @@ -8303,9 +8283,7 @@ }, "html": "<[^>]+(?:class|id)=\"phabricator-", "icon": "Phabricator.png", - "implies": [ - "PHP" - ], + "implies": "PHP", "script": "/phabricator/[a-f0-9]{8}/rsrc/js/phui/[a-z-]+\\.js$", "website": "http://phacility.com" }, @@ -8328,9 +8306,7 @@ "<[^>]+id=\"phenomic(?:root)?\"" ], "icon": "Phenomic.svg", - "implies": [ - "React" - ], + "implies": "React", "script": "/phenomic\\.browser\\.[a-f0-9]+\\.js", "website": "https://phenomic.io/" }, @@ -9417,9 +9393,7 @@ 9 ], "icon": "SlickStack.png", - "implies": [ - "WordPress" - ], + "implies": "WordPress", "headers": { "x-powered-by": "SlickStack" }, @@ -9698,9 +9672,7 @@ "headers": { "x-powered-by": "^Seravo" }, - "implies": [ - "WordPress" - ], + "implies": "WordPress", "icon": "seravo.svg", "website": "https://seravo.com" }, @@ -10863,9 +10835,7 @@ "cookies": { "TNEW": "" }, - "implies": [ - "Tessitura" - ], + "implies": "Tessitura", "icon": "tessitura.svg", "website": "https://www.tessituranetwork.com" }, @@ -12097,9 +12067,7 @@ "X-Wix-Server-Artifact-Id": "" }, "icon": "Wix.png", - "implies": [ - "React" - ], + "implies": "React", "js": { "wixBiSession": "" }, @@ -12201,9 +12169,7 @@ "headers": { "x-powered-by": "^WordPress\\.com VIP" }, - "implies": [ - "WordPress" - ], + "implies": "WordPress", "icon": "wpvip.svg", "website": "https://wpvip.com" }, @@ -12372,9 +12338,7 @@ "X-Powered-By": "XeoraCube" }, "html": "", - "implies": [ - "Microsoft ASP.NET" - ], + "implies": "Microsoft ASP.NET", "icon": "xeora.png", "script": "/_bi_sps_v.+\\.js", "website": "http://www.xeora.org" @@ -12525,9 +12489,7 @@ "Server": "Yaws(?: ([\\d.]+))?\\;version:\\1" }, "icon": "Yaws.png", - "implies": [ - "Erlang" - ], + "implies": "Erlang", "website": "http://yaws.hyber.org" }, "Yieldlab": { @@ -12551,9 +12513,7 @@ "]+sc-component-id: sc-" ], "icon": "styled-components.png", - "implies": [ - "React" - ], + "implies": "React", "js": { "styled": "" }, From cb0c26195fbe27a472f3d2f7bc450e97dc86c0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as=20Lundgren?= Date: Sun, 24 May 2020 17:21:05 +0200 Subject: [PATCH 24/34] Add Laravel Livewire detection --- src/apps.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/apps.json b/src/apps.json index f1e05f66e..6173b8ee1 100644 --- a/src/apps.json +++ b/src/apps.json @@ -6244,6 +6244,19 @@ "script": "/js/al/common\\.js\\?[0-9_]+", "website": "http://liveinternet.ru/rating/" }, + "Livewire": { + "cats": [ + 18, 19 + ], + "html": "<[^>]+wire:[^<]+", + "icon": "Livewire.png", + "implies": "Laravel", + "js": { + "livewire": "" + }, + "script": "livewire(?:\\.min)?\\.js", + "website": "https://laravel-livewire.com" + }, "LocalFocus": { "cats": [ 61 From a0e7eda41ee6d9212f2738a654350a10d04cf28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as=20Lundgren?= Date: Sun, 24 May 2020 17:21:15 +0200 Subject: [PATCH 25/34] Add Livewire icon --- src/icons/Livewire.png | Bin 0 -> 3176 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/icons/Livewire.png diff --git a/src/icons/Livewire.png b/src/icons/Livewire.png new file mode 100644 index 0000000000000000000000000000000000000000..bd206ef05c80148f6ac6f3a2e51092d86844fe4c GIT binary patch literal 3176 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 O0000 Date: Tue, 26 May 2020 14:42:52 +1000 Subject: [PATCH 26/34] Add puppeteer driver --- .editorconfig | 12 +- .eslintrc.js | 24 +- .prettierrc | 5 + npm-shrinkwrap.json | 1781 ---------------------- package.json | 16 +- src/apps.json | 3 +- src/drivers/npm/browsers/puppeteer.js | 229 +-- src/drivers/puppeteer/.gitignore | 3 + src/drivers/puppeteer/Dockerfile | 34 + src/drivers/puppeteer/README.md | 96 ++ src/drivers/puppeteer/browser.js | 20 + src/drivers/puppeteer/cli.js | 109 ++ src/drivers/puppeteer/driver.js | 540 +++++++ src/drivers/puppeteer/index.js | 12 + src/drivers/puppeteer/package.json | 30 + src/drivers/puppeteer/yarn.lock | 296 ++++ yarn.lock | 1991 +++++++++++++++++++++++++ 17 files changed, 3303 insertions(+), 1898 deletions(-) create mode 100644 .prettierrc delete mode 100644 npm-shrinkwrap.json create mode 100644 src/drivers/puppeteer/.gitignore create mode 100644 src/drivers/puppeteer/Dockerfile create mode 100644 src/drivers/puppeteer/README.md create mode 100644 src/drivers/puppeteer/browser.js create mode 100755 src/drivers/puppeteer/cli.js create mode 100644 src/drivers/puppeteer/driver.js create mode 100755 src/drivers/puppeteer/index.js create mode 100644 src/drivers/puppeteer/package.json create mode 100644 src/drivers/puppeteer/yarn.lock create mode 100644 yarn.lock diff --git a/.editorconfig b/.editorconfig index 0f1786729..5d1263484 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,13 @@ +# editorconfig.org root = true [*] -charset = utf-8 -end_of_line = lf -indent_size = 2 indent_style = space -insert_final_newline = true +indent_size = 2 +end_of_line = lf +charset = utf-8 trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.eslintrc.js b/.eslintrc.js index d262d9909..8ff448efd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,20 @@ module.exports = { - "extends": "airbnb-base", - "rules": { - "no-param-reassign": 0 - } -}; + root: true, + env: { + browser: true, + node: true + }, + parserOptions: { + parser: 'babel-eslint' + }, + extends: [ + '@nuxtjs', + 'prettier', + 'prettier/vue', + 'plugin:prettier/recommended', + 'plugin:nuxt/recommended' + ], + plugins: [ + 'prettier' + ], +} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..59639c50d --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": false, + "arrowParens": "always", + "singleQuote": true +} diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json deleted file mode 100644 index 221001f31..000000000 --- a/npm-shrinkwrap.json +++ /dev/null @@ -1,1781 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "acorn": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", - "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, - "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "chai": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", - "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", - "dev": true, - "requires": { - "assertion-error": "^1.0.1", - "check-error": "^1.0.1", - "deep-eql": "^3.0.0", - "get-func-name": "^2.0.0", - "pathval": "^1.0.0", - "type-detect": "^4.0.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "dev": true, - "requires": { - "color-name": "1.1.1" - } - }, - "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", - "dev": true - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, - "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, - "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" - } - }, - "eslint-config-airbnb-base": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.0.0.tgz", - "integrity": "sha512-hUFXRlE6AY84z0qYh4wKdtSF4EqDnyT8sxrvTpcXCV4ENSLF8li5yNA1yDM26iinH8Ierbpc4lv8Rp62uX6VSQ==", - "dev": true, - "requires": { - "eslint-restricted-globals": "^0.1.1", - "object.assign": "^4.1.0", - "object.entries": "^1.0.4" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "eslint-module-utils": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", - "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", - "dev": true, - "requires": { - "debug": "^2.6.8", - "pkg-dir": "^1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.13.0.tgz", - "integrity": "sha512-t6hGKQDMIt9N8R7vLepsYXgDfeuhp6ZJSgtrLEDxonpSubyxUZHjhm6LsAaZX8q6GYVxkbT3kTsV9G5mBCFR6A==", - "dev": true, - "requires": { - "contains-path": "^0.1.0", - "debug": "^2.6.8", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.2.0", - "has": "^1.0.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", - "read-pkg-up": "^2.0.0", - "resolve": "^1.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - } - } - }, - "eslint-restricted-globals": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", - "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", - "dev": true - }, - "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "file-type": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-7.4.0.tgz", - "integrity": "sha1-KnyU9ioAMBULt9m2xwz6HT51nIY=" - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", - "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true - }, - "html-comment-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", - "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=" - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-svg": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", - "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", - "requires": { - "html-comment-regex": "^1.1.0" - } - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.entries": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.0.4.tgz", - "integrity": "sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.6.1", - "function-bind": "^1.1.0", - "has": "^1.0.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "read-chunk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz", - "integrity": "sha1-agTAkoAF7Z1C4aasVgDhnLx/9lU=", - "requires": { - "pify": "^3.0.0", - "safe-buffer": "^5.1.1" - } - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", - "dev": true - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", - "dev": true, - "requires": { - "path-parse": "^1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "*" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, - "spdx-correct": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } -} diff --git a/package.json b/package.json index e7bee5930..d9df08782 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,17 @@ "read-chunk": "2.1.*" }, "devDependencies": { - "chai": "^4.1.2", - "eslint": "^4.19.1", - "eslint-config-airbnb-base": "^13.0.0", - "eslint-plugin-import": "^2.13.0", - "mocha": "^5.2.0" + "@nuxtjs/eslint-config": "^1.0.1", + "@nuxtjs/eslint-module": "^1.2.0", + "babel-eslint": "^10.1.0", + "chai": "^4.2.0", + "dotenv": "^8.2.0", + "eslint": "^6.1.0", + "eslint-config-prettier": "^4.1.0", + "eslint-plugin-nuxt": "^0.5.2", + "eslint-plugin-prettier": "^3.1.3", + "mocha": "^5.2.0", + "prettier": "^1.16.4" }, "scripts": { "test": "mocha -R spec src", diff --git a/src/apps.json b/src/apps.json index 41f87971e..f5a176cb9 100644 --- a/src/apps.json +++ b/src/apps.json @@ -3369,8 +3369,7 @@ "icon": "elm.svg", "js": { "Elm.Main.init": "\\;version:0.19", - "Elm.Main.embed": "\\;version:0.18", - "Elm": "\\;confidence:50" + "Elm.Main.embed": "\\;version:0.18" }, "website": "https://elm-lang.org/" }, diff --git a/src/drivers/npm/browsers/puppeteer.js b/src/drivers/npm/browsers/puppeteer.js index 7b0779adf..9e4d5f8e4 100644 --- a/src/drivers/npm/browsers/puppeteer.js +++ b/src/drivers/npm/browsers/puppeteer.js @@ -1,218 +1,245 @@ -const { - AWS_LAMBDA_FUNCTION_NAME, - CHROME_BIN, -} = process.env; +const { AWS_LAMBDA_FUNCTION_NAME, CHROME_BIN } = process.env -let chromium; -let puppeteer; +let chromium +let puppeteer if (AWS_LAMBDA_FUNCTION_NAME) { // eslint-disable-next-line global-require, import/no-unresolved - chromium = require('chrome-aws-lambda'); - - ({ puppeteer } = chromium); + chromium = require('chrome-aws-lambda') + ;({ puppeteer } = chromium) } else { // eslint-disable-next-line global-require - puppeteer = require('puppeteer'); + puppeteer = require('puppeteer') } -const Browser = require('../browser'); +const Browser = require('../browser') function getJs() { const dereference = (obj, level = 0) => { try { // eslint-disable-next-line no-undef if (level > 5 || (level && obj === window)) { - return '[Removed]'; + return '[Removed]' } if (Array.isArray(obj)) { - obj = obj.map(item => dereference(item, level + 1)); + obj = obj.map((item) => dereference(item, level + 1)) } - if (typeof obj === 'function' || (typeof obj === 'object' && obj !== null)) { - const newObj = {}; + if ( + typeof obj === 'function' || + (typeof obj === 'object' && obj !== null) + ) { + const newObj = {} Object.keys(obj).forEach((key) => { - newObj[key] = dereference(obj[key], level + 1); - }); + newObj[key] = dereference(obj[key], level + 1) + }) - return newObj; + return newObj } - return obj; + return obj } catch (error) { - return undefined; + return undefined } - }; + } // eslint-disable-next-line no-undef - return dereference(window); + return dereference(window) } class PuppeteerBrowser extends Browser { constructor(options) { - options.maxWait = options.maxWait || 60; + options.maxWait = options.maxWait || 60 - super(options); + super(options) } async visit(url) { - let done = false; - let browser; + let done = false + let browser try { await new Promise(async (resolve, reject) => { try { - browser = await puppeteer.launch(chromium ? { - args: [...chromium.args, '--ignore-certificate-errors'], - defaultViewport: chromium.defaultViewport, - executablePath: await chromium.executablePath, - headless: chromium.headless, - } : { - args: ['--no-sandbox', '--headless', '--disable-gpu', '--ignore-certificate-errors'], - executablePath: CHROME_BIN, - }); + browser = await puppeteer.launch( + chromium + ? { + args: [...chromium.args, '--ignore-certificate-errors'], + defaultViewport: chromium.defaultViewport, + executablePath: await chromium.executablePath, + headless: chromium.headless + } + : { + args: [ + '--no-sandbox', + '--headless', + '--disable-gpu', + '--ignore-certificate-errors' + ], + executablePath: CHROME_BIN + } + ) browser.on('disconnected', () => { if (!done) { - reject(new Error('browser: disconnected')); + reject(new Error('browser: disconnected')) } - }); + }) - const page = await browser.newPage(); + const page = await browser.newPage() - page.setDefaultTimeout(this.options.maxWait * 1.1); + page.setDefaultTimeout(this.options.maxWait * 1.1) - await page.setRequestInterception(true); + await page.setRequestInterception(true) - page.on('error', error => reject(new Error(`page error: ${error.message || error}`))); + page.on('error', (error) => + reject(new Error(`page error: ${error.message || error}`)) + ) - let responseReceived = false; + let responseReceived = false page.on('request', (request) => { try { if ( - responseReceived - && request.isNavigationRequest() - && request.frame() === page.mainFrame() - && request.url() !== url + responseReceived && + request.isNavigationRequest() && + request.frame() === page.mainFrame() && + request.url() !== url ) { - this.log(`abort navigation to ${request.url()}`); + this.log(`abort navigation to ${request.url()}`) - request.abort('aborted'); + request.abort('aborted') } else if (!done) { if (!['document', 'script'].includes(request.resourceType())) { - request.abort(); + request.abort() } else { - request.continue(); + request.continue() } } } catch (error) { - reject(new Error(`page error: ${error.message || error}`)); + reject(new Error(`page error: ${error.message || error}`)) } - }); + }) page.on('response', (response) => { try { if (!this.statusCode) { - this.statusCode = response.status(); + this.statusCode = response.status() - this.headers = {}; + this.headers = {} - const headers = response.headers(); + const headers = response.headers() Object.keys(headers).forEach((key) => { - this.headers[key] = Array.isArray(headers[key]) ? headers[key] : [headers[key]]; - }); + this.headers[key] = Array.isArray(headers[key]) + ? headers[key] + : [headers[key]] + }) - this.contentType = headers['content-type'] || null; + this.contentType = headers['content-type'] || null } if (response.status() < 300 || response.status() > 399) { - responseReceived = true; + responseReceived = true } } catch (error) { - reject(new Error(`page error: ${error.message || error}`)); + reject(new Error(`page error: ${error.message || error}`)) } - }); + }) page.on('console', ({ _type, _text, _location }) => { if (!/Failed to load resource: net::ERR_FAILED/.test(_text)) { - this.log(`${_text} (${_location.url}: ${_location.lineNumber})`, _type); + this.log( + `${_text} (${_location.url}: ${_location.lineNumber})`, + _type + ) } - }); + }) if (this.options.userAgent) { - await page.setUserAgent(this.options.userAgent); + await page.setUserAgent(this.options.userAgent) } try { await Promise.race([ page.goto(url, { waitUntil: 'domcontentloaded' }), // eslint-disable-next-line no-shadow - new Promise((resolve, reject) => setTimeout(() => reject(new Error('timeout')), this.options.maxWait)), - ]); + new Promise((resolve, reject) => + setTimeout( + () => reject(new Error('timeout')), + this.options.maxWait + ) + ) + ]) } catch (error) { - throw new Error(error.message || error.toString()); + throw new Error(error.message || error.toString()) } // eslint-disable-next-line no-undef - const links = await page.evaluateHandle(() => Array.from(document.getElementsByTagName('a')).map(({ - hash, hostname, href, pathname, protocol, rel, - }) => ({ - hash, - hostname, - href, - pathname, - protocol, - rel, - }))); - - this.links = await links.jsonValue(); + const links = await page.evaluateHandle(() => + Array.from(document.getElementsByTagName('a')).map( + ({ hash, hostname, href, pathname, protocol, rel }) => ({ + hash, + hostname, + href, + pathname, + protocol, + rel + }) + ) + ) + + this.links = await links.jsonValue() // eslint-disable-next-line no-undef - const scripts = await page.evaluateHandle(() => Array.from(document.getElementsByTagName('script')).map(({ - src, - }) => src)); + const scripts = await page.evaluateHandle(() => + Array.from(document.getElementsByTagName('script')).map( + ({ src }) => src + ) + ) - this.scripts = (await scripts.jsonValue()).filter(script => script); + this.scripts = (await scripts.jsonValue()).filter((script) => script) - this.js = await page.evaluate(getJs); + this.js = await page.evaluate(getJs) - this.cookies = (await page.cookies()).map(({ - name, value, domain, path, - }) => ({ - name, value, domain, path, - })); + this.cookies = (await page.cookies()).map( + ({ name, value, domain, path }) => ({ + name, + value, + domain, + path + }) + ) - this.html = await page.content(); + this.html = await page.content() - resolve(); + resolve() } catch (error) { - reject(new Error(`visit error: ${error.message || error}`)); + reject(new Error(`visit error: ${error.message || error}`)) } - }); + }) } catch (error) { - this.log(`visit error: ${error.message || error} (${url})`, 'error'); + this.log(`visit error: ${error.message || error} (${url})`, 'error') - throw new Error(error.message || error.toString()); + throw new Error(error.message || error.toString()) } finally { - done = true; + done = true if (browser) { try { - await browser.close(); + await browser.close() - this.log('browser close ok'); + this.log('browser close ok') } catch (error) { - this.log(`browser close error: ${error.message || error}`, 'error'); + this.log(`browser close error: ${error.message || error}`, 'error') } } } - this.log(`visit ok (${url})`); + this.log(`visit ok (${url})`) } } -module.exports = PuppeteerBrowser; +module.exports = PuppeteerBrowser diff --git a/src/drivers/puppeteer/.gitignore b/src/drivers/puppeteer/.gitignore new file mode 100644 index 000000000..5558dedd3 --- /dev/null +++ b/src/drivers/puppeteer/.gitignore @@ -0,0 +1,3 @@ +/apps.json +/wappalyzer.js +/node_modules diff --git a/src/drivers/puppeteer/Dockerfile b/src/drivers/puppeteer/Dockerfile new file mode 100644 index 000000000..4c1c3596b --- /dev/null +++ b/src/drivers/puppeteer/Dockerfile @@ -0,0 +1,34 @@ +FROM node:12-alpine + +MAINTAINER Wappalyzer + +ENV WAPPALYZER_ROOT /opt/wappalyzer +ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true +ENV CHROME_BIN /usr/bin/chromium-browser + +RUN apk update && apk add --no-cache \ + nodejs \ + nodejs-npm \ + udev \ + chromium \ + ttf-freefont + +RUN mkdir -p "$WAPPALYZER_ROOT/browsers" + +WORKDIR "$WAPPALYZER_ROOT" + +ADD apps.json . +ADD browser.js . +ADD browsers/zombie.js ./browsers +ADD browsers/puppeteer.js ./browsers +ADD cli.js . +ADD driver.js . +ADD index.js . +ADD package.json . +ADD wappalyzer.js . + +RUN npm i && npm i puppeteer + +RUN /usr/bin/chromium-browser --version + +ENTRYPOINT ["node", "cli.js"] diff --git a/src/drivers/puppeteer/README.md b/src/drivers/puppeteer/README.md new file mode 100644 index 000000000..72f39600b --- /dev/null +++ b/src/drivers/puppeteer/README.md @@ -0,0 +1,96 @@ +# Wappalyzer + +[Wappalyzer](https://www.wappalyzer.com/) is a +[cross-platform](https://www.wappalyzer.com/nodejs) utility that uncovers the +technologies used on websites. It detects +[content management systems](https://www.wappalyzer.com/technologies/cms), [ecommerce platforms](https://www.wappalyzer.com/technologies/ecommerce), [web servers](https://www.wappalyzer.com/technologies/web-servers), [JavaScript frameworks](https://www.wappalyzer.com/technologies/javascript-frameworks), +[analytics tools](https://www.wappalyzer.com/technologies/analytics) and +[many more](https://www.wappalyzer.com/technologies). + + +## Installation + +```shell +$ npm i -g wappalyzer # Globally +$ npm i wappalyzer --save # As a dependency +``` + +To use Puppeteer (headless Chrome browser), you must install the NPM package manually: + +```shell +$ npm i puppeteer@^2.0.0 +``` + + +## Run from the command line + +``` +wappalyzer [options] +``` + +### Options + +``` +-b, --browser=... Specify which headless browser to use (zombie or puppeteer) +-c, --chunk-size=... Process links in chunks +-d, --debug Output debug messages +-t, --delay=ms Wait for ms milliseconds between requests +-h, --help This text +--html-max-cols=... Limit the number of HTML characters per line processed +--html-max-rows=... Limit the number of HTML lines processed +-D, --max-depth=... Don't analyse pages more than num levels deep +-m, --max-urls=... Exit when num URLs have been analysed +-w, --max-wait=... Wait no more than ms milliseconds for page resources to load +-p, --password=... Password to be used for basic HTTP authentication (zombie only) +-P, --pretty Pretty-print JSON output +--proxy=... Proxy URL, e.g. 'http://user:pass@proxy:8080' (zombie only) +-r, --recursive Follow links on pages (crawler) +-a, --user-agent=... Set the user agent string +-u, --username=... Username to be used for basic HTTP authentication (zombie only) +``` + + +## Run from a script + +```javascript +const Wappalyzer = require('wappalyzer'); + +const url = 'https://www.wappalyzer.com'; + +const options = { + // browser: 'puppeteer', + debug: false, + delay: 500, + maxDepth: 3, + maxUrls: 10, + maxWait: 5000, + recursive: true, + userAgent: 'Wappalyzer', + htmlMaxCols: 2000, + htmlMaxRows: 2000, +}; + +const wappalyzer = new Wappalyzer(url, options); + +// Optional: capture log output +// wappalyzer.on('log', params => { +// const { message, source, type } = params; +// }); + +// Optional: do something on page visit +// wappalyzer.on('visit', params => { +// const { browser, pageUrl } = params; +// }); + +wappalyzer.analyze() + .then((json) => { + process.stdout.write(`${JSON.stringify(json, null, 2)}\n`); + + process.exit(0); + }) + .catch((error) => { + process.stderr.write(`${error}\n`); + + process.exit(1); + }); +``` diff --git a/src/drivers/puppeteer/browser.js b/src/drivers/puppeteer/browser.js new file mode 100644 index 000000000..532a75aa3 --- /dev/null +++ b/src/drivers/puppeteer/browser.js @@ -0,0 +1,20 @@ +class Browser { + constructor(options) { + this.options = options; + + this.window = null; + this.document = null; + this.statusCode = null; + this.contentType = null; + this.headers = null; + this.statusCode = null; + this.contentType = null; + this.html = null; + this.js = null; + this.links = null; + this.scripts = null; + this.cookies = null; + } +} + +module.exports = Browser; diff --git a/src/drivers/puppeteer/cli.js b/src/drivers/puppeteer/cli.js new file mode 100755 index 000000000..8a9d04f78 --- /dev/null +++ b/src/drivers/puppeteer/cli.js @@ -0,0 +1,109 @@ +#!/usr/bin/env node + +const Wappalyzer = require('./driver') + +const args = process.argv.slice(2) + +const options = {} + +let url +let arg + +const aliases = { + a: 'userAgent', + b: 'batchSize', + d: 'debug', + t: 'delay', + h: 'help', + D: 'maxDepth', + m: 'maxUrls', + P: 'pretty', + r: 'recursive', + w: 'maxWait' +} + +while (true) { + // eslint-disable-line no-constant-condition + arg = args.shift() + + if (!arg) { + break + } + + const matches = /^-?-([^=]+)(?:=(.+)?)?/.exec(arg) + + if (matches) { + const key = + aliases[matches[1]] || + matches[1].replace(/-\w/g, (_matches) => _matches[1].toUpperCase()) + // eslint-disable-next-line no-nested-ternary + const value = matches[2] + ? matches[2] + : args[0] && !args[0].startsWith('-') + ? args.shift() + : true + + options[key] = value + } else { + url = arg + } +} + +if (!url || options.help) { + process.stdout.write(`Usage: + wappalyzer [options] + +Examples: + wappalyzer https://www.example.com + node cli.js https://www.example.com -r -D 3 -m 50 + docker wappalyzer/cli https://www.example.com --pretty + +Options: + -b, --batch-size=... Process links in batches + -d, --debug Output debug messages + -t, --delay=ms Wait for ms milliseconds between requests + -h, --help This text + --html-max-cols=... Limit the number of HTML characters per line processed + --html-max-rows=... Limit the number of HTML lines processed + -D, --max-depth=... Don't analyse pages more than num levels deep + -m, --max-urls=... Exit when num URLs have been analysed + -w, --max-wait=... Wait no more than ms milliseconds for page resources to load + -P, --pretty Pretty-print JSON output + -r, --recursive Follow links on pages (crawler) + -a, --user-agent=... Set the user agent string +`) + + process.exit(1) +} + +;(async function() { + const wappalyzer = await new Wappalyzer(options) + + try { + await wappalyzer.init() + + const site = await wappalyzer.open(url) + + site.on('error', (error) => { + process.stderr.write(`page error: ${error}\n`) + }) + + await new Promise((resolve) => setTimeout(resolve, 1000)) + + const results = await site.analyze() + + process.stdout.write( + `${JSON.stringify(results, null, options.pretty ? 2 : null)}\n` + ) + + await wappalyzer.destroy() + + process.exit(0) + } catch (error) { + process.stderr.write(error.toString()) + + await wappalyzer.destroy() + + process.exit(1) + } +})() diff --git a/src/drivers/puppeteer/driver.js b/src/drivers/puppeteer/driver.js new file mode 100644 index 000000000..b8fb2534c --- /dev/null +++ b/src/drivers/puppeteer/driver.js @@ -0,0 +1,540 @@ +const { URL } = require('url') +const fs = require('fs') +const LanguageDetect = require('languagedetect') +const Wappalyzer = require('./wappalyzer') + +const { AWS_LAMBDA_FUNCTION_NAME } = process.env + +let puppeteer + +if (AWS_LAMBDA_FUNCTION_NAME) { + // eslint-disable-next-line global-require, import/no-unresolved + ;({ + chromium: { puppeteer } + } = require('chrome-aws-lambda')) +} else { + // eslint-disable-next-line global-require + puppeteer = require('puppeteer') +} + +const languageDetect = new LanguageDetect() + +languageDetect.setLanguageType('iso2') + +const json = JSON.parse(fs.readFileSync('./apps.json')) + +const extensions = /^([^.]+$|\.(asp|aspx|cgi|htm|html|jsp|php)$)/ + +const errorTypes = { + RESPONSE_NOT_OK: 'Response was not ok', + NO_RESPONSE: 'No response from server', + NO_HTML_DOCUMENT: 'No HTML document' +} + +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)) +} + +function getJs() { + const dereference = (obj, level = 0) => { + try { + // eslint-disable-next-line no-undef + if (level > 5 || (level && obj === window)) { + return '[Removed]' + } + + if (Array.isArray(obj)) { + obj = obj.map((item) => dereference(item, level + 1)) + } + + if ( + typeof obj === 'function' || + (typeof obj === 'object' && obj !== null) + ) { + const newObj = {} + + Object.keys(obj).forEach((key) => { + newObj[key] = dereference(obj[key], level + 1) + }) + + return newObj + } + + return obj + } catch (error) { + return undefined + } + } + + // eslint-disable-next-line no-undef + return dereference(window) +} + +function processJs(window, patterns) { + const js = {} + + Object.keys(patterns).forEach((appName) => { + js[appName] = {} + + Object.keys(patterns[appName]).forEach((chain) => { + js[appName][chain] = {} + + patterns[appName][chain].forEach((pattern, index) => { + const properties = chain.split('.') + + let value = properties.reduce( + (parent, property) => + parent && parent[property] ? parent[property] : null, + window + ) + + value = + typeof value === 'string' || typeof value === 'number' + ? value + : !!value + + if (value) { + js[appName][chain][index] = value + } + }) + }) + }) + + return js +} + +function processHtml(html, maxCols, maxRows) { + if (maxCols || maxRows) { + const batchs = [] + const rows = html.length / maxCols + + for (let i = 0; i < rows; i += 1) { + if (i < maxRows / 2 || i > rows - maxRows / 2) { + batchs.push(html.slice(i * maxCols, (i + 1) * maxCols)) + } + } + + html = batchs.join('\n') + } + + return html +} + +class Driver { + constructor(options = {}) { + this.options = { + batchSize: 5, + debug: false, + delay: 500, + htmlMaxCols: 2000, + htmlMaxRows: 3000, + maxDepth: 3, + maxUrls: 10, + maxWait: 5000, + recursive: false, + ...options + } + + this.options.debug = Boolean(+this.options.debug) + this.options.recursive = Boolean(+this.options.recursive) + this.options.delay = this.options.recursive + ? parseInt(this.options.delay, 10) + : 0 + this.options.maxDepth = parseInt(this.options.maxDepth, 10) + this.options.maxUrls = parseInt(this.options.maxUrls, 10) + this.options.maxWait = parseInt(this.options.maxWait, 10) + this.options.htmlMaxCols = parseInt(this.options.htmlMaxCols, 10) + this.options.htmlMaxRows = parseInt(this.options.htmlMaxRows, 10) + + this.destroyed = false + } + + async init() { + this.log('Launching browser...') + + try { + this.browser = await puppeteer.launch({ + args: [ + '--no-sandbox', + '--headless', + '--disable-gpu', + '--ignore-certificate-errors' + ] + }) + + this.browser.on('disconnected', async () => { + this.log('Browser disconnected') + + if (!this.destroyed) { + await this.init() + } + }) + } catch (error) { + throw new Error(error.toString()) + } + } + + async destroy() { + this.destroyed = true + + if (this.browser) { + try { + await sleep(1) + + await this.browser.close() + + this.log('Done') + } catch (error) { + throw new Error(error.toString()) + } + } + } + + open(url) { + return new Site(url, this) + } + + log(message, source = 'driver', type = 'debug') { + if (this.options.debug) { + // eslint-disable-next-line no-console + console.log(`${type.toUpperCase()} | ${source} | ${message}`) + } + } +} + +class Site { + constructor(url, driver) { + ;({ options: this.options, browser: this.browser } = driver) + + this.driver = driver + + try { + this.originalUrl = new URL(url) + } catch (error) { + throw new Error(error.message || error.toString()) + } + + this.wappalyzer = new Wappalyzer() + + this.wappalyzer.apps = json.apps + this.wappalyzer.categories = json.categories + + this.wappalyzer.parseJsPatterns() + + this.wappalyzer.driver.log = (message, source, type) => + this.log(message, source, type) + this.wappalyzer.driver.displayApps = (detected, meta, context) => + this.displayApps(detected, meta, context) + + this.analyzedUrls = {} + this.technologies = [] + this.meta = {} + + this.listeners = {} + + this.headers = {} + } + + async init() {} + + on(event, callback) { + if (!this.listeners[event]) { + this.listeners[event] = [] + } + + this.listeners[event].push(callback) + } + + emit(event, params) { + if (this.listeners[event]) { + this.listeners[event].forEach((listener) => listener(params)) + } + } + + log(...args) { + this.emit('log', ...args) + + this.driver.log(...args) + } + + async fetch(url, index, depth) {} + + async goto(url) { + // Return when the URL is a duplicate or maxUrls has been reached + if ( + this.analyzedUrls[url.href] || + Object.keys(this.analyzedUrls).length >= this.options.maxUrls + ) { + return + } + + this.log(`Navigate to ${url}`, 'page') + + this.analyzedUrls[url.href] = { + status: 0 + } + + if (!this.browser) { + throw new Error('Browser closed') + } + + const page = await this.browser.newPage() + + page.setDefaultTimeout(this.options.maxWait) + + await page.setRequestInterception(true) + + page.on('error', (error) => this.emit('error', error)) + + let responseReceived = false + + page.on('request', (request) => { + try { + if ( + (responseReceived && request.isNavigationRequest()) || + request.frame() !== page.mainFrame() || + !['document', 'script'].includes(request.resourceType()) + ) { + request.abort('blockedbyclient') + } else { + request.continue() + } + } catch (error) { + this.emit('error', error) + } + }) + + page.on('response', (response) => { + try { + if (response.url() === url.href) { + this.analyzedUrls[url.href] = { + status: response.status() + } + + const headers = response.headers() + + Object.keys(headers).forEach((key) => { + this.headers[key] = [ + ...(this.headers[key] || []), + ...(Array.isArray(headers[key]) ? headers[key] : [headers[key]]) + ] + }) + + this.contentType = headers['content-type'] || null + + if (response.status() >= 300 && response.status() < 400) { + if (this.headers.location) { + url = new URL(this.headers.location.slice(-1)) + } + } else { + responseReceived = true + } + } + } catch (error) { + this.emit('error', error) + } + }) + + if (this.options.userAgent) { + await page.setUserAgent(this.options.userAgent) + } + + try { + await Promise.race([ + page.goto(url.href, { waitUntil: 'domcontentloaded' }), + new Promise((resolve, reject) => + setTimeout(() => reject(new Error('Timeout')), this.options.maxWait) + ) + ]) + } catch (error) { + this.emit('error', error) + } + + await sleep(1000) + + const links = await ( + await page.evaluateHandle(() => + Array.from(document.getElementsByTagName('a')).map( + ({ hash, hostname, href, pathname, protocol, rel }) => ({ + hash, + hostname, + href, + pathname, + protocol, + rel + }) + ) + ) + ).jsonValue() + + // eslint-disable-next-line no-undef + const scripts = ( + await ( + await page.evaluateHandle(() => + Array.from(document.getElementsByTagName('script')).map( + ({ src }) => src + ) + ) + ).jsonValue() + ).filter((script) => script) + + const js = processJs(await page.evaluate(getJs), this.wappalyzer.jsPatterns) + + const cookies = (await page.cookies()).map( + ({ name, value, domain, path }) => ({ + name, + value, + domain, + path + }) + ) + + const html = processHtml( + await page.content(), + this.options.htmlMaxCols, + this.options.htmlMaxRows + ) + + // Validate response + if (!this.analyzedUrls[url.href].status) { + throw new Error('NO_RESPONSE') + } + + let language = null + + try { + const [attrs] = languageDetect.detect( + html.replace(/<\/?[^>]+(>|$)/g, ' '), + 1 + ) + + if (attrs) { + ;[language] = attrs + } + } catch (error) { + this.log(`${error} (${url.href})`, 'driver', 'error') + } + + await this.wappalyzer.analyze(url, { + cookies, + headers: this.headers, + html, + js, + scripts, + language + }) + + const reducedLinks = Array.prototype.reduce.call( + links, + (results, link) => { + if ( + results && + Object.prototype.hasOwnProperty.call( + Object.getPrototypeOf(results), + 'push' + ) && + link.protocol && + link.protocol.match(/https?:/) && + link.rel !== 'nofollow' && + link.hostname === url.hostname && + extensions.test(link.pathname) + ) { + results.push(new URL(link.href.split('#')[0])) + } + + return results + }, + [] + ) + + this.emit('goto', url) + + return reducedLinks + } + + async analyze(url = this.originalUrl, index = 1, depth = 1) { + try { + await sleep(this.options.delay * index) + + const links = await this.goto(url) + + if (links && this.options.recursive && depth < this.options.maxDepth) { + await this.batch(links.slice(0, this.options.maxUrls), depth + 1) + } + } catch (error) { + const type = + error.message && errorTypes[error.message] + ? error.message + : 'UNKNOWN_ERROR' + const message = + error.message && errorTypes[error.message] + ? errorTypes[error.message] + : 'Unknown error' + + this.analyzedUrls[url.href] = { + status: 0, + error: { + type, + message + } + } + + this.log(`${message} (${url.href})`, 'driver', 'error') + } + + return { + urls: this.analyzedUrls, + applications: this.technologies, + meta: this.meta + } + } + + async batch(links, depth, batch = 0) { + if (links.length === 0) { + return + } + + const batched = links.splice(0, this.options.batchSize) + + await Promise.all( + batched.map((link, index) => this.analyze(link, index, depth)) + ) + + await this.batch(links, depth, batch + 1) + } + + displayApps(technologies, meta) { + this.meta = meta + + Object.keys(technologies).forEach((name) => { + const { + confidenceTotal: confidence, + version, + props: { cats, icon, website, cpe } + } = technologies[name] + + const categories = cats.reduce((categories, id) => { + categories[id] = json.categories[id].name + + return categories + }, {}) + + if (!this.technologies.some(({ name: _name }) => name === _name)) { + this.technologies.push({ + name, + confidence, + version: version || null, + icon: icon || 'default.svg', + website, + cpe: cpe || null, + categories + }) + } + }) + } +} + +module.exports = Driver + +module.exports.processJs = processJs +module.exports.processHtml = processHtml diff --git a/src/drivers/puppeteer/index.js b/src/drivers/puppeteer/index.js new file mode 100755 index 000000000..81cf5899f --- /dev/null +++ b/src/drivers/puppeteer/index.js @@ -0,0 +1,12 @@ +const Driver = require('./driver'); + +class Wappalyzer { + constructor(pageUrl, options) { + // eslint-disable-next-line import/no-dynamic-require, global-require + const Browser = require(`./browsers/${options.browser || 'zombie'}`); + + return new Driver(Browser, pageUrl, options); + } +} + +module.exports = Wappalyzer; diff --git a/src/drivers/puppeteer/package.json b/src/drivers/puppeteer/package.json new file mode 100644 index 000000000..6c2059d93 --- /dev/null +++ b/src/drivers/puppeteer/package.json @@ -0,0 +1,30 @@ +{ + "name": "wappalyzer", + "description": "Identify technology on websites", + "homepage": "https://www.wappalyzer.com", + "version": "6.0.0", + "author": "Wappalyzer", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/aliasio/wappalyzer" + }, + "funding": { + "url": "https://github.com/sponsors/aliasio" + }, + "main": "index.js", + "files": [ + "apps.json", + "cli.js", + "driver.js", + "index.js", + "wappalyzer.js" + ], + "bin": { + "wappalyzer": "./cli.js" + }, + "dependencies": { + "languagedetect": "^2.0.0", + "puppeteer": "^2.0.0" + } +} diff --git a/src/drivers/puppeteer/yarn.lock b/src/drivers/puppeteer/yarn.lock new file mode 100644 index 000000000..0fb2fe9c8 --- /dev/null +++ b/src/drivers/puppeteer/yarn.lock @@ -0,0 +1,296 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/mime-types@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.0.tgz#9ca52cda363f699c69466c2a6ccdaad913ea7a73" + integrity sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM= + +agent-base@5: + version "5.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" + integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +debug@4, debug@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +extract-zip@^1.6.6: + version "1.7.0" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" + integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA== + dependencies: + concat-stream "^1.6.2" + debug "^2.6.9" + mkdirp "^0.5.4" + yauzl "^2.10.0" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +https-proxy-agent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b" + integrity sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg== + dependencies: + agent-base "5" + debug "4" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +languagedetect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/languagedetect/-/languagedetect-2.0.0.tgz#4b8fa2b7593b2a3a02fb1100891041c53238936c" + integrity sha512-AZb/liiQ+6ZoTj4f1J0aE6OkzhCo8fyH+tuSaPfSo8YHCWLFJrdSixhtO2TYdIkjcDQNaR4RmGaV2A5FJklDMQ== + +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.25: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime@^2.0.3: + version "2.4.5" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.5.tgz#d8de2ecb92982dedbb6541c9b6841d7f218ea009" + integrity sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^0.5.4: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +proxy-from-env@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +puppeteer@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-2.1.1.tgz#ccde47c2a688f131883b50f2d697bd25189da27e" + integrity sha512-LWzaDVQkk1EPiuYeTOj+CZRIjda4k2s5w4MK4xoH2+kgWV/SDlkYHmxatDdtYrciHUKSXTsGgPgPP8ILVdBsxg== + dependencies: + "@types/mime-types" "^2.1.0" + debug "^4.1.0" + extract-zip "^1.6.6" + https-proxy-agent "^4.0.0" + mime "^2.0.3" + mime-types "^2.1.25" + progress "^2.0.1" + proxy-from-env "^1.0.0" + rimraf "^2.6.1" + ws "^6.1.0" + +readable-stream@^2.2.2: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +rimraf@^2.6.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..57f1682cd --- /dev/null +++ b/yarn.lock @@ -0,0 +1,1991 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + +"@babel/generator@^7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.6.tgz#5408c82ac5de98cda0d77d8124e99fa1f2170a43" + integrity sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ== + dependencies: + "@babel/types" "^7.9.6" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-function-name@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" + integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.9.5" + +"@babel/helper-get-function-arity@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" + integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-split-export-declaration@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" + integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" + integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== + +"@babel/highlight@^7.8.3": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.7.0", "@babel/parser@^7.8.6", "@babel/parser@^7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.6.tgz#3b1bbb30dabe600cd72db58720998376ff653bc7" + integrity sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q== + +"@babel/template@^7.8.3": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/traverse@^7.7.0": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.6.tgz#5540d7577697bf619cc57b92aa0f1c231a94f442" + integrity sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.6" + "@babel/helper-function-name" "^7.9.5" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.9.6" + "@babel/types" "^7.9.6" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.7.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.5", "@babel/types@^7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.6.tgz#2c5502b427251e9de1bd2dff95add646d95cc9f7" + integrity sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA== + dependencies: + "@babel/helper-validator-identifier" "^7.9.5" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@nuxtjs/eslint-config@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@nuxtjs/eslint-config/-/eslint-config-1.1.2.tgz#cde4c950014a781bcc34abbfef9c62546d8fc34c" + integrity sha512-uKBdza1/Poz32gEodQ9MSW8M9CU4RPdvEiSLX5LWyavrbjhXW9iIbzJzSDlgMhD1QfQ5WrWv1iqL3Bh/ArbIgw== + dependencies: + eslint-config-standard "^12.0.0" + eslint-plugin-import "^2.18.0" + eslint-plugin-jest "^22.10.0" + eslint-plugin-node "^9.1.0" + eslint-plugin-promise "^4.2.1" + eslint-plugin-standard "^4.0.0" + eslint-plugin-unicorn "^9.1.1" + eslint-plugin-vue "^5.2.3" + +"@nuxtjs/eslint-module@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@nuxtjs/eslint-module/-/eslint-module-1.2.0.tgz#a1d014690d505309c16ced2ded3b729cbc479306" + integrity sha512-ZVweM95atKQIqKPmrYS532SyO0/Uqi5wXc1uUiPZVy2MTVjqlC/7uHJ/XSxpvnt78kBW9z64Fxgf5pZggSNXgA== + dependencies: + consola "^2.11.3" + eslint-loader "^4.0.2" + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/json-schema@^7.0.3": + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" + integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== + +"@typescript-eslint/experimental-utils@^1.13.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz#b08c60d780c0067de2fb44b04b432f540138301e" + integrity sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "1.13.0" + eslint-scope "^4.0.0" + +"@typescript-eslint/typescript-estree@1.13.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz#8140f17d0f60c03619798f1d628b8434913dc32e" + integrity sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw== + dependencies: + lodash.unescape "4.0.1" + semver "5.5.0" + +acorn-jsx@^5.0.0, acorn-jsx@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" + integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== + +acorn@^6.0.2: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +acorn@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe" + integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ== + +ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0: + version "6.12.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" + integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-escapes@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + dependencies: + type-fest "^0.11.0" + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-includes@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" + integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0" + is-string "^1.0.5" + +array.prototype.flat@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" + integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +babel-eslint@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" + integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +chai@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.0" + type-detect "^4.0.5" + +chalk@^2.0.0, chalk@^2.1.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + +clean-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7" + integrity sha1-jffHquUf02h06PjQW5GAvBGj/tc= + dependencies: + escape-string-regexp "^1.0.5" + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-width@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" + integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +consola@^2.11.3: + version "2.12.1" + resolved "https://registry.yarnpkg.com/consola/-/consola-2.12.1.tgz#88e9311a02cb88a7f6f9488239dd30b6ba99cbb0" + integrity sha512-aEkkju9ZcEa9y2MhzNhfmTUws/CEZZ0LKu0FxftSU3HygPfVMMIMSYyYct+xBN6XNRhsaDZjw2HAv3m2ammXSA== + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dotenv@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.5: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-ast-utils@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz#3d58ba557801cfb1c941d68131ee9f8c34bd1586" + integrity sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA== + dependencies: + lodash.get "^4.4.2" + lodash.zip "^4.2.0" + +eslint-config-prettier@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz#c55c1fcac8ce4518aeb77906984e134d9eb5a4f0" + integrity sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA== + dependencies: + get-stdin "^6.0.0" + +eslint-config-standard@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" + integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ== + +eslint-import-resolver-node@^0.3.2: + version "0.3.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" + integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg== + dependencies: + debug "^2.6.9" + resolve "^1.13.1" + +eslint-loader@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-4.0.2.tgz#386a1e21bcb613b3cf2d252a3b708023ccfb41ec" + integrity sha512-EDpXor6lsjtTzZpLUn7KmXs02+nIjGcgees9BYjNkWra3jVq5vVa8IoCKgzT2M7dNNeoMBtaSG83Bd40N3poLw== + dependencies: + find-cache-dir "^3.3.1" + fs-extra "^8.1.0" + loader-utils "^2.0.0" + object-hash "^2.0.3" + schema-utils "^2.6.5" + +eslint-module-utils@^2.4.1: + version "2.6.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" + integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== + dependencies: + debug "^2.6.9" + pkg-dir "^2.0.0" + +eslint-plugin-es@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.1.tgz#12acae0f4953e76ba444bfd1b2271081ac620998" + integrity sha512-5fa/gR2yR3NxQf+UXkeLeP8FBBl6tSgdrAz1+cF84v1FMM4twGwQoqTnn+QxFLcPOrF4pdKEJKDB/q9GoyJrCA== + dependencies: + eslint-utils "^1.4.2" + regexpp "^2.0.1" + +eslint-plugin-import@^2.18.0: + version "2.20.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d" + integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg== + dependencies: + array-includes "^3.0.3" + array.prototype.flat "^1.2.1" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.4.1" + has "^1.0.3" + minimatch "^3.0.4" + object.values "^1.1.0" + read-pkg-up "^2.0.0" + resolve "^1.12.0" + +eslint-plugin-jest@^22.10.0: + version "22.21.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.21.0.tgz#8137294645866636160487d9764224b9a43e2eb1" + integrity sha512-OaqnSS7uBgcGiqXUiEnjoqxPNKvR4JWG5mSRkzVoR6+vDwlqqp11beeql1hYs0HTbdhiwrxWLxbX0Vx7roG3Ew== + dependencies: + "@typescript-eslint/experimental-utils" "^1.13.0" + +eslint-plugin-node@^9.1.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-9.2.0.tgz#b1911f111002d366c5954a6d96d3cd5bf2a3036a" + integrity sha512-2abNmzAH/JpxI4gEOwd6K8wZIodK3BmHbTxz4s79OIYwwIt2gkpEXlAouJXu4H1c9ySTnRso0tsuthSOZbUMlA== + dependencies: + eslint-plugin-es "^1.4.1" + eslint-utils "^1.4.2" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-plugin-nuxt@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-nuxt/-/eslint-plugin-nuxt-0.5.2.tgz#638cdfd0fc0473d285ca848e7e30b8b8e6f59f91" + integrity sha512-kOWUSrix6h+gGTCe6He51ett065yAzXsMiteKkBo5pdjc94A3gBMBrWtRZGyZGv91P1wRcJpF8l4CWMhNm3oWg== + dependencies: + eslint-plugin-vue "^6.2.2" + semver "^7.1.3" + vue-eslint-parser "^7.0.0" + +eslint-plugin-prettier@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz#ae116a0fc0e598fdae48743a4430903de5b4e6ca" + integrity sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-promise@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" + integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== + +eslint-plugin-standard@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" + integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== + +eslint-plugin-unicorn@^9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-9.1.1.tgz#1588a0473f9a0e37cfbbcf7552065a0b0a96ce26" + integrity sha512-SHh/N54pRu5KXlS4Boa1qbWM7yTNl6VpuYJ8Qc1O3TJDr+CDUwEEdUtVlVSV/dBUE97BC8Xk0+Y5zphn21qlCA== + dependencies: + clean-regexp "^1.0.0" + eslint-ast-utils "^1.0.0" + import-modules "^1.1.0" + lodash.camelcase "^4.1.1" + lodash.defaultsdeep "^4.6.0" + lodash.kebabcase "^4.0.1" + lodash.snakecase "^4.0.1" + lodash.topairs "^4.3.0" + lodash.upperfirst "^4.2.0" + regexpp "^2.0.1" + reserved-words "^0.1.2" + safe-regex "^2.0.1" + +eslint-plugin-vue@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-5.2.3.tgz#3ee7597d823b5478804b2feba9863b1b74273961" + integrity sha512-mGwMqbbJf0+VvpGR5Lllq0PMxvTdrZ/ZPjmhkacrCHbubJeJOt+T6E3HUzAifa2Mxi7RSdJfC9HFpOeSYVMMIw== + dependencies: + vue-eslint-parser "^5.0.0" + +eslint-plugin-vue@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-6.2.2.tgz#27fecd9a3a24789b0f111ecdd540a9e56198e0fe" + integrity sha512-Nhc+oVAHm0uz/PkJAWscwIT4ijTrK5fqNqz9QB1D35SbbuMG1uB6Yr5AJpvPSWg+WOw7nYNswerYh0kOk64gqQ== + dependencies: + natural-compare "^1.4.0" + semver "^5.6.0" + vue-eslint-parser "^7.0.0" + +eslint-scope@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.4.2, eslint-utils@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^6.1.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" + integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^7.0.0" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.3" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" + integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== + dependencies: + acorn "^6.0.2" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +espree@^6.1.2, espree@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== + dependencies: + acorn "^7.1.1" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.1.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" + integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" + integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-type@7.4.*: + version "7.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.4.0.tgz#2a7c94f62a0030150bb7d9b6c70cfa1d3e759c86" + integrity sha1-KnyU9ioAMBULt9m2xwz6HT51nIY= + +find-cache-dir@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + +glob-parent@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +html-comment-regex@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.6.tgz#643194ad4bf2712f37852e386b6998eff0db2106" + integrity sha512-cgXgkypZBcCnOgSihyeqbo6gjIaIyDqPQB7Ra4vhE9m6kigdGoQDMHjviFhRZo3IMlRy6yElosoviMs5YxZXUA== + +import-fresh@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-modules@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/import-modules/-/import-modules-1.1.0.tgz#748db79c5cc42bb9701efab424f894e72600e9dc" + integrity sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw= + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inquirer@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29" + integrity sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^3.0.0" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +is-svg@2.1.*: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" + integrity sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk= + dependencies: + html-comment-regex "^1.1.0" + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +isarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.camelcase@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.defaultsdeep@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" + integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.kebabcase@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= + +lodash.snakecase@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" + integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= + +lodash.topairs@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.topairs/-/lodash.topairs-4.3.0.tgz#3b6deaa37d60fb116713c46c5f17ea190ec48d64" + integrity sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ= + +lodash.unescape@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" + integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= + +lodash.upperfirst@^4.2.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" + integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984= + +lodash.zip@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" + integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= + +lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mocha@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +object-hash@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" + integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== + +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.values@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +pathval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^1.16.4: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +read-chunk@2.1.*: + version "2.1.0" + resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655" + integrity sha1-agTAkoAF7Z1C4aasVgDhnLx/9lU= + dependencies: + pify "^3.0.0" + safe-buffer "^5.1.1" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +regexp-tree@~0.1.1: + version "0.1.21" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.21.tgz#55e2246b7f7d36f1b461490942fa780299c400d7" + integrity sha512-kUUXjX4AnqnR8KRTCrayAo9PzYMRKmVoGgaz2tBuz0MF3g1ZbGebmtW0yFHfFK9CmBjQKeYIgoL22pFLBJY7sw== + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +reserved-words@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.2.tgz#00a0940f98cd501aeaaac316411d9adc52b31ab1" + integrity sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +rxjs@^6.5.3: + version "6.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" + integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-2.1.1.tgz#f7128f00d056e2fe5c11e81a1324dd974aadced2" + integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A== + dependencies: + regexp-tree "~0.1.1" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^2.6.5: + version "2.6.6" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.6.tgz#299fe6bd4a3365dc23d99fd446caff8f1d6c330c" + integrity sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== + +semver@^6.0.0, semver@^6.1.0, semver@^6.1.2: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.1.3: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +source-map@^0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimleft@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" + integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimstart "^1.0.0" + +string.prototype.trimright@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" + integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimend "^1.0.0" + +string.prototype.trimstart@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-json-comments@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" + integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== + +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +tslib@^1.9.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +v8-compile-cache@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vue-eslint-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz#00f4e4da94ec974b821a26ff0ed0f7a78402b8a1" + integrity sha512-JlHVZwBBTNVvzmifwjpZYn0oPWH2SgWv5dojlZBsrhablDu95VFD+hriB1rQGwbD+bms6g+rAFhQHk6+NyiS6g== + dependencies: + debug "^4.1.0" + eslint-scope "^4.0.0" + eslint-visitor-keys "^1.0.0" + espree "^4.1.0" + esquery "^1.0.1" + lodash "^4.17.11" + +vue-eslint-parser@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz#9cdbcc823e656b087507a1911732b867ac101e83" + integrity sha512-Kr21uPfthDc63nDl27AGQEhtt9VrZ9nkYk/NTftJ2ws9XiJwzJJCnCr3AITQ2jpRMA0XPGDECxYH8E027qMK9Q== + dependencies: + debug "^4.1.1" + eslint-scope "^5.0.0" + eslint-visitor-keys "^1.1.0" + espree "^6.2.1" + esquery "^1.0.1" + lodash "^4.17.15" + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" From d9c504a19cdd061d695b0e3c118d05d636e8b5b0 Mon Sep 17 00:00:00 2001 From: Elbert Alias <77259+AliasIO@users.noreply.github.com> Date: Tue, 26 May 2020 14:59:28 +1000 Subject: [PATCH 27/34] Update README --- src/drivers/puppeteer/README.md | 48 ++++++++++++++++----------------- src/drivers/puppeteer/cli.js | 2 -- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/drivers/puppeteer/README.md b/src/drivers/puppeteer/README.md index 72f39600b..acfd9cbea 100644 --- a/src/drivers/puppeteer/README.md +++ b/src/drivers/puppeteer/README.md @@ -31,8 +31,7 @@ wappalyzer [options] ### Options ``` --b, --browser=... Specify which headless browser to use (zombie or puppeteer) --c, --chunk-size=... Process links in chunks +-b, --batch-size=... Process links in batches -d, --debug Output debug messages -t, --delay=ms Wait for ms milliseconds between requests -h, --help This text @@ -41,12 +40,9 @@ wappalyzer [options] -D, --max-depth=... Don't analyse pages more than num levels deep -m, --max-urls=... Exit when num URLs have been analysed -w, --max-wait=... Wait no more than ms milliseconds for page resources to load --p, --password=... Password to be used for basic HTTP authentication (zombie only) -P, --pretty Pretty-print JSON output ---proxy=... Proxy URL, e.g. 'http://user:pass@proxy:8080' (zombie only) -r, --recursive Follow links on pages (crawler) -a, --user-agent=... Set the user agent string --u, --username=... Username to be used for basic HTTP authentication (zombie only) ``` @@ -58,7 +54,6 @@ const Wappalyzer = require('wappalyzer'); const url = 'https://www.wappalyzer.com'; const options = { - // browser: 'puppeteer', debug: false, delay: 500, maxDepth: 3, @@ -70,27 +65,30 @@ const options = { htmlMaxRows: 2000, }; -const wappalyzer = new Wappalyzer(url, options); +;(async function() { + const wappalyzer = await new Wappalyzer(options) -// Optional: capture log output -// wappalyzer.on('log', params => { -// const { message, source, type } = params; -// }); + try { + await wappalyzer.init() -// Optional: do something on page visit -// wappalyzer.on('visit', params => { -// const { browser, pageUrl } = params; -// }); + const site = await wappalyzer.open(url) -wappalyzer.analyze() - .then((json) => { - process.stdout.write(`${JSON.stringify(json, null, 2)}\n`); + site.on('error', (error) => { + process.stderr.write(`error: ${error}\n`) + }) - process.exit(0); - }) - .catch((error) => { - process.stderr.write(`${error}\n`); + const results = await site.analyze() - process.exit(1); - }); -``` + process.stdout.write(`${JSON.stringify(results, null, 2)}\n`) + + await wappalyzer.destroy() + + process.exit(0) + } catch (error) { + process.stderr.write(error.toString()) + + await wappalyzer.destroy() + + process.exit(1) + } +})() diff --git a/src/drivers/puppeteer/cli.js b/src/drivers/puppeteer/cli.js index 8a9d04f78..9348ce709 100755 --- a/src/drivers/puppeteer/cli.js +++ b/src/drivers/puppeteer/cli.js @@ -88,8 +88,6 @@ Options: process.stderr.write(`page error: ${error}\n`) }) - await new Promise((resolve) => setTimeout(resolve, 1000)) - const results = await site.analyze() process.stdout.write( From 492b83f1105de67492c70cb42a91f5fda713b831 Mon Sep 17 00:00:00 2001 From: Arseny Sokolov Date: Tue, 26 May 2020 16:10:48 +0800 Subject: [PATCH 28/34] Add gRPC detection --- src/apps.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/apps.json b/src/apps.json index 2046355f5..d116e01c8 100644 --- a/src/apps.json +++ b/src/apps.json @@ -4664,6 +4664,16 @@ "script": "assets\\.growingio\\.com/([\\d.]+)/gio.js\\;version:\\1", "website": "https://www.growingio.com/" }, + "gRPC": { + "cats": [ + 19 + ], + "icon": "gRPC.png", + "headers": { + "Content-Type": "^application\\/grpc.+$" + }, + "website": "https://grpc.io" + }, "HERE": { "cats": [ 35 From f5f5a65691817276a64363e29b7c490d6d0ae0d7 Mon Sep 17 00:00:00 2001 From: Arseny Sokolov Date: Tue, 26 May 2020 16:11:01 +0800 Subject: [PATCH 29/34] Add gRPC icon --- src/icons/gRPC.png | Bin 0 -> 1472 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/icons/gRPC.png diff --git a/src/icons/gRPC.png b/src/icons/gRPC.png new file mode 100644 index 0000000000000000000000000000000000000000..c35182c02bf146be335b8f968ee6865e538e82d3 GIT binary patch literal 1472 zcmV;x1wZfNLa{CCW8OA4?p*;d`-{T?6> z^<|lW?WV^L&gl=tEdi)|Caed97r_{aAl$&f7z3Z0EHK zr8kIvZGnGV{xU|eh8yAgEIS;aqG;OWTYk9{NRErvgs!U4f#p00H4pv*Q=l?;0?G_o-P=WXF?b6$LdD z?E+6O23JaosQ{P%(<+Lp(-b8|I%XCb(1HOdt*vJCgrG^2^?SUFngas{NG+b5ZF5?_ znx5L8|8{DPDXJ?i6&8oXwAt=+qN{Zr64R>TvL@hJ=}5P0@Q4y-ImVz;IgVD{KyJ7m1x9@bz~*Nx@7Now z%41f+hbyM6E^qWUiw^g>m81SF`?xM)VnmP-Bo+vif(jHFHVG{{%+oQ)>ci&TpT;;B zoIDoGd3UMyzARW-G(Vzi+akfht8qE$8+4y`we-hy$FHqU^B{7&_<6i3*1E-Mf489~6AKWkm07Z4Wrsb)Azu`#qtQ16fH8)!My9+C7l0Yd1A%dv} zmw!rH0PDv#@=94Q%{XKpT(L%8Sn;_4S-MISQ>`GUabIT;~^ow3Dx>}C%@$aVJs!}c>)obyRoQRssx(x^a@$PsyF z^|&Dc;6~au4&P++Bs_PGShQNBju?X;;_Vk74JCC;nwj0F+%9N-4J zwvK$5Q0WH-Q2qyt%hh8y)EV_5h@yEv@S%sp&_lr!uF?~ELjgcK%5y&hAq%6S5;&8R zdhGhITrrj4*Rwq#!FIu;K_;>N!ag4*QHB)cWrDbY0p69-6}+gx$4HzD?l0V{U(DqUE;L+ z93zrFbR!|`e#vT+huxhUm0DGC`Sd9UgD3_eZ5ai5UJxQ_s&;Jup2Ls-b`d_l3{^17 zaPu}jW)5(W=0Z?!8>lr0mZIU7l<|*_E)@hJp}j--xuT-(KvNUKqKwG%3r2cVQXOd* z{|cP>WY@`y-daS;qLJS;`fEuYD^ISUH-XE#`<)Zr-}iPq=yqlnLVu0MRG`0x2D Date: Tue, 26 May 2020 16:25:40 +0800 Subject: [PATCH 30/34] Change gRCP category. --- src/apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps.json b/src/apps.json index d116e01c8..5f88fbe6e 100644 --- a/src/apps.json +++ b/src/apps.json @@ -4666,7 +4666,7 @@ }, "gRPC": { "cats": [ - 19 + 18 ], "icon": "gRPC.png", "headers": { From 1b3eff362645c201c83894babde94a26c36ace82 Mon Sep 17 00:00:00 2001 From: Behzad Soleimani Neisyani Date: Tue, 26 May 2020 19:47:22 +0430 Subject: [PATCH 31/34] Update apps.json - add sotel platform Add Sotel platform as ac Software as a Service on the cloud for businesses. --- src/apps.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/apps.json b/src/apps.json index 2046355f5..e2a93002e 100644 --- a/src/apps.json +++ b/src/apps.json @@ -10272,6 +10272,16 @@ "script": "^/js/bundles/sonar\\.js?v=([\\d.]+)$\\;version:\\1", "website": "https://www.sonarqube.org/" }, + "Sotel": { + "cats": [ + 1 + ], + "icon": "Sotel.png", + "meta": { + "generator": "sotel" + }, + "website": "https://www.soteledu.com/en/" + }, "SoundManager": { "cats": [ 59 From 3913d57edffb827268d09e545e9e53cabea03ae5 Mon Sep 17 00:00:00 2001 From: Behzad Soleimani Neisyani Date: Tue, 26 May 2020 19:50:48 +0430 Subject: [PATCH 32/34] Create Sotel.png Add icon of Sotel platform --- src/icons/Sotel.png | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/icons/Sotel.png diff --git a/src/icons/Sotel.png b/src/icons/Sotel.png new file mode 100644 index 000000000..4f8ae1787 --- /dev/null +++ b/src/icons/Sotel.png @@ -0,0 +1,67 @@ +‰PNG + + +IHDR @ @ ھiqق gAMA ±ژ|ûQ“ cHRM ‡ Œ ‎R پ@ }y é‹ <ه جs<…w +9iCCPPhotoshop ICC profile Hا‌–wTTׇد½wz،ح0R†ق»ہ ز{“^Eaک`(34±!¢EDڑ"HPؤ€رP$VD±T°$(1ET,oFض‹®¬¼÷ٍٍûم¬oي³÷¹ûى½دZ ’§/——Kگتًƒ<œé‘Qtى €`€) LVF؛_°{ةثح…‍!r_ًzX¼pسذ3€Nےں¤Yé|پèک ›³9,ˆ8%Kگ.¶دٹک—,f%f¾(Aث‰9a‘ +>û,²£کظ©<¶ˆإ9§³Sظbîٌ¶L!Gؤˆ¯ˆ 3¹œ,ك±Fٹ0•+â7âطT3 IlpX‰"61‰ن"âه àH _qـW,àd ؤ—rIKدلst–.فشعڑA÷نd¥pأ &+™ةgس]زRس™¼ ïüY2âعزEE¶4µ¶´4432‎ھPےuَoJـغEzّ¹g­ے‹ي¯üز `ج‰j³َ‹-® +€خ- بفûbس8 €¤¨o×؟؛Mîڈٍذ]9ٌLaٹ€.®+-%Mب§g¤3Y؛لں‡ّ‏uAœxںأE„‰¦ŒثKµ›او +¸i<:—÷ںڑّأ‏¤إ¹‰زّPcŒ€شu*@~ي( + رûإ]ے£o¾ّ0 ~yل*“‹sےï7‎gء¥â%ƒ›ً9خ%(„خٍ3÷ؤد H*گت@è C`¬€-pnہّƒ VH©€²@ط +A1ط ِ€jPA3hاA'8خƒKà¸nƒû`L€g`¼ a!2Dپن!Hز‡ج d¹A¾P إB Byذf¨*ƒھ،z¨ْ: ‌‡®@ƒذ]h ڑ†~‡قءL‚©°¬أ ط ِپCàUp¼خ… àp%ـ …;àًَ5ّ6< +?ƒç€¢ٹ" ؤٌG¢گx„ڈ¬Gٹگ +¤iE؛‘>ن&2ٹج oQEG¢lQ‍¨P µµU‚ھFFu zQ7Qc¨YشG4­ˆضGغ ½ذèt؛]پnB·£/¢o£'ذ¯1 +£چ±آxb"1Iکµکج>Lوf3ژ™أb±ٍX}¬ضثؤ +°…ط*ىQىYىvûGؤ©àجpî¸(—ڈ«ہء‌ء +ل&q x)¼&قïڈgمsً¥ّF|7‏:~؟@گ&hى!„$آ&B%،•p‘ً€ً’H$ھ­‰پD.q#±’xŒx™8F|K’!é‘\Hر$!iééé.é%™Lض";’£بٍr3ùùùچEآHآK‚-±A¢F¢CbHâ¹$^RSزIrµd®d…ن ةë’3Rx)-))¦شz©©“R#RsزiSiéTéé#زW¤§d°2Z2n2l™™ƒ2dئ)E‌âBaQ6S))T U›êEM¢S؟£Pgeed—ة†ةfثضب‍–¥!4-ڑ-…VJ;N¦½[¢´ؤi gةِ%­K†–جث-•s”مبةµةف–{'O—w“O–ك%ك)ےP¥ §¨گ¥°_ل¢آجRêRغ¥¬¥EKڈ/½§+ê))®U<¨ط¯8§¤¬ن،”®T¥tAiF™¦ى¨œ¤\®|FyZ…¢b¯آU)W9«ٍ”.Kw¢§ذ+é½ôYUEUOU،j½ê€ê‚ڑ¶Z¨Z¾Z›عCu‚:C=^½\½G}VCEأO#O£Eم‍&^“،™¨¹W³Os^K[+\k«V§ض”¶œ¶—v®v‹ِ²ژƒخ‌‌[؛]†n²î>فz°‍…^¢^چقu}XكRں«؟Oذ m`mہ3h01$:f¶ژرŒ|چٍچ:چ‍kGï2î3‏hba’bزhrكTئشغ4ك´غôw3=3–Yچظ-s²¹»ùَ.َثô—q–ي_vا‚bلg±ص¢ا⃥•%ك²صrعJأ*ضھضj„Ae0J—­رضخض¬OY؟µ±´ط·ùحضذ6ظِˆيشrيهœهچثايشىکvُv£ِtûXûِ£ھL‡‡اژêژlا&اI']§$§£Nد‌Mœùخيخَ.6.ë\خ¹"®®E®n2n،nصnڈـصــ[ـg=,<ضzœَD{ْxîٌٍRٍby5{حz[y¯َîُ!ùûTû<ِصَهûvûء~ق~»‎¬ذ\ء[رéü½üwû? ذXًc &0 °&ًIگiP^P_0%8&ّHًëçگزگû،:،آذ‍0ة°è°و°ùp×ً²ًرمˆu×""¹‘]Qط¨°¨¦¨¹•n+÷¬œˆ¶ˆ.Œ^¥½*{ص•ص +«SVںژ‘ŒaئœˆEا†ا‰}دôg60çâ¼âjمfY.¬½¬glGv9{ڑcا)مLئغإ—إO%ط%ىNکNtH¬Hœل؛p«¹/’<“ê’و“‎“%J OiKإ¥ئ¦‍نةً’y½iتiظiƒéْé…é£klضىY3ث÷ل7e@«2؛TردT؟PG¸E8–iںY“ù&+,ëD¶t6/»?G/g{خd®{î·kQkYk{ٍTَ6هچ­sZW؟Z·¾gƒْ†‚ +=6قDط”¼é§|“ü²üW›أ7w(l,كâ±¥¥P¢گ_8²صvkف6ش6î¶پيوغ«¶,b]-6)®(~_آ*¹ْچé7•ك|ع؟c ش²tےNجNقخل]»—I—ه–چïِغفQN//*µ'fد•ٹeu{ {…{G+}+»ھ4ھvV½¯N¬¾]م\سV«X»½v~{كذ~ا‎­uJuإuïpـ©÷¨ïhذj¨8ˆ9کyًIcXcك·Œo››ڑٹ›>â=t¸·ظھ¹ùˆâ‘ز¸Eط2}4ْèچï\؟ëj5l­o£µا„ا‍~û‎ًqںم=''Zذü،¶‌ز^شuنtجv&vژvEv +‍ô>ظسmغف‏£رڈ‡N©‍ھ9-{؛ô لLء™Ogsدخ‌K?7s>لüxOLد‎ nُِ\ô¹xù’û¥ }N}g/غ]>uإوتة«Œ«‌×,¯uô[ô·ےdٌSû€ه@اu«ë]7¬ot.<3ن0t‏¦ëحK·¼n]»½âِàpèً‌‘è‘ر;ى;SwS—yoل‏ئèE¥Vْïاہ9@~ئ`@\‰أh0êƒفcëرڈًèعaTŒh +شمت ?ء-سے€K¢~Fg(üMَ@‎VŒخ™ھڈ N<س“Aٌ§pGع°rامّpےَhُص# +pٍ‌‎ˆx±؟n3جü—›2 #³خؤضٹڈ±§fƒ~††Xrêèں6¯صتںغإطŒéƒ_ا çP\4وhٌ×±ش%qDء'%/©ج؟¾ôïـ¯‡أ–JH€.\>لاH´تyفأبr+œ¹¬ج§ڈœ:ْو Yeaْ÷—صGôAâànحêXد™d1ظ0kؤ÷T}epXSà µàح‌O¢ّب»je°­Œ? +سNG~ت‎تîQ¤³چTy¢¬!ع}}ر8V2"–ٍbKkك«Dïhkقz ّë#ہَK¸¨,×ژµ4j‘b(J:œ ©ِLL.کKàQ§œhu¢¦­ص®R~NQدٌ…ـک^4ة ™ê÷‍ً…+B¯لژا±¦Q3ِù£>|k ~½£7r_ـش7ءذ»ِî >yHb‰ث lكى,ضژإإz 9ّى_عXpع30½ًU´أFه'›DڈüRگ0,s"¹"A=ق6شé <¬{ـًFٌذA/‌ثپ4‡ٌü?<±‍£²½; ب< p¦§xپظ„9پh”yةGgسمoعù'@vr!چs¨!كqٹ،$F…è„ل0چe¼«)bْU…bh£لح~‏¦•وp\¢£ڑم +’*½ w  ; +¨«$0ن…ٌs è³–ے²YèI•â5ْEفأNqس® +;Bشa¶³ˆ$éذG؛اے”z:\:^nي ++‌dئجL.گ‡G8Hما$›1ـء9ِ‚قPDـْ+à¼yہک‰ہآûپة3ُƒ9Tf<±¦rp…EےGba&ژQe‎ِ½DEzâ µT‍¯•¸وœ6ينeش¤pإçؤE‰Hم±;ئ§àîرةع½ wHgwْ™ہOGEَ؟ہ·¯àىع±Œي8ة6®@€dّآcع±n`6Y،&T´P °ٹ[Eë~n%8ز²ڈüذآUصع +~ص¦¥œھ;xK~b×>Oد°ل‌ط5+ دLHEژDIذ»”\—ذ.‎ +ٌ†*¼^(نcءpض££@+'¢:B~ھٹ%ٌ™•ZعtAT‰ ؛ُ <•j4 f–H‹ع+HS$)’éب‡ةط}è^مo;™nâ pO»÷4'غŒطجتàچ*H4گاïg¥Y1‡Né +=; ٍ0ًٍ“شùù…Rèh§rمق`¦‡9y•tdXVFf~»ةغ"K®چ + ’>¨…OH­}eeüç4(ش + œ8ç ³°pB£6~ں”iإ¦ؤّdخµtم ~½çf–»دةZ$$!;ظغ™›RنôvGبيT»uم²:¢¦ح=¥ِ366cs­ںsèê4ن?Dûd!¤S¢0R QJ!‎–™aإ¾¹ظب²v^”خّّ-زىmˆںŒ#ئ"‍گ£¯ +ٌ²‎0î£گٍ—™K6‚‘;؟T…ــح<µ²K{ٌ}°ےک]ـˆُet أ؛ë-ڈA¦#FK9ن.…+i– +#&ùٹ=‍ق:ىاeEIxç,êفcا°ڑئ›èل9—ھ_»E9سaلN†wf¶îˆvًإAآKع ,خù¼ں—÷àYq/ه4›¤¥Sزp[Aد•¤>إ*fèُ¹f5{Uxث]H*^é#Dِ.¾¨(£#X $M"”§‡¾>¥^ّ†0a]=ِشرةة‍ذ !ؤ§¦¥مخآ‍¨Nض°’ه©صزôiµْ¥دب<µ¸ég@”¶~® سن›4^°{Nئ âêٹ”¸ؤ0پU!¼  ïئ ژ¬>خ®‌ُJظںvتا“Gظ~E¹`„¢9¨ôژH4¤„"uژ¹Qش*”Bqيxoµ؛^ءëG•9إMْبI`ثo¥y·‏EQژqہع©ث1ëَ0Y»0mمJ¹کpRن.é™طك°د}~7%¯ءˆV“•D­`ءّQ™x%¬0c\²‘ٹذ€$7³¤_أي{\ّثّ“Hغv<ثٹvc-‰Z{~yجû»î’L}ُ"{¸éI!ؤ\}ç5’ë?5r¥€آص?ؤڑqVl<ô.ح]†·ـڈ™أوcsùûبIH@rل]¸ًمF +ب¢ژ؟$غ†[sيکب6 ّˆ/JَB™“.’ؤ×‍Feأù+”‌w®S‚چ~%ïc jeل|إ³ï ¥1ع¬4ûj•—ٹïW¶W®VZ‎ +J ش¬x¢ٹ2tU‌ٍfچ_y·ض¯¼XهSً´‍Z +›9ةRيَة"âW”ح÷*تsE)}Cشpl©‌c3à™†`‌_‎j×V"شHrë|‡غ@âبs{P‎و!mً‰G)¨×> $ه!ة‘‰TS5îDK ‡›wSك$"ءڑژ+¼Hg){¸ج‡[¶µâ¦üDٍ|،Vُ`vRŒ¶ءx؛ـ عڈ;‹¸<كژµµAـXگJ{¶àç_ـ'eصaخ=G›@Oً°O©فہkط½6s.1¦نکy³iثq‍ë¤إذƒڈoCغِ&Xط_اXnbق¬tŒsl:ىNXسlى8#:$cz.ک2بڑ5ِ\b،¨ +ٹحژ،×¼ƒؤ—¥à¤ھٌ=CA%‎ئ–VضQDxbں›و$bz¢r-‰êYàJJô0ù¤ëCS*‚ +نڑ*ھQê‰کْbj’‍ô,Qےخ*6‌¥wr€ ـؤ¾ٹn ہڑڑ N>‰#Nءم&§LFr‰‚3‍‍چئ5•*¯ؤ‎ad_X„عwث, ؟c’‏‹§ژ6D1?أGپEزعHلu چت™¦%ؤ¨*vھق +’.ُˆ§h،“–7سIRپؤ)“îe[»~لq¨ًW¸لعق Kھ +gç1ô]8ü§]7aIOàIعةع“; +ژ#êcىⳑ4,5ïزمtŒ%ظدءV »}‚vء@ءu 8ّ*›!تoy`jثàFSFk®XZa縑ص‚­5k9/’Tه|½ن€آث€sںZKک»ƒةGعCc,إ،'w ٍچ8ْز>T.? çک ½m<‹œtآٌ7¼عîصژKBCF¤-¥q¦P_چwùآّ×—صhlcnِ†TzضbîGq•¹ع›Ijع’ثvJq‰2پ©&«ق‏*-Ni.ئçںدv’„\اtّb»ـ‡¹ے +ûِ>„é¶I7<ط¸®ِA(4ت_îFٍکt8Oد€s|yAپ¯¼Mحûژaنœ?ضL;’G¦"}Z.÷iْر‍!خ|cأüîچفx}}9ضUڈ7® &‎IOڈگ÷YS¸ْ)ہگ 8 S€]§ڈعقـللGœ،< z%p&چ–َ7‎œé±[مژ9هèl.~ +£ے¨›aخ‹i›ءB#¹IJج ¢\فمfëà€8Fد ک-}O+7ءه‹×ل‍—¾TW؟–<³zg +½²Cy5S©7ب#َQك×؟¾6;FgHجئ‏ˆآبGبµFع*)ؤJ$0و]6¾ز6•à"ma5Œsو"â +لہ¶¢mO¯1wZ}ùD&ذ¾ôn«آE¬ئ]/ذًي5ê“‌¬T;’ىd¥طو=×ىھأ¢Wwà[÷}‚هںض¯ى +2“n/i a ث¦Woذؤ!R=b,ح>’bِ™ê°J‚µ–£qul ç!×ژFB~2J~؟قR‰حتhزŒWלى/هR4آدجFت8فأفà³½ُxàµ](op£‍µ³د°wy"س،HŒع ٹL’éگL~5,وں]¨يءfٍء=$ءح my»شaQâىC$E’ +€َ_،Sىjîاkضأک2کF. ·+ƒءz ش ‹سٹٹ×JPûقaX3Xh¼pCشدqI´F8 +‌شëf‎`¼ْ¹+J*غpثس›PرàC«7چمû +qD C +S0;%ڈق<Nîو"ü\هدXعjדY!ج4ز(a®G…شçگ‹2w80w9X¾‎5Lsٍ@b®zت1´أ_هإî;ضآت¾[آ>ـRW'q„l6‹ ™N^‎هLLظ!⢬ صëXقôع/%®e¯v?)™¢¤†ûط‎چ؛کLِoo‚ttr€ً@écغà9à"ëبôن\P€ü«F02l\‎îأ׈à{ڈnہ†¼J+چ¶v©‎پpD8¬½ .جIئكï:§êGVYفنY K_”ط¸…زû):d§¶زٍ²إح‏لٍM {†tr@ˆ5ëُے¢ض`è3Fف=U-q=پ#®üs¬طXخfئ¢و·…1P†wE4Gگژ‌8, ++ï™…¢A'x$Iتں4Dآش(³)§¥)زqجى~Qُت^T­<¤=‏ 6 +'ہ‌فŒgق)پحfb®عXأ؟9أ»B}ٹہم cو„¼uïVو~OطB\¶jE¸ژM’Cثءq„cطٍفTasو³sصƒفAJصïںكئ#Ae8`îہےnبج]ق ن©‹خ+آٍ_ںƒ4.F·ط»”Uàv„·±ü‍–ké|ج!6Aإكyç®؟†حس×s‎uضو—×”!•­r”U،¸¤ATدUےdه?¹³pC½+€8qح¼Qَّآiبpvز—,‏‹:C ­:@<ذ°ê(<û[0âgا»8!ں—>9„;‏¼‘V?ئژثءشQ™ppُح,5›6àPµG•° }Mفç‌ذكô‘ث¥C­a%ûŒغوڈءƒ×MB^z—w/³o¸ڑـàذتھو Nèً²¯0üGمصءvl9ط„›—|†²7)6ؤ(حl…'چHGAf"RV4P*o¤‍÷“œنïy;¦DŒn‰َ÷إfyَ«½رس آھ‎›¸D>‰#ؤظ‹‏:Yn‘ûù8O¥“ة/’('uèQê)ڑZِ §1ن>يhْ´Ys¨ڑ؛ءژأ-X¸t Jھ]œ”ق`…Y2q؛ڑNêپي‡Z°·آ…™Zق–ثoZX +¥*XLLîé;و¨™t¦“Q$¯تهOc‎،8فA´ùBŒ:حiBtF lٍطf‏†8W ;¨B‏D†÷-جq`ة-Spل$‎qZWىcˆ³5َؤü–ث‍ں¾ْ¨nxü3|؛§‍قŒھBQ‰S†g 7فث¦pأِ2تS.g:چœ79“y| ;½‚¬$ص9’m”F‰پrg‰ ±ةLgظD8±”6{B(­nأ‍ٹ6¬ظQ‹ƒüىçu­ق0¼شVٍژˆ#3ï¯U„¨*‏ٍس¸مزر¸‎b¶د'B ٌX“tŒ{C“;„ï.^‹i§eaTA*‍'7ىçٹ7·0ڑ!6oت`ŒبMئl†] H&هٍE°«¼_jئ‏ھ6T4ْک£Ax‎l؛ôصRمگ¢+‘Nحوuy‰8mp +ئ¥`وiظHI²1ڈي8\ëءgûêٌو¦J2G¼ً3­lش +™ژW°g¸ءxص9'ƒ>; ،چ2÷ء58oB.؛Yë¤‏ûa¾=1sh¸ƒ“©lٍمق—·£xں<ں سسfµ›Ilل +[¸jF}kدl!/y¾"a,Q"،e…W[¢©hx:.b/pي¬"dبS§@om:ٹOwصâL.ب¢ش(<œ„‚ّîo×0²ٌ‡v‏ںî{a‍e/?ydrط¼¼ٍI)rطحI¥P­نْtھcع¯مô$ü%ô£>fv§×حٹ—~رثSل>¢{FéRëµ|m_·مXْ^‰–Eظ6- H`'d)F‹{OئxA§ëxكDFPNھùCRشٌe¦كZ®‏@ ïà™Fوj´›€±3Omœنٌr§@بOت&Uہة4H wک}vہع‌µ8Pçإغھًلض*صطمّ†¬îيژ(ôة¥Bùè êY ِ²4‎ُ£ƒ¨néغk³vHâˆ‍9¶éc’Q]اے‌è“ن©ژ”Auv#BJQ +–‍ ©89YQغ×^_C‡U×{Q]مAuµ›[?·،J>ث£«؛رOM/‚(¬ + yîط³S&ْTd2O½»÷½؛SUvY8×خھ نق°‚ê0†ëf‘°,xâ»9Jكئb(’ٹ‰Cس0ap2Fن$©df¥h’ùثهêح97إOe³‡è¤½ى/¶—µ •%•7„چJ3•›”ر•c€÷Zُذ·1‌%°؟èstsU¾¢ً‘ْ}…ڈ‌¤×ژ¼ےپfFب¼©y¬é5b~’—°ˆٍCˆژdة_~Zکyے¼e.زم’‚6éض|Q¼خص_Qوإî£>ہإتA'¨N‘–OْظK4¨؟س.5d“h،­ê^ —rPوظ1¯( × Kئ¹yٍ™°¯گë و€î، ؤAqچ%-!”{#ـ³“s‡لVے¤•·fî'3ZF¦XQؤmX²£س¬کک•€)ظlpئخٌ +;àے;€ےز؟؛ُO— IEND®B`‚ From cb1668fb042729ab65a4e04b501e5069e294ed0c Mon Sep 17 00:00:00 2001 From: Elbert Alias <77259+AliasIO@users.noreply.github.com> Date: Thu, 28 May 2020 08:57:53 +1000 Subject: [PATCH 33/34] Add alerts, fix dark mode --- .../webextension/_locales/ca/messages.json | 1 + .../webextension/_locales/de/messages.json | 2 + .../webextension/_locales/el/messages.json | 2 + .../webextension/_locales/en/messages.json | 1 + .../webextension/_locales/es/messages.json | 2 + .../webextension/_locales/fa/messages.json | 2 + .../webextension/_locales/fr/messages.json | 2 + .../webextension/_locales/gl_ES/messages.json | 1 + .../webextension/_locales/gr/messages.json | 2 + .../webextension/_locales/id/messages.json | 2 + .../webextension/_locales/it/messages.json | 2 + .../webextension/_locales/ja/messages.json | 1 + .../webextension/_locales/pl/messages.json | 2 + .../webextension/_locales/pt/messages.json | 1 + .../webextension/_locales/pt_BR/messages.json | 2 + .../webextension/_locales/ro/messages.json | 2 + .../webextension/_locales/ru/messages.json | 2 + .../webextension/_locales/sk/messages.json | 2 + .../webextension/_locales/tr/messages.json | 2 + .../webextension/_locales/uk/messages.json | 2 + .../webextension/_locales/uz/messages.json | 2 + .../webextension/_locales/zh_CN/messages.json | 1 + .../webextension/_locales/zh_TW/messages.json | 2 + src/drivers/webextension/css/popup.css | 108 ++-- src/drivers/webextension/html/popup.html | 10 +- src/drivers/webextension/js/driver.js | 339 ++++++----- src/drivers/webextension/js/options.js | 86 +-- src/drivers/webextension/js/popup.js | 327 ++++++----- src/wappalyzer.js | 538 ++++++++++-------- 29 files changed, 829 insertions(+), 619 deletions(-) diff --git a/src/drivers/webextension/_locales/ca/messages.json b/src/drivers/webextension/_locales/ca/messages.json index 825dcf3e4..721464c9d 100644 --- a/src/drivers/webextension/_locales/ca/messages.json +++ b/src/drivers/webextension/_locales/ca/messages.json @@ -15,6 +15,7 @@ "termsAccept": { "message": "Acceptar" }, "termsContent": { "message": "Aquesta extensió envia informació anònima sobre els llocs web que visiteu, inclosos el nom de domini i les tecnologies identificades a wappalyzer.com. Això pot desactivar-se a Opcions." }, "privacyPolicy": { "message": "Política de privadesa" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Taulers de missatgeria" }, "categoryName3": { "message": "Gestor de bases de dades" }, diff --git a/src/drivers/webextension/_locales/de/messages.json b/src/drivers/webextension/_locales/de/messages.json index f49ecc216..847dbf1fa 100644 --- a/src/drivers/webextension/_locales/de/messages.json +++ b/src/drivers/webextension/_locales/de/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Immer Icon anzeigen" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Nachrichten Board" }, "categoryName3": { "message": "Datenbankverwaltung" }, diff --git a/src/drivers/webextension/_locales/el/messages.json b/src/drivers/webextension/_locales/el/messages.json index 6f46ccd03..766f7f9b7 100644 --- a/src/drivers/webextension/_locales/el/messages.json +++ b/src/drivers/webextension/_locales/el/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Always show icon" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Διαδικτυακό Φόρουμ" }, "categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" }, diff --git a/src/drivers/webextension/_locales/en/messages.json b/src/drivers/webextension/_locales/en/messages.json index c2b6245c7..f65fc1a43 100644 --- a/src/drivers/webextension/_locales/en/messages.json +++ b/src/drivers/webextension/_locales/en/messages.json @@ -15,6 +15,7 @@ "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Message boards" }, "categoryName3": { "message": "Database managers" }, diff --git a/src/drivers/webextension/_locales/es/messages.json b/src/drivers/webextension/_locales/es/messages.json index ee0a480ee..14d102648 100644 --- a/src/drivers/webextension/_locales/es/messages.json +++ b/src/drivers/webextension/_locales/es/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Always show icon" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "Gestor de Contenido" }, "categoryName2": { "message": "Foro" }, "categoryName3": { "message": "Gestor de Bases de Datos" }, diff --git a/src/drivers/webextension/_locales/fa/messages.json b/src/drivers/webextension/_locales/fa/messages.json index 1407f089b..adb30b530 100644 --- a/src/drivers/webextension/_locales/fa/messages.json +++ b/src/drivers/webextension/_locales/fa/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "همیشه نماد را نشان بده" }, "termsAccept": { "message": "قبول" }, "termsContent": { "message": "این افزونه اطلاعات وب‌سایت‌های بازدید شده توسط شما را به صورت ناشناس ارسال می‌کند، مانند آدرس سایت و تکنولوژی‌های استفاده شده در آن سایت را ارسال می‌کند. اطلاعات بیشتر در wappalyzer.com. شما می‌توانید این افزونه را غیرفعال کنید." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "سیستم مدیریت محتوا" }, "categoryName2": { "message": "انجمن پیام" }, "categoryName3": { "message": "مدیریت پایگاه داده" }, diff --git a/src/drivers/webextension/_locales/fr/messages.json b/src/drivers/webextension/_locales/fr/messages.json index 88a4ba138..37fd1c2ce 100644 --- a/src/drivers/webextension/_locales/fr/messages.json +++ b/src/drivers/webextension/_locales/fr/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": " Toujours afficher l'icône" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Forum" }, "categoryName3": { "message": "Gestionnaire de base de données" }, diff --git a/src/drivers/webextension/_locales/gl_ES/messages.json b/src/drivers/webextension/_locales/gl_ES/messages.json index 6e54050a1..795060901 100644 --- a/src/drivers/webextension/_locales/gl_ES/messages.json +++ b/src/drivers/webextension/_locales/gl_ES/messages.json @@ -15,6 +15,7 @@ "termsAccept": { "message": "Aceptar" }, "termsContent": { "message": "Esta extensión envía anonimamente información acerca das webs que visitas, incluindo dominio e aplicativos identificados, a wappalyzer.com. Isto pode ser desactivado nas preferencias." }, "privacyPolicy": { "message": "Política de privacidade" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Taboleiro de mensaxes" }, "categoryName3": { "message": "Xestor de base de datos" }, diff --git a/src/drivers/webextension/_locales/gr/messages.json b/src/drivers/webextension/_locales/gr/messages.json index 6dceaf22c..b631044ee 100644 --- a/src/drivers/webextension/_locales/gr/messages.json +++ b/src/drivers/webextension/_locales/gr/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Always show icon" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Διαδικτυακό Φόρουμ" }, "categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" }, diff --git a/src/drivers/webextension/_locales/id/messages.json b/src/drivers/webextension/_locales/id/messages.json index 31f4b64f7..11d46d599 100644 --- a/src/drivers/webextension/_locales/id/messages.json +++ b/src/drivers/webextension/_locales/id/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Always show icon" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "Sistem Pengelola Konten" }, "categoryName2": { "message": "Papan Pesan" }, "categoryName3": { "message": "Pengelola Basis Data" }, diff --git a/src/drivers/webextension/_locales/it/messages.json b/src/drivers/webextension/_locales/it/messages.json index 0f6f656d1..27882408a 100644 --- a/src/drivers/webextension/_locales/it/messages.json +++ b/src/drivers/webextension/_locales/it/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Always show icon" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Forum" }, "categoryName3": { "message": "Gestore di Database" }, diff --git a/src/drivers/webextension/_locales/ja/messages.json b/src/drivers/webextension/_locales/ja/messages.json index 362b88f5f..666d4d957 100644 --- a/src/drivers/webextension/_locales/ja/messages.json +++ b/src/drivers/webextension/_locales/ja/messages.json @@ -15,6 +15,7 @@ "termsAccept": { "message": "受諾する" }, "termsContent": { "message": "この拡張機能は、ドメイン名や特定された技術など、アクセスしたWebサイトに関する匿名情報をwappalyzer.comに送信します。これは設定で無効にできます。" }, "privacyPolicy": { "message": "プライバシーポリシー" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "メッセージボード" }, "categoryName3": { "message": "データベースマネージャー" }, diff --git a/src/drivers/webextension/_locales/pl/messages.json b/src/drivers/webextension/_locales/pl/messages.json index b04f2400e..90e83acfd 100644 --- a/src/drivers/webextension/_locales/pl/messages.json +++ b/src/drivers/webextension/_locales/pl/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Zawsze pokazuj tą ikonę" }, "termsAccept": { "message": "Akceptuj" }, "termsContent": { "message": "To rozszerzenie wysyła anonimowe informacje o stronach, które odwiedzasz, uwzględniając nazwy domen i zidentyfikowane technologie do wappalyzer.com. Opcja może zostać wyłączona w ustawieniach." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "System zarządzania treścią" }, "categoryName2": { "message": "Forum" }, "categoryName3": { "message": "Menedżer baz danych" }, diff --git a/src/drivers/webextension/_locales/pt/messages.json b/src/drivers/webextension/_locales/pt/messages.json index e358292b1..a7fd7a55a 100644 --- a/src/drivers/webextension/_locales/pt/messages.json +++ b/src/drivers/webextension/_locales/pt/messages.json @@ -15,6 +15,7 @@ "termsAccept": { "message": "Aceitar" }, "termsContent": { "message": "Esta extensão envia informações anónimas sobre os sites que visitas, incluindo o nome de domínio e as tecnologias identificadas, para o wappalyzer.com. Isso pode ser desativado nas configurações." }, "privacyPolicy": { "message": "Políticas de Privacidade" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Fórum" }, "categoryName3": { "message": "Gestor de Base de Dados" }, diff --git a/src/drivers/webextension/_locales/pt_BR/messages.json b/src/drivers/webextension/_locales/pt_BR/messages.json index 217d81b16..e32b108aa 100644 --- a/src/drivers/webextension/_locales/pt_BR/messages.json +++ b/src/drivers/webextension/_locales/pt_BR/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Sempre mostrar ícone" }, "termsAccept": { "message": "Aceitar" }, "termsContent": { "message": "Esta extensão envia informações anônimas sobre os sites que você visita, incluindo domínio e tecnologias identificadas para wappalyzer.com. Este comportamento pode ser desativado nas configurações." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Fórum" }, "categoryName3": { "message": "Gestão de Banco de Dados" }, diff --git a/src/drivers/webextension/_locales/ro/messages.json b/src/drivers/webextension/_locales/ro/messages.json index 68415aa06..a3036e74a 100644 --- a/src/drivers/webextension/_locales/ro/messages.json +++ b/src/drivers/webextension/_locales/ro/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Afișează icon tot timpul" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Forum de discuții" }, "categoryName3": { "message": "Manager baze de date" }, diff --git a/src/drivers/webextension/_locales/ru/messages.json b/src/drivers/webextension/_locales/ru/messages.json index 6d7a691fb..1c73c5907 100644 --- a/src/drivers/webextension/_locales/ru/messages.json +++ b/src/drivers/webextension/_locales/ru/messages.json @@ -67,6 +67,8 @@ "categoryPin": { "message": "Always show icon" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName54": { "message": "SEO" }, "categoryName55": { "message": "Бухгалтерский учёт" }, "categoryName56": { "message": "Криптомайнер" }, diff --git a/src/drivers/webextension/_locales/sk/messages.json b/src/drivers/webextension/_locales/sk/messages.json index e07d4c928..b9ed2ce77 100644 --- a/src/drivers/webextension/_locales/sk/messages.json +++ b/src/drivers/webextension/_locales/sk/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Always show icon" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Message Board" }, "categoryName3": { "message": "Správca databáz" }, diff --git a/src/drivers/webextension/_locales/tr/messages.json b/src/drivers/webextension/_locales/tr/messages.json index 5ded59dd2..63167726a 100644 --- a/src/drivers/webextension/_locales/tr/messages.json +++ b/src/drivers/webextension/_locales/tr/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Her zaman bu kategorinin ikonunu kullan" }, "termsAccept": { "message": "Kabul Ediyorum" }, "termsContent": { "message": "Bu eklenti, ziyaret ettiğiniz web site bilgilerini, alan adları ve tespit edilen teknolojiler ile beraber anonim olarak wappalyzer.com'a gönderir. Bunu, eklenti ayarlarından değiştirebilirsiniz." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "İçerik Yönetim Sistemi" }, "categoryName2": { "message": "Mesaj Tahtası" }, "categoryName3": { "message": "Veritabanı Yöneticisi" }, diff --git a/src/drivers/webextension/_locales/uk/messages.json b/src/drivers/webextension/_locales/uk/messages.json index 176a02601..c8c28983f 100644 --- a/src/drivers/webextension/_locales/uk/messages.json +++ b/src/drivers/webextension/_locales/uk/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Always show icon" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS" }, "categoryName2": { "message": "Форум" }, "categoryName3": { "message": "Менеджер БД" }, diff --git a/src/drivers/webextension/_locales/uz/messages.json b/src/drivers/webextension/_locales/uz/messages.json index 6557c08d1..b0af1ba9f 100644 --- a/src/drivers/webextension/_locales/uz/messages.json +++ b/src/drivers/webextension/_locales/uz/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "Always show icon" }, "termsAccept": { "message": "Accept" }, "termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to wappalyzer.com. This can be disabled in the settings." }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "CMS (KBT)" }, "categoryName2": { "message": "Forum" }, "categoryName3": { "message": "MB boshqaruvi" }, diff --git a/src/drivers/webextension/_locales/zh_CN/messages.json b/src/drivers/webextension/_locales/zh_CN/messages.json index 270801b1a..2aadbda4c 100644 --- a/src/drivers/webextension/_locales/zh_CN/messages.json +++ b/src/drivers/webextension/_locales/zh_CN/messages.json @@ -15,6 +15,7 @@ "termsAccept": { "message": "接受" }, "termsContent": { "message": "此扩展程序发送关于您访问的网站的匿名信息至 wappalyzer.com,包含域名和检测到的技术。这可以在设置中禁用。" }, "privacyPolicy": { "message": "隐私政策" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "内容管理系统(CMS)" }, "categoryName2": { "message": "消息板" }, "categoryName3": { "message": "数据库管理器" }, diff --git a/src/drivers/webextension/_locales/zh_TW/messages.json b/src/drivers/webextension/_locales/zh_TW/messages.json index ac32f3009..9ca2612f3 100644 --- a/src/drivers/webextension/_locales/zh_TW/messages.json +++ b/src/drivers/webextension/_locales/zh_TW/messages.json @@ -14,6 +14,8 @@ "categoryPin": { "message": "永遠顯示圖示" }, "termsAccept": { "message": "接受" }, "termsContent": { "message": "這個擴充功能將你所造訪網站的網域名稱和識別到的技術等資訊,匿名傳送至 wappalyzer.com。你可以在選項中停用。" }, + "privacyPolicy": { "message": "Privacy policy" }, + "createAlert": { "message": "Create an alert for this website" }, "categoryName1": { "message": "內容管理系統(CMS)" }, "categoryName2": { "message": "留言板/討論區" }, "categoryName3": { "message": "資料庫管理" }, diff --git a/src/drivers/webextension/css/popup.css b/src/drivers/webextension/css/popup.css index c8968157c..14ecfd695 100644 --- a/src/drivers/webextension/css/popup.css +++ b/src/drivers/webextension/css/popup.css @@ -31,6 +31,24 @@ body { display: none; } +.footer { + align-items: center; + border-top: 1px solid #dbdbdb; + height: 3rem; + display: flex; + padding: 0 1.5rem; +} + +.footer__link { + color: #4608ad; + text-decoration: none; +} + +.footer__link:hover, .footer__link:active { + color: #4608ad; + text-decoration: underline; +} + .container { min-height: 5rem; padding: 1rem 1.5rem 0rem 1.5rem; @@ -202,50 +220,68 @@ body { margin-top: 1rem; } -/* Add alternative color palette for Dark mode theme. */ -body.theme-mode-sync { - background: linear-gradient(160deg, #32067c, #150233); -} +@media (prefers-color-scheme: dark) { + /* Add alternative color palette for Dark mode theme. */ + body.theme-mode-sync { + background: linear-gradient(160deg, #32067c, #150233); + } -.theme-mode-sync .header { - border-bottom: 1px solid #000; -} + .theme-mode-sync .header { + border-bottom: 1px solid rgba(255, 255, 255, .2); + } -.theme-mode-sync .header__logo--dark { - display: inline-block; -} + .theme-mode-sync .header__logo--dark { + display: inline-block; + } -.theme-mode-sync .header__logo--light { - display: none; -} + .theme-mode-sync .header__logo--light { + display: none; + } -.theme-mode-sync .container { - color: white; -} + .theme-mode-sync .footer { + border-top: 1px solid rgba(255, 255, 255, .2); + } -.theme-mode-sync .detected__category-link, .theme-mode-sync .detected__app { - color: white; -} + .theme-mode-sync .footer__link { + color: rgba(255, 255, 255, .8); + } -.theme-mode-sync .detected__category-link:hover { - color: white; - border-bottom: 1px solid white; -} + .theme-mode-sync .footer__link:hover, .theme-mode-sync .footer__link:active { + color: rgba(255, 255, 255, .8); + } -.theme-mode-sync .detected__app-version, .theme-mode-sync .detected__app-confidence { - background-color: #4608ad; -} + .theme-mode-sync .container { + color: white; + } -.theme-mode-sync .detected__app:hover .detected__app-name { - border-bottom: 1px solid white; -} + .theme-mode-sync .detected__category-link { + color: #fff; + } -.theme-mode-sync .detected__app:hover .theme-mode-sync .detected__app-version, -.theme-mode-sync .detected__app:hover .theme-mode-sync .detected__app-confidence { - border-bottom: none; -} + .theme-mode-sync .detected__app { + color: rgba(255, 255, 255, .8); + } -.theme-mode-sync .terms__accept, -.theme-mode-sync .terms__privacy { - color: white; + .theme-mode-sync .detected__category-link:hover { + color: white; + border-bottom: 1px solid white; + } + + .theme-mode-sync .detected__app-version, .theme-mode-sync .detected__app-confidence { + background-color: #4608ad; + } + + .theme-mode-sync .detected__app:hover .detected__app-name { + border-bottom: 1px solid white; + } + + .theme-mode-sync .detected__app:hover .theme-mode-sync .detected__app-version, + .theme-mode-sync .detected__app:hover .theme-mode-sync .detected__app-confidence { + border-bottom: none; + } + + .theme-mode-sync .terms__accept, + .theme-mode-sync .terms__privacy { + color: white; + } } diff --git a/src/drivers/webextension/html/popup.html b/src/drivers/webextension/html/popup.html index 730a1f496..15fdc91dd 100644 --- a/src/drivers/webextension/html/popup.html +++ b/src/drivers/webextension/html/popup.html @@ -14,8 +14,8 @@

@@ -24,11 +24,15 @@
- +
+ + diff --git a/src/drivers/webextension/js/driver.js b/src/drivers/webextension/js/driver.js index 84e4eae35..5a264616e 100644 --- a/src/drivers/webextension/js/driver.js +++ b/src/drivers/webextension/js/driver.js @@ -10,29 +10,29 @@ /** global: fetch */ /** global: Wappalyzer */ -const wappalyzer = new Wappalyzer(); +const wappalyzer = new Wappalyzer() -const tabCache = {}; -const robotsTxtQueue = {}; +const tabCache = {} +const robotsTxtQueue = {} -let categoryOrder = []; +let categoryOrder = [] browser.tabs.onRemoved.addListener((tabId) => { - tabCache[tabId] = null; -}); + tabCache[tabId] = null +}) function userAgent() { - const url = chrome.extension.getURL('/'); + const url = chrome.extension.getURL('/') if (url.match(/^moz-/)) { - return 'firefox'; + return 'firefox' } if (url.match(/^ms-browser-/)) { - return 'edge'; + return 'edge' } - return 'chrome'; + return 'chrome' } /** @@ -40,22 +40,22 @@ function userAgent() { */ function getOption(name, defaultValue = null) { return new Promise(async (resolve, reject) => { - let value = defaultValue; + let value = defaultValue try { - const option = await browser.storage.local.get(name); + const option = await browser.storage.local.get(name) if (option[name] !== undefined) { - value = option[name]; + value = option[name] } } catch (error) { - wappalyzer.log(error.message, 'driver', 'error'); + wappalyzer.log(error.message, 'driver', 'error') - return reject(error.message); + return reject(error.message) } - return resolve(value); - }); + return resolve(value) + }) } /** @@ -64,15 +64,15 @@ function getOption(name, defaultValue = null) { function setOption(name, value) { return new Promise(async (resolve, reject) => { try { - await browser.storage.local.set({ [name]: value }); + await browser.storage.local.set({ [name]: value }) } catch (error) { - wappalyzer.log(error.message, 'driver', 'error'); + wappalyzer.log(error.message, 'driver', 'error') - return reject(error.message); + return reject(error.message) } - return resolve(); - }); + return resolve() + }) } /** @@ -81,8 +81,8 @@ function setOption(name, value) { function openTab(args) { browser.tabs.create({ url: args.url, - active: args.background === undefined || !args.background, - }); + active: args.background === undefined || !args.background + }) } /** @@ -92,321 +92,346 @@ async function post(url, body) { try { const response = await fetch(url, { method: 'POST', - body: JSON.stringify(body), - }); + body: JSON.stringify(body) + }) - wappalyzer.log(`POST ${url}: ${response.status}`, 'driver'); + wappalyzer.log(`POST ${url}: ${response.status}`, 'driver') } catch (error) { - wappalyzer.log(`POST ${url}: ${error}`, 'driver', 'error'); + wappalyzer.log(`POST ${url}: ${error}`, 'driver', 'error') } } // Capture response headers -browser.webRequest.onCompleted.addListener(async (request) => { - const headers = {}; +browser.webRequest.onCompleted.addListener( + async (request) => { + const headers = {} - if (request.responseHeaders) { - const url = wappalyzer.parseUrl(request.url); + if (request.responseHeaders) { + const url = wappalyzer.parseUrl(request.url) - let tab; + let tab - try { - [tab] = await browser.tabs.query({ url: [url.href] }); - } catch (error) { - wappalyzer.log(error, 'driver', 'error'); - } + try { + ;[tab] = await browser.tabs.query({ url: [url.href] }) + } catch (error) { + wappalyzer.log(error, 'driver', 'error') + } - if (tab) { - request.responseHeaders.forEach((header) => { - const name = header.name.toLowerCase(); + if (tab) { + request.responseHeaders.forEach((header) => { + const name = header.name.toLowerCase() - headers[name] = headers[name] || []; + headers[name] = headers[name] || [] - headers[name].push((header.value || header.binaryValue || '').toString()); - }); + headers[name].push( + (header.value || header.binaryValue || '').toString() + ) + }) - if (headers['content-type'] && /\/x?html/.test(headers['content-type'][0])) { - wappalyzer.analyze(url, { headers }, { tab }); + if ( + headers['content-type'] && + /\/x?html/.test(headers['content-type'][0]) + ) { + wappalyzer.analyze(url, { headers }, { tab }) + } } } - } -}, { urls: ['http://*/*', 'https://*/*'], types: ['main_frame'] }, ['responseHeaders']); + }, + { urls: ['http://*/*', 'https://*/*'], types: ['main_frame'] }, + ['responseHeaders'] +) browser.runtime.onConnect.addListener((port) => { port.onMessage.addListener(async (message) => { if (message.id === undefined) { - return; + return } if (message.id !== 'log') { - wappalyzer.log(`Message from ${port.name}: ${message.id}`, 'driver'); + wappalyzer.log(`Message from ${port.name}: ${message.id}`, 'driver') } - const pinnedCategory = await getOption('pinnedCategory'); + const pinnedCategory = await getOption('pinnedCategory') - const url = wappalyzer.parseUrl(port.sender.tab ? port.sender.tab.url : ''); + const url = wappalyzer.parseUrl(port.sender.tab ? port.sender.tab.url : '') - const cookies = await browser.cookies.getAll({ domain: `.${url.hostname}`, firstPartyDomain: null }); + const cookies = await browser.cookies.getAll({ + domain: `.${url.hostname}`, + firstPartyDomain: null + }) - let response; + let response switch (message.id) { case 'log': - wappalyzer.log(message.subject, message.source); + wappalyzer.log(message.subject, message.source) - break; + break case 'init': - wappalyzer.analyze(url, { cookies }, { tab: port.sender.tab }); + wappalyzer.analyze(url, { cookies }, { tab: port.sender.tab }) - break; + break case 'analyze': if (message.subject.html) { - browser.i18n.detectLanguage(message.subject.html) + browser.i18n + .detectLanguage(message.subject.html) .then(({ languages }) => { const language = languages .filter(({ percentage }) => percentage >= 75) - .map(({ language: lang }) => lang)[0]; + .map(({ language: lang }) => lang)[0] - message.subject.language = language; + message.subject.language = language - wappalyzer.analyze(url, message.subject, { tab: port.sender.tab }); - }); + wappalyzer.analyze(url, message.subject, { tab: port.sender.tab }) + }) } else { - wappalyzer.analyze(url, message.subject, { tab: port.sender.tab }); + wappalyzer.analyze(url, message.subject, { tab: port.sender.tab }) } - await setOption('hostnameCache', wappalyzer.hostnameCache); + await setOption('hostnameCache', wappalyzer.hostnameCache) - break; + break case 'ad_log': - wappalyzer.cacheDetectedAds(message.subject); + wappalyzer.cacheDetectedAds(message.subject) - break; + break case 'get_apps': response = { tabCache: tabCache[message.tab.id], apps: wappalyzer.apps, categories: wappalyzer.categories, pinnedCategory, - termsAccepted: userAgent() === 'chrome' || await getOption('termsAccepted', false), - }; + termsAccepted: + userAgent() === 'chrome' || + (await getOption('termsAccepted', false)) + } - break; + break case 'set_option': - await setOption(message.key, message.value); + await setOption(message.key, message.value) - break; + break case 'get_js_patterns': response = { - patterns: wappalyzer.jsPatterns, - }; + patterns: wappalyzer.jsPatterns + } - break; + break case 'update_theme_mode': // Sync theme mode to popup. response = { - themeMode: await getOption('themeMode', false), - }; + themeMode: await getOption('themeMode', false) + } - break; + break default: - // Do nothing + // Do nothing } if (response) { port.postMessage({ id: message.id, - response, - }); + response + }) } - }); -}); + }) +}) -wappalyzer.driver.document = document; +wappalyzer.driver.document = document /** * Log messages to console */ wappalyzer.driver.log = (message, source, type) => { - const log = ['warn', 'error'].indexOf(type) !== -1 ? type : 'log'; + const log = ['warn', 'error'].includes(type) ? type : 'log' - console[log](`[wappalyzer ${type}]`, `[${source}]`, message); // eslint-disable-line no-console -}; + console[log](`[wappalyzer ${type}]`, `[${source}]`, message) // eslint-disable-line no-console +} /** * Display apps */ wappalyzer.driver.displayApps = async (detected, meta, context) => { - const { tab } = context; + const { tab } = context if (tab === undefined) { - return; + return } tabCache[tab.id] = tabCache[tab.id] || { - detected: [], - }; + detected: [] + } - tabCache[tab.id].detected = detected; + tabCache[tab.id].detected = detected - const pinnedCategory = await getOption('pinnedCategory'); - const dynamicIcon = await getOption('dynamicIcon', true); + const pinnedCategory = await getOption('pinnedCategory') + const dynamicIcon = await getOption('dynamicIcon', true) - let found = false; + let found = false // Find the main application to display - [pinnedCategory].concat(categoryOrder).forEach((match) => { + ;[pinnedCategory].concat(categoryOrder).forEach((match) => { Object.keys(detected).forEach((appName) => { - const app = detected[appName]; + const app = detected[appName] app.props.cats.forEach((category) => { if (category === match && !found) { - let icon = app.props.icon && dynamicIcon ? app.props.icon : 'default.svg'; + let icon = + app.props.icon && dynamicIcon ? app.props.icon : 'default.svg' if (/\.svg$/i.test(icon)) { - icon = `converted/${icon.replace(/\.svg$/, '.png')}`; + icon = `converted/${icon.replace(/\.svg$/, '.png')}` } try { browser.pageAction.setIcon({ tabId: tab.id, - path: `../images/icons/${icon}`, - }); + path: `../images/icons/${icon}` + }) } catch (e) { // Firefox for Android does not support setIcon see https://bugzilla.mozilla.org/show_bug.cgi?id=1331746 } - found = true; + found = true } - }); - }); - }); + }) + }) + }) - browser.pageAction.show(tab.id); -}; + browser.pageAction.show(tab.id) +} /** * Fetch and cache robots.txt for host */ wappalyzer.driver.getRobotsTxt = async (host, secure = false) => { if (robotsTxtQueue[host]) { - return robotsTxtQueue[host]; + return robotsTxtQueue[host] } - const tracking = await getOption('tracking', true); - const robotsTxtCache = await getOption('robotsTxtCache', {}); + const tracking = await getOption('tracking', true) + const robotsTxtCache = await getOption('robotsTxtCache', {}) robotsTxtQueue[host] = new Promise(async (resolve) => { if (!tracking) { - return resolve([]); + return resolve([]) } if (host in robotsTxtCache) { - return resolve(robotsTxtCache[host]); + return resolve(robotsTxtCache[host]) } - const timeout = setTimeout(() => resolve([]), 3000); + const timeout = setTimeout(() => resolve([]), 3000) - let response; + let response try { - response = await fetch(`http${secure ? 's' : ''}://${host}/robots.txt`, { redirect: 'follow', mode: 'no-cors' }); + response = await fetch(`http${secure ? 's' : ''}://${host}/robots.txt`, { + redirect: 'follow', + mode: 'no-cors' + }) } catch (error) { - wappalyzer.log(error, 'driver', 'error'); + wappalyzer.log(error, 'driver', 'error') - return resolve([]); + return resolve([]) } - clearTimeout(timeout); + clearTimeout(timeout) - const robotsTxt = response.ok ? await response.text() : ''; + const robotsTxt = response.ok ? await response.text() : '' - robotsTxtCache[host] = Wappalyzer.parseRobotsTxt(robotsTxt); + robotsTxtCache[host] = Wappalyzer.parseRobotsTxt(robotsTxt) - await setOption('robotsTxtCache', robotsTxtCache); + await setOption('robotsTxtCache', robotsTxtCache) - delete robotsTxtQueue[host]; + delete robotsTxtQueue[host] - return resolve(robotsTxtCache[host]); - }); + return resolve(robotsTxtCache[host]) + }) - return robotsTxtQueue[host]; -}; + return robotsTxtQueue[host] +} /** * Anonymously track detected applications for research purposes */ wappalyzer.driver.ping = async (hostnameCache = {}, adCache = []) => { - const tracking = await getOption('tracking', true); - const termsAccepted = userAgent() === 'chrome' || await getOption('termsAccepted', false); + const tracking = await getOption('tracking', true) + const termsAccepted = + userAgent() === 'chrome' || (await getOption('termsAccepted', false)) if (tracking && termsAccepted) { if (Object.keys(hostnameCache).length) { - post('https://api.wappalyzer.com/ping/v1/', hostnameCache); + post('https://api.wappalyzer.com/ping/v1/', hostnameCache) } if (adCache.length) { - post('https://ad.wappalyzer.com/log/wp/', adCache); + post('https://ad.wappalyzer.com/log/wp/', adCache) } - await setOption('robotsTxtCache', {}); + await setOption('robotsTxtCache', {}) } -}; +} // Init -(async () => { +;(async () => { // Technologies try { - const response = await fetch('../apps.json'); - const json = await response.json(); + const response = await fetch('../apps.json') + const json = await response.json() - wappalyzer.apps = json.apps; - wappalyzer.categories = json.categories; + wappalyzer.apps = json.apps + wappalyzer.categories = json.categories } catch (error) { - wappalyzer.log(`GET apps.json: ${error.message}`, 'driver', 'error'); + wappalyzer.log(`GET apps.json: ${error.message}`, 'driver', 'error') } - wappalyzer.parseJsPatterns(); + wappalyzer.parseJsPatterns() categoryOrder = Object.keys(wappalyzer.categories) - .map(categoryId => parseInt(categoryId, 10)) - .sort((a, b) => wappalyzer.categories[a].priority - wappalyzer.categories[b].priority); + .map((categoryId) => parseInt(categoryId, 10)) + .sort( + (a, b) => + wappalyzer.categories[a].priority - wappalyzer.categories[b].priority + ) // Version check - const { version } = browser.runtime.getManifest(); - const previousVersion = await getOption('version'); - const upgradeMessage = await getOption('upgradeMessage', true); + const { version } = browser.runtime.getManifest() + const previousVersion = await getOption('version') + const upgradeMessage = await getOption('upgradeMessage', true) if (previousVersion === null) { openTab({ - url: `${wappalyzer.config.websiteURL}installed`, - }); + url: `${wappalyzer.config.websiteURL}installed` + }) } else if (version !== previousVersion && upgradeMessage) { openTab({ url: `${wappalyzer.config.websiteURL}upgraded?v${version}`, - background: true, - }); + background: true + }) } - await setOption('version', version); + await setOption('version', version) // Hostname cache - wappalyzer.hostnameCache = await getOption('hostnameCache', {}); + wappalyzer.hostnameCache = await getOption('hostnameCache', {}) // Run content script on all tabs try { - const tabs = await browser.tabs.query({ url: ['http://*/*', 'https://*/*'] }); + const tabs = await browser.tabs.query({ + url: ['http://*/*', 'https://*/*'] + }) tabs.forEach(async (tab) => { try { await browser.tabs.executeScript(tab.id, { - file: '../js/content.js', - }); + file: '../js/content.js' + }) } catch (error) { // } - }); + }) } catch (error) { - wappalyzer.log(error, 'driver', 'error'); + wappalyzer.log(error, 'driver', 'error') } -})(); +})() diff --git a/src/drivers/webextension/js/options.js b/src/drivers/webextension/js/options.js index 03c6ae504..29d11d5d4 100644 --- a/src/drivers/webextension/js/options.js +++ b/src/drivers/webextension/js/options.js @@ -3,29 +3,29 @@ /* globals browser Wappalyzer */ /* eslint-env browser */ -const wappalyzer = new Wappalyzer(); +const wappalyzer = new Wappalyzer() /** * Get a value from localStorage */ function getOption(name, defaultValue = null) { return new Promise(async (resolve, reject) => { - let value = defaultValue; + let value = defaultValue try { - const option = await browser.storage.local.get(name); + const option = await browser.storage.local.get(name) if (option[name] !== undefined) { - value = option[name]; + value = option[name] } } catch (error) { - wappalyzer.log(error.message, 'driver', 'error'); + wappalyzer.log(error.message, 'driver', 'error') - return reject(error.message); + return reject(error.message) } - return resolve(value); - }); + return resolve(value) + }) } /** @@ -34,72 +34,76 @@ function getOption(name, defaultValue = null) { function setOption(name, value) { return new Promise(async (resolve, reject) => { try { - await browser.storage.local.set({ [name]: value }); + await browser.storage.local.set({ [name]: value }) } catch (error) { - wappalyzer.log(error.message, 'driver', 'error'); + wappalyzer.log(error.message, 'driver', 'error') - return reject(error.message); + return reject(error.message) } - return resolve(); - }); + return resolve() + }) } document.addEventListener('DOMContentLoaded', async () => { - const nodes = document.querySelectorAll('[data-i18n]'); + const nodes = document.querySelectorAll('[data-i18n]') Array.prototype.forEach.call(nodes, (node) => { - node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n); - }); + node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n) + }) document.querySelector('#github').addEventListener('click', () => { - window.open(wappalyzer.config.githubURL); - }); + window.open(wappalyzer.config.githubURL) + }) document.querySelector('#twitter').addEventListener('click', () => { - window.open(wappalyzer.config.twitterURL); - }); + window.open(wappalyzer.config.twitterURL) + }) document.querySelector('#wappalyzer').addEventListener('click', () => { - window.open(wappalyzer.config.websiteURL); - }); + window.open(wappalyzer.config.websiteURL) + }) - let el; - let value; + let el + let value // Upgrade message - value = await getOption('upgradeMessage', true); + value = await getOption('upgradeMessage', true) - el = document.querySelector('#option-upgrade-message'); + el = document.querySelector('#option-upgrade-message') - el.checked = value; + el.checked = value - el.addEventListener('change', e => setOption('upgradeMessage', e.target.checked)); + el.addEventListener('change', (e) => + setOption('upgradeMessage', e.target.checked) + ) // Dynamic icon - value = await getOption('dynamicIcon', true); + value = await getOption('dynamicIcon', true) - el = document.querySelector('#option-dynamic-icon'); + el = document.querySelector('#option-dynamic-icon') - el.checked = value; + el.checked = value - el.addEventListener('change', e => setOption('dynamicIcon', e.target.checked)); + el.addEventListener('change', (e) => + setOption('dynamicIcon', e.target.checked) + ) // Tracking - value = await getOption('tracking', true); + value = await getOption('tracking', true) - el = document.querySelector('#option-tracking'); + el = document.querySelector('#option-tracking') - el.checked = value; + el.checked = value - el.addEventListener('change', e => setOption('tracking', e.target.checked)); + el.addEventListener('change', (e) => setOption('tracking', e.target.checked)) // Theme Mode - value = await getOption('themeMode', false); + value = await getOption('themeMode', false) - el = document.querySelector('#option-theme-mode'); + el = document.querySelector('#option-theme-mode') - el.checked = value; + el.checked = value - el.addEventListener('change', e => setOption('themeMode', e.target.checked)); -}); + el.addEventListener('change', (e) => setOption('themeMode', e.target.checked)) +}) diff --git a/src/drivers/webextension/js/popup.js b/src/drivers/webextension/js/popup.js index cf5d2d95d..d04c65d9f 100644 --- a/src/drivers/webextension/js/popup.js +++ b/src/drivers/webextension/js/popup.js @@ -4,217 +4,267 @@ /** global: browser */ /** global: jsonToDOM */ -let pinnedCategory = null; -let termsAccepted = false; +let pinnedCategory = null +let termsAccepted = false const port = browser.runtime.connect({ - name: 'popup.js', -}); + name: 'popup.js' +}) function slugify(string) { - return string.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/(?:^-|-$)/, ''); + return string + .toLowerCase() + .replace(/[^a-z0-9-]/g, '-') + .replace(/--+/g, '-') + .replace(/(?:^-|-$)/, '') } function i18n() { - const nodes = document.querySelectorAll('[data-i18n]'); + const nodes = document.querySelectorAll('[data-i18n]') Array.prototype.forEach.call(nodes, (node) => { - node.innerHTML = browser.i18n.getMessage(node.dataset.i18n); - }); + node.innerHTML = browser.i18n.getMessage(node.dataset.i18n) + }) } function replaceDom(domTemplate) { - const container = document.getElementsByClassName('container')[0]; + const container = document.getElementsByClassName('container')[0] while (container.firstChild) { - container.removeChild(container.firstChild); + container.removeChild(container.firstChild) } - container.appendChild(jsonToDOM(domTemplate, document, {})); + container.appendChild(jsonToDOM(domTemplate, document, {})) - i18n(); + i18n() - Array.from(document.querySelectorAll('.detected__category-pin-wrapper')).forEach((pin) => { + Array.from( + document.querySelectorAll('.detected__category-pin-wrapper') + ).forEach((pin) => { pin.addEventListener('click', () => { - const categoryId = parseInt(pin.dataset.categoryId, 10); + const categoryId = parseInt(pin.dataset.categoryId, 10) if (categoryId === pinnedCategory) { - pin.className = 'detected__category-pin-wrapper'; + pin.className = 'detected__category-pin-wrapper' - pinnedCategory = null; + pinnedCategory = null } else { - const active = document.querySelector('.detected__category-pin-wrapper--active'); + const active = document.querySelector( + '.detected__category-pin-wrapper--active' + ) if (active) { - active.className = 'detected__category-pin-wrapper'; + active.className = 'detected__category-pin-wrapper' } - pin.className = 'detected__category-pin-wrapper detected__category-pin-wrapper--active'; + pin.className = + 'detected__category-pin-wrapper detected__category-pin-wrapper--active' - pinnedCategory = categoryId; + pinnedCategory = categoryId } port.postMessage({ id: 'set_option', key: 'pinnedCategory', - value: pinnedCategory, - }); - }); - }); + value: pinnedCategory + }) + }) + }) } function replaceDomWhenReady(dom) { if (/complete|interactive|loaded/.test(document.readyState)) { - replaceDom(dom); + replaceDom(dom) } else { document.addEventListener('DOMContentLoaded', () => { - replaceDom(dom); - }); + replaceDom(dom) + }) } } function appsToDomTemplate(response) { - let template = []; + let template = [] if (response.tabCache && Object.keys(response.tabCache.detected).length > 0) { - const categories = {}; + const categories = {} // Group apps by category for (const appName in response.tabCache.detected) { response.apps[appName].cats.forEach((cat) => { - categories[cat] = categories[cat] || { apps: [] }; + categories[cat] = categories[cat] || { apps: [] } - categories[cat].apps[appName] = appName; - }); + categories[cat].apps[appName] = appName + }) } for (const cat in categories) { - const apps = []; + const apps = [] for (const appName in categories[cat].apps) { - const { confidence, version } = response.tabCache.detected[appName]; - - apps.push( + const { confidence, version } = response.tabCache.detected[appName] + + apps.push([ + 'a', + { + class: 'detected__app', + target: '_blank', + href: `https://www.wappalyzer.com/technologies/${slugify(appName)}` + }, [ - 'a', { - class: 'detected__app', - target: '_blank', - href: `https://www.wappalyzer.com/technologies/${slugify(appName)}`, - }, [ - 'img', { - class: 'detected__app-icon', - src: `../images/icons/${response.apps[appName].icon || 'default.svg'}`, - }, - ], [ - 'span', { - class: 'detected__app-name', - }, - appName, - ], version ? [ - 'span', { - class: 'detected__app-version', - }, - version, - ] : null, confidence < 100 ? [ - 'span', { - class: 'detected__app-confidence', - }, - `${confidence}% sure`, - ] : null, + 'img', + { + class: 'detected__app-icon', + src: `../images/icons/${response.apps[appName].icon || + 'default.svg'}` + } + ], + [ + 'span', + { + class: 'detected__app-name' + }, + appName ], - ); + version + ? [ + 'span', + { + class: 'detected__app-version' + }, + version + ] + : null, + confidence < 100 + ? [ + 'span', + { + class: 'detected__app-confidence' + }, + `${confidence}% sure` + ] + : null + ]) } - template.push( + template.push([ + 'div', + { + class: 'detected__category' + }, [ - 'div', { - class: 'detected__category', - }, [ - 'div', { - class: 'detected__category-name', - }, [ - 'a', { - class: 'detected__category-link', - target: '_blank', - href: `https://www.wappalyzer.com/categories/${slugify(response.categories[cat].name)}`, - }, - browser.i18n.getMessage(`categoryName${cat}`), - ], [ - 'span', { - class: `detected__category-pin-wrapper${pinnedCategory == cat ? ' detected__category-pin-wrapper--active' : ''}`, - 'data-category-id': cat, - title: browser.i18n.getMessage('categoryPin'), - }, [ - 'img', { - class: 'detected__category-pin detected__category-pin--active', - src: '../images/pin-active.svg', - }, - ], [ - 'img', { - class: 'detected__category-pin detected__category-pin--inactive', - src: '../images/pin.svg', - }, - ], - ], - ], [ - 'div', { - class: 'detected__apps', + 'div', + { + class: 'detected__category-name' + }, + [ + 'a', + { + class: 'detected__category-link', + target: '_blank', + href: `https://www.wappalyzer.com/categories/${slugify( + response.categories[cat].name + )}` }, - apps, + browser.i18n.getMessage(`categoryName${cat}`) ], + [ + 'span', + { + class: `detected__category-pin-wrapper${ + pinnedCategory == cat + ? ' detected__category-pin-wrapper--active' + : '' + }`, + 'data-category-id': cat, + title: browser.i18n.getMessage('categoryPin') + }, + [ + 'img', + { + class: 'detected__category-pin detected__category-pin--active', + src: '../images/pin-active.svg' + } + ], + [ + 'img', + { + class: + 'detected__category-pin detected__category-pin--inactive', + src: '../images/pin.svg' + } + ] + ] ], - ); + [ + 'div', + { + class: 'detected__apps' + }, + apps + ] + ]) } template = [ - 'div', { - class: 'detected', + 'div', + { + class: 'detected' }, - template, - ]; + template + ] } else { template = [ - 'div', { - class: 'empty', + 'div', + { + class: 'empty' }, [ - 'span', { - class: 'empty__text', + 'span', + { + class: 'empty__text' }, - browser.i18n.getMessage('noAppsDetected'), - ], - ]; + browser.i18n.getMessage('noAppsDetected') + ] + ] } - return template; + return template } async function getApps() { try { const tabs = await browser.tabs.query({ active: true, - currentWindow: true, - }); + currentWindow: true + }) + + const url = new URL(tabs[0].url) + + document.querySelector( + '.footer__link' + ).href = `https://www.wappalyzer.com/alerts/manage?url=${encodeURIComponent( + `${url.protocol}//${url.hostname}` + )}` port.postMessage({ id: 'get_apps', - tab: tabs[0], - }); + tab: tabs[0] + }) } catch (error) { - console.error(error); // eslint-disable-line no-console + console.error(error) // eslint-disable-line no-console } } /** * Async function to update body class based on option. */ -async function getThemeMode() { +function getThemeMode() { try { port.postMessage({ - id: 'update_theme_mode', - }); + id: 'update_theme_mode' + }) } catch (error) { - console.error(error); // eslint-disable-line no-console + console.error(error) // eslint-disable-line no-console } } @@ -224,50 +274,51 @@ async function getThemeMode() { */ function updateThemeMode(res) { if (res.hasOwnProperty('themeMode') && res.themeMode !== false) { - document.body.classList.add('theme-mode-sync'); + document.body.classList.add('theme-mode-sync') } } + function displayApps(response) { - pinnedCategory = response.pinnedCategory; // eslint-disable-line prefer-destructuring - termsAccepted = response.termsAccepted; // eslint-disable-line prefer-destructuring + pinnedCategory = response.pinnedCategory // eslint-disable-line prefer-destructuring + termsAccepted = response.termsAccepted // eslint-disable-line prefer-destructuring if (termsAccepted) { - replaceDomWhenReady(appsToDomTemplate(response)); + replaceDomWhenReady(appsToDomTemplate(response)) } else { - i18n(); + i18n() - const wrapper = document.querySelector('.terms__wrapper'); + const wrapper = document.querySelector('.terms__wrapper') document.querySelector('.terms__accept').addEventListener('click', () => { port.postMessage({ id: 'set_option', key: 'termsAccepted', - value: true, - }); + value: true + }) - wrapper.classList.remove('terms__wrapper--active'); + wrapper.classList.remove('terms__wrapper--active') - getApps(); - }); + getApps() + }) - wrapper.classList.add('terms__wrapper--active'); + wrapper.classList.add('terms__wrapper--active') } } port.onMessage.addListener((message) => { switch (message.id) { case 'get_apps': - displayApps(message.response); + displayApps(message.response) - break; + break case 'update_theme_mode': - updateThemeMode(message.response); + updateThemeMode(message.response) - break; + break default: - // Do nothing + // Do nothing } -}); +}) -getThemeMode(); -getApps(); +getThemeMode() +getApps() diff --git a/src/wappalyzer.js b/src/wappalyzer.js index 771de8426..603ea119e 100644 --- a/src/wappalyzer.js +++ b/src/wappalyzer.js @@ -8,130 +8,137 @@ const validation = { hostname: /(www.)?((.+?)\.(([a-z]{2,3}\.)?[a-z]{2,6}))$/, - hostnameBlacklist: /((local|dev(elopment)?|stag(e|ing)?|test(ing)?|demo(shop)?|admin|google|cache)\.|\/admin|\.local)/, -}; + hostnameBlacklist: /((local|dev(elopment)?|stag(e|ing)?|test(ing)?|demo(shop)?|admin|google|cache)\.|\/admin|\.local)/ +} /** * Enclose string in array */ function asArray(value) { - return value instanceof Array ? value : [value]; + return Array.isArray(value) ? value : [value] } /** * */ function asyncForEach(iterable, iterator) { - return Promise.all((iterable || []) - .map(item => new Promise(resolve => setTimeout(() => resolve(iterator(item)), 1)))); + return Promise.all( + (iterable || []).map( + (item) => + new Promise((resolve) => setTimeout(() => resolve(iterator(item)), 1)) + ) + ) } /** * Mark application as detected, set confidence and version */ function addDetected(app, pattern, type, value, key) { - app.detected = true; + app.detected = true // Set confidence level - app.confidence[`${type} ${key ? `${key} ` : ''}${pattern.regex}`] = pattern.confidence === undefined ? 100 : parseInt(pattern.confidence, 10); + app.confidence[`${type} ${key ? `${key} ` : ''}${pattern.regex}`] = + pattern.confidence === undefined ? 100 : parseInt(pattern.confidence, 10) // Detect version number if (pattern.version) { - const versions = []; - const matches = pattern.regex.exec(value); + const versions = [] + const matches = pattern.regex.exec(value) - let { version } = pattern; + let { version } = pattern if (matches) { matches.forEach((match, i) => { // Parse ternary operator - const ternary = new RegExp(`\\\\${i}\\?([^:]+):(.*)$`).exec(version); + const ternary = new RegExp(`\\\\${i}\\?([^:]+):(.*)$`).exec(version) if (ternary && ternary.length === 3) { - version = version.replace(ternary[0], match ? ternary[1] : ternary[2]); + version = version.replace(ternary[0], match ? ternary[1] : ternary[2]) } // Replace back references - version = version.trim().replace(new RegExp(`\\\\${i}`, 'g'), match || ''); - }); + version = version + .trim() + .replace(new RegExp(`\\\\${i}`, 'g'), match || '') + }) - if (version && versions.indexOf(version) === -1) { - versions.push(version); + if (version && !versions.includes(version)) { + versions.push(version) } if (versions.length) { // Use the longest detected version number - app.version = versions.reduce((a, b) => (a.length > b.length ? a : b)); + app.version = versions.reduce((a, b) => (a.length > b.length ? a : b)) } } } } function resolveExcludes(apps, detected) { - const excludes = []; - const detectedApps = Object.assign({}, apps, detected); + const excludes = [] + const detectedApps = Object.assign({}, apps, detected) // Exclude app in detected apps only Object.keys(detectedApps).forEach((appName) => { - const app = detectedApps[appName]; + const app = detectedApps[appName] if (app.props.excludes) { asArray(app.props.excludes).forEach((excluded) => { - excludes.push(excluded); - }); + excludes.push(excluded) + }) } - }); + }) // Remove excluded applications Object.keys(apps).forEach((appName) => { - if (excludes.indexOf(appName) > -1) { - delete apps[appName]; + if (excludes.includes(appName)) { + delete apps[appName] } - }); + }) } class Application { constructor(name, props, detected) { - this.confidence = {}; - this.confidenceTotal = 0; - this.detected = Boolean(detected); - this.excludes = []; - this.name = name; - this.props = props; - this.version = ''; + this.confidence = {} + this.confidenceTotal = 0 + this.detected = Boolean(detected) + this.excludes = [] + this.name = name + this.props = props + this.version = '' } /** * Calculate confidence total */ getConfidence() { - let total = 0; + let total = 0 Object.keys(this.confidence).forEach((id) => { - total += this.confidence[id]; - }); + total += this.confidence[id] + }) - this.confidenceTotal = Math.min(total, 100); + this.confidenceTotal = Math.min(total, 100) - return this.confidenceTotal; + return this.confidenceTotal } } class Wappalyzer { constructor() { - this.apps = {}; - this.categories = {}; - this.driver = {}; - this.jsPatterns = {}; - this.detected = {}; - this.hostnameCache = {}; - this.adCache = []; + this.apps = {} + this.categories = {} + this.driver = {} + this.jsPatterns = {} + this.detected = {} + this.hostnameCache = {} + this.adCache = [] this.config = { websiteURL: 'https://www.wappalyzer.com/', twitterURL: 'https://twitter.com/Wappalyzer', - githubURL: 'https://github.com/AliasIO/Wappalyzer', - }; + githubURL: 'https://github.com/AliasIO/Wappalyzer' + } } /** @@ -139,124 +146,135 @@ class Wappalyzer { */ log(message, source, type) { if (this.driver.log) { - this.driver.log(message, source || '', type || 'debug'); + this.driver.log(message, source || '', type || 'debug') } } analyze(url, data, context) { - const apps = {}; - const promises = []; - const startTime = new Date(); - const { - scripts, - cookies, - headers, - js, - } = data; - - let { html } = data; + const apps = {} + const promises = [] + const startTime = new Date() + const { scripts, cookies, headers, js } = data + + let { html } = data if (this.detected[url.canonical] === undefined) { - this.detected[url.canonical] = {}; + this.detected[url.canonical] = {} } - const metaTags = []; + const metaTags = [] // Additional information - let language = null; + let language = null if (html) { if (typeof html !== 'string') { - html = ''; + html = '' } - let matches = data.html.match(new RegExp(']*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"', 'i')); + let matches = data.html.match( + new RegExp(']*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"', 'i') + ) - language = matches && matches.length ? matches[1] : data.language || null; + language = matches && matches.length ? matches[1] : data.language || null // Meta tags - const regex = /]+>/ig; + const regex = /]+>/gi do { - matches = regex.exec(html); + matches = regex.exec(html) if (!matches) { - break; + break } - metaTags.push(matches[0]); - } while (matches); + metaTags.push(matches[0]) + } while (matches) } Object.keys(this.apps).forEach((appName) => { - apps[appName] = this.detected[url.canonical] && this.detected[url.canonical][appName] - ? this.detected[url.canonical][appName] - : new Application(appName, this.apps[appName]); + apps[appName] = + this.detected[url.canonical] && this.detected[url.canonical][appName] + ? this.detected[url.canonical][appName] + : new Application(appName, this.apps[appName]) - const app = apps[appName]; + const app = apps[appName] - promises.push(this.analyzeUrl(app, url)); + promises.push(this.analyzeUrl(app, url)) if (html) { - promises.push(this.analyzeHtml(app, html)); - promises.push(this.analyzeMeta(app, metaTags)); + promises.push(this.analyzeHtml(app, html)) + promises.push(this.analyzeMeta(app, metaTags)) } if (scripts) { - promises.push(this.analyzeScripts(app, scripts)); + promises.push(this.analyzeScripts(app, scripts)) } if (cookies) { - promises.push(this.analyzeCookies(app, cookies)); + promises.push(this.analyzeCookies(app, cookies)) } if (headers) { - promises.push(this.analyzeHeaders(app, headers)); + promises.push(this.analyzeHeaders(app, headers)) } - }); + }) if (js) { Object.keys(js).forEach((appName) => { if (typeof js[appName] !== 'function') { - promises.push(this.analyzeJs(apps[appName], js[appName])); + promises.push(this.analyzeJs(apps[appName], js[appName])) } - }); + }) } return new Promise(async (resolve) => { - await Promise.all(promises); + await Promise.all(promises) Object.keys(apps).forEach((appName) => { - const app = apps[appName]; + const app = apps[appName] if (!app.detected || !app.getConfidence()) { - delete apps[app.name]; + delete apps[app.name] } - }); + }) - resolveExcludes(apps, this.detected[url]); - this.resolveImplies(apps, url.canonical); + resolveExcludes(apps, this.detected[url]) + this.resolveImplies(apps, url.canonical) - this.cacheDetectedApps(apps, url.canonical); - this.trackDetectedApps(apps, url, language); + this.cacheDetectedApps(apps, url.canonical) + this.trackDetectedApps(apps, url, language) - this.log(`Processing ${Object.keys(data).join(', ')} took ${((new Date() - startTime) / 1000).toFixed(2)}s (${url.hostname})`, 'core'); + this.log( + `Processing ${Object.keys(data).join(', ')} took ${( + (new Date() - startTime) / + 1000 + ).toFixed(2)}s (${url.hostname})`, + 'core' + ) if (Object.keys(apps).length) { - this.log(`Identified ${Object.keys(apps).join(', ')} (${url.hostname})`, 'core'); + this.log( + `Identified ${Object.keys(apps).join(', ')} (${url.hostname})`, + 'core' + ) } - this.driver.displayApps(this.detected[url.canonical], { language }, context); + this.driver.displayApps( + this.detected[url.canonical], + { language }, + context + ) - return resolve(); - }); + return resolve() + }) } /** * Cache detected ads */ cacheDetectedAds(ad) { - this.adCache.push(ad); + this.adCache.push(ad) } /** @@ -264,58 +282,65 @@ class Wappalyzer { */ robotsTxtAllows(url) { return new Promise(async (resolve, reject) => { - const parsed = this.parseUrl(url); + const parsed = this.parseUrl(url) if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') { - return reject(); + return reject() } - const robotsTxt = await this.driver.getRobotsTxt(parsed.host, parsed.protocol === 'https:'); - - if (robotsTxt.some(disallowedPath => parsed.pathname.indexOf(disallowedPath) === 0)) { - return reject(); + const robotsTxt = await this.driver.getRobotsTxt( + parsed.host, + parsed.protocol === 'https:' + ) + + if ( + robotsTxt.some( + (disallowedPath) => parsed.pathname.indexOf(disallowedPath) === 0 + ) + ) { + return reject() } - return resolve(); - }); + return resolve() + }) } /** * Parse a URL */ parseUrl(url) { - const a = this.driver.document.createElement('a'); + const a = this.driver.document.createElement('a') - a.href = url; + a.href = url - a.canonical = `${a.protocol}//${a.host}${a.pathname}`; + a.canonical = `${a.protocol}//${a.host}${a.pathname}` - return a; + return a } /** * */ static parseRobotsTxt(robotsTxt) { - const disallow = []; + const disallow = [] - let userAgent; + let userAgent robotsTxt.split('\n').forEach((line) => { - let matches = /^User-agent:\s*(.+)$/i.exec(line.trim()); + let matches = /^User-agent:\s*(.+)$/i.exec(line.trim()) if (matches) { - userAgent = matches[1].toLowerCase(); + userAgent = matches[1].toLowerCase() } else if (userAgent === '*' || userAgent === 'wappalyzer') { - matches = /^Disallow:\s*(.+)$/i.exec(line.trim()); + matches = /^Disallow:\s*(.+)$/i.exec(line.trim()) if (matches) { - disallow.push(matches[1]); + disallow.push(matches[1]) } } - }); + }) - return disallow; + return disallow } /** @@ -323,15 +348,15 @@ class Wappalyzer { */ ping() { if (Object.keys(this.hostnameCache).length > 50) { - this.driver.ping(this.hostnameCache); + this.driver.ping(this.hostnameCache) - this.hostnameCache = {}; + this.hostnameCache = {} } if (this.adCache.length > 50) { - this.driver.ping({}, this.adCache); + this.driver.ping({}, this.adCache) - this.adCache = []; + this.adCache = [] } } @@ -340,55 +365,55 @@ class Wappalyzer { */ parsePatterns(patterns) { if (!patterns) { - return []; + return [] } - let parsed = {}; + let parsed = {} // Convert string to object containing array containing string - if (typeof patterns === 'string' || patterns instanceof Array) { + if (typeof patterns === 'string' || Array.isArray(patterns)) { patterns = { - main: asArray(patterns), - }; + main: asArray(patterns) + } } Object.keys(patterns).forEach((key) => { - parsed[key] = []; + parsed[key] = [] asArray(patterns[key]).forEach((pattern) => { - const attrs = {}; + const attrs = {} pattern.split('\\;').forEach((attr, i) => { if (i) { // Key value pairs - attr = attr.split(':'); + attr = attr.split(':') if (attr.length > 1) { - attrs[attr.shift()] = attr.join(':'); + attrs[attr.shift()] = attr.join(':') } } else { - attrs.string = attr; + attrs.string = attr try { - attrs.regex = new RegExp(attr.replace('/', '\/'), 'i'); // Escape slashes in regular expression + attrs.regex = new RegExp(attr.replace('/', '/'), 'i') // Escape slashes in regular expression } catch (error) { - attrs.regex = new RegExp(); + attrs.regex = new RegExp() - this.log(`${error.message}: ${attr}`, 'error', 'core'); + this.log(`${error.message}: ${attr}`, 'error', 'core') } } - }); + }) - parsed[key].push(attrs); - }); - }); + parsed[key].push(attrs) + }) + }) // Convert back to array if the original pattern list was an array (or string) if ('main' in parsed) { - parsed = parsed.main; + parsed = parsed.main } - return parsed; + return parsed } /** @@ -397,49 +422,60 @@ class Wappalyzer { parseJsPatterns() { Object.keys(this.apps).forEach((appName) => { if (this.apps[appName].js) { - this.jsPatterns[appName] = this.parsePatterns(this.apps[appName].js); + this.jsPatterns[appName] = this.parsePatterns(this.apps[appName].js) } - }); + }) } resolveImplies(apps, url) { - let checkImplies = true; + let checkImplies = true const resolve = (appName) => { - const app = apps[appName]; + const app = apps[appName] if (app && app.props.implies) { asArray(app.props.implies).forEach((implied) => { - [implied] = this.parsePatterns(implied); + ;[implied] = this.parsePatterns(implied) if (!this.apps[implied.string]) { - this.log(`Implied application ${implied.string} does not exist`, 'core', 'warn'); + this.log( + `Implied application ${implied.string} does not exist`, + 'core', + 'warn' + ) - return; + return } if (!(implied.string in apps)) { - apps[implied.string] = this.detected[url] && this.detected[url][implied.string] - ? this.detected[url][implied.string] - : new Application(implied.string, this.apps[implied.string], true); - - checkImplies = true; + apps[implied.string] = + this.detected[url] && this.detected[url][implied.string] + ? this.detected[url][implied.string] + : new Application( + implied.string, + this.apps[implied.string], + true + ) + + checkImplies = true } // Apply app confidence to implied app Object.keys(app.confidence).forEach((id) => { - apps[implied.string].confidence[`${id} implied by ${appName}`] = app.confidence[id] * (implied.confidence === undefined ? 1 : implied.confidence / 100); - }); - }); + apps[implied.string].confidence[`${id} implied by ${appName}`] = + app.confidence[id] * + (implied.confidence === undefined ? 1 : implied.confidence / 100) + }) + }) } - }; + } // Implied applications // Run several passes as implied apps may imply other apps while (checkImplies) { - checkImplies = false; + checkImplies = false - Object.keys(apps).forEach(resolve); + Object.keys(apps).forEach(resolve) } } @@ -448,19 +484,18 @@ class Wappalyzer { */ cacheDetectedApps(apps, url) { Object.keys(apps).forEach((appName) => { - const app = apps[appName]; + const app = apps[appName] // Per URL - this.detected[url][appName] = app; + this.detected[url][appName] = app - Object.keys(app.confidence) - .forEach((id) => { - this.detected[url][appName].confidence[id] = app.confidence[id]; - }); - }); + Object.keys(app.confidence).forEach((id) => { + this.detected[url][appName].confidence[id] = app.confidence[id] + }) + }) if (this.driver.ping instanceof Function) { - this.ping(); + this.ping() } } @@ -469,204 +504,219 @@ class Wappalyzer { */ trackDetectedApps(apps, url, language) { if (!(this.driver.ping instanceof Function)) { - return; + return } - const hostname = `${url.protocol}//${url.hostname}`; + const hostname = `${url.protocol}//${url.hostname}` Object.keys(apps).forEach((appName) => { - const app = apps[appName]; + const app = apps[appName] if (this.detected[url.canonical][appName].getConfidence() >= 100) { if ( - validation.hostname.test(url.hostname) - && !validation.hostnameBlacklist.test(url.hostname) + validation.hostname.test(url.hostname) && + !validation.hostnameBlacklist.test(url.hostname) ) { if (!(hostname in this.hostnameCache)) { this.hostnameCache[hostname] = { applications: {}, - meta: {}, - }; + meta: {} + } } if (!(appName in this.hostnameCache[hostname].applications)) { this.hostnameCache[hostname].applications[appName] = { - hits: 0, - }; + hits: 0 + } } - this.hostnameCache[hostname].applications[appName].hits += 1; + this.hostnameCache[hostname].applications[appName].hits += 1 if (apps[appName].version) { - this.hostnameCache[hostname].applications[appName].version = app.version; + this.hostnameCache[hostname].applications[appName].version = + app.version } } } - }); + }) if (hostname in this.hostnameCache) { - this.hostnameCache[hostname].meta.language = language; + this.hostnameCache[hostname].meta.language = language } - this.ping(); + this.ping() } /** * Analyze URL */ analyzeUrl(app, url) { - const patterns = this.parsePatterns(app.props.url); + const patterns = this.parsePatterns(app.props.url) if (!patterns.length) { - return Promise.resolve(); + return Promise.resolve() } return asyncForEach(patterns, (pattern) => { if (pattern.regex.test(url.canonical)) { - addDetected(app, pattern, 'url', url.canonical); + addDetected(app, pattern, 'url', url.canonical) } - }); + }) } /** * Analyze HTML */ analyzeHtml(app, html) { - const patterns = this.parsePatterns(app.props.html); + const patterns = this.parsePatterns(app.props.html) if (!patterns.length) { - return Promise.resolve(); + return Promise.resolve() } return asyncForEach(patterns, (pattern) => { if (pattern.regex.test(html)) { - addDetected(app, pattern, 'html', html); + addDetected(app, pattern, 'html', html) } - }); + }) } /** * Analyze script tag */ analyzeScripts(app, scripts) { - const patterns = this.parsePatterns(app.props.script); + const patterns = this.parsePatterns(app.props.script) if (!patterns.length) { - return Promise.resolve(); + return Promise.resolve() } return asyncForEach(patterns, (pattern) => { scripts.forEach((uri) => { if (pattern.regex.test(uri)) { - addDetected(app, pattern, 'script', uri); + addDetected(app, pattern, 'script', uri) } - }); - }); + }) + }) } /** * Analyze meta tag */ analyzeMeta(app, metaTags) { - const patterns = this.parsePatterns(app.props.meta); - const promises = []; + const patterns = this.parsePatterns(app.props.meta) + const promises = [] if (!app.props.meta) { - return Promise.resolve(); + return Promise.resolve() } metaTags.forEach((match) => { Object.keys(patterns).forEach((meta) => { - const r = new RegExp(`(?:name|property)=["']${meta}["']`, 'i'); + const r = new RegExp(`(?:name|property)=["']${meta}["']`, 'i') if (r.test(match)) { - const content = match.match(/content=("|')([^"']+)("|')/i); - - promises.push(asyncForEach(patterns[meta], (pattern) => { - if (content && content.length === 4 && pattern.regex.test(content[2])) { - addDetected(app, pattern, 'meta', content[2], meta); - } - })); + const content = match.match(/content=("|')([^"']+)("|')/i) + + promises.push( + asyncForEach(patterns[meta], (pattern) => { + if ( + content && + content.length === 4 && + pattern.regex.test(content[2]) + ) { + addDetected(app, pattern, 'meta', content[2], meta) + } + }) + ) } - }); - }); + }) + }) - return Promise.all(promises); + return Promise.all(promises) } /** * Analyze response headers */ analyzeHeaders(app, headers) { - const patterns = this.parsePatterns(app.props.headers); - const promises = []; + const patterns = this.parsePatterns(app.props.headers) + const promises = [] Object.keys(patterns).forEach((headerName) => { if (typeof patterns[headerName] !== 'function') { - promises.push(asyncForEach(patterns[headerName], (pattern) => { - headerName = headerName.toLowerCase(); - - if (headerName in headers) { - headers[headerName].forEach((headerValue) => { - if (pattern.regex.test(headerValue)) { - addDetected(app, pattern, 'headers', headerValue, headerName); - } - }); - } - })); + promises.push( + asyncForEach(patterns[headerName], (pattern) => { + headerName = headerName.toLowerCase() + + if (headerName in headers) { + headers[headerName].forEach((headerValue) => { + if (pattern.regex.test(headerValue)) { + addDetected(app, pattern, 'headers', headerValue, headerName) + } + }) + } + }) + ) } - }); + }) - return promises ? Promise.all(promises) : Promise.resolve(); + return promises ? Promise.all(promises) : Promise.resolve() } /** * Analyze cookies */ analyzeCookies(app, cookies) { - const patterns = this.parsePatterns(app.props.cookies); - const promises = []; + const patterns = this.parsePatterns(app.props.cookies) + const promises = [] Object.keys(patterns).forEach((cookieName) => { if (typeof patterns[cookieName] !== 'function') { - const cookieNameLower = cookieName.toLowerCase(); + const cookieNameLower = cookieName.toLowerCase() - promises.push(asyncForEach(patterns[cookieName], (pattern) => { - const cookie = cookies.find(_cookie => _cookie.name.toLowerCase() === cookieNameLower); + promises.push( + asyncForEach(patterns[cookieName], (pattern) => { + const cookie = cookies.find( + (_cookie) => _cookie.name.toLowerCase() === cookieNameLower + ) - if (cookie && pattern.regex.test(cookie.value)) { - addDetected(app, pattern, 'cookies', cookie.value, cookieName); - } - })); + if (cookie && pattern.regex.test(cookie.value)) { + addDetected(app, pattern, 'cookies', cookie.value, cookieName) + } + }) + ) } - }); + }) - return promises ? Promise.all(promises) : Promise.resolve(); + return promises ? Promise.all(promises) : Promise.resolve() } /** * Analyze JavaScript variables */ analyzeJs(app, results) { - const promises = []; + const promises = [] Object.keys(results).forEach((string) => { if (typeof results[string] !== 'function') { - promises.push(asyncForEach(Object.keys(results[string]), (index) => { - const pattern = this.jsPatterns[app.name][string][index]; - const value = results[string][index]; + promises.push( + asyncForEach(Object.keys(results[string]), (index) => { + const pattern = this.jsPatterns[app.name][string][index] + const value = results[string][index] - if (pattern && pattern.regex.test(value)) { - addDetected(app, pattern, 'js', value, string); - } - })); + if (pattern && pattern.regex.test(value)) { + addDetected(app, pattern, 'js', value, string) + } + }) + ) } - }); + }) - return promises ? Promise.all(promises) : Promise.resolve(); + return promises ? Promise.all(promises) : Promise.resolve() } } if (typeof module === 'object') { - module.exports = Wappalyzer; + module.exports = Wappalyzer } From 7e4c44d63fdbc2d71a7ad8d121287cd2abb5dee6 Mon Sep 17 00:00:00 2001 From: Elbert Alias <77259+AliasIO@users.noreply.github.com> Date: Thu, 28 May 2020 10:02:00 +1000 Subject: [PATCH 34/34] Update apps.json --- src/apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps.json b/src/apps.json index 7275b49ec..3a4f5b864 100644 --- a/src/apps.json +++ b/src/apps.json @@ -4819,7 +4819,7 @@ 62 ], "headers": { - "Via": "/[\d.-]+ vegur$" + "Via": "/[\\d.-]+ vegur$" }, "implies": [ "Amazon Web Services"