PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/lib/node_modules/pm2/node_modules/systeminformation/lib
Viewing File: /usr/lib/node_modules/pm2/node_modules/systeminformation/lib/util.js
'use strict'; // @ts-check // ================================================================================== // utils.js // ---------------------------------------------------------------------------------- // Description: System Information - library // for Node.js // Copyright: (c) 2014 - 2025 // Author: Sebastian Hildebrandt // ---------------------------------------------------------------------------------- // License: MIT // ================================================================================== // 0. helper functions // ---------------------------------------------------------------------------------- const os = require('os'); const fs = require('fs'); const path = require('path'); const spawn = require('child_process').spawn; const exec = require('child_process').exec; const execSync = require('child_process').execSync; const util = require('util'); let _platform = process.platform; const _linux = (_platform === 'linux' || _platform === 'android'); const _darwin = (_platform === 'darwin'); const _windows = (_platform === 'win32'); const _freebsd = (_platform === 'freebsd'); const _openbsd = (_platform === 'openbsd'); const _netbsd = (_platform === 'netbsd'); let _cores = 0; let wmicPath = ''; let codepage = ''; let _smartMonToolsInstalled = null; let _rpi_cpuinfo = null; const WINDIR = process.env.WINDIR || 'C:\\Windows'; // powerShell let _psChild; let _psResult = ''; let _psCmds = []; let _psPersistent = false; let _powerShell = ''; const _psToUTF8 = '$OutputEncoding = [System.Console]::OutputEncoding = [System.Console]::InputEncoding = [System.Text.Encoding]::UTF8 ; '; const _psCmdStart = '--###START###--'; const _psError = '--ERROR--'; const _psCmdSeperator = '--###ENDCMD###--'; const _psIdSeperator = '--##ID##--'; const execOptsWin = { windowsHide: true, maxBuffer: 1024 * 20000, encoding: 'UTF-8', env: Object.assign({}, process.env, { LANG: 'en_US.UTF-8' }) }; const execOptsLinux = { maxBuffer: 1024 * 20000, encoding: 'UTF-8', stdio: ['pipe', 'pipe', 'ignore'] }; function toInt(value) { let result = parseInt(value, 10); if (isNaN(result)) { result = 0; } return result; } function splitByNumber(str) { let numberStarted = false; let num = ''; let cpart = ''; for (const c of str) { if ((c >= '0' && c <= '9') || numberStarted) { numberStarted = true; num += c; } else { cpart += c; } } return [cpart, num]; } const stringObj = new String(); const stringReplace = new String().replace; const stringToLower = new String().toLowerCase; const stringToString = new String().toString; const stringSubstr = new String().substr; const stringSubstring = new String().substring; const stringTrim = new String().trim; const stringStartWith = new String().startsWith; const mathMin = Math.min; function isFunction(functionToCheck) { let getType = {}; return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; } function unique(obj) { let uniques = []; let stringify = {}; for (let i = 0; i < obj.length; i++) { let keys = Object.keys(obj[i]); keys.sort(function (a, b) { return a - b; }); let str = ''; for (let j = 0; j < keys.length; j++) { str += JSON.stringify(keys[j]); str += JSON.stringify(obj[i][keys[j]]); } if (!{}.hasOwnProperty.call(stringify, str)) { uniques.push(obj[i]); stringify[str] = true; } } return uniques; } function sortByKey(array, keys) { return array.sort(function (a, b) { let x = ''; let y = ''; keys.forEach(function (key) { x = x + a[key]; y = y + b[key]; }); return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }); } function cores() { if (_cores === 0) { _cores = os.cpus().length; } return _cores; } function getValue(lines, property, separator, trimmed, lineMatch) { separator = separator || ':'; property = property.toLowerCase(); trimmed = trimmed || false; lineMatch = lineMatch || false; let result = ''; lines.some((line) => { let lineLower = line.toLowerCase().replace(/\t/g, ''); if (trimmed) { lineLower = lineLower.trim(); } if (lineLower.startsWith(property) && (lineMatch ? (lineLower.match(property + separator)) || (lineLower.match(property + ' ' + separator)) : true)) { const parts = trimmed ? line.trim().split(separator) : line.split(separator); if (parts.length >= 2) { parts.shift(); result = parts.join(separator).trim(); return true; } } }); return result; } function decodeEscapeSequence(str, base) { base = base || 16; return str.replace(/\\x([0-9A-Fa-f]{2})/g, function () { return String.fromCharCode(parseInt(arguments[1], base)); }); } function detectSplit(str) { let seperator = ''; let part = 0; str.split('').forEach(element => { if (element >= '0' && element <= '9') { if (part === 1) { part++; } } else { if (part === 0) { part++; } if (part === 1) { seperator += element; } } }); return seperator; } function parseTime(t, pmDesignator) { pmDesignator = pmDesignator || ''; t = t.toUpperCase(); let hour = 0; let min = 0; let splitter = detectSplit(t); let parts = t.split(splitter); if (parts.length >= 2) { if (parts[2]) { parts[1] += parts[2]; } let isPM = (parts[1] && (parts[1].toLowerCase().indexOf('pm') > -1) || (parts[1].toLowerCase().indexOf('p.m.') > -1) || (parts[1].toLowerCase().indexOf('p. m.') > -1) || (parts[1].toLowerCase().indexOf('n') > -1) || (parts[1].toLowerCase().indexOf('ch') > -1) || (parts[1].toLowerCase().indexOf('ös') > -1) || (pmDesignator && parts[1].toLowerCase().indexOf(pmDesignator) > -1)); hour = parseInt(parts[0], 10); min = parseInt(parts[1], 10); hour = isPM && hour < 12 ? hour + 12 : hour; return ('0' + hour).substr(-2) + ':' + ('0' + min).substr(-2); } } function parseDateTime(dt, culture) { const result = { date: '', time: '' }; culture = culture || {}; let dateFormat = (culture.dateFormat || '').toLowerCase(); let pmDesignator = (culture.pmDesignator || ''); const parts = dt.split(' '); if (parts[0]) { if (parts[0].indexOf('/') >= 0) { // Dateformat: mm/dd/yyyy or dd/mm/yyyy or dd/mm/yy or yyyy/mm/dd const dtparts = parts[0].split('/'); if (dtparts.length === 3) { if (dtparts[0].length === 4) { // Dateformat: yyyy/mm/dd result.date = dtparts[0] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[2]).substr(-2); } else if (dtparts[2].length === 2) { if ((dateFormat.indexOf('/d/') > -1 || dateFormat.indexOf('/dd/') > -1)) { // Dateformat: mm/dd/yy result.date = '20' + dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2); } else { // Dateformat: dd/mm/yy result.date = '20' + dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2); } } else { // Dateformat: mm/dd/yyyy or dd/mm/yyyy const isEN = ((dt.toLowerCase().indexOf('pm') > -1) || (dt.toLowerCase().indexOf('p.m.') > -1) || (dt.toLowerCase().indexOf('p. m.') > -1) || (dt.toLowerCase().indexOf('am') > -1) || (dt.toLowerCase().indexOf('a.m.') > -1) || (dt.toLowerCase().indexOf('a. m.') > -1)); if ((isEN || dateFormat.indexOf('/d/') > -1 || dateFormat.indexOf('/dd/') > -1) && dateFormat.indexOf('dd/') !== 0) { // Dateformat: mm/dd/yyyy result.date = dtparts[2] + '-' + ('0' + dtparts[0]).substr(-2) + '-' + ('0' + dtparts[1]).substr(-2); } else { // Dateformat: dd/mm/yyyy result.date = dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2); } } } } if (parts[0].indexOf('.') >= 0) { const dtparts = parts[0].split('.'); if (dtparts.length === 3) { if (dateFormat.indexOf('.d.') > -1 || dateFormat.indexOf('.dd.') > -1) { // Dateformat: mm.dd.yyyy result.date = dtparts[2] + '-' + ('0' + dtparts[0]).substr(-2) + '-' + ('0' + dtparts[1]).substr(-2); } else { // Dateformat: dd.mm.yyyy result.date = dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2); } } } if (parts[0].indexOf('-') >= 0) { // Dateformat: yyyy-mm-dd const dtparts = parts[0].split('-'); if (dtparts.length === 3) { result.date = dtparts[0] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[2]).substr(-2); } } } if (parts[1]) { parts.shift(); let time = parts.join(' '); result.time = parseTime(time, pmDesignator); } return result; } function parseHead(head, rights) { let space = (rights > 0); let count = 1; let from = 0; let to = 0; let result = []; for (let i = 0; i < head.length; i++) { if (count <= rights) { if (/\s/.test(head[i]) && !space) { to = i - 1; result.push({ from: from, to: to + 1, cap: head.substring(from, to + 1) }); from = to + 2; count++; } space = head[i] === ' '; } else { if (!/\s/.test(head[i]) && space) { to = i - 1; if (from < to) { result.push({ from: from, to: to, cap: head.substring(from, to) }); } from = to + 1; count++; } space = head[i] === ' '; } } to = 5000; result.push({ from: from, to: to, cap: head.substring(from, to) }); let len = result.length; for (let i = 0; i < len; i++) { if (result[i].cap.replace(/\s/g, '').length === 0) { if (i + 1 < len) { result[i].to = result[i + 1].to; result[i].cap = result[i].cap + result[i + 1].cap; result.splice(i + 1, 1); len = len - 1; } } } return result; } function findObjectByKey(array, key, value) { for (let i = 0; i < array.length; i++) { if (array[i][key] === value) { return i; } } return -1; } function getPowershell() { _powerShell = 'powershell.exe'; if (_windows) { const defaultPath = `${WINDIR}\\system32\\WindowsPowerShell\\v1.0\\powershell.exe`; if (fs.existsSync(defaultPath)) { _powerShell = defaultPath; } } } function getWmic() { if (os.type() === 'Windows_NT' && !wmicPath) { wmicPath = WINDIR + '\\system32\\wbem\\wmic.exe'; if (!fs.existsSync(wmicPath)) { try { const wmicPathArray = execSync('WHERE WMIC', execOptsWin).toString().split('\r\n'); if (wmicPathArray && wmicPathArray.length) { wmicPath = wmicPathArray[0]; } else { wmicPath = 'wmic'; } } catch (e) { wmicPath = 'wmic'; } } } return wmicPath; } function wmic(command) { return new Promise((resolve) => { process.nextTick(() => { try { powerShell(getWmic() + ' ' + command).then(stdout => { resolve(stdout, ''); }); } catch (e) { resolve('', e); } }); }); } function getVboxmanage() { return _windows ? `"${process.env.VBOX_INSTALL_PATH || process.env.VBOX_MSI_INSTALL_PATH}\\VBoxManage.exe"` : 'vboxmanage'; } function powerShellProceedResults(data) { let id = ''; let parts; let res = ''; // startID if (data.indexOf(_psCmdStart) >= 0) { parts = data.split(_psCmdStart); const parts2 = parts[1].split(_psIdSeperator); id = parts2[0]; if (parts2.length > 1) { data = parts2.slice(1).join(_psIdSeperator); } } // result; if (data.indexOf(_psCmdSeperator) >= 0) { parts = data.split(_psCmdSeperator); res = parts[0]; } let remove = -1; for (let i = 0; i < _psCmds.length; i++) { if (_psCmds[i].id === id) { remove = i; _psCmds[i].callback(res); } } if (remove >= 0) { _psCmds.splice(remove, 1); } } function powerShellStart() { if (!_psChild) { _psChild = spawn(_powerShell, ['-NoProfile', '-NoLogo', '-InputFormat', 'Text', '-NoExit', '-Command', '-'], { stdio: 'pipe', windowsHide: true, maxBuffer: 1024 * 20000, encoding: 'UTF-8', env: Object.assign({}, process.env, { LANG: 'en_US.UTF-8' }) }); if (_psChild && _psChild.pid) { _psPersistent = true; _psChild.stdout.on('data', function (data) { _psResult = _psResult + data.toString('utf8'); if (data.indexOf(_psCmdSeperator) >= 0) { powerShellProceedResults(_psResult); _psResult = ''; } }); _psChild.stderr.on('data', function () { powerShellProceedResults(_psResult + _psError); }); _psChild.on('error', function () { powerShellProceedResults(_psResult + _psError); }); _psChild.on('close', function () { if (_psChild) { _psChild.kill(); } }); } } } function powerShellRelease() { try { if (_psChild) { _psChild.stdin.write('exit' + os.EOL); _psChild.stdin.end(); _psPersistent = false; } } catch (e) { if (_psChild) { _psChild.kill(); } } _psChild = null; } function powerShell(cmd) { /// const pattern = [ /// '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', /// '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))' /// ].join('|'); if (_psPersistent) { const id = Math.random().toString(36).substring(2, 12); return new Promise((resolve) => { process.nextTick(() => { function callback(data) { resolve(data); } _psCmds.push({ id, cmd, callback, start: new Date() }); try { if (_psChild && _psChild.pid) { _psChild.stdin.write(_psToUTF8 + 'echo ' + _psCmdStart + id + _psIdSeperator + '; ' + os.EOL + cmd + os.EOL + 'echo ' + _psCmdSeperator + os.EOL); } } catch (e) { resolve(''); } }); }); } else { let result = ''; return new Promise((resolve) => { process.nextTick(() => { try { const child = spawn(_powerShell, ['-NoProfile', '-NoLogo', '-InputFormat', 'Text', '-ExecutionPolicy', 'Unrestricted', '-Command', cmd], { stdio: 'pipe', windowsHide: true, maxBuffer: 1024 * 20000, encoding: 'UTF-8', env: Object.assign({}, process.env, { LANG: 'en_US.UTF-8' }) }); if (child && !child.pid) { child.on('error', function () { resolve(result); }); } if (child && child.pid) { child.stdout.on('data', function (data) { result = result + data.toString('utf8'); }); child.stderr.on('data', function () { child.kill(); resolve(result); }); child.on('close', function () { child.kill(); resolve(result); }); child.on('error', function () { child.kill(); resolve(result); }); // try { // child.stdin.write(_psToUTF8 + cmd + os.EOL); // child.stdin.write('exit' + os.EOL); // child.stdin.end(); // } catch (e) { // child.kill(); // resolve(result); // } } else { resolve(result); } } catch (e) { resolve(result); } }); }); } } function execSafe(cmd, args, options) { let result = ''; options = options || {}; return new Promise((resolve) => { process.nextTick(() => { try { const child = spawn(cmd, args, options); if (child && !child.pid) { child.on('error', function () { resolve(result); }); } if (child && child.pid) { child.stdout.on('data', function (data) { result += data.toString(); }); child.on('close', function () { child.kill(); resolve(result); }); child.on('error', function () { child.kill(); resolve(result); }); } else { resolve(result); } } catch (e) { resolve(result); } }); }); } function getCodepage() { if (_windows) { if (!codepage) { try { const stdout = execSync('chcp', execOptsWin); const lines = stdout.toString().split('\r\n'); const parts = lines[0].split(':'); codepage = parts.length > 1 ? parts[1].replace('.', '').trim() : ''; } catch (err) { codepage = '437'; } } return codepage; } if (_linux || _darwin || _freebsd || _openbsd || _netbsd) { if (!codepage) { try { const stdout = execSync('echo $LANG', execOptsLinux); const lines = stdout.toString().split('\r\n'); const parts = lines[0].split('.'); codepage = parts.length > 1 ? parts[1].trim() : ''; if (!codepage) { codepage = 'UTF-8'; } } catch (err) { codepage = 'UTF-8'; } } return codepage; } } function smartMonToolsInstalled() { if (_smartMonToolsInstalled !== null) { return _smartMonToolsInstalled; } _smartMonToolsInstalled = false; if (_windows) { try { const pathArray = execSync('WHERE smartctl 2>nul', execOptsWin).toString().split('\r\n'); if (pathArray && pathArray.length) { _smartMonToolsInstalled = pathArray[0].indexOf(':\\') >= 0; } else { _smartMonToolsInstalled = false; } } catch (e) { _smartMonToolsInstalled = false; } } if (_linux || _darwin || _freebsd || _openbsd || _netbsd) { try { const pathArray = execSync('which smartctl 2>/dev/null', execOptsLinux).toString().split('\r\n'); _smartMonToolsInstalled = pathArray.length > 0; } catch (e) { util.noop(); } } return _smartMonToolsInstalled; } // reference values: https://elinux.org/RPi_HardwareHistory // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md // https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#hardware-revision-codes function isRaspberry(cpuinfo) { const PI_MODEL_NO = [ 'BCM2708', 'BCM2709', 'BCM2710', 'BCM2711', 'BCM2712', 'BCM2835', 'BCM2836', 'BCM2837', 'BCM2837B0' ]; if (_rpi_cpuinfo !== null) { cpuinfo = _rpi_cpuinfo; } else if (cpuinfo === undefined) { try { cpuinfo = fs.readFileSync('/proc/cpuinfo', { encoding: 'utf8' }).toString().split('\n'); _rpi_cpuinfo = cpuinfo; } catch (e) { return false; } } const hardware = getValue(cpuinfo, 'hardware'); const model = getValue(cpuinfo, 'model'); return ((hardware && PI_MODEL_NO.indexOf(hardware) > -1) || (model && model.indexOf('Raspberry Pi') > -1)); } function isRaspbian() { let osrelease = []; try { osrelease = fs.readFileSync('/etc/os-release', { encoding: 'utf8' }).toString().split('\n'); } catch (e) { return false; } const id = getValue(osrelease, 'id', '='); return (id && id.indexOf('raspbian') > -1); } function execWin(cmd, opts, callback) { if (!callback) { callback = opts; opts = execOptsWin; } let newCmd = 'chcp 65001 > nul && cmd /C ' + cmd + ' && chcp ' + codepage + ' > nul'; exec(newCmd, opts, function (error, stdout) { callback(error, stdout); }); } function darwinXcodeExists() { const cmdLineToolsExists = fs.existsSync('/Library/Developer/CommandLineTools/usr/bin/'); const xcodeAppExists = fs.existsSync('/Applications/Xcode.app/Contents/Developer/Tools'); const xcodeExists = fs.existsSync('/Library/Developer/Xcode/'); return (cmdLineToolsExists || xcodeExists || xcodeAppExists); } function nanoSeconds() { const time = process.hrtime(); if (!Array.isArray(time) || time.length !== 2) { return 0; } return +time[0] * 1e9 + +time[1]; } function countUniqueLines(lines, startingWith) { startingWith = startingWith || ''; const uniqueLines = []; lines.forEach(line => { if (line.startsWith(startingWith)) { if (uniqueLines.indexOf(line) === -1) { uniqueLines.push(line); } } }); return uniqueLines.length; } function countLines(lines, startingWith) { startingWith = startingWith || ''; const uniqueLines = []; lines.forEach(line => { if (line.startsWith(startingWith)) { uniqueLines.push(line); } }); return uniqueLines.length; } function sanitizeShellString(str, strict) { if (typeof strict === 'undefined') { strict = false; } const s = str || ''; let result = ''; const l = mathMin(s.length, 2000); for (let i = 0; i <= l; i++) { if (!(s[i] === undefined || s[i] === '>' || s[i] === '<' || s[i] === '*' || s[i] === '?' || s[i] === '[' || s[i] === ']' || s[i] === '|' || s[i] === '˚' || s[i] === '$' || s[i] === ';' || s[i] === '&' || s[i] === ']' || s[i] === '#' || s[i] === '\\' || s[i] === '\t' || s[i] === '\n' || s[i] === '\r' || s[i] === '\'' || s[i] === '`' || s[i] === '"' || s[i].length > 1 || (strict && s[i] === '(') || (strict && s[i] === ')') || (strict && s[i] === '@') || (strict && s[i] === ' ') || (strict && s[i] == '{') || (strict && s[i] == ';') || (strict && s[i] == '}'))) { result = result + s[i]; } } return result; } function isPrototypePolluted() { const s = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; let notPolluted = true; let st = ''; try { st.__proto__.replace = stringReplace; st.__proto__.toLowerCase = stringToLower; st.__proto__.toString = stringToString; st.__proto__.substr = stringSubstr; st.__proto__.substring = stringSubstring; st.__proto__.trim = stringTrim; st.__proto__.startsWith = stringStartWith; } catch (e) { Object.setPrototypeOf(st, stringObj); } notPolluted = notPolluted || (s.length !== 62); const ms = Date.now(); if (typeof ms === 'number' && ms > 1600000000000) { const l = ms % 100 + 15; for (let i = 0; i < l; i++) { const r = Math.random() * 61.99999999 + 1; const rs = parseInt(Math.floor(r).toString(), 10); const rs2 = parseInt(r.toString().split('.')[0], 10); const q = Math.random() * 61.99999999 + 1; const qs = parseInt(Math.floor(q).toString(), 10); const qs2 = parseInt(q.toString().split('.')[0], 10); notPolluted = notPolluted && (r !== q); notPolluted = notPolluted && rs === rs2 && qs === qs2; st += s[rs - 1]; } notPolluted = notPolluted && st.length === l; // string manipulation let p = Math.random() * l * 0.9999999999; let stm = st.substr(0, p) + ' ' + st.substr(p, 2000); try { stm.__proto__.replace = stringReplace; } catch (e) { Object.setPrototypeOf(stm, stringObj); } let sto = stm.replace(/ /g, ''); notPolluted = notPolluted && st === sto; p = Math.random() * l * 0.9999999999; stm = st.substr(0, p) + '{' + st.substr(p, 2000); sto = stm.replace(/{/g, ''); notPolluted = notPolluted && st === sto; p = Math.random() * l * 0.9999999999; stm = st.substr(0, p) + '*' + st.substr(p, 2000); sto = stm.replace(/\*/g, ''); notPolluted = notPolluted && st === sto; p = Math.random() * l * 0.9999999999; stm = st.substr(0, p) + '$' + st.substr(p, 2000); sto = stm.replace(/\$/g, ''); notPolluted = notPolluted && st === sto; // lower const stl = st.toLowerCase(); notPolluted = notPolluted && (stl.length === l) && stl[l - 1] && !(stl[l]); for (let i = 0; i < l; i++) { const s1 = st[i]; try { s1.__proto__.toLowerCase = stringToLower; } catch (e) { Object.setPrototypeOf(st, stringObj); } const s2 = stl ? stl[i] : ''; const s1l = s1.toLowerCase(); notPolluted = notPolluted && s1l[0] === s2 && s1l[0] && !(s1l[1]); } } return !notPolluted; } function hex2bin(hex) { return ('00000000' + (parseInt(hex, 16)).toString(2)).substr(-8); } function getFilesInPath(source) { const lstatSync = fs.lstatSync; const readdirSync = fs.readdirSync; const join = path.join; function isDirectory(source) { return lstatSync(source).isDirectory(); } function isFile(source) { return lstatSync(source).isFile(); } function getDirectories(source) { return readdirSync(source).map(function (name) { return join(source, name); }).filter(isDirectory); } function getFiles(source) { return readdirSync(source).map(function (name) { return join(source, name); }).filter(isFile); } function getFilesRecursively(source) { try { let dirs = getDirectories(source); let files = dirs .map(function (dir) { return getFilesRecursively(dir); }) .reduce(function (a, b) { return a.concat(b); }, []); return files.concat(getFiles(source)); } catch (e) { return []; } } if (fs.existsSync(source)) { return getFilesRecursively(source); } else { return []; } } function decodePiCpuinfo(lines) { if (_rpi_cpuinfo === null) { _rpi_cpuinfo = lines; } else if (lines === undefined) { lines = _rpi_cpuinfo; } // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md const oldRevisionCodes = { '0002': { type: 'B', revision: '1.0', memory: 256, manufacturer: 'Egoman', processor: 'BCM2835' }, '0003': { type: 'B', revision: '1.0', memory: 256, manufacturer: 'Egoman', processor: 'BCM2835' }, '0004': { type: 'B', revision: '2.0', memory: 256, manufacturer: 'Sony UK', processor: 'BCM2835' }, '0005': { type: 'B', revision: '2.0', memory: 256, manufacturer: 'Qisda', processor: 'BCM2835' }, '0006': { type: 'B', revision: '2.0', memory: 256, manufacturer: 'Egoman', processor: 'BCM2835' }, '0007': { type: 'A', revision: '2.0', memory: 256, manufacturer: 'Egoman', processor: 'BCM2835' }, '0008': { type: 'A', revision: '2.0', memory: 256, manufacturer: 'Sony UK', processor: 'BCM2835' }, '0009': { type: 'A', revision: '2.0', memory: 256, manufacturer: 'Qisda', processor: 'BCM2835' }, '000d': { type: 'B', revision: '2.0', memory: 512, manufacturer: 'Egoman', processor: 'BCM2835' }, '000e': { type: 'B', revision: '2.0', memory: 512, manufacturer: 'Sony UK', processor: 'BCM2835' }, '000f': { type: 'B', revision: '2.0', memory: 512, manufacturer: 'Egoman', processor: 'BCM2835' }, '0010': { type: 'B+', revision: '1.2', memory: 512, manufacturer: 'Sony UK', processor: 'BCM2835' }, '0011': { type: 'CM1', revision: '1.0', memory: 512, manufacturer: 'Sony UK', processor: 'BCM2835' }, '0012': { type: 'A+', revision: '1.1', memory: 256, manufacturer: 'Sony UK', processor: 'BCM2835' }, '0013': { type: 'B+', revision: '1.2', memory: 512, manufacturer: 'Embest', processor: 'BCM2835' }, '0014': { type: 'CM1', revision: '1.0', memory: 512, manufacturer: 'Embest', processor: 'BCM2835' }, '0015': { type: 'A+', revision: '1.1', memory: 256, manufacturer: '512MB Embest', processor: 'BCM2835' } }; const processorList = [ 'BCM2835', 'BCM2836', 'BCM2837', 'BCM2711', 'BCM2712', ]; const manufacturerList = [ 'Sony UK', 'Egoman', 'Embest', 'Sony Japan', 'Embest', 'Stadium' ]; const typeList = { '00': 'A', '01': 'B', '02': 'A+', '03': 'B+', '04': '2B', '05': 'Alpha (early prototype)', '06': 'CM1', '08': '3B', '09': 'Zero', '0a': 'CM3', '0c': 'Zero W', '0d': '3B+', '0e': '3A+', '0f': 'Internal use only', '10': 'CM3+', '11': '4B', '12': 'Zero 2 W', '13': '400', '14': 'CM4', '15': 'CM4S', '16': 'Internal use only', '17': '5', '18': 'CM5', '19': '500', '1a': 'CM5 Lite', }; const revisionCode = getValue(lines, 'revision', ':', true); const model = getValue(lines, 'model:', ':', true); const serial = getValue(lines, 'serial', ':', true); let result = {}; if ({}.hasOwnProperty.call(oldRevisionCodes, revisionCode)) { // old revision codes result = { model, serial, revisionCode, memory: oldRevisionCodes[revisionCode].memory, manufacturer: oldRevisionCodes[revisionCode].manufacturer, processor: oldRevisionCodes[revisionCode].processor, type: oldRevisionCodes[revisionCode].type, revision: oldRevisionCodes[revisionCode].revision, }; } else { // new revision code const revision = ('00000000' + getValue(lines, 'revision', ':', true).toLowerCase()).substr(-8); const memSizeCode = parseInt(hex2bin(revision.substr(2, 1)).substr(5, 3), 2) || 0; const manufacturer = manufacturerList[parseInt(revision.substr(3, 1), 10)]; const processor = processorList[parseInt(revision.substr(4, 1), 10)]; const typeCode = revision.substr(5, 2); result = { model, serial, revisionCode, memory: 256 * Math.pow(2, memSizeCode), manufacturer, processor, type: {}.hasOwnProperty.call(typeList, typeCode) ? typeList[typeCode] : '', revision: '1.' + revision.substr(7, 1), }; } return result; } function getRpiGpu(cpuinfo) { if (_rpi_cpuinfo === null && cpuinfo !== undefined) { _rpi_cpuinfo = cpuinfo; } else if (cpuinfo === undefined && _rpi_cpuinfo !== null) { cpuinfo = _rpi_cpuinfo; } else { try { cpuinfo = fs.readFileSync('/proc/cpuinfo', { encoding: 'utf8' }).toString().split('\n'); _rpi_cpuinfo = cpuinfo; } catch (e) { return false; } } const rpi = decodePiCpuinfo(cpuinfo); if (rpi.type === '4B' || rpi.type === 'CM4' || rpi.type === 'CM4S' || rpi.type === '400') { return 'VideoCore VI'; } if (rpi.type === '5' || rpi.type === '500') { return 'VideoCore VII'; } return 'VideoCore IV'; } function promiseAll(promises) { const resolvingPromises = promises.map(function (promise) { return new Promise(function (resolve) { let payload = new Array(2); promise.then(function (result) { payload[0] = result; }) .catch(function (error) { payload[1] = error; }) .then(function () { // The wrapped Promise returns an array: 0 = result, 1 = error ... we resolve all resolve(payload); }); }); }); const errors = []; const results = []; // Execute all wrapped Promises return Promise.all(resolvingPromises) .then(function (items) { items.forEach(function (payload) { if (payload[1]) { errors.push(payload[1]); results.push(null); } else { errors.push(null); results.push(payload[0]); } }); return { errors: errors, results: results }; }); } function promisify(nodeStyleFunction) { return function () { const args = Array.prototype.slice.call(arguments); return new Promise(function (resolve, reject) { args.push(function (err, data) { if (err) { reject(err); } else { resolve(data); } }); nodeStyleFunction.apply(null, args); }); }; } function promisifySave(nodeStyleFunction) { return function () { const args = Array.prototype.slice.call(arguments); return new Promise(function (resolve) { args.push(function (err, data) { resolve(data); }); nodeStyleFunction.apply(null, args); }); }; } function linuxVersion() { let result = ''; if (_linux) { try { result = execSync('uname -v', execOptsLinux).toString(); } catch (e) { result = ''; } } return result; } function plistParser(xmlStr) { const tags = ['array', 'dict', 'key', 'string', 'integer', 'date', 'real', 'data', 'boolean', 'arrayEmpty']; const startStr = '<plist version'; let pos = xmlStr.indexOf(startStr); let len = xmlStr.length; while (xmlStr[pos] !== '>' && pos < len) { pos++; } let depth = 0; let inTagStart = false; let inTagContent = false; let inTagEnd = false; let metaData = [{ tagStart: '', tagEnd: '', tagContent: '', key: '', data: null }]; let c = ''; let cn = xmlStr[pos]; while (pos < len) { c = cn; if (pos + 1 < len) { cn = xmlStr[pos + 1]; } if (c === '<') { inTagContent = false; if (cn === '/') { inTagEnd = true; } else if (metaData[depth].tagStart) { metaData[depth].tagContent = ''; if (!metaData[depth].data) { metaData[depth].data = metaData[depth].tagStart === 'array' ? [] : {}; } depth++; metaData.push({ tagStart: '', tagEnd: '', tagContent: '', key: null, data: null }); inTagStart = true; inTagContent = false; } else if (!inTagStart) { inTagStart = true; } } else if (c === '>') { if (metaData[depth].tagStart === 'true/') { inTagStart = false; inTagEnd = true; metaData[depth].tagStart = ''; metaData[depth].tagEnd = '/boolean'; metaData[depth].data = true; } if (metaData[depth].tagStart === 'false/') { inTagStart = false; inTagEnd = true; metaData[depth].tagStart = ''; metaData[depth].tagEnd = '/boolean'; metaData[depth].data = false; } if (metaData[depth].tagStart === 'array/') { inTagStart = false; inTagEnd = true; metaData[depth].tagStart = ''; metaData[depth].tagEnd = '/arrayEmpty'; metaData[depth].data = []; } if (inTagContent) { inTagContent = false; } if (inTagStart) { inTagStart = false; inTagContent = true; if (metaData[depth].tagStart === 'array') { metaData[depth].data = []; } if (metaData[depth].tagStart === 'dict') { metaData[depth].data = {}; } } if (inTagEnd) { inTagEnd = false; if (metaData[depth].tagEnd && tags.indexOf(metaData[depth].tagEnd.substr(1)) >= 0) { if (metaData[depth].tagEnd === '/dict' || metaData[depth].tagEnd === '/array') { if (depth > 1 && metaData[depth - 2].tagStart === 'array') { metaData[depth - 2].data.push(metaData[depth - 1].data); } if (depth > 1 && metaData[depth - 2].tagStart === 'dict') { metaData[depth - 2].data[metaData[depth - 1].key] = metaData[depth - 1].data; } depth--; metaData.pop(); metaData[depth].tagContent = ''; metaData[depth].tagStart = ''; metaData[depth].tagEnd = ''; } else { if (metaData[depth].tagEnd === '/key' && metaData[depth].tagContent) { metaData[depth].key = metaData[depth].tagContent; } else { if (metaData[depth].tagEnd === '/real' && metaData[depth].tagContent) { metaData[depth].data = parseFloat(metaData[depth].tagContent) || 0; } if (metaData[depth].tagEnd === '/integer' && metaData[depth].tagContent) { metaData[depth].data = parseInt(metaData[depth].tagContent) || 0; } if (metaData[depth].tagEnd === '/string' && metaData[depth].tagContent) { metaData[depth].data = metaData[depth].tagContent || ''; } if (metaData[depth].tagEnd === '/boolean') { metaData[depth].data = metaData[depth].tagContent || false; } if (metaData[depth].tagEnd === '/arrayEmpty') { metaData[depth].data = metaData[depth].tagContent || []; } if (depth > 0 && metaData[depth - 1].tagStart === 'array') { metaData[depth - 1].data.push(metaData[depth].data); } if (depth > 0 && metaData[depth - 1].tagStart === 'dict') { metaData[depth - 1].data[metaData[depth].key] = metaData[depth].data; } } metaData[depth].tagContent = ''; metaData[depth].tagStart = ''; metaData[depth].tagEnd = ''; } } metaData[depth].tagEnd = ''; inTagStart = false; inTagContent = false; } } else { if (inTagStart) { metaData[depth].tagStart += c; } if (inTagEnd) { metaData[depth].tagEnd += c; } if (inTagContent) { metaData[depth].tagContent += c; } } pos++; } return metaData[0].data; } function strIsNumeric(str) { return typeof str === 'string' && !isNaN(str) && !isNaN(parseFloat(str)); } function plistReader(output) { const lines = output.split('\n'); for (let i = 0; i < lines.length; i++) { if (lines[i].indexOf(' = ') >= 0) { const lineParts = lines[i].split(' = '); lineParts[0] = lineParts[0].trim(); if (!lineParts[0].startsWith('"')) { lineParts[0] = '"' + lineParts[0] + '"'; } lineParts[1] = lineParts[1].trim(); if (lineParts[1].indexOf('"') === -1 && lineParts[1].endsWith(';')) { const valueString = lineParts[1].substring(0, lineParts[1].length - 1); if (!strIsNumeric(valueString)) { lineParts[1] = `"${valueString}";`; } } if (lineParts[1].indexOf('"') >= 0 && lineParts[1].endsWith(';')) { const valueString = lineParts[1].substring(0, lineParts[1].length - 1).replace(/"/g, ''); if (strIsNumeric(valueString)) { lineParts[1] = `${valueString};`; } } lines[i] = lineParts.join(' : '); } lines[i] = lines[i].replace(/\(/g, '[').replace(/\)/g, ']').replace(/;/g, ',').trim(); if (lines[i].startsWith('}') && lines[i - 1] && lines[i - 1].endsWith(',')) { lines[i - 1] = lines[i - 1].substring(0, lines[i - 1].length - 1); } } output = lines.join(''); let obj = {}; try { obj = JSON.parse(output); } catch (e) { noop(); } return obj; } function semverCompare(v1, v2) { let res = 0; const parts1 = v1.split('.'); const parts2 = v2.split('.'); if (parts1[0] < parts2[0]) { res = 1; } else if (parts1[0] > parts2[0]) { res = -1; } else if (parts1[0] === parts2[0] && parts1.length >= 2 && parts2.length >= 2) { if (parts1[1] < parts2[1]) { res = 1; } else if (parts1[1] > parts2[1]) { res = -1; } else if (parts1[1] === parts2[1]) { if (parts1.length >= 3 && parts2.length >= 3) { if (parts1[2] < parts2[2]) { res = 1; } else if (parts1[2] > parts2[2]) { res = -1; } } else if (parts2.length >= 3) { res = 1; } } } return res; } function getAppleModel(key) { const appleModelIds = [ { key: 'Mac15,12', name: 'MacBook Air', size: '13-inch', processor: 'M3', year: '2024', additional: '' }, { key: 'Mac14,15', name: 'MacBook Air', size: '15-inch', processor: 'M2', year: '2024', additional: '' }, { key: 'Mac14,2', name: 'MacBook Air', size: '13-inch', processor: 'M2', year: '2022', additional: '' }, { key: 'MacBookAir10,1', name: 'MacBook Air', size: '13-inch', processor: 'M1', year: '2020', additional: '' }, { key: 'MacBookAir9,1', name: 'MacBook Air', size: '13-inch', processor: '', year: '2020', additional: '' }, { key: 'MacBookAir8,2', name: 'MacBook Air', size: '13-inch', processor: '', year: '2019', additional: '' }, { key: 'MacBookAir8,1', name: 'MacBook Air', size: '13-inch', processor: '', year: '2018', additional: '' }, { key: 'MacBookAir7,2', name: 'MacBook Air', size: '13-inch', processor: '', year: '2017', additional: '' }, { key: 'MacBookAir7,2', name: 'MacBook Air', size: '13-inch', processor: '', year: 'Early 2015', additional: '' }, { key: 'MacBookAir7,1', name: 'MacBook Air', size: '11-inch', processor: '', year: 'Early 2015', additional: '' }, { key: 'MacBookAir6,2', name: 'MacBook Air', size: '13-inch', processor: '', year: 'Early 2014', additional: '' }, { key: 'MacBookAir6,1', name: 'MacBook Air', size: '11-inch', processor: '', year: 'Early 2014', additional: '' }, { key: 'MacBookAir6,2', name: 'MacBook Air', size: '13-inch', processor: '', year: 'Mid 2013', additional: '' }, { key: 'MacBookAir6,1', name: 'MacBook Air', size: '11-inch', processor: '', year: 'Mid 2013', additional: '' }, { key: 'MacBookAir5,2', name: 'MacBook Air', size: '13-inch', processor: '', year: 'Mid 2012', additional: '' }, { key: 'MacBookAir5,1', name: 'MacBook Air', size: '11-inch', processor: '', year: 'Mid 2012', additional: '' }, { key: 'MacBookAir4,2', name: 'MacBook Air', size: '13-inch', processor: '', year: 'Mid 2011', additional: '' }, { key: 'MacBookAir4,1', name: 'MacBook Air', size: '11-inch', processor: '', year: 'Mid 2011', additional: '' }, { key: 'MacBookAir3,2', name: 'MacBook Air', size: '13-inch', processor: '', year: 'Late 2010', additional: '' }, { key: 'MacBookAir3,1', name: 'MacBook Air', size: '11-inch', processor: '', year: 'Late 2010', additional: '' }, { key: 'MacBookAir2,1', name: 'MacBook Air', size: '13-inch', processor: '', year: 'Mid 2009', additional: '' }, { key: 'Mac16,1', name: 'MacBook Pro', size: '14-inch', processor: 'M4', year: '2024', additional: '' }, { key: 'Mac16,6', name: 'MacBook Pro', size: '14-inch', processor: 'M4 Pro', year: '2024', additional: '' }, { key: 'Mac16,8', name: 'MacBook Pro', size: '14-inch', processor: 'M4 Max', year: '2024', additional: '' }, { key: 'Mac16,5', name: 'MacBook Pro', size: '16-inch', processor: 'M4 Pro', year: '2024', additional: '' }, { key: 'Mac16,6', name: 'MacBook Pro', size: '16-inch', processor: 'M4 Max', year: '2024', additional: '' }, { key: 'Mac15,3', name: 'MacBook Pro', size: '14-inch', processor: 'M3', year: 'Nov 2023', additional: '' }, { key: 'Mac15,6', name: 'MacBook Pro', size: '14-inch', processor: 'M3 Pro', year: 'Nov 2023', additional: '' }, { key: 'Mac15,8', name: 'MacBook Pro', size: '14-inch', processor: 'M3 Pro', year: 'Nov 2023', additional: '' }, { key: 'Mac15,10', name: 'MacBook Pro', size: '14-inch', processor: 'M3 Max', year: 'Nov 2023', additional: '' }, { key: 'Mac15,7', name: 'MacBook Pro', size: '16-inch', processor: 'M3 Pro', year: 'Nov 2023', additional: '' }, { key: 'Mac15,9', name: 'MacBook Pro', size: '16-inch', processor: 'M3 Pro', year: 'Nov 2023', additional: '' }, { key: 'Mac15,11', name: 'MacBook Pro', size: '16-inch', processor: 'M3 Max', year: 'Nov 2023', additional: '' }, { key: 'Mac14,5', name: 'MacBook Pro', size: '14-inch', processor: 'M2 Max', year: '2023', additional: '' }, { key: 'Mac14,9', name: 'MacBook Pro', size: '14-inch', processor: 'M2 Max', year: '2023', additional: '' }, { key: 'Mac14,6', name: 'MacBook Pro', size: '16-inch', processor: 'M2 Max', year: '2023', additional: '' }, { key: 'Mac14,10', name: 'MacBook Pro', size: '16-inch', processor: 'M2 Max', year: '2023', additional: '' }, { key: 'Mac14,7', name: 'MacBook Pro', size: '13-inch', processor: 'M2', year: '2022', additional: '' }, { key: 'MacBookPro18,3', name: 'MacBook Pro', size: '14-inch', processor: 'M1 Pro', year: '2021', additional: '' }, { key: 'MacBookPro18,4', name: 'MacBook Pro', size: '14-inch', processor: 'M1 Max', year: '2021', additional: '' }, { key: 'MacBookPro18,1', name: 'MacBook Pro', size: '16-inch', processor: 'M1 Pro', year: '2021', additional: '' }, { key: 'MacBookPro18,2', name: 'MacBook Pro', size: '16-inch', processor: 'M1 Max', year: '2021', additional: '' }, { key: 'MacBookPro17,1', name: 'MacBook Pro', size: '13-inch', processor: 'M1', year: '2020', additional: '' }, { key: 'MacBookPro16,3', name: 'MacBook Pro', size: '13-inch', processor: '', year: '2020', additional: 'Two Thunderbolt 3 ports' }, { key: 'MacBookPro16,2', name: 'MacBook Pro', size: '13-inch', processor: '', year: '2020', additional: 'Four Thunderbolt 3 ports' }, { key: 'MacBookPro16,1', name: 'MacBook Pro', size: '16-inch', processor: '', year: '2019', additional: '' }, { key: 'MacBookPro16,4', name: 'MacBook Pro', size: '16-inch', processor: '', year: '2019', additional: '' }, { key: 'MacBookPro15,3', name: 'MacBook Pro', size: '15-inch', processor: '', year: '2019', additional: '' }, { key: 'MacBookPro15,2', name: 'MacBook Pro', size: '13-inch', processor: '', year: '2019', additional: '' }, { key: 'MacBookPro15,1', name: 'MacBook Pro', size: '15-inch', processor: '', year: '2019', additional: '' }, { key: 'MacBookPro15,4', name: 'MacBook Pro', size: '13-inch', processor: '', year: '2019', additional: 'Two Thunderbolt 3 ports' }, { key: 'MacBookPro15,1', name: 'MacBook Pro', size: '15-inch', processor: '', year: '2018', additional: '' }, { key: 'MacBookPro15,2', name: 'MacBook Pro', size: '13-inch', processor: '', year: '2018', additional: 'Four Thunderbolt 3 ports' }, { key: 'MacBookPro14,1', name: 'MacBook Pro', size: '13-inch', processor: '', year: '2017', additional: 'Two Thunderbolt 3 ports' }, { key: 'MacBookPro14,2', name: 'MacBook Pro', size: '13-inch', processor: '', year: '2017', additional: 'Four Thunderbolt 3 ports' }, { key: 'MacBookPro14,3', name: 'MacBook Pro', size: '15-inch', processor: '', year: '2017', additional: '' }, { key: 'MacBookPro13,1', name: 'MacBook Pro', size: '13-inch', processor: '', year: '2016', additional: 'Two Thunderbolt 3 ports' }, { key: 'MacBookPro13,2', name: 'MacBook Pro', size: '13-inch', processor: '', year: '2016', additional: 'Four Thunderbolt 3 ports' }, { key: 'MacBookPro13,3', name: 'MacBook Pro', size: '15-inch', processor: '', year: '2016', additional: '' }, { key: 'MacBookPro11,4', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Mid 2015', additional: '' }, { key: 'MacBookPro11,5', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Mid 2015', additional: '' }, { key: 'MacBookPro12,1', name: 'MacBook Pro', size: '13-inch', processor: '', year: 'Early 2015', additional: '' }, { key: 'MacBookPro11,2', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Late 2013', additional: '' }, { key: 'MacBookPro11,3', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Late 2013', additional: '' }, { key: 'MacBookPro11,1', name: 'MacBook Pro', size: '13-inch', processor: '', year: 'Late 2013', additional: '' }, { key: 'MacBookPro10,1', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Mid 2012', additional: '' }, { key: 'MacBookPro10,2', name: 'MacBook Pro', size: '13-inch', processor: '', year: 'Late 2012', additional: '' }, { key: 'MacBookPro9,1', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Mid 2012', additional: '' }, { key: 'MacBookPro9,2', name: 'MacBook Pro', size: '13-inch', processor: '', year: 'Mid 2012', additional: '' }, { key: 'MacBookPro8,3', name: 'MacBook Pro', size: '17-inch', processor: '', year: 'Early 2011', additional: '' }, { key: 'MacBookPro8,2', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Early 2011', additional: '' }, { key: 'MacBookPro8,1', name: 'MacBook Pro', size: '13-inch', processor: '', year: 'Early 2011', additional: '' }, { key: 'MacBookPro6,1', name: 'MacBook Pro', size: '17-inch', processor: '', year: 'Mid 2010', additional: '' }, { key: 'MacBookPro6,2', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Mid 2010', additional: '' }, { key: 'MacBookPro7,1', name: 'MacBook Pro', size: '13-inch', processor: '', year: 'Mid 2010', additional: '' }, { key: 'MacBookPro5,2', name: 'MacBook Pro', size: '17-inch', processor: '', year: 'Early 2009', additional: '' }, { key: 'MacBookPro5,3', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Mid 2009', additional: '' }, { key: 'MacBookPro5,5', name: 'MacBook Pro', size: '13-inch', processor: '', year: 'Mid 2009', additional: '' }, { key: 'MacBookPro5,1', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Late 2008', additional: '' }, { key: 'MacBookPro4,1', name: 'MacBook Pro', size: '15-inch', processor: '', year: 'Early 2008', additional: '' }, { key: 'MacBook10,1', name: 'MacBook', size: '12-inch', processor: '', year: '2017', additional: '' }, { key: 'MacBook9,1', name: 'MacBook', size: '12-inch', processor: '', year: 'Early 2016', additional: '' }, { key: 'MacBook8,1', name: 'MacBook', size: '12-inch', processor: '', year: 'Early 2015', additional: '' }, { key: 'MacBook7,1', name: 'MacBook', size: '13-inch', processor: '', year: 'Mid 2010', additional: '' }, { key: 'MacBook6,1', name: 'MacBook', size: '13-inch', processor: '', year: 'Late 2009', additional: '' }, { key: 'MacBook5,2', name: 'MacBook', size: '13-inch', processor: '', year: 'Early 2009', additional: '' }, { key: 'Mac14,13', name: 'Mac Studio', size: '', processor: '', year: '2023', additional: '' }, { key: 'Mac14,14', name: 'Mac Studio', size: '', processor: '', year: '2023', additional: '' }, { key: 'Mac13,1', name: 'Mac Studio', size: '', processor: '', year: '2022', additional: '' }, { key: 'Mac13,2', name: 'Mac Studio', size: '', processor: '', year: '2022', additional: '' }, { key: 'Mac16,11', name: 'Mac mini', size: '', processor: 'M4 Pro', year: '2024', additional: '' }, { key: 'Mac16,10', name: 'Mac mini', size: '', processor: 'M4', year: '2024', additional: '' }, { key: 'Mac14,3', name: 'Mac mini', size: '', processor: 'M2', year: '2023', additional: '' }, { key: 'Mac14,12', name: 'Mac mini', size: '', processor: 'M2 Pro', year: '2023', additional: '' }, { key: 'Macmini9,1', name: 'Mac mini', size: '', processor: 'M1', year: '2020', additional: '' }, { key: 'Macmini8,1', name: 'Mac mini', size: '', processor: '', year: 'Late 2018', additional: '' }, { key: 'Macmini7,1', name: 'Mac mini', size: '', processor: '', year: 'Late 2014', additional: '' }, { key: 'Macmini6,1', name: 'Mac mini', size: '', processor: '', year: 'Late 2012', additional: '' }, { key: 'Macmini6,2', name: 'Mac mini', size: '', processor: '', year: 'Late 2012', additional: '' }, { key: 'Macmini5,1', name: 'Mac mini', size: '', processor: '', year: 'Mid 2011', additional: '' }, { key: 'Macmini5,2', name: 'Mac mini', size: '', processor: '', year: 'Mid 2011', additional: '' }, { key: 'Macmini4,1', name: 'Mac mini', size: '', processor: '', year: 'Mid 2010', additional: '' }, { key: 'Macmini3,1', name: 'Mac mini', size: '', processor: '', year: 'Early 2009', additional: '' }, { key: 'Mac16,3', name: 'iMac', size: '24-inch', processor: 'M4', year: '2024', additional: 'Four ports' }, { key: 'Mac16,2', name: 'iMac', size: '24-inch', processor: 'M4', year: '2024', additional: 'Two ports' }, { key: 'Mac15,5', name: 'iMac', size: '24-inch', processor: 'M3', year: '2023', additional: 'Four ports' }, { key: 'Mac15,4', name: 'iMac', size: '24-inch', processor: 'M3', year: '2023', additional: 'Two ports' }, { key: 'iMac21,1', name: 'iMac', size: '24-inch', processor: 'M1', year: '2021', additional: '' }, { key: 'iMac21,2', name: 'iMac', size: '24-inch', processor: 'M1', year: '2021', additional: '' }, { key: 'iMac20,1', name: 'iMac', size: '27-inch', processor: '', year: '2020', additional: 'Retina 5K' }, { key: 'iMac20,2', name: 'iMac', size: '27-inch', processor: '', year: '2020', additional: 'Retina 5K' }, { key: 'iMac19,1', name: 'iMac', size: '27-inch', processor: '', year: '2019', additional: 'Retina 5K' }, { key: 'iMac19,2', name: 'iMac', size: '21.5-inch', processor: '', year: '2019', additional: 'Retina 4K' }, { key: 'iMacPro1,1', name: 'iMac Pro', size: '', processor: '', year: '2017', additional: '' }, { key: 'iMac18,3', name: 'iMac', size: '27-inch', processor: '', year: '2017', additional: 'Retina 5K' }, { key: 'iMac18,2', name: 'iMac', size: '21.5-inch', processor: '', year: '2017', additional: 'Retina 4K' }, { key: 'iMac18,1', name: 'iMac', size: '21.5-inch', processor: '', year: '2017', additional: '' }, { key: 'iMac17,1', name: 'iMac', size: '27-inch', processor: '', year: 'Late 2015', additional: 'Retina 5K' }, { key: 'iMac16,2', name: 'iMac', size: '21.5-inch', processor: '', year: 'Late 2015', additional: 'Retina 4K' }, { key: 'iMac16,1', name: 'iMac', size: '21.5-inch', processor: '', year: 'Late 2015', additional: '' }, { key: 'iMac15,1', name: 'iMac', size: '27-inch', processor: '', year: 'Late 2014', additional: 'Retina 5K' }, { key: 'iMac14,4', name: 'iMac', size: '21.5-inch', processor: '', year: 'Mid 2014', additional: '' }, { key: 'iMac14,2', name: 'iMac', size: '27-inch', processor: '', year: 'Late 2013', additional: '' }, { key: 'iMac14,1', name: 'iMac', size: '21.5-inch', processor: '', year: 'Late 2013', additional: '' }, { key: 'iMac13,2', name: 'iMac', size: '27-inch', processor: '', year: 'Late 2012', additional: '' }, { key: 'iMac13,1', name: 'iMac', size: '21.5-inch', processor: '', year: 'Late 2012', additional: '' }, { key: 'iMac12,2', name: 'iMac', size: '27-inch', processor: '', year: 'Mid 2011', additional: '' }, { key: 'iMac12,1', name: 'iMac', size: '21.5-inch', processor: '', year: 'Mid 2011', additional: '' }, { key: 'iMac11,3', name: 'iMac', size: '27-inch', processor: '', year: 'Mid 2010', additional: '' }, { key: 'iMac11,2', name: 'iMac', size: '21.5-inch', processor: '', year: 'Mid 2010', additional: '' }, { key: 'iMac10,1', name: 'iMac', size: '21.5-inch', processor: '', year: 'Late 2009', additional: '' }, { key: 'iMac9,1', name: 'iMac', size: '20-inch', processor: '', year: 'Early 2009', additional: '' }, { key: 'Mac14,8', name: 'Mac Pro', size: '', processor: '', year: '2023', additional: '' }, { key: 'Mac14,8', name: 'Mac Pro', size: '', processor: '', year: '2023', additional: 'Rack' }, { key: 'MacPro7,1', name: 'Mac Pro', size: '', processor: '', year: '2019', additional: '' }, { key: 'MacPro7,1', name: 'Mac Pro', size: '', processor: '', year: '2019', additional: 'Rack' }, { key: 'MacPro6,1', name: 'Mac Pro', size: '', processor: '', year: 'Late 2013', additional: '' }, { key: 'MacPro5,1', name: 'Mac Pro', size: '', processor: '', year: 'Mid 2012', additional: '' }, { key: 'MacPro5,1', name: 'Mac Pro Server', size: '', processor: '', year: 'Mid 2012', additional: 'Server' }, { key: 'MacPro5,1', name: 'Mac Pro', size: '', processor: '', year: 'Mid 2010', additional: '' }, { key: 'MacPro5,1', name: 'Mac Pro Server', size: '', processor: '', year: 'Mid 2010', additional: 'Server' }, { key: 'MacPro4,1', name: 'Mac Pro', size: '', processor: '', year: 'Early 2009', additional: '' } ]; const list = appleModelIds.filter((model) => model.key === key); if (list.length === 0) { return { key: key, model: 'Apple', version: 'Unknown' }; } const features = []; if (list[0].size) { features.push(list[0].size); } if (list[0].processor) { features.push(list[0].processor); } if (list[0].year) { features.push(list[0].year); } if (list[0].additional) { features.push(list[0].additional); } return { key: key, model: list[0].name, version: list[0].name + ' (' + features.join(', ') + ')' }; } function checkWebsite(url, timeout = 5000) { const http = ((url.startsWith('https:') || url.indexOf(':443/') > 0 || url.indexOf(':8443/') > 0) ? require('https') : require('http')); const t = Date.now(); return new Promise((resolve) => { const request = http .get(url, function (res) { res.on('data', () => { }); res.on('end', () => { resolve({ url, statusCode: res.statusCode, message: res.statusMessage, time: Date.now() - t }); }); }) .on("error", function (e) { resolve({ url, statusCode: 404, message: e.message, time: Date.now() - t }); }) .setTimeout(timeout, () => { request.destroy(); resolve({ url, statusCode: 408, message: 'Request Timeout', time: Date.now() - t }); }); }); }; function cleanString(str) { return str.replace(/To Be Filled By O.E.M./g, ''); } function noop() { } exports.toInt = toInt; exports.splitByNumber = splitByNumber; exports.execOptsWin = execOptsWin; exports.execOptsLinux = execOptsLinux; exports.getCodepage = getCodepage; exports.execWin = execWin; exports.isFunction = isFunction; exports.unique = unique; exports.sortByKey = sortByKey; exports.cores = cores; exports.getValue = getValue; exports.decodeEscapeSequence = decodeEscapeSequence; exports.parseDateTime = parseDateTime; exports.parseHead = parseHead; exports.findObjectByKey = findObjectByKey; exports.getWmic = getWmic; exports.wmic = wmic; exports.darwinXcodeExists = darwinXcodeExists; exports.getVboxmanage = getVboxmanage; exports.powerShell = powerShell; exports.powerShellStart = powerShellStart; exports.powerShellRelease = powerShellRelease; exports.execSafe = execSafe; exports.nanoSeconds = nanoSeconds; exports.countUniqueLines = countUniqueLines; exports.countLines = countLines; exports.noop = noop; exports.isRaspberry = isRaspberry; exports.isRaspbian = isRaspbian; exports.sanitizeShellString = sanitizeShellString; exports.isPrototypePolluted = isPrototypePolluted; exports.decodePiCpuinfo = decodePiCpuinfo; exports.getRpiGpu = getRpiGpu; exports.promiseAll = promiseAll; exports.promisify = promisify; exports.promisifySave = promisifySave; exports.smartMonToolsInstalled = smartMonToolsInstalled; exports.linuxVersion = linuxVersion; exports.plistParser = plistParser; exports.plistReader = plistReader; exports.stringObj = stringObj; exports.stringReplace = stringReplace; exports.stringToLower = stringToLower; exports.stringToString = stringToString; exports.stringSubstr = stringSubstr; exports.stringSubstring = stringSubstring; exports.stringTrim = stringTrim; exports.stringStartWith = stringStartWith; exports.mathMin = mathMin; exports.WINDIR = WINDIR; exports.getFilesInPath = getFilesInPath; exports.semverCompare = semverCompare; exports.getAppleModel = getAppleModel; exports.checkWebsite = checkWebsite; exports.cleanString = cleanString; exports.getPowershell = getPowershell;