From 51c2ac521e5dfc61743bbe5fb26e57d2d3174b5d Mon Sep 17 00:00:00 2001 From: Lopinosaurus Date: Mon, 2 Mar 2026 12:37:37 +0100 Subject: [PATCH] all: init --- .gitignore | 1 + alert.mp3 | Bin 0 -> 90720 bytes alert.sh | 54 +++ dismiss.sh | 9 + package-lock.json | 923 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 15 + public/app.js | 275 ++++++++++++++ public/index.html | 105 ++++++ public/style.css | 330 +++++++++++++++++ server.js | 127 +++++++ 10 files changed, 1839 insertions(+) create mode 100644 .gitignore create mode 100644 alert.mp3 create mode 100755 alert.sh create mode 100755 dismiss.sh create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/app.js create mode 100644 public/index.html create mode 100644 public/style.css create mode 100644 server.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/alert.mp3 b/alert.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..592e50952fbb63ab99f4db4b571c7f0bd319df75 GIT binary patch literal 90720 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�m9C)=NUd07oO6(Xl^iqgbbd-o{?wcUDMg0&%@kqIK9A3cA1=TgZA_%R zN2v%PVoROLZ+JCNvJ27EQ7ECjUTScD<~~s};H09|`01J9W$c~(CC#wTk%oF(gxsle|Kxw4eB#t-zhJ;yUICJDmvAMerRBg0<@u2iOwcDbGEr3r*ad6xmz9;KOioz< z`uEi2p-(LCyVFjhtZ?!j^bt2V%0*dA;J5VaDPWV7ni?A!37!rHOn-~K*F#>?Uf}aO zj>PenrA&rThX2i`T$iq}R#CAI0H)B&{3%m_@okaU9KkI;xC$^sM4|^At{?|@!3D8N zH-nx}0cIk9CJ9NG2dRR%P*mf&?6qfd(t-JADIhaW=VSwLx4mVzi6P0Tr4YeWC|PNi z2Ec@7Y4VB(-kk0<>Nj=9t!BvX@Rl-!tIQ1EYaRzbdc@8wdh z3VzfON{tMGn^Ic;=3kwa*5EW{1M7pr&Z~d>XX!ycx@$Thp+ANVg2ZVLcp!HZx2$>D zxRqx$^L5=~ptB>A=r9pvVwxLXNkNk2_zg@=Ie-0}pq2eeGkEvMwZ)7WxDWmu|u z0L!^^hov{9rF)jb4XCY?i~4tP;gcb=$!I`nmE5o zA>*|C=S8(ZYlFRp_f9@p@TXw5Ri*VHptLhmR%~7pe~rL@4}F3?0KITyAvUHTl&25a z0pPKhqptuQ=Jz&YSQFe(_oYlq&fLKz7i6iufPC^6 z4^}e`&QcEIeJ5Tab$&b~LM1bKkiNo#CGok3-)UY!h3k#kIoQF}%~qCD1&6V5Ras`^ zC={*z>dSsa{?GVZ_UteJ*hoDqd=2(HoKpt+uVAM8W62lOmAiJdzQYgfiu=JiovD8H#=h}M#Ot2pNsN& zUI4NSal>nhxlk1Lr6(c*hriizD;7WB_m z^##Dc%nPzQ67g_sME>3*>)H?BbsZ5clq(xt3wpN8o!QDHM%~Jrgu?D`o$&~7-0RuK zcf^ZUIc@VHQ*W|Lh3-%`ckp~-6R{r(W*$AjzDi`j#Tvf2oxBui;POh1+G7Q(V;AzI zB$-WW$SDKjXwm%-b<*;c`toP*Z6B%)h%g2^h4967@wdz8OmA#$_4q%R%>BIfc?+0l zb;>PsbCuO!&-k9BSBo+EVbb97*#jhNnO23IC#AA{k zhZY}ie;fI;ZbREfkry(aPCsZM98FZW80{-rkk*EI1v>*C`dRkCCS&T|1HL?U?tk!6DCK7pfBHA9WYxmN9ru|m0Bk(upyPs4Dh-Q z{N)p#7CH~JA00P@bUMJBv-3jftl946i^A?}$2Rfytxw}b9!&F|9dXqrl5$Z=BRLZ_ z?~~YF5EoM|c;p25xTj7H2WUEph#zoX4!$qN%xvphj$KgENE+cB=0i7ZY80eMnO3V@ zZtj=Jf8VKWx;P=wneevw&8uh6t6&3}SflGMw_Zl^n6aW0mM?O>khQ#2(43I5`1|Sg zid)z7>vA4E8ZLEg74r%1H4Q9~Qk;Hr{xMGP`g79{Sr56=w+F_y4uxi1zt|R=0f_BZ~MFT+cKQI7h5uf`m5cC0KI6$Y_UDL z?uFl_E^ zOoSJ%@lg+&Zf`lkTZMJ|H|Sy>oju719P(Pt`C0wtiS2#RS2nj|#*yTT>zFDbPF&4> z{%8z;DpF%{{!q3pu&|caew9EMW(fV#O;;7oRP^Ev@c%Uu5P#`yHI%Sis;8yG>Q?Xb zStH&SV_(F%DW#OySlnJ+SX9!^zunT()6&CdDwdx2-;E~QckcB(q>81BeEWKGuOI%o zHplEhT_l@ua9cTztlfJ5-@Dqg$uhUQ##?l=4g$J6MyRiPMrVs%k4Fwcf4FP<+TnEQ z@snexw|@$KW^BdI{JHY;VR)KnSff03;?a%w3tc~s9`?TOcMN!}F+1k?Vvd13duHf@ z=o?4pu-e3KMH%+8qR-~|6`UJvR50gp(NOuA(DnmgIW0tHs4Su;hTJ`vbW-fq@M&AM z_{mo-V%;^-272rfEEcAoGCbLphS_1ZcJiZNGnkfL%1`i^8~ddN#XJbiG|{{v*UTdm z*mKxayW1p_bxo?~WlN`9i(U4CX;*CY&zRDu98e6hM%|;noIPPbH?VtLFe4{%blj#?FMgK zbBCj2K%sBne+tOO`DcoUjzi7`8m=n(0Yx4{xYvBKe$THe>-&17c6%iEtFLPed3~m) zR-9L+E;ZcX>p9lTh<~Pgz?L?=dphs+=aiJ}YXcPQz$UXp(Og<-1eMAJ>j}&$vAdo&x~oQZN{jxT4sA zY^%VJBB#Xk#Xs)DPyv{z8g8uzig^u_bgga0S}=5MfHfYiYa3uIJLqQP(v&!n*kFsh zyhBKA8v5eLJO#>o{Q#Wv*M7sHZTO+hem!^Ee%+w`|7n5$1oZUiN)pl|)s0IZab6u; zAq*&Ps%1X}5Zu`2B_tCjN-x+(g-EU+^|$?<0&>b$xkE*7ocV4?Ta0nqF7r{d1qn8? zBwO(QMeKd0`e4+Wsmtz>N8DU~Q;v12H%x*4W4%59wz}O$03%1X`;ECJORbqs2}h(M z_GwH`L|&upptHH{;9c24KQt(bPg?xqkhHigFX))G^Dmk@IDwA&gw_lOMeu-lv926Y zps}bd1b3eFpz#Uap7M{LQ0MZKzbcn>5e&Ws4xE50kk=Q6USiVAaJ!w55x#pN<1mdX zmO&|VRU#sh%HhdK)0Wk%`du5the;ZzZ|F(&b2ANG#+#5^qoPg`8)n z;}yd)@58s@%i_^^1F%62(#nMdyLHQ#E-77c5;HnDX7ss*fHsSe?qGA8aU&}f z3a?aw`eYG%*l%EZM6K$BRrPu&L5I25!HkI%j5N!f1`i*2KZT~tsF}+Hx1^_PY>Jce ze{m^%7Tg0@z(M;=EK)J1ukXUX0isBp!4L5X0f62H;Od`1jSQ6C0cg>1?(&}f`os?V zW`Czeu>A08alUKd8ec`}MDqRw-%`zlkUA(yp~ZJu@H`zBa@}lR*%b=--c{72py4* zzn#z26?qBnQ=;fe(QHJJOOB;G z$$&?(urmN+bmU(%N2mxK&|bl|G*-5VGej3cp@*=q^@#$1T|qIxXG26q(e;l3GdTJQ zn!RqA|L*Zg8nlhtClW<}43N^~y|~=C!b8oC|5JQ)U2Obx*Vk$P-7|W z5SCCL;uQ!B1=Q!`o1p_pe>rF%XsiylbPU$q^P=3E)(ji6hnzJHvV#`poE>!ly-&W_ zZOyIc^)Rs;;B-6c2LtT5HSH2R8f8I8G7b% z)5X-O5MX(7+$+RZt;i{xi%h-lRq|(I#sT34+o@*d)>Z>h^;MvE`VFIdUnoPicNxqA zvwgX?VJ`dNIV!$wLfB0_(3XhVlTmGP^M1jjpqBpSnTcg=l^DeO+hvLosa$F>K1A_+574?G!4Nbp8JjUyR&@ zFcFEOTN=#I(aXqj&q!K4AkN7l=be+=R*22SH@HwIOlAa6tOc_^y}Vh3(kmt71hHIxUnh z;}HuGT|7Gm!UKCia=!d}bTGDu2N+AFIMxfV$Kh-3%W1r&h}U$sX7}CzS%z)_-z1M^ z58v$_3R{U9W8^M5wheO*oZ-nmf~I386_21t&>7b;lXV_@w>f!fcDFfv6TJgTuac(f z;Jj%YP!Ex}ks|ickC2lfqUt>1R0p`dedN77w zSZvxq<+ND6zb+m=6uP-n$hQH5*COvLa}de|5FYN2wFrnw*FLhjmZ`{XQN}n%Bx4X% zD&_lW2878zo3T!CGK@o*gBTyci-6nd;Hf4{ux$QLg1Wy33K13+eJX>noxorR|G@5b zRpiZk1vW+XL_{SozQch*ksaS*-Vy2`oisoYv)}nnUIHR0gDx$_ zLy|Y|(3ePyFI7kkCQS_dCsEy$>9Y1}!EL$-e^Yhsmva;zEh0j(Ml{cQScf~%3Cq1m z@wedo0y}B5k8NrUI>)?sJ1Mpt{pz#h`3t}=M9=+g(|&}N-7ckcahRuebnuT2p2$Ni zCNc*ku-HnSwD1LIXpJw-$VTi)E&8F zDPghDO(CT@3k$!|Bop@smo2)LYi-hc;=JwDm962~JLLt?*^v?0NT z3l-_*tgtvaZYqT(6!j9zo7oA;WN|sfxUQHoU)tz^dldSBC{1AEjzKa8w$JdATS}~e zW)l_(R+T@`FwipqNJKC_groN)L8KwF7jE?TXWs)K?%EX}9xja4=qy!EX2mDWzUSDs z);_j8CPuS4ym%l-QOQuraJTn7L41rMJKa``SV9lM_o2if@z{80Q0s!CS-4|~7m#B8 z6LBRAE5N$_P}~VI)0@4$7ncbPN@LO)OSW4sY=gYF1vb#clPzxWmNO+g4Ze5D3sDkU zd%`QE&KpeYpN~%J?FmAHloM533)CT7?rgz%W2k%)p#mvJ-e4g>x8@6F%%Sg*6M_qs z>np{%JE!F-AbA)9DU;4vCZaTg01(+MW00G9!9oWSr83bg-h^aZXdXg^uFWi%)*(~yaXgM$>^2}ByQIz-%b771z=j?9l7-Rl(YIYGpvthAyeCcrF z?C4A7-^wq~r}Y*Cla0s=0B%hxVyD8T^|X?r?Y3R|Foz0{WBGYQf!G%gbofK@`3dR* zH{gso0Wk_Y{|2N1Ashey{j+Mfm1@^JoY}`Sx>hQaRv51F0j_Z?u4GI2xD~u-+)~`+ zL|IkoTvAdF3O^24sU+~@nw#X9`HP&1eq;1^ZBKd{=tV4&_gFQ2j%TAH1|ae_R@_OY z<^s}fpUH)=2lyt72kLt6X8^EA&t1JYE$SrdF1tT&0j*Vt*z7HcQek`=9gKQofd6;W zAXM3DA4dfju!IyxMLvubKt4n^g7pSkN4?$OOC~y()yEKRn8t0G8f?$Y#yIWQQK?{- z0Nf^ImZhob(Q*z`hj-JTX;VcRy!WNOL6fbubiqoycF4M5zYx@D?f0ty(+R*A4Kh{7 z{8Sg&s&W|Z)uzba0QB`RLKLStS>i(xmeCYJFY{*9K#ptM#ors+E37gR{&J*W9n$c* zD1_e^>qTfOu3gcc z)lFVyVK72z;Q43ricwf7b{OSmuY$T1+qcOp$aR7Xt{4ls2c=|=Ni&?5xI+<9wefw~ zbMWu6RQGgz~0Lb?I-aPoy@|& z7usVBPQ^!b8)=Sn4`}Hx5(Wx0ylL@W;pbkF^$1u??LhuEg}j@!E~;E$LbByD(dY9L{&F_jyeYpEDg1Vi_4DihndS`PcVao2-XEEwuQZear1?y(Ba7 zlEkFKHMUW=K~iMA>7`ddk(vU8uwK~?c0eP)>p%`-C5)9y-zrg!t!qXWGo zrp%PX3R0quzI`h;Ia^z0_A{(IZ8`tGQP2A8K&fNJxC+vKk5FoFl|t%sM!iK5iKJyt z;{mG^4_$*8(tdopmqSg9`)J+Jl)K`d^uw4-puTyidDQ34belXazN!S&RWf@yymnoD^Zg4XmYBv{CgQWW9{omI>>pKK99BP{ciZ;it_9@OkNOt&V>q^0Xh+>?x6thPrzT4;oPTZS0&{&An zV4qMXCa=SdasnP9PHRXzyLOG6f2!KA*?o0tKfinKzIWBX5}BYn_%=X>R#K09-r7;W zp1V^P#&YzaEUdIeM`Lef?OV_8i^I&2gxl1K)k3O7CiV3Fu)||dpqA$zoT4677B6QV zZgqZqR}i3(dZ+PgyoX zzl;l5yDSs>^#zkMDqZ9n{$;&-MP4?Wdw0ay+o4r9o7L<4?sW6|xd-{qSFLT-Lz9D7 zL%%!;1aOj0#h^9h!SU^by}j0zxm}rs)tl#UA3jxh>G`r)^Qxk)c5UffPR4r=WNGom z#1>3K(T;iQc-=2z@=!XFDACvmM9bK`zhVBB!6Lm;CaAz7Wd+AXVGzk&K7VaK-tuM5 zda~e|hRy!rXrtT*NdqiLLLNJSy^^Ibow;$ zaZF`esya+F?PEAKT=T=HqbnaYHdfm`gYT$n*d2eZoq23EI$4) zoP-1{Hn#8e;UP;Cz}cMbi!MS^%7Gzf9>$K4M3BVvbWXsgo(e)E7Dptz8MqiDAr0+4 zdWoLWP?o^=m58eyb@zIp_-)SgV*fiE*4t6@{Kg@pA4Ck9n5!c0`Fw|bI0g>wg|9wA zABSq>6u{lhrs*XZ9=7?LR%ATg+wvA*rJss8P|G(1uI(z*--F|S?cHqBkoBA~(%ikY zc6{;A#NnRN+VS0k!!z85kEJS8QyBRRSMyfRDF>7g(#XT#+{HEhKRP%@FKE500v?PtHM98cL$PK{E3 zseyPU{#=VMI$&B{Oi3fn*;ZdHS-O9Czi)VnMK3Y>y6$j`oU>b?g2C{zizpAaWZ9dO z=3k~u6|Z9Ep$lTZtvAjj2>5lTpjE+nlXdTFgoLj5p;PZGjIAZD9PF*J+|N~ByHo^6 z@@BK}rkYo0wGs>LiJx21%d5~h2QFQ(y zF2oKw4=)!2M-rsxH;gyORBD10%W$H09wNSFUmOzw2)Ya~$`GDces`Kg=Z9}&!k5aA zezA8$Lf^O5@Ysj%4)#pa^qv`KH8$zSPb)WpId;yyX16y$EIU#|^2nd@W|L-_m!AZ> zkRo-4NFOZb%n7E*G<~Z`e7}CsutAoouiKho8GP9$cGPn>+slGe_x*N3Ok_=Xt6`5z8N&|;CZGPQ!%*TwQujT-;)IRqa7&*gmI13 z9=^jHLb9A^g#z@&+@j0O>_2nd$|IN)JQGAreFYThwUrF>YW=-6~M%&7DcOYTLToRz!t zzvSf!favBQWETZ^pU_8szBJoTPhdGq8I+#(jbOBRP?zCVmp(GuAYHp1EU+CKWloE4 zw#XKe2NHz2uJwvX4)W3VeXkDNmP>Q|7Tx-m5*;;vnPaTL*4E`oe%@C*r(#Q^+*SIn z=S0_I1|MR&$5~Tl&EcR_1Mh@;t|V40aQek&pt>o~g*x*~@~NwHvCpoT*XLg)x>!D| z&CS1-ckS5oq2lB5j4}2tqt3UH|KM2C1ki6I?@(B#xXXU==XvlKq?zVGbxTbR^X^Ha zObL0tj%Lwp>fd_@#_-OR2#=OEMsWnE z$LRY??;p!uZX=exu`z)&vm-z289V=R;YP&teu%oGX8pPK-@mC>=lYtF@3f>8vLRDr z8%jL_cGI}++kD&pY)s=Y4~&QC4EuZfh4*gs6UxIjxhmpIrM)+lMc+3*)18&zJ0_m( z4&l5o0BK^#!o79QU)4$WKRa$3tx%0q-n)QfTjnq|#m(jCALJhYlef9LA={ZRfWr!z zY~&x@?@aAkwcq^{cDs>4N*RsnIO35uAGoD{P3_@%H~g7z>T;Op=eVRko~{ayhl|{k z647};Vi?yOCpf);MmKAFAz*2XeJAYcT=yR`OtReuh+>upk<*Wzb}0cZ#bJc7Vj&=} z4t{Q-DW$aj*+S^y5dv~EP~o&LoENgSnuo<}ldVp{FyJZ&<&FfdTKynJ45SVTA%4OA zg|~&nfiqwz06QYKl}W|m5r2aY<-YT%c~7k(_U*JoJ&?ZL0fc@%^`!9ae*b>zu~;N# zz(Ft6K?US+_boK@#JA}&IM^K8Fb&ro+S1$V*d~@;9<;V$qSPI#-sBFrJm?`?-kM0B z-EUZIUIg0z&Sh{VBsN=PV9s;>5~Mf-qbt$wOOeFTleUJuf=a-dh%!uI=^nzXlM{GH zg-CfIzh+d<`MJkQLE8`lD;BSl=q<;YCoMx{S2HpDOeX17Z{q@hSQZXE$|8eKfgPn% zb28L8i9l_G%Yn3-?F4N}%CLhN0UO~iAvT}Xn~HdX3J2f*z^5fbK8oguc??XZd*fms z0`N5kN|s%0uytv$xord9{h@7WJ^1xJ<^uRM;|S#g;KO1dm6roepbDefK%pkQL?6Ddm> zEZCnqPgybU%B6c6tjeAAtSoYjJoMw5>ix?|Mt4tl=Z^#!*i{k5JZV{9TKlySIEFES z_@39$gfaksjW={jCKn6OlkRdeF~MS>k!3!CiFK;rSb!pdMs)-Q@s8Y#|ew`4OoF`8lq`GQTNIq>=Ju`&n#234cKWQp;}|0O;qmqy2Tc|(t^6WyzVtV zx66E<(%d=vzJ;(Tw}v?^S&rsF=Iv~a3$wvwCZCls)nG|xWf^x;LtRB5k`?(sR?pNv zys|dydGP)6N=$4!F^~>Q4`pb8R{6v-&=GIm*BT^!bbT(+{L%L8;d2e#QnLRyj4-I^ z@spQvj`Ynbh62uO4SH4mW_A~Dshg}xK0EsSAoV061Wagq(F|8n{(9T4^UoO^w^L{} z`IElFF|R@P4Y5DwznIrCuVZQMr;(d9IWblkr3U;i8$cS}0(t>`m;Ej({O^u}8`Nnk zNT!SBXEVHo==OLS;qtr2gVKFHti`AFnHQGeTDoEDl${*QNO$bA-LvAd6BBblu(#F7 zCao$lx;q2=HOxuZ;=DC?*Tm-sggv3$(dWEt?%pZtItVUW`?V7KNDt?@X>tAZSuwzm zefz#alyC`KW&%5WgZ>W0L#`HI>ONnfZ#Wf*#I%DP_@M#;`KcPxXr+?+SHj>yN>TXy zNV!tafo9 z9cnBntQspwC*AG`aMY8$zSv%x1uSsmqh*_pP@`y7Ccxr|+K+NIMEE|lc2+la_cC>} zuW`Yqx*Bm2W$rtxBZwl&Ky9%V=i}1jW#Y{4sY1p|KA`85f<~`$Mh`)wS0cE`ro`+j z1QW5eWSz$YexjvNvKmj82A*;w-ra2vs^vw!!3cjxO|$J8@OQQMmu`WH*yZH4jWmPB zA7S9>S}CstD|ITh2RC40C?|JP8lkvS2~7fv2uVik;2aM?Yg5@fbVKzKz5JLRYde}+ zM=1u_Uzavp+Co4m(CdKJ9#b>HW|90bF|xsyI|i&_hI0e!xjr#WmI)^x(GtrgptNg+ zVKepO7>B_VM_L*C(n}Rc%5`MIP6CTtC$tc141*REYdi?Ni36Xky&lpLF5ye17n>#D z>D{owK`e39OjSE>6RyAcb(VrVRM39S&YwMd%mvx9-@lxtaeMBq!Fk_@quVl%o_r`B znA`8>fm$*XPt(aN(i02^w;(#C5CO>5-m^etoQI3F^_E^ma+C$%iiv1YNQzunVX#$5 zdheLjw{E|<-?ejBF{Z|G@V#T7h{NEUPBd*rxo>Up+hRv&VhZyKAKYdy&)N4A%hXg^FoPm0O;g8{acq5e7XtlwQyEa}=fa zx^b_oklr5sIH&mlbQwk`&d?WhB3hi8qJ`is^lETP;HtQkK|ro^!5*|0wk&JC6$5UXvT1q$tKtVOSs5k(KV!KTmg?RD%nhjE5Y0)eNZbAzq;_v%FwF8SzdE#XY;Z+Mtuki4}C0zB`=`JJ#&Qcg$%)* zU2Oy?z!4y(EgnMWP_9*57SxhO@6 zE^eY-*_qt&M_n{{N-H$7pGzwM7Be}R?4adDdqfMi58T3& z2?NJC26R%#;IYCp99+W1WeW#;ujTb*zaRkfcQ1hG=y+G8+vT>_RfU~Ig&{F7x2~(Q zAJf)aW>XklDeSk{3wZMrL?H=Ke1s_8RoR$dxuvyRR#{w$oP|KB;8YC*J(AjH*zh7} z*q?9_dwZV8&m~F_6MA3#_hU~^RFID-ohNf9lS`2IR_lROIDfqz)}>c(j!jx3ueTNF zmTW0T*8f{S7%azvzM}YIorG!O$aE?wg<5%1X%oEsW-m7;>3m}8@d-Fno-4C_b~;M zG6gyDvf-a>-3xzrd{&HKHdxthBcuMp=Mt&#$q!2WbpkEA6Pcn(hxwLnSnL1w@lcNe zIp0b9P+|AzQQ)|mA0W++{hYJ8P^XWd%|3eyynv-q*13%K8-^qQ^TL1s?sa(M;G3@3 z;kgSfY98aDaPW`kk2&gbZ2a}uFU8E<;uk<^xl@cu7MOh1y}bdN(ETiUA0!XAkj zj1Z-bzlxI0R9hLqH>=qAootkr4jFtaZ>hs?_~AslQ|96mnQ5oVG7AF7&-D+{RUb?? zoNPXhX628#W7@fvKF^$g@by)jjBn9cr)+NEDNV)A-w#-?9jL#Tn2HZeFkh-O_?h!3 z#*F*l^|H95*ReZgan2w0oeK~t@+wBh4`}SkoQuakiGhNBx8%?H@W*yW*X5}4Cl3K& zXw57Nz$gQy7X}xpoX>V0sw?9Mu21*0z4{cGf81rp0jPw51qI(efYk6rfGiB7R`=}O z3RB(uey_wVBq#T?%W1_UK&Cdt{h=9*a9|<{05?2&*$Kp=> z^Zlnov)pl2BSFjLclgVaiM_6AqyO4$M@{^w6X>9lwbV-y{o?YYk^;vw4L5IU^-jRd zQrVMaMT(Y#jNJdT6UgZJT59M#6$j;0d0@1`;5m@%#d{A`Buh5xY`SWEPV03%Zjz9G z#rbBvKY7}Wp-lIb7A?M-r_{JzKGFDuO0uQydFc?9=h`#bctiIwIe8^rapPCz26|GF z?!WakM2X_pWVG5_4KELp9n!Q_o@?oHC@v@8;P?n_ddo3Na7FJ*3+gwtqBQv9r%=`CgtYAqlm!u^w>wvVf^0Er>^;_ctHQ{QfS>TH5s9z^F zXzTrNCu-)PMDwkGcZ|Ir%&AEVR(Sp zzwZ#kHHndtXO=YiYhz0@;`oKk1E7;UL@gp~i)Mwys8NP(c8=}&mV7kk4BE)M)%J#u zRHp1h-=x;f+G}Rl-)0+K&yx3f>cwB#=JC1K>vD#X@y64-Df_(9!RVO}mhaT97*6tq z+Bh2%dQ$-0%BlfM4gL&n4w2%g3yr z7lFtZiMCS~tub=r1tb>Nk|j@Xy7o2M`yU39u7r&E`0F~(!Wn_^JE%MJo(_6jQs%aaW%cWU#W zoV2(w?G>YGe~GI)aZo|;+laRd`rAwWs;Y`JTOod}Z%g8&It5-{J2BE-^K0MK^>pXw zl#5%lS6)3*IJ#!Hajdb*Zdhb{i7Vl1(#(jWQSI^3sZW1iD}JhedTZtPzmFSjM`s;= z9sXzkyC?1RLHOZC&}A6OxB<{zlhwy0ORMQmmDE2azho4yc7+tIeXRa74=hzMZ`Tw^xe>$!kdJUTaMM^uqLF zmR@qX=<^F8Oh+i&0Bt(Ii#<0Zy%xy}5! zfM-#vxHtT+3%%i6Q$VaT@2!^gS;{U`b4Nk?`BmAY>hdha|LV_*l0IkxjsGk$lT!oB zGpA#^7k1)Hg#S{$p(Yojsy<738p(~D{!0{7{?ZlHg6~ID8KsYIDX^dp)+}x79F)K1#SS)xlw* z7$s?0;5BRvnuhHPTmdimtJb@5`h8Ex zk8`(}zPC5G-W}WwQE;5~{g-<9@f-j&`*k|UQ7?2+fB*ZdX~yz>RdwgD&x&_8uH@>n z4K2sF!rW3NkkLOd8s8ONkE^S1J$$KI#L0IbqSe7k@=}AXXW{}vJ(&BRG` z@xWF+=nj_(zu=Ja6P&TWRC41|V%ym(fOkKzgu#8_-_#K-OWs9ocdXt8o<6< z%lFFjZJgiN&U?qnHYKhOuY&UDt{lHUbNz+MogUW&Nl49O(-7f5HslA|(nM1p6dcm8 zna4^$|HHsrW@G*a9Wy(>ThKP2DtuNNxo}@oH@G(q*N4jAsT}Bq(D5>JvXvqFq-g!~ zS;S>!c(zF#fx=1zt)bakw%Aed?v4GIRHK{JnYR^EES8cfXai7>! zW&Y9%z@8aGy2R6!20R;(Gl-f?m;DEjGswvmZnStjWp;otM5pK2QDd=hp@5@fXm`pQ3))e+ri8o`&qx zlPDy0bxZpu%(?d)zp6w&*JI(7ipx`lt=8VL5d}rf{xDPDSS>S^I8b^mR|(I%q#bG{ z&W%rq5@qULQdX9z=9^J`c~ZlyVY0+>D`%xYQ_BDI=MX2w5;NHBJD+h5^=f<1^mUmh zseBR@vGCRFE6b^TRfY1Zb+L6hj~-iIf7IIYU()52S1DUz5079DO9?()ZFJBxDnEe_ zQAXoEZDdDwl96xb`bv;lY6H9A5AFYogIU5PkS#2~B?`sJB2(hOjb;0>ugK8lfAKOq z^a&>mP_@_ow%^lI_t9=?AemC!MH}#+y&&wKiu7l0WRplqD$-m+-iWgSd;XQ*HtgD} zhMmlVCNm##Jy@}lk^StMikaV&ebPL{-$ifvLne%k8%i;$Gn^^7)Rwz*6tMg~o$y+LBwTCT?Ihsqn4~X{2>;AI<;`4Nb-TDPYeaanS=L+5I8v3r0tAY|1IJ(5 z$<=x5*Ys_xt3~rgBP~0RzJP_b@TDJ zKT%Ro<_E%K346hW7L8W(hTX@#f+$KhPhbsemaPPMeB7 z7IWfAva+&rNN}pE>XE2=LO05WV1U#pMNNL>;PjVeBmOFDc@$TFCH(}eRxG=z z!~lnjIEr8g$${QBiYv7y8M0YDAFDQri(jH7URBf>iT=UKAyqjlUZhy8eq-unV`MS6 z($)*lnob4k+^5aOaW5~HT=2Z=v|ak^%2};jU)L?x_{P47EPgw) zKU`SL4V940RKI6bE0}7)%8(p*@mXpM{fiUb!*~f-{vbiuTCtfFr9vt7aY5#P>%s-T z*ndaR>oT*2@MxRITT&6)wDx=9)OGaLG*EwZ>YCC(cv>FBEQ;*~y*1qw{7b|9OjI7Q zb7c`rVq|MCm9CgMZIHgGZ*sMKBUNeqJ*lF)i_t&V>V-sAczzT^NAKJrYDw?%+jU3w z)4Qj*pWZm~cS~c)KTPWQzGDD2lgt_v`*x%%sVbLoT=geI){eBC`7F5EFk4`~-#nyR1HMMp7J_!&41W15{&_n1DAfcluJrwE9fFQlfQ9$e{fzXRIK|qiy zAfQszBkBBCvl*+$4+y0x*;Vpit5=_JmyAuf#;^X}&plsS z`W12qKJ>S}z$JU{eEh__J&VPIDy7df8GKK_I_mb~-n?%v)Rp|qKN9vO<31fxXi%5)yT&Gtob-vkQ zZeCYcXL-IBs(`p#!L=LrEzfI=xmjgJ+DJOiNT4ao2%((El5kmXfiV_a@*iQTPd(R~ zKksS(yx4v4I%p_MMh*x+4YdD-LK5AoOms>+p$VELy_@b+4gGdMf)z<6c*6Ro<%D(Rma?)m3F4ZptAYg{=@{r%+7s;*|>AvyUq`mZdP*%|X)17;N?0mAL z;H3vX#quy$CWxd~WPbBUU}uS#=ErXr`ko(|B^<`C{@pE_Qm53sc1+~f{&%RA;CT2IJ`vgDnd}c57g}U7W_3aiX;MJ)Q3fCV{=_T^3PUpkQ z%Pcqd_)J)SNv+v+a^_&vO$e$Jr|O?QrT+n2{a7RwlK3B3L!q+$=IUhv+A8$Ov&KG? zksJw4+|5IlGR}hGmln7`1_^r$oD_e3%oonlc=vgK*8bOLd>biE8EYGjj!v25@l<)C zshX#o?g@uFIFV4$H68XzgW`GB6B*iC;gj_D0c{7GvhtGuJvDMt>aRx%^8PhH&G~<* z1jp1s*{=_LDEj;1-Q9yzE-sN@FCqtd_RW{U!=v;&DX^yW#!9&VQJ8+i^J_on&i?)E z#i?+~+9}VMg*9(`KU{x(>E!RN3!i?w+n4>8lKl5~?X#axrWT%$Z24GU`Oxc&wmy-R zQGCqemt?t*amzepV2dJUzxTNMP2-l-uI|4J4bLjH?WAUIIguQ~T_YmS^9lT3Tj%C2 zvDH*Uf8ENwt}6dNLKk}|b30=4Rqt4iy4bnuRc=HOXfJtwGdjC)mrz=AUq?sEsh9sC z(bW^Wtf41md%o{ac)}HV*7~dPuc%!^CvQh}dM}tUga0HtzU+Adjp|Yi_z&_?pHLjE z%cP0zlx6q=ZnlGxj{7Q5Z%AcpSTQ1m`LTH(CkdwfeQA{fm3^pVnd`xo*2t1{iVS~y zh5_Lh^-^$E<@&C7kBTaPnc3g)IEE`YIx%r~LN`WxXH@v|>77xIBT`b~gUeA-q2bFG zc$^_wJVOMJPiKxqNQH*ap~sRiDWNp`wAnOYGaV5W-n-nKEKo_`$Q0)n##Isgs|z!2 z9{8}?=>nTwc#JkiQ%cwqu$MBmM(O@V0s;Z{ZKgJ%uK|?SX>_aK@jZ$&%TghoZwE_{dkyKufe6Vsu-9j zZU<15JhSh??uUQjJcEI>g(gpcP1Ig~UI`LmCd_09xRf1Vd)!KUwk zg=YTE7gP;GpalwoJbMPbw6$0vx}Zf0hxK*C20vT^uZstdARV$ z82@#*1-hu*q?T}=e~$X|CsO;s``p4={yAdHO?eniv?WNK5qm6LW$I(+Ad(XKu!@zm z`)v;G^R24mThT7p`T5`Sw;iYu_e^%OAGnq=A!oghthn&-I8KB`-Z3^*d9|(Wgvi3v z6F7WP(u4PYbk%e>)%3UDB~q?ly}n}{D81gj@k2*DKa)9irDDlzbZ=nY&f}@jxZ0h7 z)E$$GOLY)5-uouC=01RKD{Kpzl%G`CQHNm|SlJRs@2wMoR?TBtlX2(BNY;5uHBmMU z;aNDOZo0oR!zS7TTbMPnOARnc!$Um_Icj;?l9-GW1SyoJOm%EVcTiM}W4j+=CW^wU zP}hunpM>F9u|#o|7_))6woY1Ch zoUgr~?-6C+`bS|Pmh(MoOn=F4srw42&w1dNz?JsEzk9(HXvllaznl!+^(6PL`B zkA?Bnqbe*@k{D$@G$u5!T?C1~xKKD2obkTX8JC@z`r1T5|d zfIuvckP}Q%T(mAe!23I79|rWgr^o|1bcEa=D}#>wKewN2t{P=d&1=!$xj%n6t;GUl z_nNm?;a4hTVto*R4Xv9B<*3(Gyb8&pm5-G#7M2%+7PkO^&ZvC);9?=4Xof4FD1Q*V zNFJSxjG3}~YWEmz%;!=mW@bfcuwrL2MZs=YrYI|`i@LyKrmLi@q%m1pjC*qHcCRxW zj#6HtAN0=-24^_fsB97rK)m%p%G1zC6q|I4wa^Ut?$rYMiLjK#(Pw>kt1V^LL-u?5 z&-iEEi;~&o?o&>ytDr>?2(0SpMOFwm%FF-mPAQATO!(M2i4p%C$3c9`aGqZALpvh6 zAhI&8t14+Eu)BoxC)n}}1 z^+^er#VW4Iz^X&NZD_@At2ZpEneL9tt=&2s_a{t)zzoE+5*Jjmb>*{I*m814}m&h zb9;AthvAy$6U!SXmesN#B31ChOU6AMAO-+`9c(c6{-!=nm9XLOpU<$1L;DKFf=KhkBEWi!E*W0>DJ(>b-q5IKRGRbC(?>& zqlz(rBe2BObvx!P8)lcbiM|uOVz6-vOH3LVi-uP7^P6bH`T|(_ZrXVup!wZ;tp2||+|1f~0( zys&v~pH=}gwxD&NXS31$_F)tBnOn)4obj}|QHMmD|60pXCtrUFtI*S^@I zJr$spw`fj@kOjjuS@!CT!oG_d%h^8r zMjZ`y8;JhYd3l9NgqS7r{XAd}nasWywSb0#ZR*-N|xi-7%g?@Q$d2Q9x)beaxHlHAW zkk#GOsMDaEGXs^$hr%Px5-71PoDCJ7Yib4hc6*nt&+pdlYUdHYnbW(a6W2LLarjn@R%w%COBby;2&a~W7b zo(3t5JkfZMhixuH0}F)0c%#R8FqJ4;2wKa;xcfnqeeq3rR&~2f6Obnc_T8!J`P)Mq z*jMe@SPJ}HC2VN=qaa0x{`WgVV6o>wQ^Apf&}ST-Zv_Ifv8T`3r={`bE0${}IhSr; zk9e-C=1qhl3j&01@z^udTcZAf>IjOEU zCnlY-Uvd5Wo(hj;{A_T(H2%}qpQE+E995H?49||LRE?YeNGd7HO#%bB6ut25#lkzn zMrv;nKoF-q8#jj>A180zA-}6l{k{F?_}1Fbd#lm$bG5&h0lM@nAd%|-99@fc`LI>H zQ~&H8@|&&IX#MQo?9o~|ApCk@}eau;K^ck4j8xgBRmq$K6 z-aY@hDE7{*2#aV}OrT z55q^QhngJkfk!w+ngh%UCL^#3UGGt!F5zZimlmRoq7m#vrB$W0Bh{0l3D)MyqHWK+ z4QRBg_;S&h*BVX_3VP34uND|)u1p3CBv(!rjRfD_@HX~yz8Fz(-ucmDLDB0`onM^b zWtWT1AKw=~Dgd~mDeY$YCD!L))}2MC=85vH)ZjN8+|rR+&56hdg|xP}F{!Ud964Li zhJJsk!z#34QQ^$(pLX~SE#Bcm{nNX@ZDWl7~d zeh?j7f1_5LJpsdXORaP?qUh_^+5uoo=;xX{1Zk8y)s0$0o3)!@OX+CvGu2Wj2vSRR zSy_=kAKeRk({+%w$3I7#h`H~?N>@L6JdA(YjTnYNl86kCM4_CVv|=JWgO7u^;oT!^ za*nY%d}E4MUj-}4ITj6zfS-~Up&UUZ*oqsGa{ywcVKKWBJfyuDyq8%bcwW(CEi}Rc zh~frsTBI#y*I1-2ijbg9z*<>9M)|6Zurl~ore*5-T$uVaW-{Cm>)?u%HIgNBY#LB5 zM<=7YroO%$vhNkmC@?XgRL0y3Yr?`W=x71NTX?4*E2^wuwMoy)a^**7U zyJVh_+P8mKnV`9zJL|H0`>o=3pn~z)j<9H+kRrRplhok3U#wTalKntnrPN$(Pw`S; z!oIUBfMBhbx;X8>ePhkv=-lhOUl)rO>$bRM(CAJl4X8A=4|r))DS$H#3I3Ph#y^{7 zPK%|nmYa24cP=pJCSZU5-y2tK9nAWtM46yioA?D{7VfM+-b<`eY~$P(e1dE-ZH8a7 z<`fzZ@!?vmOqnRzB;q2ahw>GcJg^3gQv5Z$h6l|7brJp;f6#9@2Itsv03b)8M6kx9 z3r$i?SOb8Zxn&We2vJ-e2q8-WY>wG6zDaOQb}^5v(?d9BdtY3GtC;W=SUu)gDrmOh zy*cq6VtiGi)rR*B;F_I`h^C7<_$WSHH3=Po*>@(|rk>TwW=r}D6jUG#JlnMKI)upl zOl!q9^}Q&bea$p!@IU-^6&w7Y@oO_^6F6Q-ZSokf5;DwyWfc}$%jo%0>As%ym)Toh zEw<~z+L+r!O`8RNf7*D3yp)7)SvEc*j`*lb>6&$Y8hm!G`vPNcd+~AYK1x!d)`XHE z>wVH9Yb>ENZYXcg%FU+6+-*;ppccEs`eR{n&+Z>Ui$+Fr9SCr@f3_`N)b6MN=1ZzE zr<^GH>>>*}$u@0rM;EVr;Bq%B&>;HysXLxjldUb5H2dUxnUm7ppNsvF#)it4Mrw1Z zlf~J^o&%{7bt`~MXFYYIOpsN4q6EpB3{(&VJaY}u+A+G*9a85#?$`nsUtVn&z}fwQ zVJZ9}Veu$;5CmSb6s|NdJ)9PH-D`*=lQUt@NFO2V#nRL=>Zvh=8^U^Yye@@s6-7pe zi8A3`F(#tCGBUo9K)u^?f|&q_RnH!HY6P#yB7iDOSmf+eBT#M!3d{&R9wF%SjR~DQ z#0K;$BnC$0f!y*{$>GrZqNa2%IZqdyG@z8`I`53*dMe}nkr~5<=nZb%aSq) zG0~w7<@DJv%FXF>g@YnEBs1jEQHooHgg>1Dme0p2xoz?)7CieJYJ3*(kOlFPqO5EI zk3YGlh}j+<+a#pC z7$yu97C!}+19g=~gd2f7rGwEsrRjiNxgU+@l?Uf^1!{1$SN%nUai>6SJb7iH5bRjP|&h3i%aDK#`rT8&dBKV7Jr zpTA1)o6zO8(eiww5fAmS3A`jj0G1~`+aFo1Bh~&nP%$L!c+KSjNmU_2Lu8tb{WvkW z$ch=M|Ll|;_2diXQ#%ecQQq#S7X04UKD(SRR%82H+9f>2*7B>3x#{%FJ=68|3UPw{|m$>UJ&`uV92 zfJlFRgx0rjae(i93eD_)lJp6%?f{f@;?_BpNFJZm#Bc1DCC|dw|6Fv}O++DP>g*Su zAtCTmhk30hFAV+w^bDhe?v?Z8q@nelXl6afL>yY*CW^tpD7#3i9{dBt*Wfs;h*f1F zrNE!wC5fC&LvV;r2uCbT1mj_C)xDZWwJJpEOVmpz>Y%+u&k(N$F_Y77l0I5{+#Zs` z(8CfB>t*mB(boAnI{7zl5gJ9%o`9`BdQB3<=AiukA*p$h;m3O59ggUO za$zGBjG-aS_-j|IT5>{Kw1!n^?DD>362auE#5I;qnNg7OLpWx%wR)pkpwizkQex;% z_MRy0pZLf`Qv&zLzar+IFNRkQz>3*fRUI-7=9-;!G%?ay{^nnZ7U7K0jHXag>4!Z6 zC1j~vQ=X^l8-IHPMkTq@N>0^Qy}e4fyxsWdBc(h0t8dv#8N0MNKa!!IJbN5ae!F|G z(~ihSi}jinj3_O;aGptOL>SQiP+NoUmGoW@{<-GJwOosG05w$|f|@VNkmi)|@=sMg z$3Fv<>>iEl?f^pxZ3&KOh9|rEC@xulc4u|*)ToO0{Z>tlC;~oH887Mql4GSj0ZH(6 z6g4(LO+SCXegiJX{rzBf@as|lvQ&_Y$~&EY+Hkd6oVQlRn~1jrq#vA=22a3@{0ee< z{f;-k$Ljo6EjzKbW_tq$xe=VFwijELh`}uQ1c1W9mX{#HFPE;y;A;|N%nCTtb3>E| zC>itk%kua(AUNQQfz9IF0ATrI_03iQK9+57CBwb1`CWWp-f;~?P;U!~{61^>a2epj0pV6F96eu;jTaA5n!MO4X+F|Vi z`hpavoX_s_>CySi+A+p=yeG12uauvBuf5wtt#{jnYmZ(^?^V^zN$Kz{xa)WJi@&n{ zIabnTC~vio?R@vZ)#KYkYbT2$GT!x|OJ1Aa`@6>>SNO<^e{a;am#fsa`~IeMdLh(g z9AaC0#|V;`SGR;D1|D4)4r3QW;myA`CT3Dq&B{JNRfZBLQ=ymi>CTZNEPDW%CuObA zU%sm(GC%O#q;{BkAVyfhnm_mC6FExZje94j9VOlxp~ybkY?{OOR{P~T( z`ceL#7v5*@swdv~G^FrksfW7zNwSWh;y(uhZ@;nq(#g+W{(R5Ao-lNoYw!l4c;+AD zxKKlxr8{%?jtH0J4s_YSYPeP-4sBMsLkp+1%Ll9{U7FBsbqVibZK3QIUyAvx&_b9W z#TkJKx!_tgsVKhB@ zFpZA0I6ZPWY6N#}PgKv%eGXQGdAbds!!&$8km+N`7S3qlR%R`3y+Iy%*n~Ef37P2Y zDF3_9RE}rgOvUq}euzsJFy&vu^@8-H2pL+#$Es7eFU2Oj$fK1GCKv9D4J*^XxINiP z?WOBT>5ji?dv5F^)1Hr{{mZ@`qvY`}h~4?SrTU$;Sw6yI-+n34tr^qYbKb}Akj5__ zG`_auZ;NwvX4Q&@hu?~!6R*E$p(lo0-B#Bb$vsv#aGyKX4r6UYcopp$HlAsWM4Zv2 z>t9v(yZ$H*);0Yki+I#j#v;javpuqjlhmF$xoz4vSFa*xYjj|)MZf%?E}btIA!7iWd(d@rcXB_fw?zlgWpQvThh2cq20sd*xzS)bHGj zEial~Hr-H}?|0zwqp}ZUH|-n$yBGXFSeRgJVY=pK$SXSgfOuLkm4mFjSoLas;_yQU{d3c}74 z8Y|*kgtTQH2c=3guu?ma2=XBHo@vXNxp<7E@8>(tlIm4?@hvk>y{?2Gc46JmZ*>&D zi4xhszI~H>P4#{?PIA=X(#62XAAY*s{A#;o)3Erj$K!`r4qy2c_cLg3r(Z|V_kFv! z0>6AMoc?F;W3c`3!%t8Ac=jD6+DL}Hx@Q4X5$455l`tKJ?a7@-eqZl@^!d^2j_Q9? zp?&+f4nSet>Gq7fQSZ;szxVtdd~MrS2be(q`*zD3NxCmj%=*WKONEFEpqyBbE7`K1I32pbz4)*tRqXD;|8 zr+zyHZPxPa3uz&w-C=;wuc@Mbv80Lt+bpv@5B6=AT9zI&gluIR8Vdnz8QQ`LLQ~L4 zOw6flh->`EuzxZGm0@w# zB6w$zUX59h#deW5;$k7^?wXxd%eJ_kJSQAv7C^dCIvSI|xYvGM)#v8%sK=zNCd=J8r{rWQEi_yRfXf;S(4>DheH86V~$}i4|Iat@l1?g(fN&5aLVH znX;tFQCl@fc?_q-Xwd^5nQkxP&u2>PwxMm+L0RQKsQ?7~^R|J5%d z$ShAiBlwC5%96ZY_lu-aDcQnMBibZqGKEOWjak8ie=UYm(yK32JGtbKZ?+x&I-TQ+7BY~Byv=VxjBUr)D4M-ZX zJ*$ZtLU)O#AqK`7d)Z{@IElNn(fccp- zcwxlAvKYDYeKKB}EP~wLLaavWz{6pKjL3$(v@E2&z-htoT#s_bV1^WO4Ec_kjMUsq zdP`2RwmwX(za?!88YFV?7KCO(!Z2x{qz7o9uxoQ3loFUH)~C-4qsYV?Ln4zr51Vxi zZ7tCFHcX`9uwLfVThcZn`3*-1jWKG8M!Bt$?vmEptA_}cw=h0o1&+g*-H_5M&%PX` zdAN<&rwN#vY}Qfui%Qsfru0r5M;pA&DpxP@m!+fUZ%$z5n&iUIHR;V$tI)#F;!;V7 zr!~E(ETWtwm3ntx!g39hYDGQ&xspjYHya9h7%@6zeJNxfOW1vRDiI!HC2tcZn1i%3 z52+g)+ClRWrei&eV=cfWO%X={HnO8&mSRW`Y)!C+%&?f{3{K!3vNUt+!_KRx`(}ZT z5yDZs`4~dS+?%<@O)_)+7~eQ(kFmYK@-=n+*n0Yd9Af=2p(KAqV*wMkz_k${{8`N0 z%v92OS1*r!*N%`=2^e#YdpDxeGTjXV36Y%9W zMec(@e;p6U2(a#BpVRi9)0AEUgf?CC(8##&ymfQWuDsNXV}-aj6}E*6e@JeImEC}8 zLJnXr4w$ABRT4zs(%5Ep356&|0hW@JaSHwq>M0EX2}?YD@=5@Ik=>e}pq>MTO!>~1@yYjp!sh> z(EMt?eYVFv!nITT78P-9YKRaB%&(G>HnTdyY`ZGn>DPXk~{CkDOXxf_*JQ$$} zc!n@m7%RdjEJfOnH3fQKd{F?6K?lo4aVA4B6K(pVMft^%-!Nu*g< zp!-(}nCj@dm5BeEC;mLadHOR!aQ9^P6=|VRr69|dY_rLxPqVCdc#_E{El&a!m^XT zS=*K$>D{Wk&s@JZlKCLu!*bJZpAe5c^+_dhR{=>+{;8j1RbQjE)jm>JJmEx@^>oyF zNiJqj=0Kc?@5-&LtU-?g2gmn%BFxJUgfL}!)#4j#T7*yzQ%q&?n0#*L&20u^B3L8I$T4}D$$Mv$utKqhFz7U zw_yr{ zim~I4E!UPwx|+$A3$DXYpY8a^j1QJD#DJ?hrcWOh=A4EzcH_*Dgp0VwE}e9`0XX z^$nuDtWudeTvlb_=})~-nP#6id{17A<$0QnGuZ`{&kqV{fOhw?3b-gi>bYlu1bK9{ z0COHIg5>8DmIiBstw;w}E?aAM;D((ZKv)SpL7hdLnTTdS$*Io=`rLMVNsU@qI>jS@ zR@KKIw7c_zpFL^O1J?kHaze5|vH=ic<9FjiYS#fS)&)GN$!qNDz^%9G5fApW#B>WYSGy#~^y!5V)%|CqL zSp_j66P5ji$0_4BfFIjT$5Fks?c;anjR+v*Ij9gH&k070gI^T^6&9kEhNWpB2v!#u zcVcJoi1JpW(L8qf2&KW5;_Y^B^J$l^mVb!B>#wNFOXefObd(>4-2y>6D6CZ&yq({N zz=%o1Wq6@o2n{$UhSZhE$^mNVVjpH>1Sc8nm@$V@`dX7^@3dlZzzD6BkH@f-Xo>xpHVaB;{FSN|a|5fc)c!nK+ z=A58x__?5|O733=Bc5$)7G6~|oI3NOyLx ztv=MI&McV9uuV7cv=a9c@ip>kS^-t^zHpyZ!NHOtwgZW?V5)$`Z(EGtb;pi#$6*?l**~X(@2g(Hs;bYO_ymUIdet{wi99o)4h>m)T?}WWt^gN5S3^vtEcv7{K{Vz z*@pP*Q`GD7o)>$82A%gZD|<31@$#+*mi!#fop%@Pq`ar5;T zO9Vm;1fI$u){Sv2inje+LNKcBhW$2sg*P@7PA(jjwLL$YtALm_6q%FCe=Tixa}OX% zH+vH8B*0Wv(uB5KB^@M{WTdL(o;ht_GIDBL0XdoT^z3GCNlMYel?~|y6FaCpGKqaL z)H8OkeM!$~=wJVv69sUwQSEenC5wLUZXbiM(G&8KlmxR*rKQYwK;9)ZfjBg39X8O_ z8Q_<^*0Xwj*DJrhfL+`;4evzg@$Uh6z0S4X&CZ4E_jUe;#__2eA@e-YW^`(KO zin4JRfYo$OXAfU+W#p%w<~vb;H|?L-fMq9-J;GFCD*oZwSt+~%ndloqDWI+0RvZZQ zWIh=bMY0;QzMXLwHf9NG9Vbb47G#K-)zi$;r1hoO5@F+DLNIouC-5{4>*s)BR(uMu^JEB0AyklfpjX z1++#(0t&S_w1n&nz^QwxPS@a4?Zd&T360mLuulwS}a0GL?LMDogXI8x`- zE?6}K!YE(?6f1*+h1URJ89-%QICu&f9w7pwgDx&u@4(*x5{=Ov_W}L#V`rzH5Hq$VR$- zdHS)Cst)6%0l^BGua2)(vj`7iVPYYy4=sfbGq31~L6q4=k+o^yW}O8%Rp$VYA{$Gl zh0MStGQn^F0^HjZfW25h$@c}dDf4>eCQoDqZKT%^h_U&bg#Ii!uq14BZaK<@UXTvN*ak(GZ7H}{LO?wBs5$_*yppF5c3?Lxk1x>`Jg^yZD< z_j1SKnt;FIW^(X7oyP}OD?sb*qI3n0s7M+VV00$P&SZ&kJ_OMEVY3o62f8ST%uRHt zp>hfMB+}oWQu?$^VC=hRk;_-Yf5 z>NAyIe)oH5ABt1*@Bp(s6H!0i9h)r}8G`5%%FLQ$NlqYK2tQ()Mfhs!3vJb1ZB$N( z8W#)eTD#2<#&-q8rRW9ZatQpLPKC%83O(<<$R#wA&i6jK^|oFD<)+Y#ROg#t=gBfI zb|c=6UGPxnL+_I-FXl2Hh77@`SZTOKKfZMAY&&Wi4YO0mz!_$CaLgtNHcT}h>ZH0j z58{M8%5$4t`EUvG$&^>>jd8N|u4dKqz7pNqL-9^GKk7)-eHxW!n!&rL$m5UUt$-At~{8-}xSufus zYJ!VbR)`7d)5&A;4=ZrtzYlF4mfe-93dNSD?u|ukL!|mZo7MB*_pbR(Ku)Ke{{dx_ zKYpFJ*%t+d>lsa}y!bFXhn$rFRttY|5wahy}lWfW=p( z?pxpgxA~bD@9OlF_o3}0w-XD7Xa?*8&KOhJq~Nrar<#NnwS;{k>%slg%MUJ|WY~)c z2#*~Lxp+qV5OtSM8K#anlOd@{hjrqC)L=BCxLurGx9*zPxNPqyZ*z@gXf?m=ggZ z(cL$(ZN#+l+#yU%T6cizgW+9>3qZ^FFde1?*U2T@;YG(`NZ7V$E48#i_%_qf8Mypc zdC(0ZsQ{z0hM(UW*lj}-tznNi&qyk`G5OH)1U+=C)qr))Y$y^dhJ-QsK#>wAmnj8K zVyn;+9T4Ed^G;!}AbrHHF||<4v~5HLaUwM|py5c9 z+pXER_?j;3v%-bHYBEUY1VWCpMnNb2R=aVmif?MbEh1{q^y=Q@g~mR&T}(PJzW#3R z*+-?T7n5Lu@LdCp!Sg<&$15d#*b#eMwK6~X1Fh|=BJ(SE^h7p;^D6^}0ofVKe|kgj z=uP~U)!nP!00WI90pBu{-U%cK@))&=-suN{_-*jK5ja2w%71;=@vY%4yv3CT<1EVD z!GH_O=p6#dZ4z*0-K25e{Jbe2G)KZ7)J-wp&UQq+s(!f{slkA&5aDD=JfgIVMk8tH zh{QMAx${d*>&*np^gJLO7j68A7*Nzgs;;#}82B7>amHY?#y{0$^wc%2trI;D&V;{E ziL$yr77#U=Y0W(8vg`Hx!_Rz%UH2G#(IuVtZhqECt~x0Z>$02uIcO}Tg(KCHyBQ%$CE0y_1grkE0YHu-^wCGo?sguCNn!k&0<&&Wy8(xEtnO~wa#0vDy2`U@+Ujw ztQTWfi7NdHv{2avQ*0f?-3DRn15$^gxvHtBOCGpbW3H%~wf#%^mugX*W1vPQ%Vjh7 zSF1^chjyn6pARW^YV=e)-5ngr(&%A%j5RLExwz~%rFOlTh&Q3$c-dw0)vj=}lNM(z z6GHPNkqHCuh4>^?(T&w`YP^k}oYjMZ7mb)RJyht#pskJ>pP zQK(!tDV3EDPq!eDuo7rVHVK|?ot_Z3er#}5+yo3~!3xEr$G{nXA7t9sk3rez03mvm ztLX7Hvt-kGB`0B6EnI6Or=)=AUu`Mgo0IT3az@_hTq6bcc`>E4kHgd|)sHQOKMP2q z%Qz1ZxU|U9}R8D;z|b)LT=7w z4~ot{H3L4V&48=<}>GwLjCsjx##PBTmaO42gFyLo6_IBdZ8K6r8HXZ{t{rDpc`bdH8M6Pf*~}J zmI0|6_){!nOfX*Nlyoqt*pUOcD7jUuk@eRjE3X!gjBM@)Ot`0kCZtt7Afsgjm@ibx z&(pnX%GZ3(a-D&j3_e^xmtNwMFFcCcql=I5$-|G^H?j__J;k6z$F@^7g-=l#fg`HC z@%u^cu>jydd%BsVNbCp!{&VAWbcD*s9-aCGm7iC!@(({ z^EiI<@3o#`leb16D^|-^?;@9t>!o1>L|ZXQ+ymwSd8>mE;a45Cn@=p`F|Ii+26?7H zG#(Q=*@V!sPwp?7CVy-8_<+}c=s#9}X9_RhwS#<*&)@%sb#aR9WBE$8@i@!B^-xD% zh**5oJ$=H7`P9%yN3>o2p<=;QEIo#kc1)o8mypL#mz=neYf8+;De{canX&j+0q;NQ z1aJf1-#W5#>HYV2(UC7C|GuMgBxLuSpGvJ>lP{o8BA_e1{PTk+>NY=Pf@5NKnxDzy zaN18jv6$X?x?JJ({CQO>*J1jfx_g^5N7hnbAA8-iGY%RxJv*xU_5Pcx506Z_W=Ulx(pFwo zLWt+yWuj=29DeJ}aj77f4Res~)PDOe|8x}1Pt2FE@Me~m@Vf2THBajD^?$1Ej7p~- zgor9N{#3{^fv#M=B4$S!vlZW;QmUeCmnJItvA_8A^3;vdedWvP+<&O4JB7v+9mK*T zQy%V}eitjw{Z0J(4r!A5+mhPN?DI)(Abx*ie*Wm2 z9RrPbkA2O)|5{V4xg_TVM`GtsbEB6j0;?K+uy zaH_$Y8$YY4r>yu;{!=?KCuu%gZUt8c#5|QR__l_BBarR_88dEZhY=utmE$66cH$U2b2&DdFR1&l=zxwdC zTjF&lONxbCRv#7{cS#xbig$*+KJhGH{@)S0&k-55H(u}NmunRF%(ToND7fPG{BXZu z-QRy-+IAvV*Lu%=_fMDH#y%MwJ{T42ztQ@fH$U4wRopL1;`{4kp6!V>BiJ(i-=$;1 zDi^Z7j$%fl5%N_I!q|s8Dus#D>$ABLR{Nh#l+2ct^s`&Et;@s*MPjAoou~vN1Jzt$ zp%fi@rb#%%MP39=M2$;jhLYOk+xxC|`%H~6931JfD^kA$K$}}lec+4t|5iz~Vq}f^ zt_UX$A`{Qi8iJfu3<7t!8EQrux-VKVJ+u3sm%ia2k?S-$laf_^+1)!iwevcGtssg!UGPPs(8`=2 zZ-hp69B@4$q%CP2nQS63MiTbbIux{jJWfehLnm=Hh}1uRf@2@$cH+Rk6y2paEq#Kl z7xArg$?yE!+#)DXmZN2#8y6+(ZtdLb`e3_G^z~HlP75FQdj!Ui&A68zM3F^Fix}5W zNWGy5I`ClxHNL$_4Sr}4A^w%i@z){6ec3E^ zfsAP`Tw|NAXM8G(QeE=p?bm3Rt3GCSr1M2Ah34?ZO;k9kf{qO)@A})I(j$r|0sqQM zRe}s#mR(0vrd9JO(-bzgIZT<5PbzU-Ov!TqIbM(vlh2{7Da#j<7M-L*b9$69IkYvS zP;eN?5;rGN3876-JCBzaS*z)e9}D%2`36|OoyQ|H>ED*B;;(l0LgN-4x+RlsWU$oG1fJ;oP2?I`$iTLM z6H$5yTY4?((n4dYw!?RW>MPfFZ*93$*gR@3jn$5{%&o|BR#s2lDjqFW+=wzM`$8 zqf?H%d*v%rbAuav)*adwSS$03<*;{9CjQm2o(JdFX~HTpH%{YDR&wz1&jbWW7eUME zb(~amk$^ktV(;n1%<}WXBGj_CZ)$`!!pb)zK-+_VpRw^*6#zu~7&# zpu6fBt0F0gtrAO09TJbN|qNd7B508q{cR6etQ zev2SLRGwd^42l+zb5#~oRlqsq#XDO_G)&@kn@UHc_)fu3}1(jD6*)+Tl&}e#i zB78(Gr1XhlRF+kh;?))rRN? z@+uiebrV%`F^H@9;s9jmLrGSRRK0svf>%@h2L%WEdu`6NvXaVbrV5&zV_%@|K=8-p z0ZG1Ta*hM31U0R0zgaW_lEhql-YQWC2}_e)v{9$2a9-wb7SOiWZJ$)E(U-5;Ui0-$ zw8qBf&&k@a*@nH(p8cZO?6#}X`@2GX#?`vX(r>L7Gvnzptn#hXoAOp%hwnD$feWj_ zWtbSl>Y;Rr;_@PyQmpy|oA=Fr0S%Mj;H5OQ)7X#>W*BE;)sb5NXMMq4?l~NdJE9w} zFI%Ar))$N_io0$KRGgcM9(U(9#Tn7H+)^Lz+q??B#l7nVzUfjJRGzyOMrb@1xJ<0) zr4B;^5JRwSFnREl(am#=KKkL{+i{r(@=Cmb>S6tr`BvP~D^MQ0(=U%*e=!gI8d7V2 z6fBJNrytf1yMnV%<&ih7w-38RfW-+72l{}T;9#ES-fT^x2fM+0`-=%}n#nW5Igjo>A{{1dvr6a&i|h1nypmMnRqMn&y)0t-0|EPo&O>bkpwrRlo7+|ne)1dg zsP<29N+${kJl4z79Fk64&s0wQUBtD-+&){n=C?~C<4S31z^=QL^3#WRl`gib^#q<# zYwQ9~JI{{Byz$j(nXGQf7uxWTiagU8Srrw6>tC`Wa2aYteI@y_4kyl9v|R8C%aKI5Sq@f0?w$gn7nq^ zS=Jo(^`K~$5{NkFuZRZdAbPatuVh`$yQ71p57Rs5Is_tovpR<(0QK091n|ebc{k!_ zZ%z%Sf|G!E8{Q2TpKruLxKlbrS~>`;ywv5#;v1He4@ZYC7r2BlE`W>06407i*d|UE zEPn;3T6Gy`rnx2VLg4uko&5g1Bz5Z86G&H?t~^iyW)h6Aj$hm>1reVg?T(UWNf!Aw&Y>7Ot$qCnSNZR zi(mSY;r-gcP!40Y6sPh5BKP09y|G7@!jd)a!P0b;4Tz zn91={dLpiSPhMkR&XB{BXJw9^UziS6rhpcwf~_ow0(T$bOQADV!Z^~fCnpQuemM+- zrOOY)!@8Y9#OPwxj^;}s*(<*B<4rju#4NaU)5Q1Xv)$p*WHg>m0RrCdkGUWJ^8Mwl zVq)<1iDxe;<#z4r>3)PO61S;7GE5v&6YZxKwojrTbotCJWflvRq!O4Cdh;LhZwvu) z=kU~~Wqzp*hPkq()U>{(l;hZEAYp@c-wZoCEPYC^J9oW0_sX9W4yZu6QN!_ie^wpZ z+tVKB;>Og!5L!g@qG-aj>O2~ak4DRj5*4-&s|s--!_J2lH`9@0!-h!CeM-EXslT}9 z*TWWF?+_DxVKZrG@n^1b10sZhtLRyFj9Z%7f zq4AeLLGss*bp6pETmY3#!s+7kq zX&W;10Q>R`f?FhYF4i7x<$l9y<6yN_>seXk#DHxwyU(sFd?B~+MTW48@fO8*o=gvi)Hne z`U~IYN%AaGNdIFXoLF9C`a)=#^#8;4@7~RuYNLFQsqfvx^)B43O)ie2cmMNNp(hpCU}TFKV{0;nG=i`NB`9WD$)Jq3j0!8FJ5Fe5~UM zSRgFSP_u^9!M^!Sg5iW@hbvDRGB_WlDrB@ZF&bpds<~`?dQ!;TrDs{L$7MJRTzzO7 zpXq$3&;IJ)LtRIcixN$ym~5N*a^4J|Ws|%)vLyChYFneYRwGO9;;pEP=`IV+ANhEn zi2dXJut&QhLDgaA-2;(_DmgE=_;@bvsF>iyw#dFSP{Vr>hu%Am9kR7?o&T=`Gvn_? z^)LEscJBuJ+Isi?#)KjzRmM0T>)pF|-{VO*Alks#4g|pa>3m&{^$ZOR&{xo*^Hmu? zFh4I{DkAw>P=-b31h2>S&;$-QjRT7&yh>)8tGBx4htcaTn_AD@cGiEP@}+ZfYLdcb z({~mwzS`&CF)iD5Y5I5QK?WV zGz3Vgc$^dhazP?4okFT=U`i#snweGAUCO0r7MEMvs+C$mX@P)ADuFX61J#6hDlbb* zOY;C53%KnxyMP zG2ouxD$~>7M0hR>$}UlK%jR66*&?>?`ogk}1}l2A7#^PBGDw*GL`s3j(s5Stq1{P6 zRz!v?D88RzQZJFJ{6P#k(nmZU;)t5}XQYAanS?Aiyd5;37yuA2D@1=^TkbhrK zPs>tYN%#Ci0X?-_ROPmO-8$>F_H;?xo!O?>TJNq+J2`K)y0)LEn)XcFHJjd?txE3< z{l?c9A;#Am8Y*hGX2A=)Ejp|&kzx}AgEPCtyft1f>Prm`4Ga#`|CW{+s&W+==MP(3 z`_iU`My2gMWidJY@Wg~=2SM`-#KkXqd=C#kDE|VpH{%jeCTCz^_5hK?DNKfwU&u&u E0O^cBO#lD@ literal 0 HcmV?d00001 diff --git a/alert.sh b/alert.sh new file mode 100755 index 0000000..12969c6 --- /dev/null +++ b/alert.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Usage: ./alert.sh "MESSAGE" [-i image_file] [-f html_file] +set -euo pipefail + +PORT="${DASHBOARD_PORT:-3000}" + +MESSAGE="" +HTML_FILE="" +IMAGE_FILE="" + +while [[ $# -gt 0 ]]; do + case "$1" in + -i|--image) IMAGE_FILE="$2"; shift 2 ;; + -f|--html) HTML_FILE="$2"; shift 2 ;; + -h|--help) echo "Usage: $0 [\"MESSAGE\"] [-i image_file] [-f html_file]" >&2; exit 0 ;; + -*) echo "Option inconnue : $1" >&2; exit 1 ;; + *) MESSAGE="$1"; shift ;; + esac +done + +if [ -z "$MESSAGE" ] && [ -z "$HTML_FILE" ] && [ -z "$IMAGE_FILE" ]; then + echo "Usage: $0 [\"MESSAGE\"] [-i image_file] [-f html_file]" >&2 + exit 1 +fi + +# Build jq args +JQARGS=(--arg msg "$MESSAGE") + +HTML="" +if [ -n "$HTML_FILE" ] && [ -f "$HTML_FILE" ]; then + HTML=$(cat "$HTML_FILE") +fi +JQARGS+=(--arg html "$HTML") + +IMAGE="" +if [ -n "$IMAGE_FILE" ] && [ -f "$IMAGE_FILE" ]; then + case "${IMAGE_FILE##*.}" in + jpg|jpeg) MIME="image/jpeg" ;; + png) MIME="image/png" ;; + gif) MIME="image/gif" ;; + webp) MIME="image/webp" ;; + *) MIME="image/png" ;; + esac + IMAGE="data:${MIME};base64,$(base64 "$IMAGE_FILE" | tr -d '\n')" +fi +JQARGS+=(--arg image "$IMAGE") + +PAYLOAD=$(jq -n "${JQARGS[@]}" '{"message":$msg,"html":$html,"image":$image}') + +curl -sf -X POST "http://localhost:${PORT}/api/alert" \ + -H "Content-Type: application/json" \ + -d "$PAYLOAD" \ + && echo "✓ Alerte déclenchée : $MESSAGE" \ + || echo "✗ Serveur non disponible sur le port ${PORT}" diff --git a/dismiss.sh b/dismiss.sh new file mode 100755 index 0000000..f53d7b1 --- /dev/null +++ b/dismiss.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Usage: ./dismiss.sh +set -euo pipefail + +PORT="${DASHBOARD_PORT:-3000}" + +curl -sf -X DELETE "http://localhost:${PORT}/api/alert" \ + && echo "✓ Alerte révoquée" \ + || echo "✗ Serveur non disponible sur le port ${PORT}" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..0b20e78 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,923 @@ +{ + "name": "cyber-dashboard", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cyber-dashboard", + "version": "1.0.0", + "dependencies": { + "express": "^4.18.2", + "fast-xml-parser": "^4.3.2", + "node-fetch": "^2.7.0", + "ws": "^8.16.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/fast-xml-parser": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.4.tgz", + "integrity": "sha512-jE8ugADnYOBsu1uaoayVl1tVKAMNOXyjwvv2U6udEA2ORBhDooJDWoGxTkhd4Qn4yh59JVVt/pKXtjPwx9OguQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..99c7616 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "cyber-dashboard", + "version": "1.0.0", + "description": "Cyber analyst personal dashboard", + "main": "server.js", + "scripts": { + "start": "node server.js" + }, + "dependencies": { + "express": "^4.18.2", + "fast-xml-parser": "^4.3.2", + "node-fetch": "^2.7.0", + "ws": "^8.16.0" + } +} diff --git a/public/app.js b/public/app.js new file mode 100644 index 0000000..3984800 --- /dev/null +++ b/public/app.js @@ -0,0 +1,275 @@ +'use strict'; + +// ── WebSocket ──────────────────────────────────────────────────────────────── + +let ws; +let wsReconnectTimer; + +function connectWS() { + const proto = location.protocol === 'https:' ? 'wss:' : 'ws:'; + ws = new WebSocket(`${proto}//${location.host}`); + + ws.addEventListener('open', () => { + setWsStatus('CONNECTÉ', 'ok'); + updateInfoWS('CONNECTÉ'); + if (wsReconnectTimer) { clearTimeout(wsReconnectTimer); wsReconnectTimer = null; } + }); + + ws.addEventListener('message', evt => { + let msg; + try { msg = JSON.parse(evt.data); } catch { return; } + + if (msg.type === 'alert') { + showAlert(msg.message, msg.html, msg.image); + } else if (msg.type === 'dismiss') { + hideAlert(); + } + }); + + ws.addEventListener('close', () => { + setWsStatus('DÉCONNECTÉ', 'err'); + updateInfoWS('DÉCONNECTÉ'); + wsReconnectTimer = setTimeout(connectWS, 3000); + }); + + ws.addEventListener('error', () => { + ws.close(); + }); +} + +function setWsStatus(text, cls) { + const el = document.getElementById('ws-status'); + el.textContent = text; + el.className = 'widget-status ' + (cls || ''); +} + +function updateInfoWS(text) { + document.getElementById('info-ws').textContent = text; +} + +// ── Alert overlay ──────────────────────────────────────────────────────────── + +const overlay = document.getElementById('alert-overlay'); +const alertMessageEl = document.getElementById('alert-message'); +const alertHtmlEl = document.getElementById('alert-html'); +const alertIconEl = document.getElementById('alert-icon'); +const alertImageEl = document.getElementById('alert-image'); +const infoAlert = document.getElementById('info-alert'); + +// ── Alarm sound ─────────────────────────────────────────────────────────────── + +const alarmAudio = new Audio('/alert.mp3'); + +function playAlertSound() { + alarmAudio.currentTime = 0; + alarmAudio.play().catch(err => console.error('Audio play failed:', err)); +} + +function stopAlertSound() { + alarmAudio.pause(); + alarmAudio.currentTime = 0; +} + +// ── Alert overlay ───────────────────────────────────────────────────────────── + +let autoDismissTimer = null; + +function showAlert(message, html, image) { + // Image + if (image && image.trim()) { + alertImageEl.innerHTML = ``; + alertIconEl.style.display = 'none'; + } else { + alertImageEl.innerHTML = ''; + alertIconEl.style.display = ''; + } + + // Text / HTML + alertMessageEl.textContent = message || ''; + alertMessageEl.style.display = (message && !image) ? '' : (message ? '' : 'none'); + alertHtmlEl.innerHTML = (html && html.trim()) ? html : ''; + + // Show overlay + overlay.classList.remove('hidden'); + overlay.style.animation = 'none'; + void overlay.offsetWidth; + overlay.style.animation = ''; + + infoAlert.textContent = 'ACTIVE'; + infoAlert.style.color = 'var(--red)'; + + playAlertSound(); + + if (autoDismissTimer) clearTimeout(autoDismissTimer); + autoDismissTimer = setTimeout(hideAlert, 60_000); +} + +function hideAlert() { + if (autoDismissTimer) { clearTimeout(autoDismissTimer); autoDismissTimer = null; } + overlay.classList.add('hidden'); + stopAlertSound(); + infoAlert.textContent = 'INACTIVE'; + infoAlert.style.color = ''; +} + +// ── Clock ──────────────────────────────────────────────────────────────────── + +const clockTime = document.getElementById('clock-time'); +const clockDate = document.getElementById('clock-date'); +const headerClock = document.getElementById('header-clock'); +const infoHost = document.getElementById('info-host'); + +const DAYS = ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi']; +const MONTHS = ['Jan','Fév','Mar','Avr','Mai','Jun','Jul','Aoû','Sep','Oct','Nov','Déc']; + +function pad(n) { return String(n).padStart(2, '0'); } + +function updateClock() { + const now = new Date(); + const h = pad(now.getHours()); + const m = pad(now.getMinutes()); + const s = pad(now.getSeconds()); + const timeStr = `${h}:${m}:${s}`; + const dateStr = `${DAYS[now.getDay()]} ${pad(now.getDate())} ${MONTHS[now.getMonth()]} ${now.getFullYear()}`; + + clockTime.textContent = timeStr; + clockDate.textContent = dateStr; + headerClock.textContent = `${dateStr} ${timeStr}`; +} + +// ── ANSSI / CERT-FR feed ───────────────────────────────────────────────────── + +const anssiList = document.getElementById('anssi-list'); +const anssiStatus = document.getElementById('anssi-status'); + +async function loadAnssi() { + anssiStatus.textContent = '...'; + anssiStatus.className = 'widget-status'; + try { + const resp = await fetch('/api/feeds/anssi'); + if (!resp.ok) throw new Error(`HTTP ${resp.status}`); + const items = await resp.json(); + anssiList.innerHTML = ''; + + if (!items.length) { + anssiList.innerHTML = '
  • Aucun bulletin
  • '; + return; + } + + items.forEach(item => { + const li = document.createElement('li'); + li.className = 'anssi-item'; + + const date = item.pubDate + ? new Date(item.pubDate).toLocaleDateString('fr-FR', { day: '2-digit', month: 'short', year: 'numeric' }) + : ''; + + li.innerHTML = ` +
    ${escapeHtml(item.title)} + ${date ? `${escapeHtml(date)}` : ''} + `; + anssiList.appendChild(li); + }); + + anssiStatus.textContent = `${items.length} bulletins`; + anssiStatus.className = 'widget-status ok'; + } catch (err) { + anssiStatus.textContent = 'ERREUR'; + anssiStatus.className = 'widget-status err'; + anssiList.innerHTML = `
  • Erreur : ${escapeHtml(err.message)}
  • `; + } +} + +// ── CVE feed ────────────────────────────────────────────────────────────────── + +const cveList = document.getElementById('cve-list'); +const cveStatus = document.getElementById('cve-status'); + +function severityClass(cvss) { + if (cvss === undefined || cvss === null) return 'unknown'; + const score = parseFloat(cvss); + if (isNaN(score)) return 'unknown'; + if (score >= 9.0) return 'critical'; + if (score >= 7.0) return 'high'; + if (score >= 4.0) return 'medium'; + return 'low'; +} + +function severityLabel(cvss) { + const cls = severityClass(cvss); + const map = { critical: 'CRITIQUE', high: 'ÉLEVÉ', medium: 'MOYEN', low: 'FAIBLE', unknown: '???' }; + return map[cls]; +} + +async function loadCve() { + cveStatus.textContent = '...'; + cveStatus.className = 'widget-status'; + try { + const resp = await fetch('/api/feeds/cve'); + if (!resp.ok) throw new Error(`HTTP ${resp.status}`); + const items = await resp.json(); + cveList.innerHTML = ''; + + if (!items.length) { + cveList.innerHTML = '
  • Aucune CVE
  • '; + return; + } + + items.forEach(item => { + const cvss = item.cvss ?? item['cvss-score'] ?? null; + const cls = severityClass(cvss); + const label = severityLabel(cvss); + const desc = item.summary || item.description || ''; + const cveId = item.id || item['cve-id'] || 'CVE-????-????'; + + const li = document.createElement('li'); + li.className = 'cve-item'; + li.innerHTML = ` + ${escapeHtml(label)} +
    +
    ${escapeHtml(cveId)}
    +
    ${escapeHtml(desc)}
    +
    + `; + cveList.appendChild(li); + }); + + cveStatus.textContent = `${items.length} CVEs`; + cveStatus.className = 'widget-status ok'; + } catch (err) { + cveStatus.textContent = 'ERREUR'; + cveStatus.className = 'widget-status err'; + cveList.innerHTML = `
  • Erreur : ${escapeHtml(err.message)}
  • `; + } +} + +// ── Init ───────────────────────────────────────────────────────────────────── + +function init() { + infoHost.textContent = location.host; + + connectWS(); + updateClock(); + setInterval(updateClock, 1000); + + loadAnssi(); + loadCve(); + setInterval(loadAnssi, 5 * 60 * 1000); + setInterval(loadCve, 5 * 60 * 1000); +} + +// ── Helpers ─────────────────────────────────────────────────────────────────── + +function escapeHtml(str) { + return String(str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +} + +function escapeAttr(str) { + return String(str).replace(/"/g, '"').replace(/'/g, '''); +} + +document.addEventListener('DOMContentLoaded', init); diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..a8e958e --- /dev/null +++ b/public/index.html @@ -0,0 +1,105 @@ + + + + + + Cyber Dashboard + + + + + + + + +
    +
    + +
    +
    + +
    +
    + + +
    + + +
    +
    + KASPERSKY CYBERMAP + LIVE +
    +
    + +
    +
    + + +
    +
    + CERT-FR / ANSSI + ... +
    +
    +
      +
    • Chargement...
    • +
    +
    +
    + + +
    +
    + DERNIÈRES CVEs + ... +
    +
    +
      +
    • Chargement...
    • +
    +
    +
    + + +
    +
    + SYSTÈME + WS... +
    +
    +
    +
    +
    +
    + SERVEUR + +
    +
    + WEBSOCKET + +
    +
    + ALERTE + INACTIVE +
    +
    +
    +
    + +
    + + + + diff --git a/public/style.css b/public/style.css new file mode 100644 index 0000000..a09f7a9 --- /dev/null +++ b/public/style.css @@ -0,0 +1,330 @@ +/* ── Reset & base ────────────────────────────────────────────────────────── */ +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + +:root { + --bg: #0a0a0a; + --bg-widget: #0f0f0f; + --bg-header: #111111; + --border: #1a2a1a; + --green: #00ff41; + --green-dim: #00aa2a; + --green-dark:#003310; + --red: #ff0033; + --red-dim: #aa0022; + --orange: #ff7700; + --yellow: #ffcc00; + --text: #c8ffc8; + --text-dim: #5a7a5a; + --font: 'Courier New', Courier, monospace; +} + +html, body { + height: 100%; + background: var(--bg); + color: var(--text); + font-family: var(--font); + font-size: 13px; + overflow: hidden; +} + +/* ── Header ──────────────────────────────────────────────────────────────── */ +header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 16px; + height: 40px; + background: var(--bg-header); + border-bottom: 1px solid var(--border); +} + +.logo { + color: var(--green); + font-size: 14px; + font-weight: bold; + letter-spacing: 3px; + text-shadow: 0 0 8px var(--green); +} + +#header-clock { + color: var(--green-dim); + font-size: 13px; + letter-spacing: 1px; +} + +/* ── Grid ────────────────────────────────────────────────────────────────── */ +main.grid { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr 1fr; + gap: 8px; + padding: 8px; + height: calc(100vh - 40px); +} + +/* ── Widget ──────────────────────────────────────────────────────────────── */ +.widget { + display: flex; + flex-direction: column; + background: var(--bg-widget); + border: 1px solid var(--border); + border-radius: 4px; + overflow: hidden; +} + +.widget-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 6px 12px; + background: var(--bg-header); + border-bottom: 1px solid var(--border); + flex-shrink: 0; +} + +.widget-title { + color: var(--green); + font-size: 11px; + letter-spacing: 2px; + font-weight: bold; +} + +.widget-status { + font-size: 10px; + letter-spacing: 1px; + color: var(--green-dim); +} + +.widget-status.ok { color: var(--green); } +.widget-status.err { color: var(--red); } + +.widget-body { + flex: 1; + overflow: hidden; + padding: 8px; +} + +/* ── Iframe widget ───────────────────────────────────────────────────────── */ +.iframe-container { + padding: 0; +} + +.iframe-container iframe { + width: 100%; + height: 100%; + border: none; + display: block; +} + +/* ── Feed list ───────────────────────────────────────────────────────────── */ +.feed-list { + list-style: none; + height: 100%; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 4px; +} + +.feed-list::-webkit-scrollbar { width: 4px; } +.feed-list::-webkit-scrollbar-track { background: transparent; } +.feed-list::-webkit-scrollbar-thumb { background: var(--green-dark); border-radius: 2px; } + +.feed-loading { + color: var(--text-dim); + font-style: italic; + padding: 8px 0; +} + +/* ANSSI items */ +.anssi-item { + border-bottom: 1px solid var(--border); + padding: 6px 4px; +} + +.anssi-item a { + color: var(--green); + text-decoration: none; + font-size: 12px; + display: block; + margin-bottom: 2px; + line-height: 1.4; +} + +.anssi-item a:hover { text-decoration: underline; } + +.anssi-date { + color: var(--text-dim); + font-size: 10px; +} + +/* CVE items */ +.cve-item { + display: flex; + align-items: flex-start; + gap: 8px; + border-bottom: 1px solid var(--border); + padding: 6px 4px; +} + +.cve-badge { + flex-shrink: 0; + font-size: 9px; + font-weight: bold; + letter-spacing: 1px; + padding: 2px 6px; + border-radius: 2px; + text-transform: uppercase; + min-width: 60px; + text-align: center; +} + +.badge-critical { background: var(--red); color: #fff; } +.badge-high { background: var(--orange); color: #000; } +.badge-medium { background: var(--yellow); color: #000; } +.badge-low { background: var(--green-dim); color: #000; } +.badge-unknown { background: #333; color: var(--text-dim); } + +.cve-info { flex: 1; min-width: 0; } + +.cve-id { + color: var(--green); + font-size: 12px; + font-weight: bold; +} + +.cve-desc { + color: var(--text-dim); + font-size: 11px; + margin-top: 2px; + line-height: 1.3; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* ── Clock widget ────────────────────────────────────────────────────────── */ +.clock-widget { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 16px; + height: 100%; +} + +#clock-time { + font-size: 48px; + color: var(--green); + text-shadow: 0 0 16px var(--green); + letter-spacing: 4px; +} + +#clock-date { + font-size: 14px; + color: var(--green-dim); + letter-spacing: 2px; +} + +.server-info { + width: 100%; + max-width: 280px; + border: 1px solid var(--border); + border-radius: 2px; + overflow: hidden; +} + +.info-row { + display: flex; + border-bottom: 1px solid var(--border); +} + +.info-row:last-child { border-bottom: none; } + +.info-label { + width: 100px; + padding: 5px 8px; + background: var(--bg-header); + color: var(--text-dim); + font-size: 10px; + letter-spacing: 1px; + flex-shrink: 0; +} + +.info-value { + padding: 5px 8px; + color: var(--green-dim); + font-size: 10px; + letter-spacing: 1px; +} + +/* ── Alert overlay ───────────────────────────────────────────────────────── */ +#alert-overlay { + position: fixed; + inset: 0; + z-index: 9999; + background: rgba(180, 0, 0, 0.92); + display: flex; + align-items: center; + justify-content: center; + animation: flash-bg 1s ease-in-out infinite; +} + +#alert-overlay.hidden { display: none; } + +@keyframes flash-bg { + 0% { background: rgba(200, 0, 0, 0.92); } + 50% { background: rgba(80, 0, 0, 0.98); } + 100% { background: rgba(200, 0, 0, 0.92); } +} + +#alert-content { + text-align: center; + max-width: 80vw; + padding: 48px; +} + +#alert-icon { + font-size: 80px; + color: #fff; + animation: pulse 1s ease-in-out infinite alternate; + margin-bottom: 24px; +} + +#alert-image { + margin-bottom: 24px; +} + +#alert-image img { + max-width: min(600px, 80vw); + max-height: 40vh; + object-fit: contain; + border: 3px solid rgba(255,255,255,0.3); + border-radius: 4px; + box-shadow: 0 0 40px rgba(255,0,0,0.6); +} + +@keyframes pulse { + from { opacity: 1; transform: scale(1); } + to { opacity: 0.6; transform: scale(1.05); } +} + +#alert-message { + font-size: 36px; + color: #fff; + font-weight: bold; + letter-spacing: 4px; + text-shadow: 0 0 20px rgba(255,255,255,0.5); + text-transform: uppercase; + line-height: 1.3; +} + +#alert-html { + margin-top: 24px; + color: #ffcccc; + font-size: 16px; + line-height: 1.6; +} + +/* ── Utility ──────────────────────────────────────────────────────────────── */ +.hidden { display: none !important; } diff --git a/server.js b/server.js new file mode 100644 index 0000000..7e7c951 --- /dev/null +++ b/server.js @@ -0,0 +1,127 @@ +'use strict'; + +const express = require('express'); +const http = require('http'); +const WebSocket = require('ws'); +const fetch = require('node-fetch'); +const { XMLParser } = require('fast-xml-parser'); +const path = require('path'); + +const PORT = process.env.DASHBOARD_PORT || 3000; + +const app = express(); +app.use(express.json({ limit: '10mb' })); +app.use(express.static(path.join(__dirname, 'public'))); + +const server = http.createServer(app); +const wss = new WebSocket.Server({ server }); + +// Alert state +let alertState = { active: false, message: '', html: '', image: '' }; + +// Broadcast to all connected WS clients +function broadcast(data) { + const payload = JSON.stringify(data); + wss.clients.forEach(client => { + if (client.readyState === WebSocket.OPEN) { + client.send(payload); + } + }); +} + +// Send current state to newly connected client +wss.on('connection', ws => { + if (alertState.active) { + ws.send(JSON.stringify({ + type: 'alert', + message: alertState.message, + html: alertState.html, + image: alertState.image + })); + } +}); + +// ── Routes ────────────────────────────────────────────────────────────────── + +app.get('/alert.mp3', (_req, res) => res.sendFile(path.resolve('alert.mp3'))); + +// Proxy: strip X-Frame-Options and CSP, forward any URL +app.get('/proxy', async (req, res) => { + const { url } = req.query; + if (!url) return res.status(400).json({ error: 'Missing url parameter' }); + + try { + const upstream = await fetch(url, { + headers: { 'User-Agent': 'CyberDashboard/1.0' }, + timeout: 10000 + }); + const contentType = upstream.headers.get('content-type') || 'text/html'; + res.set('Content-Type', contentType); + res.removeHeader('X-Frame-Options'); + res.removeHeader('Content-Security-Policy'); + upstream.body.pipe(res); + } catch (err) { + res.status(502).json({ error: 'Proxy fetch failed', detail: err.message }); + } +}); + +// Alert: GET state +app.get('/api/alert', (req, res) => { + res.json(alertState); +}); + +// Alert: POST (trigger) +app.post('/api/alert', (req, res) => { + const { message = '', html = '', image = '' } = req.body; + alertState = { active: true, message, html, image }; + broadcast({ type: 'alert', message, html, image }); + res.json({ ok: true }); +}); + +// Alert: DELETE (dismiss) +app.delete('/api/alert', (req, res) => { + alertState = { active: false, message: '', html: '', image: '' }; + broadcast({ type: 'dismiss' }); + res.json({ ok: true }); +}); + +// ANSSI / CERT-FR RSS feed +app.get('/api/feeds/anssi', async (req, res) => { + try { + const response = await fetch('https://www.cert.ssi.gouv.fr/feed/', { + headers: { 'User-Agent': 'CyberDashboard/1.0' }, + timeout: 10000 + }); + const xml = await response.text(); + const parser = new XMLParser({ ignoreAttributes: false }); + const parsed = parser.parse(xml); + const items = parsed?.rss?.channel?.item || []; + const entries = (Array.isArray(items) ? items : [items]).map(item => ({ + title: item.title || '', + link: item.link || '', + pubDate: item.pubDate || '', + description: item.description || '' + })); + res.json(entries); + } catch (err) { + res.status(502).json({ error: 'Feed fetch failed', detail: err.message }); + } +}); + +// Last 10 CVEs from CIRCL +app.get('/api/feeds/cve', async (req, res) => { + try { + const response = await fetch('https://cve.circl.lu/api/last/10', { + headers: { 'User-Agent': 'CyberDashboard/1.0' }, + timeout: 10000 + }); + const data = await response.json(); + res.json(data); + } catch (err) { + res.status(502).json({ error: 'CVE fetch failed', detail: err.message }); + } +}); + +server.listen(PORT, () => { + console.log(`Cyber Dashboard running on http://localhost:${PORT}`); +});