From 9ddf54ba8af5135ffda05d08f94d504a2407857a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Thu, 7 Mar 2024 12:44:32 +0100 Subject: [PATCH 1/3] PHP: Support http:// https:// and ssl:// stream wrappers --- package-lock.json | 5 +- package.json | 1 + packages/php-wasm/compile/build.js | 1 + .../public/kitchen-sink/8_0_30/php_8_0.wasm | Bin 9984784 -> 9984784 bytes .../web/public/kitchen-sink/php_8_0.js | 2 +- packages/php-wasm/web/src/lib/index.ts | 2 +- packages/php-wasm/web/src/lib/web-php.ts | 560 +++++++++++++++++- .../remote/src/lib/worker-thread.ts | 6 +- 8 files changed, 571 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 82d34131a6..a2f124f476 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "file-saver": "^2.0.5", "follow-redirects": "1.15.2", "fs-extra": "11.1.1", + "node-forge": "1.3.1", "octokit": "3.1.1", "octokit-plugin-create-pull-request": "5.1.1", "react": "^18.2.0", @@ -32918,8 +32919,8 @@ }, "node_modules/node-forge": { "version": "1.3.1", - "dev": true, - "license": "(BSD-3-Clause OR GPL-2.0)", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "engines": { "node": ">= 6.13.0" } diff --git a/package.json b/package.json index 2420479f77..5a91afa438 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "file-saver": "^2.0.5", "follow-redirects": "1.15.2", "fs-extra": "11.1.1", + "node-forge": "1.3.1", "octokit": "3.1.1", "octokit-plugin-create-pull-request": "5.1.1", "react": "^18.2.0", diff --git a/packages/php-wasm/compile/build.js b/packages/php-wasm/compile/build.js index badafc90e4..94a78e9eb9 100644 --- a/packages/php-wasm/compile/build.js +++ b/packages/php-wasm/compile/build.js @@ -124,6 +124,7 @@ const platformDefaults = { WITH_MBSTRING: 'yes', WITH_MBREGEX: 'yes', WITH_OPENSSL: 'yes', + WITH_WS_NETWORKING_PROXY: 'yes', }, node: { WITH_ICONV: 'yes', diff --git a/packages/php-wasm/web/public/kitchen-sink/8_0_30/php_8_0.wasm b/packages/php-wasm/web/public/kitchen-sink/8_0_30/php_8_0.wasm index 725abf700e50c26290de2cb8f6dd885c930e39e2..bc4ba1cb9250208ff3b4e4d968bf258b6f694eef 100755 GIT binary patch delta 16085 zcmbVTcU)9Q*S>Ri@4~_^unMf82nY&F)CI(bg$pVc6tH0udn{37VoYo?5wKy2C9r!3 zyRrA!N24hAt|0b`y#^%$im`mp>|RaYFYouyx4+-vob#MBXZo4BcbD1QZ)s&>AFHsAv9RD)?y9a?^qr zf0z38#fMTFZW>?sw`npfnCFx?9UWd4;=Bl~MW}NNG+}C}^Os}DTK4C!&T#=GkJaDr zyv_yvy>rr;-8reR?Sgi*3K#XqH6)i^zoMU`ce%LU94Mk)@^Y4TSO4~F1nZq|@uFFs zTn_O8-DWbgVVzw@>Ja|HXD;6m@RaT@tHCMh=@JjMO;49@E>M?z>2eS1ltC_UHiJ*9 z;u`%kS;qFQa`jsQ{bmQlSYG<`Btv!1(~}JoIoEYEJQcxTbTKsHwOG0ve$Zkf*7i0u zaD{$nh~fQ3-tfC|M$am!r@WVO2w4B##(H3Ldm9tL9`rUggL92OMmHWLYM`;F0o?kX z@xm6eEMrKB8ygbhp4<;u&UE*3R7lxO_f)72X1U8w;A0f`sYbxO`>fJ3_n)|rvckO+ zY>!vCzb~#|Ntoio*)aa_Tq5qgKE4x8Abk zDB)r+vG}%GcKuLd{VlU>_@JD+|3Q&m?XH^;@1yHHC?8!*|EZj!Yo~aGcwK+(ZTHs3 z$ZnWj!q?Bzj0aOZ*n=sib~Vwj$jzpaU~4v;2BUjkTTIz}3NYJk_{7?Wz{pJ1C4iB; zO`q|3nweuV@FAJE*R%_4@hy`t`!?59%ExZtQ4^m-+WCZu@3-_5CXvUPc+&I=>QARk zw|Mwod8P&$a9Uux08YQYXzB*_$VF2)HFmGFv+u9}>*;AJ;We3@mSCbsxih5SsP z1$WG{;E_%Y*b%x=v9&C;H4<5p7qDsHSJeD~GBb-RQXZqm^NRBaXfR=PRTs}{^g&n8 z#v06+U1P0MJZm(9)6m(T@6kg#RPn?*rrR9st>W1ZS{v%Q7Oa$dehJny+p|7c?mmk* zU7PK>4yC)z@m$E0%*$UrbKJnUZS?%!9X_>kJ;y^`pX*s`I$D3JofpWPU2123R8|Qs z^02yK0STdEaHxpC2K$pZH7W+jiQZoe%u*B5^d z;^{*xuc1{2`6Q7Y8AAv8u%Ux|+kb_uwClWYOaN+qQ|kMekNoWSzEzm!mG94dcA!Kd z#bq4!uFMX5S23lLEOtq$GGebgU(xII@!H=?c{>(XOfeX)rvZIa>V zn^7{!kCjZSI$<$cN=Mi5Z$Xx_oErYy2a4|t*@&6`C#o4=+%(Hu6qCmmtwD69h2A}@ z(84ag^=$Yie{rz)s+Znq_H!~Ae;1R%vgmQTlDvvds~j+DJh`1AE(~De!oatmim&fx zkXM0>ys8$n9nFs25R{Jrrk*UQHPjv~NW-VL&yJuRzQz6b2G!)Nsm=Z%Enhwz4hF5~ z_BV%uI&wYnXi!t$`x$3~Lb$#yKj;g-o_#I`*|#>m9E1sGaaV#W@M2xB2DRcNx8PdP zXfW^VL40SVUv~sMcQfcSURm8cK}|8qZ0Mgs%Xz7aB|#0bR%ybkpdzs7@}LnwH9aB9czWHVFw% zMS}8JsHsL;8jS`wSDw)9s?jJToqZ6OuW*PhjRu3!Rpx8OQO4C^aFvm#RMo}c>MEaF z@IloZTwLY-(>|!q2ED6{G^IK_8Jt~Z^w+;>NRI`fmv1{xz5^sckgwi0*A|4v!Xd6K zTJ1OlGeju!*|IAk;n&DXc42#H*-gG|s|kFKvGYpJ&kDpBH(B`LTCJTio<9t)RcD29 z{TfGUj{r&D#I{umJD@dgE%vsb(;VBuCi#WU^dmc&XLMMZmHeFHnis}g^FH})3EyJF zYmXMe>y4qwCzx5lfb^kot9>Z{P##bFc36JWP?xc1uIB zxb2oNFjFhHTXOj#`*MecA6naXSh|B%*lEEbLkH}%@Wiuur-dh{r#mf?+%;gA1=kch zVwYtM&}X|WRXA$MvGDvoA;%H}^k9yqfG_dvTuTV73~6cxjxyHaj0K7K0z*DO!V_KS zMax?-r1?s;*(FObOkZ5GY~;Dv^P1&bsFSZbB7Jt#(vX+Tx@Eb^`FD3M_Vs`IfyGZt zR???WEPiAA7cq$%J-aK{qS7A7jHBTZ;9iF z1rH1#)>3T=TfZ)R2=9~q)Ty%}+@B}14yVJz5_)LB!aI@w|pUts|E34XRCuu<;?7+dd*4mjza3a6~c3-M)^f!~L3m7m>%yxs8mt z;)6;b&5CFR)iOJxuLpS6;)n*^?Zonk7hYodLzcTMLg(dH^3+^Y5E=*`SYCfUW#{rD zR#wNd`mroxvawNNskfY-Cdx%+-X1qaU-?b(J>qdxl3%^KZRgf=X1kqUHrwsHabk1- zbQZ0R3>P(1Hkj$RPLa*%dR=6DP5Di`)|n*@32!A&Uq9zx${5cio?k@wle)#RuK({U86_F&>wnImToBbJ|23 zS%dv>BeITYdcDFdkH;uow0YS_Z4upB80l|1ImrR%Ssic|dsG;CgqT*MYux>&>TYHG zZbwEF(+(AXqT=(I@ouC-Yt1=lHaPL)bg?wVO+!SD)>Xb&>dkM$lb?ATpk10^#yvyM zW2eT}!@+VeW9(1$*w~+P?hB=1eZfWF2C@%k>-6c&UP4& zAYXqdxt12SX;!<|WaRk|(64V)SzhJvpM_QY!FY_dY}+ikN9zTzz3YqhP}9Zf`ud_p z=9O9odn_VijQn_mnG?!j6a+5T7lR>e;;sR9*8uLyZS=;v{!j7c*$7thDo7p}Ms z%pmgCvt@+egQipe&CRNlOSI+YW(~$hDm$63MoAn{&F`dVn zbws!#)+}@;hS=PydB0?wqCe8+$GVdptW`<#;?|f8+Nf#F4DgJjO=H;6rt;h*4*oGi z4r8-s%4a(Ai%joZ^5u#+2pgBmzmX#PxKyrADD@}qLyw6mCEOC!K*w21B0 z82pEEvEOUJpQXokB3{`4vc@A1+ z4*g+X>^#;ZJGKfh4@L1LyQpbn?7nJ_Ff+7>u@lb(l80T~`iwt&*u_h%WMgci&iGz^ zBJ{w}PGCtaR+C65>#U25sL0R0DL!#yow*=Yi*uJCQ16hqL=FrLiF+Hug#n3i!$dAz zN{)L=xXZ;(adS8y-Z?IZ8^XK9ZPsEH-u*OgrVn4%-+vcpC4^?^N5nDxh!$0wk+m72 zTUvlxvd}H9O8b(dtg3hX(Fo1^rDi&`O?)-#+9tlLxcLqJs!eUm3}(egX;>J~Pvw+N0pLg!mqs>3^zP&-U>>#7hh4rnU%E z*dA?}OHG~PgK1y~$P?`{>)Rpz4iT-Zsar>Q4Ni)$qS>~CET-wJT^nG^Cj8m*4o_CQov@)qLYGr|^+bml5O#4b?18aSz z{c8i+&El@LKNT)6eZeZYblXs*=0gMUl1pEbk>AQt+8J@a975RHIz+(PW(C|z}I0jk`Jc9K%A~pfKz?3g~Mej+p16g zK@`h3P>UhCUX7Q9{Kb=#tE_C|g3eW*__O*d%4SD!1i#wArWuk`jkuY(_$Fru`r(8Q zBw~yh6W}5T3~|#F$?*|zY|mkPqm#{vc>Q&8TJo)xn(JlWltgx{tP|sng1nbri|AO5 zoM-PNIzC?k{`_*sPp5&m?boSCBh#@{>M7}q6HAnz&7(UOAjR)sFBWuq^9Py7o=@+* zupN28W?k%j${VlNdK7hTtRV#~ySQ`JMwM>j0oX}Cc)Ox(^tk3E7e07qKhA!kr)zcb z?y(00ualq7sfhPO|FACOuao385C0c@az2l>>wm*VH#j`=O$FKOpFtKdIjl>r_VX)f zfq}OGbF@n<|Gb8ut%&VVccKNZyaf(*5o$L4Z9Re-4ZKE&^$}_^@R}TIHtTNbGG_y} zZrP14{hh(PKj_l_Gg3m=$XzFpQd%dr>q4+ov0dAd(hQ%tuFNMc^ z_M$MQP&Dtul}>8$tkLUtv32e@x39yql6;gtzLOGWp12%?)S^=D7M=eJEdOZCr=Q$S znPZ-Wl1?p7MW+r}xVY@2aSOY4HwAa>2k5)&$A$g;0zG{{#TU=RkM5^z(D+?{XqGE~ z+!|%LbX3OvaqKM0wmwc-E24$H|44}vO;=!b!iD<7MtVe7JWKI6?R&##YQjI@3(r#O zR=5UlNzV8PKUqf2&r_uyVkNcTl{tHNmgPp8ZwKeK?mPxFJx8rq}u(|%5K4_8EvT$2F>^cm=LPzUSqaw)_^8@R+>HF zY*+<{IUvFkQ7^z@&Nz5*0B9iSOVA+DV9*fISD>MwuR-5{hJn5X4F`P(`W`d_G!irl zG#WGp^aE%t=ts~`pmCs7P#P#5G#)eoG!ZljG#QiungW^%ng*H<`WZ9>G!rxnG@Bhf z_)FnUDd(vqtf8xyWe${__e#P@=CwRC*(4_xOTwndIw7-M62hP8gpJQ6VKcb@MM;Q! zsuPZYZw0rUk%W4G=!E5mpo1^UfnKB&>d=+jGeeS>K9_`uVx2GyVYYxTN0_KTb%G~~ zGw?B|C85y^ov`$vB~d#|j8 zrUdjeJ6CHj<$=EmY=d_e)5FdN24wvtrUt;l1qQ-HLe{Htv)z*53Rwe+gv@=o9R8am zI2s`cY3C$C2TTNIKsKoIEXce{j{EI$$UJW7E6E;%%MUNu%j)cb$J0SUS#^D0qa3e; z$2rno6r5H0A>9;|)hYaak)t{u+K7SXZd~?-%w4(M3&26}BWrJ^Lbs%`m+j%D|(x>7OHI^3Fi;a`6 zAo^JL{!P|EH*%E@bhTPYZnT#6a~ zP-oFUP-cD8h+wU?MsOlOm9PwKIq>S)zb){CSkD;s6~itsJbZ;Z7S=j+B;8*+Ys zjP{yNq%+H&ZB1|? zi|M_&)=|Vnd(5*QA&pq|`PKz)d{-S@W9_anzI!3rcNA~Dg*IPj^=AnitnUmJCp~lw zYYeyGb2ML~f!nDUeVVU0(~TXd2c5PH1G11E*=6)alI=))%AJZoJ= zOa`^h+@F6|uu}!ry?^5Yc9i1_&RYXSlE(I2w0O%vrSl#HTOj_ZiMFASl^r0rNs0Go0ETH?0*H}2j+dt+RoWD9&O6S z#7#LV388x=A&(A!WS#zBV7JHC26nj4dm_~8$a91st^Oun@SkuVoBY^1gqZ&o z{C7zhv00+-CR-q_`P4f5-}SKLPpx&yf5BaftRXrl9#MXEjQ(0;t)k=Ymgm#OC00K= zs>B*ZLg~B`Yc*V}_mo&uoUt*y-`cnI;J4PGRKBI9;i8a(cJn>))wiOs2XfQ_NjNf0 z6!t_cdR_J(F5)MFq!ZgCvJCbk^a(SjG z?7J-qhah)(CJHBSNy1^sd2dDGe4&&o9D#CSt|+{`DG5g*-$VsjkdHyWfeJEjNWyW* zl~KX5>ymH+atVUIxh4rGAzy-jEy$-JUxa_ptCDaUvL61nE0S;q@-z77U&b^-F06>g zqtW@0ud`H*@CdCw3nd?c0w5Pa-j6^j=)pP2Z+mNnY3RXu$QRJFx#+sYz*We_hM;3wrPr@;3M%M5F(J{3HC|pwUH;x4=IN@-xW!@c$AWcn*2OVNqz04ipPQ zs_;8sEa<_XFl<1eU1;?S$O94RC0bnqc_jh`LN0~81^zzhK^f$e2pWbCyo5Y_hek-i z6ug4$gDE(OMwdfgiI@W9*N{6RW&}F$7i249cE6S?32&erL7>^_!CT1f;B*qLeg}C| zMNx2q{2uat_|!uWIwHv&$I#8plY~x?cR(Hhxi{p|-lFgjav#WzAn$-Y8ge1ZS|Dda zJ|${|lJlZ~LBOG)Beu$J`*HQiL^JcUw8EbSv@Wq#BV%YsVw>eN9~aD}FkM)x6`G!q zgk_LBb`pdK>@~6NBGos%lmugdAe`GG3K@{yAa@%h3cVn^L!LWU6dJHA8rv2TC)-S& zt*hqWX@u_cusxxLF1FqOmu-x*Erwn)*bM)N11mJzmi?Cm#Um%uyY9A=|1QX2tNeeI zF*9ui+W_sq3poNF_qIj5(G|K}_Rs3nHW!3kk42kfM4NV9_8EW47#~$zYaI!}f>PhhhQvJeKT76hExK z9O{UaPG^MK;{A&EBUQGQgcdOIn`xSA?uZ6-WW`~&Br$3{T$bi zd0kswKM@fMu>wcHmp8f>{NbOV-k2t0VgCK$mC3#;^YG)OZt6E|2~kVf&oS zWe+24{v^sDjpXzz+;|7qedB2S)F+a_X^Dz&Q*kYtq@_*j*@pVu#@KAd*sM}rZmKQ? zY=1r5FU0TIeT*IGci8!4Bn@+f-iZm?$%fUp1xZqWRNbFtN87$2(h9UVVtZ3tm`>`9 zhIXcwI9r&s=@FI#>m6q^Yjh=-kgzVXpIX`Gin@X`$ZBV(UmM#gvV=ZqV>>I2z$3_D zy1%XMbH5vKPnb7%~xG^sV?ORTz-a5XlJYCcNBI` zi&UQi)u%3op)Nb#&bG)TZN@^}%)ahnixwp#`eURUdfDQA?qCg%MiSz;Ytv7T+Gln~ zs%CDzZ5gEI9E@%&bZ#1+0#~iMjfaGLKr(?$2a;xim^uBXx`e7O zkAQL7sNxnCua2VCsZ)PjSpPfN?3|Ep?a^DSE}2*}oVKcXl8S$iaGbWOcsCW_42;uu z74NO$T2!T_6jh~OLN%OrsxG5dmkd30=RQ}JmC$7z>}Pf_tyV4QZV_-qxQ4~$ce zif60%AYhj zHvz`!sES|WIO-RS2+rx4YPhZzh=4Pv<0^hz#b2OToN)iJSNuT5mmmhGlPdmH#S?*X zI;G;pD&7!{Pvw73tA;YwkPT-}XH@(z6;FUKr#uxGQXPvv3612Gui}!5MK=*w%c+WruUGME2+zq+#kZ;WLWEpM^AIxX0>W_$P+d-` zE*ga66sY3oReU{)uBVo7Y~Q6iKbM40Kp}A9r`3DaWeUQr0fnl#lp1JgKDX`NyW=C5i;V3skm9igW{yBU>slr0lFhe!mfq~N^ z6<1U|8W^X=D!xd?4BJvw-jEnK<)@dR5u$@aT3^$}jK^Q8APIL}!b zYaF@g37-9Uipd1dv-BNso-`+e^PHCsKc36(!H?&tUbsT?J7YPv2S1iJFvsPu5H}`% z?2JTX_%Q<)!2=Xk=HaBR&D{c=v}G6yWG!t|`sEW_3YkH3pV%7cJ7L2P!2?Yf6FdtbmhmxvALQX?)X~t_wv~Es4)=C5KBJdj z+Xm{3Fa|<^(J0W?f7xD=mMrFtE#F}3SOPfDDIoe2jO1dcfJ&^IUU}<5+*yFH5~R_G zV1EnG^>u<-f}e6;LweF`fyyk>mTeAHCYaiMhAAr<*GMP?)xxwnr#2E!Le_3^$U7kS zhY!b>LH=q35-jA|kmq7ubNNTeBk8zEr8y~}dm@!e8)K!Uwu~v!_Etc=515=d7)K6epd~x$%YVPSBx=0QVt2`RA7Fq9zB;i!grG@d5nm|Pi5Gu{m!B4K8W&X#c-e-|Kc}w8qCBhmw%z;<-BmE40wXGqf%y@41U-CiNJM`VTY9 zU}X^@pU}J^iW%QJKO6$|9&`Rmso|nmE=j^D?4~iS!APYO{{ipx(aH&lbYm&wlz1)a z!xoKK+(q!;CMpv}qaO}1RAc{m(tT5uO4KbwaiYC4l&Zv!jmuCD6KT#)eoS6DsQ9xl zr(*SxhHU3FC0`^z(&;mlKq9mCGnCgNiDs*2EBJ}>J?fdMTsA$y4jhI1WX@rnTo};3 z>|Lhvy^Ef|kl~*KI(C7Qr4PZ2xV3o0TExr?l|S?tFliNn9$+D>6br%66}zogUb>LI zG-<1nNKVtmTa_@fmz~_ITqI&~5naArxvkrWe!P52XE3FfPtG5B#|g5=>V&FDwVfe{ zLY~R;n9`l}p8#yvUy?BHjaF#*8gD&tHF$+FdsT*q{LLUt@Zo%|a2fJ`JY)BQ&n56P zu)jNrHzDXtIj#ytTeO0;Kr6JZCkdVhar?*JFciLrz+2E?b}AM14^gBxGUH^rey8Fu zQPjMQCL~ZDmUvDDIVJYSMj73Rxi5fvelX1f1!BL3on!awpFACVycA)>#w%`qmeXU zL;28|v~-rKkJ_{}-cEc@&`nyJg*Dnz!rNJ7J}~ipK3yTvI>d*bmuN5ipfySd;~CnY zvs=`r16V{$p^5Jg&>Bv(C%I22IlyA z-=R?kXw_+d&fKXDOe{Z54;yG5vFJ1_GtjC;`VxauLK_)qm}G@mN(XUqD#S86hl}GN zzNE(>lJD4gH`)*TmNoXEz4qYdz7 z>c4KJymrnf4rzp0~k3QpHzb+4=i3C4tEDgp)N&Jm#b*igD<0TtJ8|_$w z9wzIlPY8{ZBovltpAdQwKk%&)3dH{MmVF&cn-IMY`>it0*iCFpP5QY=QmOkV2s35} zQXT#L6B>lXkjjz6udsR9iBBjp@ojpsHf@LBjtAAD%Qa%rIeI*t#_Gy2x@G5Bg$R0^ zU~)?%>00p_{w=c}U4SWziK6YKh8P?_Iy;JXl4>BJAA1-@Q_%_>85U3w9o7I1bR$6g#|;^DLL*vBPjEe`2J)iYxy6~^7U;W1G)UsVo{(sb#z6TC=m7e4 zW1uTBBonB@QT|GL6TJbH9H3$}y2W2mpQ0V2u^N2o$Y?r*w5GSYfxoftLF+Vus}Jqi z1V|8uDu^v?LY)XMaVwg_cPy>Y43^1AOp|HPX7HUz$2UVovk-O`J>Co(B9iuO4ut=j zqZwV%oUSl_f}XboMSv3Mr!lZ{=o9*D3_VM{==U;Rk0YR3EbU6FvoW!Bk%)cZ(-MA9 zcHpZe)~6+%$A3UVEoSOVpT1X|SwJE+dtre!>__qcISH&wf4a*+hA`7`nq_G0%r9T~ zyi<>)Vw@iT)Nv!)c=ZW!4NST8pN4(x#yGmtj6FYDp*)w~ROlT&xl9i%rpx?RBO7f% zfy(8$LqZ-}N`#;85&?%c?%Wf9rSI)OgPF9FR^zQ*y^_Y`$L7T==@|Wg{Te>;tktVB zzmW6KzrJqA_w>bw6)(1b6V0j0UiXRC)ITIukg1T0p;Xu_xsH-v7*XNXQjg>J3^|O9I%!+jNMT_)(YFn4yvE z`fIw@J^|CT+4in&Q2AMvmua&H@k;wh*@H27C#CFJWF+mb%O1kfW4i2VoOf|@lpdq< z1y0$q7~?{x?4JpKWj0iw-J6`Fr}f!!+`FPn_EhoRe!9>l`z864DX!TegjA(_4B5V@ z;<6z-h*3E4e3X9;L% L8mrbmyU6%IeRmmz delta 16085 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 Oi-yi*e(lnq8UG*Qss921 diff --git a/packages/php-wasm/web/public/kitchen-sink/php_8_0.js b/packages/php-wasm/web/public/kitchen-sink/php_8_0.js index 241398b699..007609b20e 100644 --- a/packages/php-wasm/web/public/kitchen-sink/php_8_0.js +++ b/packages/php-wasm/web/public/kitchen-sink/php_8_0.js @@ -40,7 +40,7 @@ export function init(RuntimeName, PHPLoader) { // The rest of the code comes from the built php.js file and esm-suffix.js var Module=typeof PHPLoader!="undefined"?PHPLoader:{};var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=RuntimeName==="WEB";var ENVIRONMENT_IS_WORKER=RuntimeName==="WORKER";var ENVIRONMENT_IS_NODE=RuntimeName==="NODE";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||false;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;var runtimeKeepaliveCounter=0;function keepRuntimeAlive(){return noExitRuntime||runtimeKeepaliveCounter>0}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();SOCKFS.root=FS.mount(SOCKFS,{},null);PIPEFS.root=FS.mount(PIPEFS,{},null);callRuntimeCallbacks(__ATINIT__)}function exitRuntime(){___funcs_on_exit();callRuntimeCallbacks(__ATEXIT__);FS.quit();TTY.shutdown();runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}var wasmBinaryFile;wasmBinaryFile=dependencyFilename;if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then((response=>{if(!response["ok"]){throw"failed to load wasm binary file at '"+binaryFile+"'"}return response["arrayBuffer"]()})).catch((()=>getBinarySync(binaryFile)))}}return Promise.resolve().then((()=>getBinarySync(binaryFile)))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then((binary=>WebAssembly.instantiate(binary,imports))).then((instance=>instance)).then(receiver,(reason=>{err("failed to asynchronously prepare wasm: "+reason);abort(reason)}))}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then((response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,(function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)}))}))}return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"a":wasmImports};function receiveInstance(instance,module){var exports=instance.exports;exports=Asyncify.instrumentWasmExports(exports);Module["asm"]=exports;wasmMemory=Module["asm"]["Ya"];updateMemoryViews();wasmTable=Module["asm"]["ab"];addOnInit(Module["asm"]["Za"]);removeRunDependency("wasm-instantiate");return exports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult);return{}}var tempDouble;var tempI64;function ExitStatus(status){this.name="ExitStatus";this.message=`Program terminated with exit(${status})`;this.status=status}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";Module["UTF8ToString"]=UTF8ToString;var ___assert_fail=(condition,filename,line,func)=>{abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])};var ___call_sighandler=(fp,sig)=>(a1=>dynCall_vi.apply(null,[fp,a1]))(sig);var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter((p=>!!p)),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:function(){var paths=Array.prototype.slice.call(arguments);return PATH.normalize(paths.join("/"))},join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>crypto.getRandomValues(view)}else abort("initRandomDevice")};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter((p=>!!p)),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};Module["lengthBytesUTF8"]=lengthBytesUTF8;var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init:function(){},shutdown:function(){},register:function(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open:function(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close:function(stream){stream.tty.ops.fsync(stream.tty)},fsync:function(stream){stream.tty.ops.fsync(stream.tty)},read:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}},ioctl_tcgets:function(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets:function(tty,optional_actions,data){return 0},ioctl_tiocgwinsz:function(tty){return[24,80]}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var zeroMemory=(address,size)=>{HEAPU8.fill(0,address,address+size);return address};var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var mmapAlloc=size=>{size=alignMemory(size,65536);var ptr=_emscripten_builtin_memalign(65536,size);if(!ptr)return 0;return zeroMemory(ptr,size)};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url,(arrayBuffer=>{assert(arrayBuffer,`Loading data file "${url}" failed (no arrayBuffer).`);onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)}),(event=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}}));if(dep)addRunDependency(dep)};var preloadPlugins=Module["preloadPlugins"]||[];function FS_handledByPreloadPlugin(byteArray,fullname,finish,onerror){if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach((function(plugin){if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}}));return handled}function FS_createPreloadedFile(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish){var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,(()=>{if(onerror)onerror();removeRunDependency(dep)}))){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,(byteArray=>processData(byteArray)),onerror)}else{processData(url)}}function FS_modeStringToFlags(str){var flagModes={"r":0,"r+":2,"w":512|64|1,"w+":512|64|2,"a":1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags}function FS_getMode(canRead,canWrite){var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode}var ERRNO_CODES={};var PROXYFS={mount(mount){return PROXYFS.createNode(null,"/",mount.opts.fs.lstat(mount.opts.root).mode,0)},createNode(parent,name,mode,dev){if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node=FS.createNode(parent,name,mode);node.node_ops=PROXYFS.node_ops;node.stream_ops=PROXYFS.stream_ops;return node},realPath(node){var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)},node_ops:{getattr(node){var path=PROXYFS.realPath(node);var stat;try{stat=node.mount.opts.fs.lstat(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}},setattr(node,attr){var path=PROXYFS.realPath(node);try{if(attr.mode!==undefined){node.mount.opts.fs.chmod(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);node.mount.opts.fs.utime(path,date,date)}if(attr.size!==undefined){node.mount.opts.fs.truncate(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},lookup(parent,name){try{var path=PATH.join2(PROXYFS.realPath(parent),name);var mode=parent.mount.opts.fs.lstat(path).mode;var node=PROXYFS.createNode(parent,name,mode);return node}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},mknod(parent,name,mode,dev){var node=PROXYFS.createNode(parent,name,mode,dev);var path=PROXYFS.realPath(node);try{if(FS.isDir(node.mode)){node.mount.opts.fs.mkdir(path,node.mode)}else{node.mount.opts.fs.writeFile(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}return node},rename(oldNode,newDir,newName){var oldPath=PROXYFS.realPath(oldNode);var newPath=PATH.join2(PROXYFS.realPath(newDir),newName);try{oldNode.mount.opts.fs.rename(oldPath,newPath);oldNode.name=newName;oldNode.parent=newDir}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},unlink(parent,name){var path=PATH.join2(PROXYFS.realPath(parent),name);try{parent.mount.opts.fs.unlink(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},rmdir(parent,name){var path=PATH.join2(PROXYFS.realPath(parent),name);try{parent.mount.opts.fs.rmdir(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},readdir(node){var path=PROXYFS.realPath(node);try{return node.mount.opts.fs.readdir(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},symlink(parent,newName,oldPath){var newPath=PATH.join2(PROXYFS.realPath(parent),newName);try{parent.mount.opts.fs.symlink(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},readlink(node){var path=PROXYFS.realPath(node);try{return node.mount.opts.fs.readlink(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}},stream_ops:{open(stream){var path=PROXYFS.realPath(stream.node);try{stream.nfd=stream.node.mount.opts.fs.open(path,stream.flags)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},close(stream){try{stream.node.mount.opts.fs.close(stream.nfd)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},read(stream,buffer,offset,length,position){try{return stream.node.mount.opts.fs.read(stream.nfd,buffer,offset,length,position)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},write(stream,buffer,offset,length,position){try{return stream.node.mount.opts.fs.write(stream.nfd,buffer,offset,length,position)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}},llseek(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){try{var stat=stream.node.node_ops.getattr(stream.node);position+=stat.size}catch(e){throw new FS.ErrnoError(ERRNO_CODES[e.code])}}}if(position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}return position}}};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path,opts={})=>{path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter((p=>!!p));var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:node=>{var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?`${mount}/${path}`:mount+path}path=path?`${node.name}/${path}`:node.name;node=node.parent}},hashName:(parentid,name)=>{var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:node=>{var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:node=>{var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:(parent,name)=>{var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:(parent,name,mode,rdev)=>{var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:node=>{FS.hashRemoveNode(node)},isRoot:node=>node===node.parent,isMountpoint:node=>!!node.mounted,isFile:mode=>(mode&61440)===32768,isDir:mode=>(mode&61440)===16384,isLink:mode=>(mode&61440)===40960,isChrdev:mode=>(mode&61440)===8192,isBlkdev:mode=>(mode&61440)===24576,isFIFO:mode=>(mode&61440)===4096,isSocket:mode=>(mode&49152)===49152,flagsToPermissionString:flag=>{var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:(node,perms)=>{if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup:dir=>{var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:(dir,name)=>{try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:(dir,name,isdir)=>{var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:(node,flags)=>{if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:()=>{for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked:fd=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream:(stream,fd=-1)=>{if(!FS.FSStream){FS.FSStream=function(){this.shared={}};FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get(){return this.node},set(val){this.node=val}},isRead:{get(){return(this.flags&2097155)!==1}},isWrite:{get(){return(this.flags&2097155)!==0}},isAppend:{get(){return this.flags&1024}},flags:{get(){return this.shared.flags},set(val){this.shared.flags=val}},position:{get(){return this.shared.position},set(val){this.shared.position=val}}})}stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:fd=>{FS.streams[fd]=null},chrdev_stream_ops:{open:stream=>{var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:()=>{throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice:(dev,ops)=>{FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts:mount=>{var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:(populate,callback)=>{if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach((mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)}))},mount:(type,opts,mountpoint)=>{var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:mountpoint=>{var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach((hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}}));node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:(parent,name)=>parent.node_ops.lookup(parent,name),mknod:(path,mode,dev)=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:(path,mode)=>{mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:(path,mode)=>{mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:(path,mode)=>{var dirs=path.split("/");var d="";for(var i=0;i{if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink:(oldpath,newpath)=>{if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename:(old_path,new_path)=>{var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir:path=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(54)}return node.node_ops.readdir(node)},unlink:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink:path=>{var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return PATH_FS.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))},stat:(path,dontFollow)=>{var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(44)}if(!node.node_ops.getattr){throw new FS.ErrnoError(63)}return node.node_ops.getattr(node)},lstat:path=>FS.stat(path,true),chmod:(path,mode,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})},lchmod:(path,mode)=>{FS.chmod(path,mode,true)},fchmod:(fd,mode)=>{var stream=FS.getStreamChecked(fd);FS.chmod(stream.node,mode)},chown:(path,uid,gid,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{timestamp:Date.now()})},lchown:(path,uid,gid)=>{FS.chown(path,uid,gid,true)},fchown:(fd,uid,gid)=>{var stream=FS.getStreamChecked(fd);FS.chown(stream.node,uid,gid)},truncate:(path,len)=>{if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})},ftruncate:(fd,len)=>{var stream=FS.getStreamChecked(fd);if((stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.truncate(stream.node,len)},utime:(path,atime,mtime)=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})},open:(path,flags,mode)=>{if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;mode=typeof mode=="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path=="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close:stream=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed:stream=>stream.fd===null,llseek:(stream,offset,whence)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read:(stream,buffer,offset,length,position)=>{if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write:(stream,buffer,offset,length,position,canOwn)=>{if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},allocate:(stream,offset,length)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap:(stream,length,position,prot,flags)=>{if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync:(stream,buffer,offset,length,mmapFlags)=>{if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:stream=>0,ioctl:(stream,cmd,arg)=>{if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile:(path,opts={})=>{opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile:(path,data,opts={})=>{opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir:path=>{var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories:()=>{FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices:()=>{FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories:()=>{FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:()=>{var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup:(parent,name)=>{var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams:()=>{if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},ensureErrnoError:()=>{if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.name="ErrnoError";this.node=node;this.setErrno=function(errno){this.errno=errno};this.setErrno(errno);this.message="FS error"};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach((code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""}))},staticInit:()=>{FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS,"PROXYFS":PROXYFS}},init:(input,output,error)=>{FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:()=>{FS.init.initialized=false;_fflush(0);for(var i=0;i{var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath:(path,dontResolveLastLink)=>{try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath:(parent,path,canRead,canWrite)=>{parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current},createFile:(parent,name,properties,canRead,canWrite)=>{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile:(parent,name,data,canRead,canWrite,canOwn)=>{var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:stream=>{stream.seekable=false},close:stream=>{if(output&&output.buffer&&output.buffer.length){output(10)}},read:(stream,buffer,offset,length,pos)=>{var bytesRead=0;for(var i=0;i{for(var i=0;i{if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;if(typeof XMLHttpRequest!="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(read_){try{obj.contents=intArrayFromString(read_(obj.url),true);obj.usedBytes=obj.contents.length}catch(e){throw new FS.ErrnoError(29)}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}},createLazyFile:(parent,name,url,canRead,canWrite)=>{function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter((chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]}));if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach((key=>{var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}}));function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node}};Module["FS"]=FS;var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt:function(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat:function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAP32[buf+12>>2]=stat.uid;HEAP32[buf+16>>2]=stat.gid;HEAP32[buf+20>>2]=stat.rdev;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+24>>2]=tempI64[0],HEAP32[buf+28>>2]=tempI64[1];HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAPU32[buf+48>>2]=atime%1e3*1e3;tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+56>>2]=tempI64[0],HEAP32[buf+60>>2]=tempI64[1];HEAPU32[buf+64>>2]=mtime%1e3*1e3;tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+72>>2]=tempI64[0],HEAP32[buf+76>>2]=tempI64[1];HEAPU32[buf+80>>2]=ctime%1e3*1e3;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+88>>2]=tempI64[0],HEAP32[buf+92>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},varargs:undefined,get(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStreamChecked(fd);return stream}};function ___syscall__newselect(nfds,readfds,writefds,exceptfds,timeout){try{var total=0;var srcReadLow=readfds?HEAP32[readfds>>2]:0,srcReadHigh=readfds?HEAP32[readfds+4>>2]:0;var srcWriteLow=writefds?HEAP32[writefds>>2]:0,srcWriteHigh=writefds?HEAP32[writefds+4>>2]:0;var srcExceptLow=exceptfds?HEAP32[exceptfds>>2]:0,srcExceptHigh=exceptfds?HEAP32[exceptfds+4>>2]:0;var dstReadLow=0,dstReadHigh=0;var dstWriteLow=0,dstWriteHigh=0;var dstExceptLow=0,dstExceptHigh=0;var allLow=(readfds?HEAP32[readfds>>2]:0)|(writefds?HEAP32[writefds>>2]:0)|(exceptfds?HEAP32[exceptfds>>2]:0);var allHigh=(readfds?HEAP32[readfds+4>>2]:0)|(writefds?HEAP32[writefds+4>>2]:0)|(exceptfds?HEAP32[exceptfds+4>>2]:0);var check=function(fd,low,high,val){return fd<32?low&val:high&val};for(var fd=0;fd>2]:0,tv_usec=readfds?HEAP32[timeout+8>>2]:0;timeoutInMillis=(tv_sec+tv_usec/1e6)*1e3}flags=stream.stream_ops.poll(stream,timeoutInMillis)}if(flags&1&&check(fd,srcReadLow,srcReadHigh,mask)){fd<32?dstReadLow=dstReadLow|mask:dstReadHigh=dstReadHigh|mask;total++}if(flags&4&&check(fd,srcWriteLow,srcWriteHigh,mask)){fd<32?dstWriteLow=dstWriteLow|mask:dstWriteHigh=dstWriteHigh|mask;total++}if(flags&2&&check(fd,srcExceptLow,srcExceptHigh,mask)){fd<32?dstExceptLow=dstExceptLow|mask:dstExceptHigh=dstExceptHigh|mask;total++}}if(readfds){HEAP32[readfds>>2]=dstReadLow;HEAP32[readfds+4>>2]=dstReadHigh}if(writefds){HEAP32[writefds>>2]=dstWriteLow;HEAP32[writefds+4>>2]=dstWriteHigh}if(exceptfds){HEAP32[exceptfds>>2]=dstExceptLow;HEAP32[exceptfds+4>>2]=dstExceptHigh}return total}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var SOCKFS={mount(mount){Module["websocket"]=Module["websocket"]&&"object"===typeof Module["websocket"]?Module["websocket"]:{};Module["websocket"]._callbacks={};Module["websocket"]["on"]=function(event,callback){if("function"===typeof callback){this._callbacks[event]=callback}return this};Module["websocket"].emit=function(event,param){if("function"===typeof this._callbacks[event]){this._callbacks[event].call(this,param)}};return FS.createNode(null,"/",16384|511,0)},createSocket(family,type,protocol){type&=~526336;var streaming=type==1;if(streaming&&protocol&&protocol!=6){throw new FS.ErrnoError(66)}var sock={family:family,type:type,protocol:protocol,server:null,error:null,peers:{},pending:[],recv_queue:[],sock_ops:SOCKFS.websocket_sock_ops};var name=SOCKFS.nextname();var node=FS.createNode(SOCKFS.root,name,49152,0);node.sock=sock;var stream=FS.createStream({path:name,node:node,flags:2,seekable:false,stream_ops:SOCKFS.stream_ops});sock.stream=stream;return sock},getSocket(fd){var stream=FS.getStream(fd);if(!stream||!FS.isSocket(stream.node.mode)){return null}return stream.node.sock},stream_ops:{poll(stream){var sock=stream.node.sock;return sock.sock_ops.poll(sock)},ioctl(stream,request,varargs){var sock=stream.node.sock;return sock.sock_ops.ioctl(sock,request,varargs)},read(stream,buffer,offset,length,position){var sock=stream.node.sock;var msg=sock.sock_ops.recvmsg(sock,length);if(!msg){return 0}buffer.set(msg.buffer,offset);return msg.buffer.length},write(stream,buffer,offset,length,position){var sock=stream.node.sock;return sock.sock_ops.sendmsg(sock,buffer,offset,length)},close(stream){var sock=stream.node.sock;sock.sock_ops.close(sock)}},nextname(){if(!SOCKFS.nextname.current){SOCKFS.nextname.current=0}return"socket["+SOCKFS.nextname.current+++"]"},websocket_sock_ops:{createPeer(sock,addr,port){var ws;if(typeof addr=="object"){ws=addr;addr=null;port=null}if(ws){if(ws._socket){addr=ws._socket.remoteAddress;port=ws._socket.remotePort}else{var result=/ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);if(!result){throw new Error("WebSocket URL must be in the format ws(s)://address:port")}addr=result[1];port=parseInt(result[2],10)}}else{try{var runtimeConfig=Module["websocket"]&&"object"===typeof Module["websocket"];var url="ws:#".replace("#","//");if(runtimeConfig){if("function"===typeof Module["websocket"]["url"]) { url = Module["websocket"]["url"](...arguments); -}else if ("string" === typeof Module["websocket"]["url"]){url=Module["websocket"]["url"]}}if(url==="ws://"||url==="wss://"){var parts=addr.split("/");url=url+parts[0]+":"+port+"/"+parts.slice(1).join("/")}var subProtocols="binary";if(runtimeConfig){if("string"===typeof Module["websocket"]["subprotocol"]){subProtocols=Module["websocket"]["subprotocol"]}}var opts=undefined;if(subProtocols!=="null"){subProtocols=subProtocols.replace(/^ +| +$/g,"").split(/ *, */);opts=subProtocols}if(runtimeConfig&&null===Module["websocket"]["subprotocol"]){subProtocols="null";opts=undefined}var WebSocketConstructor;{WebSocketConstructor=WebSocket}if (Module['websocket']['decorator']) {WebSocketConstructor = Module['websocket']['decorator'](WebSocketConstructor);}ws = new WebSocketConstructor(url,opts);ws.binaryType="arraybuffer"}catch(e){throw new FS.ErrnoError(23)}}var peer={addr:addr,port:port,socket:ws,dgram_send_queue:[]};SOCKFS.websocket_sock_ops.addPeer(sock,peer);SOCKFS.websocket_sock_ops.handlePeerEvents(sock,peer);if(sock.type===2&&typeof sock.sport!="undefined"){peer.dgram_send_queue.push(new Uint8Array([255,255,255,255,"p".charCodeAt(0),"o".charCodeAt(0),"r".charCodeAt(0),"t".charCodeAt(0),(sock.sport&65280)>>8,sock.sport&255]))}return peer},getPeer(sock,addr,port){return sock.peers[addr+":"+port]},addPeer(sock,peer){sock.peers[peer.addr+":"+peer.port]=peer},removePeer(sock,peer){delete sock.peers[peer.addr+":"+peer.port]},handlePeerEvents(sock,peer){var first=true;var handleOpen=function(){Module["websocket"].emit("open",sock.stream.fd);try{var queued=peer.dgram_send_queue.shift();while(queued){peer.socket.send(queued);queued=peer.dgram_send_queue.shift()}}catch(e){peer.socket.close()}};function handleMessage(data){if(typeof data=="string"){var encoder=new TextEncoder;data=encoder.encode(data)}else{assert(data.byteLength!==undefined);if(data.byteLength==0){return}data=new Uint8Array(data)}var wasfirst=first;first=false;if(wasfirst&&data.length===10&&data[0]===255&&data[1]===255&&data[2]===255&&data[3]===255&&data[4]==="p".charCodeAt(0)&&data[5]==="o".charCodeAt(0)&&data[6]==="r".charCodeAt(0)&&data[7]==="t".charCodeAt(0)){var newport=data[8]<<8|data[9];SOCKFS.websocket_sock_ops.removePeer(sock,peer);peer.port=newport;SOCKFS.websocket_sock_ops.addPeer(sock,peer);return}sock.recv_queue.push({addr:peer.addr,port:peer.port,data:data});Module["websocket"].emit("message",sock.stream.fd)}if(ENVIRONMENT_IS_NODE){peer.socket.on("open",handleOpen);peer.socket.on("message",(function(data,isBinary){if(!isBinary){return}handleMessage(new Uint8Array(data).buffer)}));peer.socket.on("close",(function(){Module["websocket"].emit("close",sock.stream.fd)}));peer.socket.on("error",(function(error){sock.error=14;Module["websocket"].emit("error",[sock.stream.fd,sock.error,"ECONNREFUSED: Connection refused"])}))}else{peer.socket.onopen=handleOpen;peer.socket.onclose=function(){Module["websocket"].emit("close",sock.stream.fd)};peer.socket.onmessage=function peer_socket_onmessage(event){handleMessage(event.data)};peer.socket.onerror=function(error){sock.error=14;Module["websocket"].emit("error",[sock.stream.fd,sock.error,"ECONNREFUSED: Connection refused"])}}},poll(sock){if(sock.type===1&&sock.server){return sock.pending.length?64|1:0}var mask=0;var dest=sock.type===1?SOCKFS.websocket_sock_ops.getPeer(sock,sock.daddr,sock.dport):null;if(sock.recv_queue.length||!dest||dest&&dest.socket.readyState===dest.socket.CLOSING||dest&&dest.socket.readyState===dest.socket.CLOSED){mask|=64|1}if(!dest||dest&&dest.socket.readyState===dest.socket.OPEN){mask|=4}if(dest&&dest.socket.readyState===dest.socket.CLOSING||dest&&dest.socket.readyState===dest.socket.CLOSED){mask|=16}return mask},ioctl(sock,request,arg){switch(request){case 21531:var bytes=0;if(sock.recv_queue.length){bytes=sock.recv_queue[0].data.length}HEAP32[arg>>2]=bytes;return 0;default:return 28}},close(sock){if(sock.server){try{sock.server.close()}catch(e){}sock.server=null}var peers=Object.keys(sock.peers);for(var i=0;i{HEAP32[___errno_location()>>2]=value;return value};var inetPton4=str=>{var b=str.split(".");for(var i=0;i<4;i++){var tmp=Number(b[i]);if(isNaN(tmp))return null;b[i]=tmp}return(b[0]|b[1]<<8|b[2]<<16|b[3]<<24)>>>0};var jstoi_q=str=>parseInt(str);var inetPton6=str=>{var words;var w,offset,z;var valid6regx=/^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i;var parts=[];if(!valid6regx.test(str)){return null}if(str==="::"){return[0,0,0,0,0,0,0,0]}if(str.startsWith("::")){str=str.replace("::","Z:")}else{str=str.replace("::",":Z:")}if(str.indexOf(".")>0){str=str.replace(new RegExp("[.]","g"),":");words=str.split(":");words[words.length-4]=jstoi_q(words[words.length-4])+jstoi_q(words[words.length-3])*256;words[words.length-3]=jstoi_q(words[words.length-2])+jstoi_q(words[words.length-1])*256;words=words.slice(0,words.length-2)}else{words=str.split(":")}offset=0;z=0;for(w=0;w{switch(family){case 2:addr=inetPton4(addr);zeroMemory(sa,16);if(addrlen){HEAP32[addrlen>>2]=16}HEAP16[sa>>1]=family;HEAP32[sa+4>>2]=addr;HEAP16[sa+2>>1]=_htons(port);break;case 10:addr=inetPton6(addr);zeroMemory(sa,28);if(addrlen){HEAP32[addrlen>>2]=28}HEAP32[sa>>2]=family;HEAP32[sa+8>>2]=addr[0];HEAP32[sa+12>>2]=addr[1];HEAP32[sa+16>>2]=addr[2];HEAP32[sa+20>>2]=addr[3];HEAP16[sa+2>>1]=_htons(port);break;default:return 5}return 0};var DNS={address_map:{id:1,addrs:{},names:{}},lookup_name:name=>{var res=inetPton4(name);if(res!==null){return name}res=inetPton6(name);if(res!==null){return name}var addr;if(DNS.address_map.addrs[name]){addr=DNS.address_map.addrs[name]}else{var id=DNS.address_map.id++;assert(id<65535,"exceeded max address mappings of 65535");addr="172.29."+(id&255)+"."+(id&65280);DNS.address_map.names[addr]=name;DNS.address_map.addrs[name]=addr}return addr},lookup_addr:addr=>{if(DNS.address_map.names[addr]){return DNS.address_map.names[addr]}return null}};function ___syscall_accept4(fd,addr,addrlen,flags,d1,d2){try{var sock=getSocketFromFD(fd);var newsock=sock.sock_ops.accept(sock);if(addr){var errno=writeSockaddr(addr,newsock.family,DNS.lookup_name(newsock.daddr),newsock.dport,addrlen)}return newsock.stream.fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var inetNtop4=addr=>(addr&255)+"."+(addr>>8&255)+"."+(addr>>16&255)+"."+(addr>>24&255);var inetNtop6=ints=>{var str="";var word=0;var longest=0;var lastzero=0;var zstart=0;var len=0;var i=0;var parts=[ints[0]&65535,ints[0]>>16,ints[1]&65535,ints[1]>>16,ints[2]&65535,ints[2]>>16,ints[3]&65535,ints[3]>>16];var hasipv4=true;var v4part="";for(i=0;i<5;i++){if(parts[i]!==0){hasipv4=false;break}}if(hasipv4){v4part=inetNtop4(parts[6]|parts[7]<<16);if(parts[5]===-1){str="::ffff:";str+=v4part;return str}if(parts[5]===0){str="::";if(v4part==="0.0.0.0")v4part="";if(v4part==="0.0.0.1")v4part="1";str+=v4part;return str}}for(word=0;word<8;word++){if(parts[word]===0){if(word-lastzero>1){len=0}lastzero=word;len++}if(len>longest){longest=len;zstart=word-longest+1}}for(word=0;word<8;word++){if(longest>1){if(parts[word]===0&&word>=zstart&&word{var family=HEAP16[sa>>1];var port=_ntohs(HEAPU16[sa+2>>1]);var addr;switch(family){case 2:if(salen!==16){return{errno:28}}addr=HEAP32[sa+4>>2];addr=inetNtop4(addr);break;case 10:if(salen!==28){return{errno:28}}addr=[HEAP32[sa+8>>2],HEAP32[sa+12>>2],HEAP32[sa+16>>2],HEAP32[sa+20>>2]];addr=inetNtop6(addr);break;default:return{errno:5}}return{family:family,addr:addr,port:port}};function getSocketAddress(addrp,addrlen,allowNull){if(allowNull&&addrp===0)return null;var info=readSockaddr(addrp,addrlen);if(info.errno)throw new FS.ErrnoError(info.errno);info.addr=DNS.lookup_addr(info.addr)||info.addr;return info}function ___syscall_bind(fd,addr,addrlen,d1,d2,d3){try{var sock=getSocketFromFD(fd);var info=getSocketAddress(addr,addrlen);sock.sock_ops.bind(sock,info.addr,info.port);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_chdir(path){try{path=SYSCALLS.getStr(path);FS.chdir(path);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_chmod(path,mode){try{path=SYSCALLS.getStr(path);FS.chmod(path,mode);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_connect(fd,addr,addrlen,d1,d2,d3){try{var sock=getSocketFromFD(fd);var info=getSocketAddress(addr,addrlen);sock.sock_ops.connect(sock,info.addr,info.port);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_dup(fd){try{var old=SYSCALLS.getStreamFromFD(fd);return FS.createStream(old).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_dup3(fd,newfd,flags){try{var old=SYSCALLS.getStreamFromFD(fd);if(old.fd===newfd)return-28;var existing=FS.getStream(newfd);if(existing)FS.close(existing);return FS.createStream(old,newfd).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_faccessat(dirfd,path,amode,flags){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);if(amode&~7){return-28}var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function convertI32PairToI53Checked(lo,hi){return hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN}function ___syscall_fallocate(fd,mode,offset_low,offset_high,len_low,len_high){var offset=convertI32PairToI53Checked(offset_low,offset_high);var len=convertI32PairToI53Checked(len_low,len_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.allocate(stream,offset,len);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fchmod(fd,mode){try{FS.fchmod(fd,mode);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fchown32(fd,owner,group){try{FS.fchown(fd,owner,group);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fchownat(dirfd,path,owner,group,flags){try{path=SYSCALLS.getStr(path);var nofollow=flags&256;flags=flags&~256;path=SYSCALLS.calculateAt(dirfd,path);(nofollow?FS.lchown:FS.chown)(path,owner,group);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.createStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 5:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fdatasync(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fstat64(fd,buf){try{var stream=SYSCALLS.getStreamFromFD(fd);return SYSCALLS.doStat(FS.stat,stream.path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ftruncate64(fd,length_low,length_high){var length=convertI32PairToI53Checked(length_low,length_high);try{if(isNaN(length))return 61;FS.ftruncate(fd,length);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);Module["stringToUTF8"]=stringToUTF8;function ___syscall_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd)+1;if(size>>0,(tempDouble=id,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos>>2]=tempI64[0],HEAP32[dirp+pos+4>>2]=tempI64[1];tempI64=[(idx+1)*struct_size>>>0,(tempDouble=(idx+1)*struct_size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos+8>>2]=tempI64[0],HEAP32[dirp+pos+12>>2]=tempI64[1];HEAP16[dirp+pos+16>>1]=280;HEAP8[dirp+pos+18>>0]=type;stringToUTF8(name,dirp+pos+19,256);pos+=struct_size;idx+=1}FS.llseek(stream,idx*struct_size,0);return pos}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_getpeername(fd,addr,addrlen,d1,d2,d3){try{var sock=getSocketFromFD(fd);if(!sock.daddr){return-53}var errno=writeSockaddr(addr,sock.family,DNS.lookup_name(sock.daddr),sock.dport,addrlen);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_getsockname(fd,addr,addrlen,d1,d2,d3){try{var sock=getSocketFromFD(fd);var errno=writeSockaddr(addr,sock.family,DNS.lookup_name(sock.saddr||"0.0.0.0"),sock.sport,addrlen);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_getsockopt(fd,level,optname,optval,optlen,d1){try{var sock=getSocketFromFD(fd);if(level===1){if(optname===4){HEAP32[optval>>2]=sock.error;HEAP32[optlen>>2]=4;sock.error=null;return 0}}return-50}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=SYSCALLS.get();HEAP32[argp>>2]=termios.c_iflag||0;HEAP32[argp+4>>2]=termios.c_oflag||0;HEAP32[argp+8>>2]=termios.c_cflag||0;HEAP32[argp+12>>2]=termios.c_lflag||0;for(var i=0;i<32;i++){HEAP8[argp+i+17>>0]=termios.c_cc[i]||0}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=SYSCALLS.get();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17>>0])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag:c_iflag,c_oflag:c_oflag,c_cflag:c_cflag,c_lflag:c_lflag,c_cc:c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=SYSCALLS.get();HEAP16[argp>>1]=winsize[0];HEAP16[argp+2>>1]=winsize[1]}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_listen(fd,backlog){try{var sock=getSocketFromFD(fd);sock.sock_ops.listen(sock,backlog);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_lstat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.lstat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_mkdirat(dirfd,path,mode){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_newfstatat(dirfd,path,buf,flags){try{path=SYSCALLS.getStr(path);var nofollow=flags&256;var allowEmpty=flags&4096;flags=flags&~6400;path=SYSCALLS.calculateAt(dirfd,path,allowEmpty);return SYSCALLS.doStat(nofollow?FS.lstat:FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var PIPEFS={BUCKET_BUFFER_SIZE:8192,mount(mount){return FS.createNode(null,"/",16384|511,0)},createPipe(){var pipe={buckets:[],refcnt:2};pipe.buckets.push({buffer:new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),offset:0,roffset:0});var rName=PIPEFS.nextname();var wName=PIPEFS.nextname();var rNode=FS.createNode(PIPEFS.root,rName,4096,0);var wNode=FS.createNode(PIPEFS.root,wName,4096,0);rNode.pipe=pipe;wNode.pipe=pipe;var readableStream=FS.createStream({path:rName,node:rNode,flags:0,seekable:false,stream_ops:PIPEFS.stream_ops});rNode.stream=readableStream;var writableStream=FS.createStream({path:wName,node:wNode,flags:1,seekable:false,stream_ops:PIPEFS.stream_ops});wNode.stream=writableStream;return{readable_fd:readableStream.fd,writable_fd:writableStream.fd}},stream_ops:{poll(stream){var pipe=stream.node.pipe;if((stream.flags&2097155)===1){return 256|4}if(pipe.buckets.length>0){for(var i=0;i0){return 64|1}}}return 0},ioctl(stream,request,varargs){return 28},fsync(stream){return 28},read(stream,buffer,offset,length,position){var pipe=stream.node.pipe;var currentLength=0;for(var i=0;i=dataLen){currBucket.buffer.set(data,currBucket.offset);currBucket.offset+=dataLen;return dataLen}else if(freeBytesInCurrBuffer>0){currBucket.buffer.set(data.subarray(0,freeBytesInCurrBuffer),currBucket.offset);currBucket.offset+=freeBytesInCurrBuffer;data=data.subarray(freeBytesInCurrBuffer,data.byteLength)}var numBuckets=data.byteLength/PIPEFS.BUCKET_BUFFER_SIZE|0;var remElements=data.byteLength%PIPEFS.BUCKET_BUFFER_SIZE;for(var i=0;i0){var newBucket={buffer:new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),offset:data.byteLength,roffset:0};pipe.buckets.push(newBucket);newBucket.buffer.set(data)}return dataLen},close(stream){var pipe=stream.node.pipe;pipe.refcnt--;if(pipe.refcnt===0){pipe.buckets=null}}},nextname(){if(!PIPEFS.nextname.current){PIPEFS.nextname.current=0}return"pipe["+PIPEFS.nextname.current+++"]"}};function ___syscall_pipe(fdPtr){try{if(fdPtr==0){throw new FS.ErrnoError(21)}var res=PIPEFS.createPipe();HEAP32[fdPtr>>2]=res.readable_fd;HEAP32[fdPtr+4>>2]=res.writable_fd;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_poll(fds,nfds,timeout){try{var nonzero=0;for(var i=0;i>2];var events=HEAP16[pollfd+4>>1];var mask=32;var stream=FS.getStream(fd);if(stream){mask=SYSCALLS.DEFAULT_POLLMASK;if (stream.stream_ops?.poll){mask=stream.stream_ops.poll(stream,-1)}}mask&=events|8|16;if(mask)nonzero++;HEAP16[pollfd+6>>1]=mask}return nonzero}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_readlinkat(dirfd,path,buf,bufsize){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_recvfrom(fd,buf,len,flags,addr,addrlen){try{var sock=getSocketFromFD(fd);var msg=sock.sock_ops.recvmsg(sock,len);if(!msg)return 0;if(addr){var errno=writeSockaddr(addr,sock.family,DNS.lookup_name(msg.addr),msg.port,addrlen)}HEAPU8.set(msg.buffer,buf);return msg.buffer.byteLength}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_renameat(olddirfd,oldpath,newdirfd,newpath){try{oldpath=SYSCALLS.getStr(oldpath);newpath=SYSCALLS.getStr(newpath);oldpath=SYSCALLS.calculateAt(olddirfd,oldpath);newpath=SYSCALLS.calculateAt(newdirfd,newpath);FS.rename(oldpath,newpath);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_rmdir(path){try{path=SYSCALLS.getStr(path);FS.rmdir(path);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_sendto(fd,message,length,flags,addr,addr_len){try{var sock=getSocketFromFD(fd);var dest=getSocketAddress(addr,addr_len,true);if(!dest){return FS.write(sock.stream,HEAP8,message,length)}return sock.sock_ops.sendmsg(sock,HEAP8,message,length,dest.addr,dest.port)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_socket(domain,type,protocol){try{var sock=SOCKFS.createSocket(domain,type,protocol);return sock.stream.fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_statfs64(path,size,buf){try{path=SYSCALLS.getStr(path);HEAP32[buf+4>>2]=4096;HEAP32[buf+40>>2]=4096;HEAP32[buf+8>>2]=1e6;HEAP32[buf+12>>2]=5e5;HEAP32[buf+16>>2]=5e5;HEAP32[buf+20>>2]=FS.nextInode;HEAP32[buf+24>>2]=1e6;HEAP32[buf+28>>2]=42;HEAP32[buf+44>>2]=2;HEAP32[buf+36>>2]=255;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_symlink(target,linkpath){try{target=SYSCALLS.getStr(target);linkpath=SYSCALLS.getStr(linkpath);FS.symlink(target,linkpath);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_unlinkat(dirfd,path,flags){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);if(flags===0){FS.unlink(path)}else if(flags===512){FS.rmdir(path)}else{abort("Invalid flags passed to unlinkat")}return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function readI53FromI64(ptr){return HEAPU32[ptr>>2]+HEAP32[ptr+4>>2]*4294967296}function ___syscall_utimensat(dirfd,path,times,flags){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path,true);if(!times){var atime=Date.now();var mtime=atime}else{var seconds=readI53FromI64(times);var nanoseconds=HEAP32[times+8>>2];atime=seconds*1e3+nanoseconds/(1e3*1e3);times+=16;seconds=readI53FromI64(times);nanoseconds=HEAP32[times+8>>2];mtime=seconds*1e3+nanoseconds/(1e3*1e3)}FS.utime(path,atime,mtime);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var nowIsMonotonic=true;var __emscripten_get_now_is_monotonic=()=>nowIsMonotonic;var __emscripten_throw_longjmp=()=>{throw Infinity};function __gmtime_js(time_low,time_high,tmPtr){var time=convertI32PairToI53Checked(time_low,time_high);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getUTCSeconds();HEAP32[tmPtr+4>>2]=date.getUTCMinutes();HEAP32[tmPtr+8>>2]=date.getUTCHours();HEAP32[tmPtr+12>>2]=date.getUTCDate();HEAP32[tmPtr+16>>2]=date.getUTCMonth();HEAP32[tmPtr+20>>2]=date.getUTCFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getUTCDay();var start=Date.UTC(date.getUTCFullYear(),0,1,0,0,0,0);var yday=(date.getTime()-start)/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday}var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var MONTH_DAYS_LEAP_CUMULATIVE=[0,31,60,91,121,152,182,213,244,274,305,335];var MONTH_DAYS_REGULAR_CUMULATIVE=[0,31,59,90,120,151,181,212,243,273,304,334];var ydayFromDate=date=>{var leap=isLeapYear(date.getFullYear());var monthDaysCumulative=leap?MONTH_DAYS_LEAP_CUMULATIVE:MONTH_DAYS_REGULAR_CUMULATIVE;var yday=monthDaysCumulative[date.getMonth()]+date.getDate()-1;return yday};function __localtime_js(time_low,time_high,tmPtr){var time=convertI32PairToI53Checked(time_low,time_high);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}var __mktime_js=function(tmPtr){var ret=(()=>{var date=new Date(HEAP32[tmPtr+20>>2]+1900,HEAP32[tmPtr+16>>2],HEAP32[tmPtr+12>>2],HEAP32[tmPtr+8>>2],HEAP32[tmPtr+4>>2],HEAP32[tmPtr>>2],0);var dst=HEAP32[tmPtr+32>>2];var guessedOffset=date.getTimezoneOffset();var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dstOffset=Math.min(winterOffset,summerOffset);if(dst<0){HEAP32[tmPtr+32>>2]=Number(summerOffset!=winterOffset&&dstOffset==guessedOffset)}else if(dst>0!=(dstOffset==guessedOffset)){var nonDstOffset=Math.max(winterOffset,summerOffset);var trueOffset=dst>0?dstOffset:nonDstOffset;date.setTime(date.getTime()+(trueOffset-guessedOffset)*6e4)}HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getYear();return date.getTime()/1e3})();return setTempRet0((tempDouble=ret,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)),ret>>>0};function __mmap_js(len,prot,flags,fd,offset_low,offset_high,allocated,addr){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);var res=FS.mmap(stream,len,offset,prot,flags);var ptr=res.ptr;HEAP32[allocated>>2]=res.allocated;HEAPU32[addr>>2]=ptr;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function __munmap_js(addr,len,prot,flags,fd,offset_low,offset_high){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);if(prot&2){SYSCALLS.doMsync(addr,stream,len,flags,offset)}FS.munmap(stream)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var timers={};var handleException=e=>{if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e)};var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){if(Module["onExit"])Module["onExit"](code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;if(!keepRuntimeAlive()){exitRuntime()}_proc_exit(status)};var _exit=exitJS;Module["_exit"]=_exit;var maybeExit=()=>{if(runtimeExited){return}if(!keepRuntimeAlive()){try{_exit(EXITSTATUS)}catch(e){handleException(e)}}};var callUserCallback=func=>{if(runtimeExited||ABORT){return}try{func();maybeExit()}catch(e){handleException(e)}};var _emscripten_get_now;_emscripten_get_now=()=>performance.now();var __setitimer_js=(which,timeout_ms)=>{if(timers[which]){clearTimeout(timers[which].id);delete timers[which]}if(!timeout_ms)return 0;var id=setTimeout((()=>{delete timers[which];callUserCallback((()=>__emscripten_timeout(which,_emscripten_get_now())))}),timeout_ms);timers[which]={id:id,timeout_ms:timeout_ms};return 0};var stringToNewUTF8=str=>{var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8(str,ret,size);return ret};var __tzset_js=(timezone,daylight,tzname)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);function extractZone(date){var match=date.toTimeString().match(/\(([A-Za-z ]+)\)$/);return match?match[1]:"GMT"}var winterName=extractZone(winter);var summerName=extractZone(summer);var winterNamePtr=stringToNewUTF8(winterName);var summerNamePtr=stringToNewUTF8(summerName);if(summerOffset>2]=winterNamePtr;HEAPU32[tzname+4>>2]=summerNamePtr}else{HEAPU32[tzname>>2]=summerNamePtr;HEAPU32[tzname+4>>2]=winterNamePtr}};var _abort=()=>{abort("")};function _emscripten_date_now(){return Date.now()}var getHeapMax=()=>2147483648;var _emscripten_get_heap_max=()=>getHeapMax();var _emscripten_memcpy_big=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var growMemory=size=>{var b=wasmMemory.buffer;var pages=size-b.byteLength+65535>>>16;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var runtimeKeepalivePush=()=>{runtimeKeepaliveCounter+=1};var runtimeKeepalivePop=()=>{runtimeKeepaliveCounter-=1};var safeSetTimeout=(func,timeout)=>{runtimeKeepalivePush();return setTimeout((()=>{runtimeKeepalivePop();callUserCallback(func)}),timeout)};var _emscripten_sleep=function(ms){return Asyncify.handleSleep((wakeUp=>safeSetTimeout(wakeUp,ms)))};Module["_emscripten_sleep"]=_emscripten_sleep;_emscripten_sleep.isAsync=true;var ENV = PHPLoader.ENV || {};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i>0]=str.charCodeAt(i)}HEAP8[buffer>>0]=0};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;getEnvStrings().forEach((function(string,i){var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;stringToAscii(string,ptr);bufSize+=string.length+1}));return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach((function(string){bufSize+=string.length+1}));HEAPU32[penviron_buf_size>>2]=bufSize;return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function _fd_fdstat_get(fd,pbuf){try{var rightsBase=0;var rightsInheriting=0;var flags=0;{var stream=SYSCALLS.getStreamFromFD(fd);var type=stream.tty?2:FS.isDir(stream.mode)?3:FS.isLink(stream.mode)?7:4}HEAP8[pbuf>>0]=type;HEAP16[pbuf+2>>1]=flags;tempI64=[rightsBase>>>0,(tempDouble=rightsBase,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[pbuf+8>>2]=tempI64[0],HEAP32[pbuf+12>>2]=tempI64[1];tempI64=[rightsInheriting>>>0,(tempDouble=rightsInheriting,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[pbuf+16>>2]=tempI64[0],HEAP32[pbuf+20>>2]=tempI64[1];return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(typeof offset!=="undefined"){offset+=curr}}return ret};function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var _getaddrinfo=(node,service,hint,out)=>{var addr=0;var port=0;var flags=0;var family=0;var type=0;var proto=0;var ai;function allocaddrinfo(family,type,proto,canon,addr,port){var sa,salen,ai;var errno;salen=family===10?28:16;addr=family===10?inetNtop6(addr):inetNtop4(addr);sa=_malloc(salen);errno=writeSockaddr(sa,family,addr,port);assert(!errno);ai=_malloc(32);HEAP32[ai+4>>2]=family;HEAP32[ai+8>>2]=type;HEAP32[ai+12>>2]=proto;HEAPU32[ai+24>>2]=canon;HEAPU32[ai+20>>2]=sa;if(family===10){HEAP32[ai+16>>2]=28}else{HEAP32[ai+16>>2]=16}HEAP32[ai+28>>2]=0;return ai}if(hint){flags=HEAP32[hint>>2];family=HEAP32[hint+4>>2];type=HEAP32[hint+8>>2];proto=HEAP32[hint+12>>2]}if(type&&!proto){proto=type===2?17:6}if(!type&&proto){type=proto===17?2:1}if(proto===0){proto=6}if(type===0){type=1}if(!node&&!service){return-2}if(flags&~(1|2|4|1024|8|16|32)){return-1}if(hint!==0&&HEAP32[hint>>2]&2&&!node){return-1}if(flags&32){return-2}if(type!==0&&type!==1&&type!==2){return-7}if(family!==0&&family!==2&&family!==10){return-6}if(service){service=UTF8ToString(service);port=parseInt(service,10);if(isNaN(port)){if(flags&1024){return-2}return-8}}if(!node){if(family===0){family=2}if((flags&1)===0){if(family===2){addr=_htonl(2130706433)}else{addr=[0,0,0,1]}}ai=allocaddrinfo(family,type,proto,null,addr,port);HEAPU32[out>>2]=ai;return 0}node=UTF8ToString(node);addr=inetPton4(node);if(addr!==null){if(family===0||family===2){family=2}else if(family===10&&flags&8){addr=[0,0,_htonl(65535),addr];family=10}else{return-2}}else{addr=inetPton6(node);if(addr!==null){if(family===0||family===10){family=10}else{return-2}}}if(addr!=null){ai=allocaddrinfo(family,type,proto,node,addr,port);HEAPU32[out>>2]=ai;return 0}if(flags&4){return-2}node=DNS.lookup_name(node);addr=inetPton4(node);if(family===0){family=2}else if(family===10){addr=[0,0,_htonl(65535),addr]}ai=allocaddrinfo(family,type,proto,null,addr,port);HEAPU32[out>>2]=ai;return 0};var getHostByName=name=>{var ret=_malloc(20);var nameBuf=stringToNewUTF8(name);HEAPU32[ret>>2]=nameBuf;var aliasesBuf=_malloc(4);HEAPU32[aliasesBuf>>2]=0;HEAPU32[ret+4>>2]=aliasesBuf;var afinet=2;HEAP32[ret+8>>2]=afinet;HEAP32[ret+12>>2]=4;var addrListBuf=_malloc(12);HEAPU32[addrListBuf>>2]=addrListBuf+8;HEAPU32[addrListBuf+4>>2]=0;HEAP32[addrListBuf+8>>2]=inetPton4(DNS.lookup_name(name));HEAPU32[ret+16>>2]=addrListBuf;return ret};var _gethostbyaddr=(addr,addrlen,type)=>{if(type!==2){setErrNo(5);return null}addr=HEAP32[addr>>2];var host=inetNtop4(addr);var lookup=DNS.lookup_addr(host);if(lookup){host=lookup}return getHostByName(host)};var _gethostbyname=name=>getHostByName(UTF8ToString(name));var _gethostbyname_r=(name,ret,buf,buflen,out,err)=>{var data=_gethostbyname(name);_memcpy(ret,data,20);_free(data);HEAP32[err>>2]=0;HEAPU32[out>>2]=ret;return 0};var _getloadavg=(loadavg,nelem)=>{var limit=Math.min(nelem,3);var doubleSize=8;for(var i=0;i>3]=.1}return limit};var _getnameinfo=(sa,salen,node,nodelen,serv,servlen,flags)=>{var info=readSockaddr(sa,salen);if(info.errno){return-6}var port=info.port;var addr=info.addr;var overflowed=false;if(node&&nodelen){var lookup;if(flags&1||!(lookup=DNS.lookup_addr(addr))){if(flags&8){return-2}}else{addr=lookup}var numBytesWrittenExclNull=stringToUTF8(addr,node,nodelen);if(numBytesWrittenExclNull+1>=nodelen){overflowed=true}}if(serv&&servlen){port=""+port;var numBytesWrittenExclNull=stringToUTF8(port,serv,servlen);if(numBytesWrittenExclNull+1>=servlen){overflowed=true}}if(overflowed){return-12}return 0};var Protocols={list:[],map:{}};var _setprotoent=stayopen=>{function allocprotoent(name,proto,aliases){var nameBuf=_malloc(name.length+1);stringToAscii(name,nameBuf);var j=0;var length=aliases.length;var aliasListBuf=_malloc((length+1)*4);for(var i=0;i>2]=aliasBuf}HEAPU32[aliasListBuf+j>>2]=0;var pe=_malloc(12);HEAPU32[pe>>2]=nameBuf;HEAPU32[pe+4>>2]=aliasListBuf;HEAP32[pe+8>>2]=proto;return pe}var list=Protocols.list;var map=Protocols.map;if(list.length===0){var entry=allocprotoent("tcp",6,["TCP"]);list.push(entry);map["tcp"]=map["6"]=entry;entry=allocprotoent("udp",17,["UDP"]);list.push(entry);map["udp"]=map["17"]=entry}_setprotoent.index=0};var _getprotobyname=name=>{name=UTF8ToString(name);_setprotoent(true);var result=Protocols.map[name];return result};var _getprotobynumber=number=>{_setprotoent(true);var result=Protocols.map[number];return result};var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var allocateUTF8OnStack=stringToUTF8OnStack;var PHPWASM={init:function(){FS.mkdir("/internal");PHPWASM.EventEmitter=ENVIRONMENT_IS_NODE?require("events").EventEmitter:class EventEmitter{constructor(){this.listeners={}}emit(eventName,data){if(this.listeners[eventName]){this.listeners[eventName].forEach((callback=>{callback(data)}))}}once(eventName,callback){const self=this;function removedCallback(){callback(...arguments);self.removeListener(eventName,removedCallback)}this.on(eventName,removedCallback)}removeAllListeners(eventName){if(eventName){delete this.listeners[eventName]}else{this.listeners={}}}removeListener(eventName,callback){if(this.listeners[eventName]){const idx=this.listeners[eventName].indexOf(callback);if(idx!==-1){this.listeners[eventName].splice(idx,1)}}}};PHPWASM.child_proc_by_fd={};PHPWASM.child_proc_by_pid={};PHPWASM.input_devices={}},getAllWebSockets:function(sock){const webSockets=new Set;if(sock.server){sock.server.clients.forEach((ws=>{webSockets.add(ws)}))}for(const peer of PHPWASM.getAllPeers(sock)){webSockets.add(peer.socket)}return Array.from(webSockets)},getAllPeers:function(sock){const peers=new Set;if(sock.server){sock.pending.filter((pending=>pending.peers)).forEach((pending=>{for(const peer of Object.values(pending.peers)){peers.add(peer)}}))}if(sock.peers){for(const peer of Object.values(sock.peers)){peers.add(peer)}}return Array.from(peers)},awaitData:function(ws){return PHPWASM.awaitEvent(ws,"message")},awaitConnection:function(ws){if(ws.OPEN===ws.readyState){return[Promise.resolve(),PHPWASM.noop]}return PHPWASM.awaitEvent(ws,"open")},awaitClose:function(ws){if([ws.CLOSING,ws.CLOSED].includes(ws.readyState)){return[Promise.resolve(),PHPWASM.noop]}return PHPWASM.awaitEvent(ws,"close")},awaitError:function(ws){if([ws.CLOSING,ws.CLOSED].includes(ws.readyState)){return[Promise.resolve(),PHPWASM.noop]}return PHPWASM.awaitEvent(ws,"error")},awaitEvent:function(ws,event){let resolve;const listener=()=>{resolve()};const promise=new Promise((function(_resolve){resolve=_resolve;ws.once(event,listener)}));const cancel=()=>{ws.removeListener(event,listener);setTimeout(resolve)};return[promise,cancel]},noop:function(){},spawnProcess:function(command,args,options){if(Module["spawnProcess"]){const spawnedPromise=Module["spawnProcess"](command,args,options);return Promise.resolve(spawnedPromise).then((function(spawned){if(!spawned||!spawned.on){throw new Error("spawnProcess() must return an EventEmitter but returned a different type.")}return spawned}))}if(ENVIRONMENT_IS_NODE){return require("child_process").spawn(command,args,{...options,shell:true,stdio:["pipe","pipe","pipe"],timeout:100})}const e=new Error("popen(), proc_open() etc. are unsupported in the browser. Call php.setSpawnHandler() "+"and provide a callback to handle spawning processes, or disable a popen(), proc_open() "+"and similar functions via php.ini.");e.code="SPAWN_UNSUPPORTED";throw e},shutdownSocket:function(socketd,how){const sock=getSocketFromFD(socketd);const peer=Object.values(sock.peers)[0];if(!peer){return-1}try{peer.socket.close();SOCKFS.websocket_sock_ops.removePeer(sock,peer);return 0}catch(e){console.log("Socket shutdown error",e);return-1}}};function _js_create_input_device(deviceId){let dataBuffer=[];let dataCallback;const filename="proc_id_"+deviceId;const device=FS.createDevice("/dev",filename,(function(){}),(function(byte){try{dataBuffer.push(byte);if(dataCallback){dataCallback(new Uint8Array(dataBuffer));dataBuffer=[]}}catch(e){console.error(e);throw e}}));const devicePath="/dev/"+filename;PHPWASM.input_devices[deviceId]={devicePath:devicePath,onData:function(cb){dataCallback=cb;dataBuffer.forEach((function(data){cb(data)}));dataBuffer.length=0}};return allocateUTF8OnStack(devicePath)}function _js_fd_read(fd,iov,iovcnt,pnum){if(Asyncify.state===Asyncify.State.Normal){var returnCode;var stream;let num=0;try{stream=SYSCALLS.getStreamFromFD(fd);const num=doReadv(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError")){throw e}if(e.errno!==6||!(stream?.fd in PHPWASM.child_proc_by_fd)){HEAPU32[pnum>>2]=0;return returnCode}}}return Asyncify.handleSleep((function(wakeUp){var retries=0;var interval=50;var timeout=5e3;var maxRetries=timeout/interval;function poll(){var returnCode;var stream;let num;try{stream=SYSCALLS.getStreamFromFD(fd);num=doReadv(stream,iov,iovcnt);returnCode=0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError")){console.error(e);throw e}returnCode=e.errno}const success=returnCode===0;const failure=++retries>maxRetries||!(fd in PHPWASM.child_proc_by_fd)||PHPWASM.child_proc_by_fd[fd]?.exited||FS.isClosed(stream);if(success){HEAPU32[pnum>>2]=num;wakeUp(0)}else if(failure){HEAPU32[pnum>>2]=0;wakeUp(returnCode===6?0:returnCode)}else{setTimeout(poll,interval)}}poll()}))}function _js_module_onMessage(data,bufPtr){if(typeof Asyncify==="undefined"){return}if(Module["onMessage"]){const dataStr=UTF8ToString(data);return Asyncify.handleSleep((wakeUp=>{Module["onMessage"](dataStr).then((response=>{const responseBytes=typeof response==="string"?(new TextEncoder).encode(response):response;const responseSize=responseBytes.byteLength;const responsePtr=_malloc(responseSize+1);HEAPU8.set(responseBytes,responsePtr);HEAPU8[responsePtr+responseSize]=0;HEAPU8[bufPtr]=responsePtr;HEAPU8[bufPtr+1]=responsePtr>>8;HEAPU8[bufPtr+2]=responsePtr>>16;HEAPU8[bufPtr+3]=responsePtr>>24;wakeUp(responseSize)})).catch((e=>{console.error(e);wakeUp(0)}))}))}}function _js_open_process(command,argsPtr,argsLength,descriptorsPtr,descriptorsLength,cwdPtr,cwdLength,envPtr,envLength){if(!command){return 1}const cmdstr=UTF8ToString(command);if(!cmdstr.length){return 0}let argsArray=[];if(argsLength){for(var i=0;i>2]))}}const cwdstr=cwdPtr?UTF8ToString(cwdPtr):null;let envObject=null;if(envLength){envObject={};for(var i=0;i>2]);const splitAt=envEntry.indexOf("=");if(splitAt===-1){continue}const key=envEntry.substring(0,splitAt);const value=envEntry.substring(splitAt+1);envObject[key]=value}}var std={};for(var i=0;i>2];std[HEAPU32[descriptorPtr>>2]]={child:HEAPU32[descriptorPtr+4>>2],parent:HEAPU32[descriptorPtr+8>>2]}}return Asyncify.handleSleep((async wakeUp=>{let cp;try{const options={};if(cwdstr!==null){options.cwd=cwdstr}if(envObject!==null){options.env=envObject}cp=PHPWASM.spawnProcess(cmdstr,argsArray,options);if(cp instanceof Promise){cp=await cp}}catch(e){if(e.code==="SPAWN_UNSUPPORTED"){wakeUp(1);return}console.error(e);wakeUp(1);throw e}const ProcInfo={pid:cp.pid,exited:false,stdinFd:std[0]?.child,stdinIsDevice:std[0]?.child in PHPWASM.input_devices,stdoutChildFd:std[1]?.child,stdoutParentFd:std[1]?.parent,stderrChildFd:std[2]?.child,stderrParentFd:std[2]?.parent,stdout:new PHPWASM.EventEmitter,stderr:new PHPWASM.EventEmitter};if(ProcInfo.stdoutChildFd)PHPWASM.child_proc_by_fd[ProcInfo.stdoutChildFd]=ProcInfo;if(ProcInfo.stderrChildFd)PHPWASM.child_proc_by_fd[ProcInfo.stderrChildFd]=ProcInfo;if(ProcInfo.stdoutParentFd)PHPWASM.child_proc_by_fd[ProcInfo.stdoutParentFd]=ProcInfo;if(ProcInfo.stderrParentFd)PHPWASM.child_proc_by_fd[ProcInfo.stderrParentFd]=ProcInfo;PHPWASM.child_proc_by_pid[ProcInfo.pid]=ProcInfo;cp.on("exit",(function(code){ProcInfo.exitCode=code;ProcInfo.exited=true;ProcInfo.stdout.emit("data");ProcInfo.stderr.emit("data")}));if(ProcInfo.stdoutChildFd){const stdoutStream=SYSCALLS.getStreamFromFD(ProcInfo.stdoutChildFd);let stdoutAt=0;cp.stdout.on("data",(function(data){ProcInfo.stdout.emit("data",data);stdoutStream.stream_ops.write(stdoutStream,data,0,data.length,stdoutAt);stdoutAt+=data.length}))}if(ProcInfo.stderrChildFd){const stderrStream=SYSCALLS.getStreamFromFD(ProcInfo.stderrChildFd);let stderrAt=0;cp.stderr.on("data",(function(data){ProcInfo.stderr.emit("data",data);stderrStream.stream_ops.write(stderrStream,data,0,data.length,stderrAt);stderrAt+=data.length}))}try{await new Promise(((resolve,reject)=>{cp.on("spawn",resolve);cp.on("error",reject)}))}catch(e){console.error(e);wakeUp(1);return}if(ProcInfo.stdinIsDevice){PHPWASM.input_devices[ProcInfo.stdinFd].onData((function(data){if(!data)return;const dataStr=new TextDecoder("utf-8").decode(data);cp.stdin.write(dataStr)}));wakeUp(ProcInfo.pid);return}if(ProcInfo.stdinFd){const stdinStream=SYSCALLS.getStreamFromFD(ProcInfo.stdinFd);if(stdinStream.node){const CHUNK_SIZE=1024;const buffer=new Uint8Array(CHUNK_SIZE);let offset=0;while(true){const bytesRead=stdinStream.stream_ops.read(stdinStream,buffer,0,CHUNK_SIZE,offset);if(bytesRead===null||bytesRead===0){break}try{cp.stdin.write(buffer.subarray(0,bytesRead))}catch(e){console.error(e);return 1}if(bytesRead{let cp;try{cp=PHPWASM.spawnProcess(cmdstr,[]);if(cp instanceof Promise){cp=await cp}}catch(e){console.error(e);if(e.code==="SPAWN_UNSUPPORTED"){return 1}throw e}const outByteArrays=[];cp.stdout.on("data",(function(data){outByteArrays.push(data)}));const outputPath="/tmp/popen_output";cp.on("exit",(function(exitCode){const outBytes=new Uint8Array(outByteArrays.reduce(((acc,curr)=>acc+curr.length),0));let offset=0;for(const byteArray of outByteArrays){outBytes.set(byteArray,offset);offset+=byteArray.length}FS.writeFile(outputPath,outBytes);HEAPU8[exitCodePtr]=exitCode;wakeUp(allocateUTF8OnStack(outputPath))}))}))}function _js_process_status(pid,exitCodePtr){if(!PHPWASM.child_proc_by_pid[pid]){return-1}if(PHPWASM.child_proc_by_pid[pid].exited){HEAPU32[exitCodePtr>>2]=PHPWASM.child_proc_by_pid[pid].exitCode;return 1}return 0}function _js_waitpid(pid,exitCodePtr){if(!PHPWASM.child_proc_by_pid[pid]){return-1}return Asyncify.handleSleep((wakeUp=>{const poll=function(){if(PHPWASM.child_proc_by_pid[pid]?.exited){HEAPU32[exitCodePtr>>2]=PHPWASM.child_proc_by_pid[pid].exitCode;wakeUp(pid)}else{setTimeout(poll,50)}};poll()}))}var arraySum=(array,index)=>{var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum};var MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];var addDays=(date,days)=>{var newDate=new Date(date.getTime());while(days>0){var leap=isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var _strftime=(s,maxsize,format,tm)=>{var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}return thisDate.getFullYear()}return thisDate.getFullYear()-1}var EXPANSION_RULES_2={"%a":date=>WEEKDAYS[date.tm_wday].substring(0,3),"%A":date=>WEEKDAYS[date.tm_wday],"%b":date=>MONTHS[date.tm_mon].substring(0,3),"%B":date=>MONTHS[date.tm_mon],"%C":date=>{var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":date=>leadingNulls(date.tm_mday,2),"%e":date=>leadingSomething(date.tm_mday,2," "),"%g":date=>getWeekBasedYear(date).toString().substring(2),"%G":date=>getWeekBasedYear(date),"%H":date=>leadingNulls(date.tm_hour,2),"%I":date=>{var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":date=>leadingNulls(date.tm_mday+arraySum(isLeapYear(date.tm_year+1900)?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,date.tm_mon-1),3),"%m":date=>leadingNulls(date.tm_mon+1,2),"%M":date=>leadingNulls(date.tm_min,2),"%n":()=>"\n","%p":date=>{if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}return"PM"},"%S":date=>leadingNulls(date.tm_sec,2),"%t":()=>"\t","%u":date=>date.tm_wday||7,"%U":date=>{var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":date=>{var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":date=>date.tm_wday,"%W":date=>{var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":date=>(date.tm_year+1900).toString().substring(2),"%Y":date=>date.tm_year+1900,"%z":date=>{var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":date=>date.tm_zone,"%%":()=>"%"};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1};var _strptime=(buf,format,tm)=>{var pattern=UTF8ToString(format);var SPECIAL_CHARS="\\!@#$^&*()+=-[]/{}|:<>?,.";for(var i=0,ii=SPECIAL_CHARS.length;i=0;i=pattern.indexOf("%")){capture.push(pattern[i+1]);pattern=pattern.replace(new RegExp("\\%"+pattern[i+1],"g"),"")}var matches=new RegExp("^"+pattern,"i").exec(UTF8ToString(buf));function initDate(){function fixup(value,min,max){return typeof value!="number"||isNaN(value)?min:value>=min?value<=max?value:max:min}return{year:fixup(HEAP32[tm+20>>2]+1900,1970,9999),month:fixup(HEAP32[tm+16>>2],0,11),day:fixup(HEAP32[tm+12>>2],1,31),hour:fixup(HEAP32[tm+8>>2],0,23),min:fixup(HEAP32[tm+4>>2],0,59),sec:fixup(HEAP32[tm>>2],0,59)}}if(matches){var date=initDate();var value;var getMatch=symbol=>{var pos=capture.indexOf(symbol);if(pos>=0){return matches[pos+1]}return};if(value=getMatch("S")){date.sec=jstoi_q(value)}if(value=getMatch("M")){date.min=jstoi_q(value)}if(value=getMatch("H")){date.hour=jstoi_q(value)}else if(value=getMatch("I")){var hour=jstoi_q(value);if(value=getMatch("p")){hour+=value.toUpperCase()[0]==="P"?12:0}date.hour=hour}if(value=getMatch("Y")){date.year=jstoi_q(value)}else if(value=getMatch("y")){var year=jstoi_q(value);if(value=getMatch("C")){year+=jstoi_q(value)*100}else{year+=year<69?2e3:1900}date.year=year}if(value=getMatch("m")){date.month=jstoi_q(value)-1}else if(value=getMatch("b")){date.month=MONTH_NUMBERS[value.substring(0,3).toUpperCase()]||0}if(value=getMatch("d")){date.day=jstoi_q(value)}else if(value=getMatch("j")){var day=jstoi_q(value);var leapYear=isLeapYear(date.year);for(var month=0;month<12;++month){var daysUntilMonth=arraySum(leapYear?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,month-1);if(day<=daysUntilMonth+(leapYear?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[month]){date.day=day-daysUntilMonth}}}else if(value=getMatch("a")){var weekDay=value.substring(0,3).toUpperCase();if(value=getMatch("U")){var weekDayNumber=DAY_NUMBERS_SUN_FIRST[weekDay];var weekNumber=jstoi_q(value);var janFirst=new Date(date.year,0,1);var endDate;if(janFirst.getDay()===0){endDate=addDays(janFirst,weekDayNumber+7*(weekNumber-1))}else{endDate=addDays(janFirst,7-janFirst.getDay()+weekDayNumber+7*(weekNumber-1))}date.day=endDate.getDate();date.month=endDate.getMonth()}else if(value=getMatch("W")){var weekDayNumber=DAY_NUMBERS_MON_FIRST[weekDay];var weekNumber=jstoi_q(value);var janFirst=new Date(date.year,0,1);var endDate;if(janFirst.getDay()===1){endDate=addDays(janFirst,weekDayNumber+7*(weekNumber-1))}else{endDate=addDays(janFirst,7-janFirst.getDay()+1+weekDayNumber+7*(weekNumber-1))}date.day=endDate.getDate();date.month=endDate.getMonth()}}var fullDate=new Date(date.year,date.month,date.day,date.hour,date.min,date.sec,0);HEAP32[tm>>2]=fullDate.getSeconds();HEAP32[tm+4>>2]=fullDate.getMinutes();HEAP32[tm+8>>2]=fullDate.getHours();HEAP32[tm+12>>2]=fullDate.getDate();HEAP32[tm+16>>2]=fullDate.getMonth();HEAP32[tm+20>>2]=fullDate.getFullYear()-1900;HEAP32[tm+24>>2]=fullDate.getDay();HEAP32[tm+28>>2]=arraySum(isLeapYear(fullDate.getFullYear())?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,fullDate.getMonth()-1)+fullDate.getDate()-1;HEAP32[tm+32>>2]=0;return buf+intArrayFromString(matches[0]).length-1}return 0};function _wasm_poll_socket(socketd,events,timeout){if(typeof Asyncify==="undefined"){return 0}const POLLIN=1;const POLLPRI=2;const POLLOUT=4;const POLLERR=8;const POLLHUP=16;const POLLNVAL=32;return Asyncify.handleSleep((wakeUp=>{const polls=[];if(socketd in PHPWASM.child_proc_by_fd){const procInfo=PHPWASM.child_proc_by_fd[socketd];if(procInfo.exited){wakeUp(0);return}polls.push(PHPWASM.awaitEvent(procInfo.stdout,"data"))}else{const sock=getSocketFromFD(socketd);if(!sock){wakeUp(0);return}const lookingFor=new Set;if(events&POLLIN||events&POLLPRI){if(sock.server){for(const client of sock.pending){if((client.recv_queue||[]).length>0){wakeUp(1);return}}}else if((sock.recv_queue||[]).length>0){wakeUp(1);return}}const webSockets=PHPWASM.getAllWebSockets(sock);if(!webSockets.length){wakeUp(0);return}for(const ws of webSockets){if(events&POLLIN||events&POLLPRI){polls.push(PHPWASM.awaitData(ws));lookingFor.add("POLLIN")}if(events&POLLOUT){polls.push(PHPWASM.awaitConnection(ws));lookingFor.add("POLLOUT")}if(events&POLLHUP){polls.push(PHPWASM.awaitClose(ws));lookingFor.add("POLLHUP")}if(events&POLLERR||events&POLLNVAL){polls.push(PHPWASM.awaitError(ws));lookingFor.add("POLLERR")}}}if(polls.length===0){console.warn("Unsupported poll event "+events+", defaulting to setTimeout().");setTimeout((function(){wakeUp(0)}),timeout);return}const promises=polls.map((([promise])=>promise));const clearPolling=()=>polls.forEach((([,clear])=>clear()));let awaken=false;let timeoutId;Promise.race(promises).then((function(results){if(!awaken){awaken=true;wakeUp(1);if(timeoutId){clearTimeout(timeoutId)}clearPolling()}}));if(timeout!==-1){timeoutId=setTimeout((function(){if(!awaken){awaken=true;wakeUp(0);clearPolling()}}),timeout)}}))}function _wasm_setsockopt(socketd,level,optionName,optionValuePtr,optionLen){const optionValue=HEAPU8[optionValuePtr];const SOL_SOCKET=1;const SO_KEEPALIVE=9;const IPPROTO_TCP=6;const TCP_NODELAY=1;const isSupported=level===SOL_SOCKET&&optionName===SO_KEEPALIVE||level===IPPROTO_TCP&&optionName===TCP_NODELAY;if(!isSupported){console.warn(`Unsupported socket option: ${level}, ${optionName}, ${optionValue}`);return-1}const ws=PHPWASM.getAllWebSockets(socketd)[0];if(!ws){return-1}ws.setSocketOpt(level,optionName,optionValuePtr);return 0}function runAndAbortIfError(func){try{return func()}catch(e){abort(e)}}var Asyncify={instrumentWasmImports:function(imports){var importPatterns=[/^_dlopen_js$/,/^invoke_i$/,/^invoke_ii$/,/^invoke_iii$/,/^invoke_iiii$/,/^invoke_iiiii$/,/^invoke_iiiiii$/,/^invoke_iiiiiii$/,/^invoke_iiiiiiii$/,/^invoke_iiiiiiiiii$/,/^invoke_v$/,/^invoke_vi$/,/^invoke_vii$/,/^invoke_viidii$/,/^invoke_viii$/,/^invoke_viiii$/,/^invoke_viiiii$/,/^invoke_viiiiii$/,/^invoke_viiiiiii$/,/^invoke_viiiiiiiii$/,/^js_open_process$/,/^js_popen_to_file$/,/^js_fd_read$/,/^js_module_onMessage$/,/^js_waitpid$/,/^wasm_poll_socket$/,/^wasm_shutdown$/,/^fd_sync$/,/^__wasi_fd_sync$/,/^__asyncjs__.*$/,/^emscripten_promise_await$/,/^emscripten_idb_load$/,/^emscripten_idb_store$/,/^emscripten_idb_delete$/,/^emscripten_idb_exists$/,/^emscripten_idb_load_blob$/,/^emscripten_idb_store_blob$/,/^emscripten_sleep$/,/^emscripten_wget_data$/,/^emscripten_scan_registers$/,/^emscripten_lazy_load_code$/,/^_load_secondary_module$/,/^emscripten_fiber_swap$/,/^SDL_Delay$/];for(var x in imports){(function(x){var original=imports[x];var sig=original.sig;if(typeof original=="function"){var isAsyncifyImport=original.isAsync||importPatterns.some((pattern=>!!x.match(pattern)))}})(x)}},instrumentWasmExports:function(exports){var ret={};for(var x in exports){(function(x){var original=exports[x];if(typeof original=="function"){ret[x]=function(){Asyncify.exportCallStack.push(x);try{return original.apply(null,arguments)}finally{if(!ABORT){var y=Asyncify.exportCallStack.pop();assert(y===x);Asyncify.maybeStopUnwind()}}}}else{ret[x]=original}})(x)}return ret},State:{Normal:0,Unwinding:1,Rewinding:2,Disabled:3},state:0,StackSize:4096,currData:null,handleSleepReturnValue:0,exportCallStack:[],callStackNameToId:{},callStackIdToName:{},callStackId:0,asyncPromiseHandlers:null,sleepCallbacks:[],getCallStackId:function(funcName){var id=Asyncify.callStackNameToId[funcName];if(id===undefined){id=Asyncify.callStackId++;Asyncify.callStackNameToId[funcName]=id;Asyncify.callStackIdToName[id]=funcName}return id},maybeStopUnwind:function(){if(Asyncify.currData&&Asyncify.state===Asyncify.State.Unwinding&&Asyncify.exportCallStack.length===0){Asyncify.state=Asyncify.State.Normal;runtimeKeepalivePush();runAndAbortIfError(_asyncify_stop_unwind);if(typeof Fibers!="undefined"){Fibers.trampoline()}}},whenDone:function(){return new Promise(((resolve,reject)=>{Asyncify.asyncPromiseHandlers={resolve:resolve,reject:reject}}))},allocateData:function(){var ptr=_malloc(12+Asyncify.StackSize);Asyncify.setDataHeader(ptr,ptr+12,Asyncify.StackSize);Asyncify.setDataRewindFunc(ptr);return ptr},setDataHeader:function(ptr,stack,stackSize){HEAP32[ptr>>2]=stack;HEAP32[ptr+4>>2]=stack+stackSize},setDataRewindFunc:function(ptr){var bottomOfCallStack=Asyncify.exportCallStack[0];var rewindId=Asyncify.getCallStackId(bottomOfCallStack);HEAP32[ptr+8>>2]=rewindId},getDataRewindFunc:function(ptr){var id=HEAP32[ptr+8>>2];var name=Asyncify.callStackIdToName[id];var func=Module["asm"][name];return func},doRewind:function(ptr){var start=Asyncify.getDataRewindFunc(ptr);runtimeKeepalivePop();return start()},handleSleep:function(startAsync){if(ABORT)return;if(Asyncify.state===Asyncify.State.Normal){var reachedCallback=false;var reachedAfterCallback=false;startAsync(((handleSleepReturnValue=0)=>{if(ABORT)return;Asyncify.handleSleepReturnValue=handleSleepReturnValue;reachedCallback=true;if(!reachedAfterCallback){return}Asyncify.state=Asyncify.State.Rewinding;runAndAbortIfError((()=>_asyncify_start_rewind(Asyncify.currData)));if(typeof Browser!="undefined"&&Browser.mainLoop.func){Browser.mainLoop.resume()}var asyncWasmReturnValue,isError=false;try{asyncWasmReturnValue=Asyncify.doRewind(Asyncify.currData)}catch(err){asyncWasmReturnValue=err;isError=true}var handled=false;if(!Asyncify.currData){var asyncPromiseHandlers=Asyncify.asyncPromiseHandlers;if(asyncPromiseHandlers){Asyncify.asyncPromiseHandlers=null;(isError?asyncPromiseHandlers.reject:asyncPromiseHandlers.resolve)(asyncWasmReturnValue);handled=true}}if(isError&&!handled){throw asyncWasmReturnValue}}));reachedAfterCallback=true;if(!reachedCallback){Asyncify.state=Asyncify.State.Unwinding;Asyncify.currData=Asyncify.allocateData();if(typeof Browser!="undefined"&&Browser.mainLoop.func){Browser.mainLoop.pause()}runAndAbortIfError((()=>_asyncify_start_unwind(Asyncify.currData)))}}else if(Asyncify.state===Asyncify.State.Rewinding){Asyncify.state=Asyncify.State.Normal;runAndAbortIfError(_asyncify_stop_rewind);_free(Asyncify.currData);Asyncify.currData=null;Asyncify.sleepCallbacks.forEach((func=>callUserCallback(func)))}else{abort(`invalid state: ${Asyncify.state}`)}return Asyncify.handleSleepReturnValue},handleAsync:function(startAsync){return Asyncify.handleSleep((wakeUp=>{startAsync().then(wakeUp)}))}};function getCFunc(ident){var func=Module["_"+ident];return func}var ccall=function(ident,returnType,argTypes,args,opts){var toC={"string":str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},"array":arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); +}else if ("string" === typeof Module["websocket"]["url"]){url=Module["websocket"]["url"]}}if(url==="ws://"||url==="wss://"){var parts=addr.split("/");url=url+parts[0]+":"+port+"/"+parts.slice(1).join("/")}var subProtocols="binary";if(runtimeConfig){if("string"===typeof Module["websocket"]["subprotocol"]){subProtocols=Module["websocket"]["subprotocol"]}}var opts=undefined;if(subProtocols!=="null"){subProtocols=subProtocols.replace(/^ +| +$/g,"").split(/ *, */);opts=subProtocols}if(runtimeConfig&&null===Module["websocket"]["subprotocol"]){subProtocols="null";opts=undefined}var WebSocketConstructor;{WebSocketConstructor=WebSocket}if (Module['websocket']['decorator']) {WebSocketConstructor = Module['websocket']['decorator'](WebSocketConstructor);}ws = new WebSocketConstructor(url,opts);ws.binaryType="arraybuffer"}catch(e){throw new FS.ErrnoError(23)}}var peer={addr:addr,port:port,socket:ws,dgram_send_queue:[]};SOCKFS.websocket_sock_ops.addPeer(sock,peer);SOCKFS.websocket_sock_ops.handlePeerEvents(sock,peer);if(sock.type===2&&typeof sock.sport!="undefined"){peer.dgram_send_queue.push(new Uint8Array([255,255,255,255,"p".charCodeAt(0),"o".charCodeAt(0),"r".charCodeAt(0),"t".charCodeAt(0),(sock.sport&65280)>>8,sock.sport&255]))}return peer},getPeer(sock,addr,port){return sock.peers[addr+":"+port]},addPeer(sock,peer){sock.peers[peer.addr+":"+peer.port]=peer},removePeer(sock,peer){delete sock.peers[peer.addr+":"+peer.port]},handlePeerEvents(sock,peer){var first=true;var handleOpen=function(){Module["websocket"].emit("open",sock.stream.fd);try{var queued=peer.dgram_send_queue.shift();while(queued){peer.socket.send(queued);queued=peer.dgram_send_queue.shift()}}catch(e){peer.socket.close()}};function handleMessage(data){if(typeof data=="string"){var encoder=new TextEncoder;data=encoder.encode(data)}else{assert(data.byteLength!==undefined);if(data.byteLength==0){return}data=new Uint8Array(data)}var wasfirst=first;first=false;if(wasfirst&&data.length===10&&data[0]===255&&data[1]===255&&data[2]===255&&data[3]===255&&data[4]==="p".charCodeAt(0)&&data[5]==="o".charCodeAt(0)&&data[6]==="r".charCodeAt(0)&&data[7]==="t".charCodeAt(0)){var newport=data[8]<<8|data[9];SOCKFS.websocket_sock_ops.removePeer(sock,peer);peer.port=newport;SOCKFS.websocket_sock_ops.addPeer(sock,peer);return}sock.recv_queue.push({addr:peer.addr,port:peer.port,data:data});Module["websocket"].emit("message",sock.stream.fd)}if(ENVIRONMENT_IS_NODE){peer.socket.on("open",handleOpen);peer.socket.on("message",(function(data,isBinary){if(!isBinary){return}handleMessage(new Uint8Array(data).buffer)}));peer.socket.on("close",(function(){Module["websocket"].emit("close",sock.stream.fd)}));peer.socket.on("error",(function(error){sock.error=14;Module["websocket"].emit("error",[sock.stream.fd,sock.error,"ECONNREFUSED: Connection refused"])}))}else{peer.socket.onopen=handleOpen;peer.socket.onclose=function(){Module["websocket"].emit("close",sock.stream.fd)};peer.socket.onmessage=function peer_socket_onmessage(event){handleMessage(event.data)};peer.socket.onerror=function(error){sock.error=14;Module["websocket"].emit("error",[sock.stream.fd,sock.error,"ECONNREFUSED: Connection refused"])}}},poll(sock){if(sock.type===1&&sock.server){return sock.pending.length?64|1:0}var mask=0;var dest=sock.type===1?SOCKFS.websocket_sock_ops.getPeer(sock,sock.daddr,sock.dport):null;if(sock.recv_queue.length||!dest||dest&&dest.socket.readyState===dest.socket.CLOSING||dest&&dest.socket.readyState===dest.socket.CLOSED){mask|=64|1}if(!dest||dest&&dest.socket.readyState===dest.socket.OPEN){mask|=4}if(dest&&dest.socket.readyState===dest.socket.CLOSING||dest&&dest.socket.readyState===dest.socket.CLOSED){mask|=16}return mask},ioctl(sock,request,arg){switch(request){case 21531:var bytes=0;if(sock.recv_queue.length){bytes=sock.recv_queue[0].data.length}HEAP32[arg>>2]=bytes;return 0;default:return 28}},close(sock){if(sock.server){try{sock.server.close()}catch(e){}sock.server=null}var peers=Object.keys(sock.peers);for(var i=0;i{HEAP32[___errno_location()>>2]=value;return value};var inetPton4=str=>{var b=str.split(".");for(var i=0;i<4;i++){var tmp=Number(b[i]);if(isNaN(tmp))return null;b[i]=tmp}return(b[0]|b[1]<<8|b[2]<<16|b[3]<<24)>>>0};var jstoi_q=str=>parseInt(str);var inetPton6=str=>{var words;var w,offset,z;var valid6regx=/^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i;var parts=[];if(!valid6regx.test(str)){return null}if(str==="::"){return[0,0,0,0,0,0,0,0]}if(str.startsWith("::")){str=str.replace("::","Z:")}else{str=str.replace("::",":Z:")}if(str.indexOf(".")>0){str=str.replace(new RegExp("[.]","g"),":");words=str.split(":");words[words.length-4]=jstoi_q(words[words.length-4])+jstoi_q(words[words.length-3])*256;words[words.length-3]=jstoi_q(words[words.length-2])+jstoi_q(words[words.length-1])*256;words=words.slice(0,words.length-2)}else{words=str.split(":")}offset=0;z=0;for(w=0;w{switch(family){case 2:addr=inetPton4(addr);zeroMemory(sa,16);if(addrlen){HEAP32[addrlen>>2]=16}HEAP16[sa>>1]=family;HEAP32[sa+4>>2]=addr;HEAP16[sa+2>>1]=_htons(port);break;case 10:addr=inetPton6(addr);zeroMemory(sa,28);if(addrlen){HEAP32[addrlen>>2]=28}HEAP32[sa>>2]=family;HEAP32[sa+8>>2]=addr[0];HEAP32[sa+12>>2]=addr[1];HEAP32[sa+16>>2]=addr[2];HEAP32[sa+20>>2]=addr[3];HEAP16[sa+2>>1]=_htons(port);break;default:return 5}return 0};var DNS={address_map:{id:1,addrs:{},names:{}},lookup_name:name=>{var res=inetPton4(name);if(res!==null){return name}res=inetPton6(name);if(res!==null){return name}var addr;if(DNS.address_map.addrs[name]){addr=DNS.address_map.addrs[name]}else{var id=DNS.address_map.id++;assert(id<65535,"exceeded max address mappings of 65535");addr="172.29."+(id&255)+"."+(id&65280);DNS.address_map.names[addr]=name;DNS.address_map.addrs[name]=addr}return addr},lookup_addr:addr=>{if(DNS.address_map.names[addr]){return DNS.address_map.names[addr]}return null}};function ___syscall_accept4(fd,addr,addrlen,flags,d1,d2){try{var sock=getSocketFromFD(fd);var newsock=sock.sock_ops.accept(sock);if(addr){var errno=writeSockaddr(addr,newsock.family,DNS.lookup_name(newsock.daddr),newsock.dport,addrlen)}return newsock.stream.fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var inetNtop4=addr=>(addr&255)+"."+(addr>>8&255)+"."+(addr>>16&255)+"."+(addr>>24&255);var inetNtop6=ints=>{var str="";var word=0;var longest=0;var lastzero=0;var zstart=0;var len=0;var i=0;var parts=[ints[0]&65535,ints[0]>>16,ints[1]&65535,ints[1]>>16,ints[2]&65535,ints[2]>>16,ints[3]&65535,ints[3]>>16];var hasipv4=true;var v4part="";for(i=0;i<5;i++){if(parts[i]!==0){hasipv4=false;break}}if(hasipv4){v4part=inetNtop4(parts[6]|parts[7]<<16);if(parts[5]===-1){str="::ffff:";str+=v4part;return str}if(parts[5]===0){str="::";if(v4part==="0.0.0.0")v4part="";if(v4part==="0.0.0.1")v4part="1";str+=v4part;return str}}for(word=0;word<8;word++){if(parts[word]===0){if(word-lastzero>1){len=0}lastzero=word;len++}if(len>longest){longest=len;zstart=word-longest+1}}for(word=0;word<8;word++){if(longest>1){if(parts[word]===0&&word>=zstart&&word{var family=HEAP16[sa>>1];var port=_ntohs(HEAPU16[sa+2>>1]);var addr;switch(family){case 2:if(salen!==16){return{errno:28}}addr=HEAP32[sa+4>>2];addr=inetNtop4(addr);break;case 10:if(salen!==28){return{errno:28}}addr=[HEAP32[sa+8>>2],HEAP32[sa+12>>2],HEAP32[sa+16>>2],HEAP32[sa+20>>2]];addr=inetNtop6(addr);break;default:return{errno:5}}return{family:family,addr:addr,port:port}};function getSocketAddress(addrp,addrlen,allowNull){if(allowNull&&addrp===0)return null;var info=readSockaddr(addrp,addrlen);if(info.errno)throw new FS.ErrnoError(info.errno);info.addr=DNS.lookup_addr(info.addr)||info.addr;return info}function ___syscall_bind(fd,addr,addrlen,d1,d2,d3){try{var sock=getSocketFromFD(fd);var info=getSocketAddress(addr,addrlen);sock.sock_ops.bind(sock,info.addr,info.port);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_chdir(path){try{path=SYSCALLS.getStr(path);FS.chdir(path);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_chmod(path,mode){try{path=SYSCALLS.getStr(path);FS.chmod(path,mode);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_connect(fd,addr,addrlen,d1,d2,d3){try{var sock=getSocketFromFD(fd);var info=getSocketAddress(addr,addrlen);sock.sock_ops.connect(sock,info.addr,info.port);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_dup(fd){try{var old=SYSCALLS.getStreamFromFD(fd);return FS.createStream(old).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_dup3(fd,newfd,flags){try{var old=SYSCALLS.getStreamFromFD(fd);if(old.fd===newfd)return-28;var existing=FS.getStream(newfd);if(existing)FS.close(existing);return FS.createStream(old,newfd).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_faccessat(dirfd,path,amode,flags){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);if(amode&~7){return-28}var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function convertI32PairToI53Checked(lo,hi){return hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN}function ___syscall_fallocate(fd,mode,offset_low,offset_high,len_low,len_high){var offset=convertI32PairToI53Checked(offset_low,offset_high);var len=convertI32PairToI53Checked(len_low,len_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.allocate(stream,offset,len);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fchmod(fd,mode){try{FS.fchmod(fd,mode);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fchown32(fd,owner,group){try{FS.fchown(fd,owner,group);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fchownat(dirfd,path,owner,group,flags){try{path=SYSCALLS.getStr(path);var nofollow=flags&256;flags=flags&~256;path=SYSCALLS.calculateAt(dirfd,path);(nofollow?FS.lchown:FS.chown)(path,owner,group);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.createStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 5:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fdatasync(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fstat64(fd,buf){try{var stream=SYSCALLS.getStreamFromFD(fd);return SYSCALLS.doStat(FS.stat,stream.path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ftruncate64(fd,length_low,length_high){var length=convertI32PairToI53Checked(length_low,length_high);try{if(isNaN(length))return 61;FS.ftruncate(fd,length);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);Module["stringToUTF8"]=stringToUTF8;function ___syscall_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd)+1;if(size>>0,(tempDouble=id,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos>>2]=tempI64[0],HEAP32[dirp+pos+4>>2]=tempI64[1];tempI64=[(idx+1)*struct_size>>>0,(tempDouble=(idx+1)*struct_size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos+8>>2]=tempI64[0],HEAP32[dirp+pos+12>>2]=tempI64[1];HEAP16[dirp+pos+16>>1]=280;HEAP8[dirp+pos+18>>0]=type;stringToUTF8(name,dirp+pos+19,256);pos+=struct_size;idx+=1}FS.llseek(stream,idx*struct_size,0);return pos}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_getpeername(fd,addr,addrlen,d1,d2,d3){try{var sock=getSocketFromFD(fd);if(!sock.daddr){return-53}var errno=writeSockaddr(addr,sock.family,DNS.lookup_name(sock.daddr),sock.dport,addrlen);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_getsockname(fd,addr,addrlen,d1,d2,d3){try{var sock=getSocketFromFD(fd);var errno=writeSockaddr(addr,sock.family,DNS.lookup_name(sock.saddr||"0.0.0.0"),sock.sport,addrlen);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_getsockopt(fd,level,optname,optval,optlen,d1){try{var sock=getSocketFromFD(fd);if(level===1){if(optname===4){HEAP32[optval>>2]=sock.error;HEAP32[optlen>>2]=4;sock.error=null;return 0}}return-50}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=SYSCALLS.get();HEAP32[argp>>2]=termios.c_iflag||0;HEAP32[argp+4>>2]=termios.c_oflag||0;HEAP32[argp+8>>2]=termios.c_cflag||0;HEAP32[argp+12>>2]=termios.c_lflag||0;for(var i=0;i<32;i++){HEAP8[argp+i+17>>0]=termios.c_cc[i]||0}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=SYSCALLS.get();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17>>0])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag:c_iflag,c_oflag:c_oflag,c_cflag:c_cflag,c_lflag:c_lflag,c_cc:c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=SYSCALLS.get();HEAP16[argp>>1]=winsize[0];HEAP16[argp+2>>1]=winsize[1]}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_listen(fd,backlog){try{var sock=getSocketFromFD(fd);sock.sock_ops.listen(sock,backlog);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_lstat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.lstat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_mkdirat(dirfd,path,mode){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_newfstatat(dirfd,path,buf,flags){try{path=SYSCALLS.getStr(path);var nofollow=flags&256;var allowEmpty=flags&4096;flags=flags&~6400;path=SYSCALLS.calculateAt(dirfd,path,allowEmpty);return SYSCALLS.doStat(nofollow?FS.lstat:FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var PIPEFS={BUCKET_BUFFER_SIZE:8192,mount(mount){return FS.createNode(null,"/",16384|511,0)},createPipe(){var pipe={buckets:[],refcnt:2};pipe.buckets.push({buffer:new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),offset:0,roffset:0});var rName=PIPEFS.nextname();var wName=PIPEFS.nextname();var rNode=FS.createNode(PIPEFS.root,rName,4096,0);var wNode=FS.createNode(PIPEFS.root,wName,4096,0);rNode.pipe=pipe;wNode.pipe=pipe;var readableStream=FS.createStream({path:rName,node:rNode,flags:0,seekable:false,stream_ops:PIPEFS.stream_ops});rNode.stream=readableStream;var writableStream=FS.createStream({path:wName,node:wNode,flags:1,seekable:false,stream_ops:PIPEFS.stream_ops});wNode.stream=writableStream;return{readable_fd:readableStream.fd,writable_fd:writableStream.fd}},stream_ops:{poll(stream){var pipe=stream.node.pipe;if((stream.flags&2097155)===1){return 256|4}if(pipe.buckets.length>0){for(var i=0;i0){return 64|1}}}return 0},ioctl(stream,request,varargs){return 28},fsync(stream){return 28},read(stream,buffer,offset,length,position){var pipe=stream.node.pipe;var currentLength=0;for(var i=0;i=dataLen){currBucket.buffer.set(data,currBucket.offset);currBucket.offset+=dataLen;return dataLen}else if(freeBytesInCurrBuffer>0){currBucket.buffer.set(data.subarray(0,freeBytesInCurrBuffer),currBucket.offset);currBucket.offset+=freeBytesInCurrBuffer;data=data.subarray(freeBytesInCurrBuffer,data.byteLength)}var numBuckets=data.byteLength/PIPEFS.BUCKET_BUFFER_SIZE|0;var remElements=data.byteLength%PIPEFS.BUCKET_BUFFER_SIZE;for(var i=0;i0){var newBucket={buffer:new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),offset:data.byteLength,roffset:0};pipe.buckets.push(newBucket);newBucket.buffer.set(data)}return dataLen},close(stream){var pipe=stream.node.pipe;pipe.refcnt--;if(pipe.refcnt===0){pipe.buckets=null}}},nextname(){if(!PIPEFS.nextname.current){PIPEFS.nextname.current=0}return"pipe["+PIPEFS.nextname.current+++"]"}};function ___syscall_pipe(fdPtr){try{if(fdPtr==0){throw new FS.ErrnoError(21)}var res=PIPEFS.createPipe();HEAP32[fdPtr>>2]=res.readable_fd;HEAP32[fdPtr+4>>2]=res.writable_fd;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_poll(fds,nfds,timeout){try{var nonzero=0;for(var i=0;i>2];var events=HEAP16[pollfd+4>>1];var mask=32;var stream=FS.getStream(fd);if(stream){mask=SYSCALLS.DEFAULT_POLLMASK;if (stream.stream_ops?.poll){mask=stream.stream_ops.poll(stream,-1)}}mask&=events|8|16;if(mask)nonzero++;HEAP16[pollfd+6>>1]=mask}return nonzero}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_readlinkat(dirfd,path,buf,bufsize){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_recvfrom(fd,buf,len,flags,addr,addrlen){try{var sock=getSocketFromFD(fd);var msg=sock.sock_ops.recvmsg(sock, len, typeof flags !== "undefined" ? flags : 0);if(!msg)return 0;if(addr){var errno=writeSockaddr(addr,sock.family,DNS.lookup_name(msg.addr),msg.port,addrlen)}HEAPU8.set(msg.buffer,buf);return msg.buffer.byteLength}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_renameat(olddirfd,oldpath,newdirfd,newpath){try{oldpath=SYSCALLS.getStr(oldpath);newpath=SYSCALLS.getStr(newpath);oldpath=SYSCALLS.calculateAt(olddirfd,oldpath);newpath=SYSCALLS.calculateAt(newdirfd,newpath);FS.rename(oldpath,newpath);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_rmdir(path){try{path=SYSCALLS.getStr(path);FS.rmdir(path);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_sendto(fd,message,length,flags,addr,addr_len){try{var sock=getSocketFromFD(fd);var dest=getSocketAddress(addr,addr_len,true);if(!dest){return FS.write(sock.stream,HEAP8,message,length)}return sock.sock_ops.sendmsg(sock,HEAP8,message,length,dest.addr,dest.port)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_socket(domain,type,protocol){try{var sock=SOCKFS.createSocket(domain,type,protocol);return sock.stream.fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_statfs64(path,size,buf){try{path=SYSCALLS.getStr(path);HEAP32[buf+4>>2]=4096;HEAP32[buf+40>>2]=4096;HEAP32[buf+8>>2]=1e6;HEAP32[buf+12>>2]=5e5;HEAP32[buf+16>>2]=5e5;HEAP32[buf+20>>2]=FS.nextInode;HEAP32[buf+24>>2]=1e6;HEAP32[buf+28>>2]=42;HEAP32[buf+44>>2]=2;HEAP32[buf+36>>2]=255;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_symlink(target,linkpath){try{target=SYSCALLS.getStr(target);linkpath=SYSCALLS.getStr(linkpath);FS.symlink(target,linkpath);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_unlinkat(dirfd,path,flags){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);if(flags===0){FS.unlink(path)}else if(flags===512){FS.rmdir(path)}else{abort("Invalid flags passed to unlinkat")}return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function readI53FromI64(ptr){return HEAPU32[ptr>>2]+HEAP32[ptr+4>>2]*4294967296}function ___syscall_utimensat(dirfd,path,times,flags){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path,true);if(!times){var atime=Date.now();var mtime=atime}else{var seconds=readI53FromI64(times);var nanoseconds=HEAP32[times+8>>2];atime=seconds*1e3+nanoseconds/(1e3*1e3);times+=16;seconds=readI53FromI64(times);nanoseconds=HEAP32[times+8>>2];mtime=seconds*1e3+nanoseconds/(1e3*1e3)}FS.utime(path,atime,mtime);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var nowIsMonotonic=true;var __emscripten_get_now_is_monotonic=()=>nowIsMonotonic;var __emscripten_throw_longjmp=()=>{throw Infinity};function __gmtime_js(time_low,time_high,tmPtr){var time=convertI32PairToI53Checked(time_low,time_high);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getUTCSeconds();HEAP32[tmPtr+4>>2]=date.getUTCMinutes();HEAP32[tmPtr+8>>2]=date.getUTCHours();HEAP32[tmPtr+12>>2]=date.getUTCDate();HEAP32[tmPtr+16>>2]=date.getUTCMonth();HEAP32[tmPtr+20>>2]=date.getUTCFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getUTCDay();var start=Date.UTC(date.getUTCFullYear(),0,1,0,0,0,0);var yday=(date.getTime()-start)/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday}var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var MONTH_DAYS_LEAP_CUMULATIVE=[0,31,60,91,121,152,182,213,244,274,305,335];var MONTH_DAYS_REGULAR_CUMULATIVE=[0,31,59,90,120,151,181,212,243,273,304,334];var ydayFromDate=date=>{var leap=isLeapYear(date.getFullYear());var monthDaysCumulative=leap?MONTH_DAYS_LEAP_CUMULATIVE:MONTH_DAYS_REGULAR_CUMULATIVE;var yday=monthDaysCumulative[date.getMonth()]+date.getDate()-1;return yday};function __localtime_js(time_low,time_high,tmPtr){var time=convertI32PairToI53Checked(time_low,time_high);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}var __mktime_js=function(tmPtr){var ret=(()=>{var date=new Date(HEAP32[tmPtr+20>>2]+1900,HEAP32[tmPtr+16>>2],HEAP32[tmPtr+12>>2],HEAP32[tmPtr+8>>2],HEAP32[tmPtr+4>>2],HEAP32[tmPtr>>2],0);var dst=HEAP32[tmPtr+32>>2];var guessedOffset=date.getTimezoneOffset();var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dstOffset=Math.min(winterOffset,summerOffset);if(dst<0){HEAP32[tmPtr+32>>2]=Number(summerOffset!=winterOffset&&dstOffset==guessedOffset)}else if(dst>0!=(dstOffset==guessedOffset)){var nonDstOffset=Math.max(winterOffset,summerOffset);var trueOffset=dst>0?dstOffset:nonDstOffset;date.setTime(date.getTime()+(trueOffset-guessedOffset)*6e4)}HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getYear();return date.getTime()/1e3})();return setTempRet0((tempDouble=ret,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)),ret>>>0};function __mmap_js(len,prot,flags,fd,offset_low,offset_high,allocated,addr){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);var res=FS.mmap(stream,len,offset,prot,flags);var ptr=res.ptr;HEAP32[allocated>>2]=res.allocated;HEAPU32[addr>>2]=ptr;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function __munmap_js(addr,len,prot,flags,fd,offset_low,offset_high){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);if(prot&2){SYSCALLS.doMsync(addr,stream,len,flags,offset)}FS.munmap(stream)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var timers={};var handleException=e=>{if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e)};var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){if(Module["onExit"])Module["onExit"](code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;if(!keepRuntimeAlive()){exitRuntime()}_proc_exit(status)};var _exit=exitJS;Module["_exit"]=_exit;var maybeExit=()=>{if(runtimeExited){return}if(!keepRuntimeAlive()){try{_exit(EXITSTATUS)}catch(e){handleException(e)}}};var callUserCallback=func=>{if(runtimeExited||ABORT){return}try{func();maybeExit()}catch(e){handleException(e)}};var _emscripten_get_now;_emscripten_get_now=()=>performance.now();var __setitimer_js=(which,timeout_ms)=>{if(timers[which]){clearTimeout(timers[which].id);delete timers[which]}if(!timeout_ms)return 0;var id=setTimeout((()=>{delete timers[which];callUserCallback((()=>__emscripten_timeout(which,_emscripten_get_now())))}),timeout_ms);timers[which]={id:id,timeout_ms:timeout_ms};return 0};var stringToNewUTF8=str=>{var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8(str,ret,size);return ret};var __tzset_js=(timezone,daylight,tzname)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);function extractZone(date){var match=date.toTimeString().match(/\(([A-Za-z ]+)\)$/);return match?match[1]:"GMT"}var winterName=extractZone(winter);var summerName=extractZone(summer);var winterNamePtr=stringToNewUTF8(winterName);var summerNamePtr=stringToNewUTF8(summerName);if(summerOffset>2]=winterNamePtr;HEAPU32[tzname+4>>2]=summerNamePtr}else{HEAPU32[tzname>>2]=summerNamePtr;HEAPU32[tzname+4>>2]=winterNamePtr}};var _abort=()=>{abort("")};function _emscripten_date_now(){return Date.now()}var getHeapMax=()=>2147483648;var _emscripten_get_heap_max=()=>getHeapMax();var _emscripten_memcpy_big=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var growMemory=size=>{var b=wasmMemory.buffer;var pages=size-b.byteLength+65535>>>16;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var runtimeKeepalivePush=()=>{runtimeKeepaliveCounter+=1};var runtimeKeepalivePop=()=>{runtimeKeepaliveCounter-=1};var safeSetTimeout=(func,timeout)=>{runtimeKeepalivePush();return setTimeout((()=>{runtimeKeepalivePop();callUserCallback(func)}),timeout)};var _emscripten_sleep=function(ms){return Asyncify.handleSleep((wakeUp=>safeSetTimeout(wakeUp,ms)))};Module["_emscripten_sleep"]=_emscripten_sleep;_emscripten_sleep.isAsync=true;var ENV = PHPLoader.ENV || {};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i>0]=str.charCodeAt(i)}HEAP8[buffer>>0]=0};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;getEnvStrings().forEach((function(string,i){var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;stringToAscii(string,ptr);bufSize+=string.length+1}));return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach((function(string){bufSize+=string.length+1}));HEAPU32[penviron_buf_size>>2]=bufSize;return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function _fd_fdstat_get(fd,pbuf){try{var rightsBase=0;var rightsInheriting=0;var flags=0;{var stream=SYSCALLS.getStreamFromFD(fd);var type=stream.tty?2:FS.isDir(stream.mode)?3:FS.isLink(stream.mode)?7:4}HEAP8[pbuf>>0]=type;HEAP16[pbuf+2>>1]=flags;tempI64=[rightsBase>>>0,(tempDouble=rightsBase,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[pbuf+8>>2]=tempI64[0],HEAP32[pbuf+12>>2]=tempI64[1];tempI64=[rightsInheriting>>>0,(tempDouble=rightsInheriting,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[pbuf+16>>2]=tempI64[0],HEAP32[pbuf+20>>2]=tempI64[1];return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(typeof offset!=="undefined"){offset+=curr}}return ret};function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var _getaddrinfo=(node,service,hint,out)=>{var addr=0;var port=0;var flags=0;var family=0;var type=0;var proto=0;var ai;function allocaddrinfo(family,type,proto,canon,addr,port){var sa,salen,ai;var errno;salen=family===10?28:16;addr=family===10?inetNtop6(addr):inetNtop4(addr);sa=_malloc(salen);errno=writeSockaddr(sa,family,addr,port);assert(!errno);ai=_malloc(32);HEAP32[ai+4>>2]=family;HEAP32[ai+8>>2]=type;HEAP32[ai+12>>2]=proto;HEAPU32[ai+24>>2]=canon;HEAPU32[ai+20>>2]=sa;if(family===10){HEAP32[ai+16>>2]=28}else{HEAP32[ai+16>>2]=16}HEAP32[ai+28>>2]=0;return ai}if(hint){flags=HEAP32[hint>>2];family=HEAP32[hint+4>>2];type=HEAP32[hint+8>>2];proto=HEAP32[hint+12>>2]}if(type&&!proto){proto=type===2?17:6}if(!type&&proto){type=proto===17?2:1}if(proto===0){proto=6}if(type===0){type=1}if(!node&&!service){return-2}if(flags&~(1|2|4|1024|8|16|32)){return-1}if(hint!==0&&HEAP32[hint>>2]&2&&!node){return-1}if(flags&32){return-2}if(type!==0&&type!==1&&type!==2){return-7}if(family!==0&&family!==2&&family!==10){return-6}if(service){service=UTF8ToString(service);port=parseInt(service,10);if(isNaN(port)){if(flags&1024){return-2}return-8}}if(!node){if(family===0){family=2}if((flags&1)===0){if(family===2){addr=_htonl(2130706433)}else{addr=[0,0,0,1]}}ai=allocaddrinfo(family,type,proto,null,addr,port);HEAPU32[out>>2]=ai;return 0}node=UTF8ToString(node);addr=inetPton4(node);if(addr!==null){if(family===0||family===2){family=2}else if(family===10&&flags&8){addr=[0,0,_htonl(65535),addr];family=10}else{return-2}}else{addr=inetPton6(node);if(addr!==null){if(family===0||family===10){family=10}else{return-2}}}if(addr!=null){ai=allocaddrinfo(family,type,proto,node,addr,port);HEAPU32[out>>2]=ai;return 0}if(flags&4){return-2}node=DNS.lookup_name(node);addr=inetPton4(node);if(family===0){family=2}else if(family===10){addr=[0,0,_htonl(65535),addr]}ai=allocaddrinfo(family,type,proto,null,addr,port);HEAPU32[out>>2]=ai;return 0};var getHostByName=name=>{var ret=_malloc(20);var nameBuf=stringToNewUTF8(name);HEAPU32[ret>>2]=nameBuf;var aliasesBuf=_malloc(4);HEAPU32[aliasesBuf>>2]=0;HEAPU32[ret+4>>2]=aliasesBuf;var afinet=2;HEAP32[ret+8>>2]=afinet;HEAP32[ret+12>>2]=4;var addrListBuf=_malloc(12);HEAPU32[addrListBuf>>2]=addrListBuf+8;HEAPU32[addrListBuf+4>>2]=0;HEAP32[addrListBuf+8>>2]=inetPton4(DNS.lookup_name(name));HEAPU32[ret+16>>2]=addrListBuf;return ret};var _gethostbyaddr=(addr,addrlen,type)=>{if(type!==2){setErrNo(5);return null}addr=HEAP32[addr>>2];var host=inetNtop4(addr);var lookup=DNS.lookup_addr(host);if(lookup){host=lookup}return getHostByName(host)};var _gethostbyname=name=>getHostByName(UTF8ToString(name));var _gethostbyname_r=(name,ret,buf,buflen,out,err)=>{var data=_gethostbyname(name);_memcpy(ret,data,20);_free(data);HEAP32[err>>2]=0;HEAPU32[out>>2]=ret;return 0};var _getloadavg=(loadavg,nelem)=>{var limit=Math.min(nelem,3);var doubleSize=8;for(var i=0;i>3]=.1}return limit};var _getnameinfo=(sa,salen,node,nodelen,serv,servlen,flags)=>{var info=readSockaddr(sa,salen);if(info.errno){return-6}var port=info.port;var addr=info.addr;var overflowed=false;if(node&&nodelen){var lookup;if(flags&1||!(lookup=DNS.lookup_addr(addr))){if(flags&8){return-2}}else{addr=lookup}var numBytesWrittenExclNull=stringToUTF8(addr,node,nodelen);if(numBytesWrittenExclNull+1>=nodelen){overflowed=true}}if(serv&&servlen){port=""+port;var numBytesWrittenExclNull=stringToUTF8(port,serv,servlen);if(numBytesWrittenExclNull+1>=servlen){overflowed=true}}if(overflowed){return-12}return 0};var Protocols={list:[],map:{}};var _setprotoent=stayopen=>{function allocprotoent(name,proto,aliases){var nameBuf=_malloc(name.length+1);stringToAscii(name,nameBuf);var j=0;var length=aliases.length;var aliasListBuf=_malloc((length+1)*4);for(var i=0;i>2]=aliasBuf}HEAPU32[aliasListBuf+j>>2]=0;var pe=_malloc(12);HEAPU32[pe>>2]=nameBuf;HEAPU32[pe+4>>2]=aliasListBuf;HEAP32[pe+8>>2]=proto;return pe}var list=Protocols.list;var map=Protocols.map;if(list.length===0){var entry=allocprotoent("tcp",6,["TCP"]);list.push(entry);map["tcp"]=map["6"]=entry;entry=allocprotoent("udp",17,["UDP"]);list.push(entry);map["udp"]=map["17"]=entry}_setprotoent.index=0};var _getprotobyname=name=>{name=UTF8ToString(name);_setprotoent(true);var result=Protocols.map[name];return result};var _getprotobynumber=number=>{_setprotoent(true);var result=Protocols.map[number];return result};var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var allocateUTF8OnStack=stringToUTF8OnStack;var PHPWASM={init:function(){FS.mkdir("/internal");PHPWASM.EventEmitter=ENVIRONMENT_IS_NODE?require("events").EventEmitter:class EventEmitter{constructor(){this.listeners={}}emit(eventName,data){if(this.listeners[eventName]){this.listeners[eventName].forEach((callback=>{callback(data)}))}}once(eventName,callback){const self=this;function removedCallback(){callback(...arguments);self.removeListener(eventName,removedCallback)}this.on(eventName,removedCallback)}removeAllListeners(eventName){if(eventName){delete this.listeners[eventName]}else{this.listeners={}}}removeListener(eventName,callback){if(this.listeners[eventName]){const idx=this.listeners[eventName].indexOf(callback);if(idx!==-1){this.listeners[eventName].splice(idx,1)}}}};PHPWASM.child_proc_by_fd={};PHPWASM.child_proc_by_pid={};PHPWASM.input_devices={}},getAllWebSockets:function(sock){const webSockets=new Set;if(sock.server){sock.server.clients.forEach((ws=>{webSockets.add(ws)}))}for(const peer of PHPWASM.getAllPeers(sock)){webSockets.add(peer.socket)}return Array.from(webSockets)},getAllPeers:function(sock){const peers=new Set;if(sock.server){sock.pending.filter((pending=>pending.peers)).forEach((pending=>{for(const peer of Object.values(pending.peers)){peers.add(peer)}}))}if(sock.peers){for(const peer of Object.values(sock.peers)){peers.add(peer)}}return Array.from(peers)},awaitData:function(ws){return PHPWASM.awaitEvent(ws,"message")},awaitConnection:function(ws){if(ws.OPEN===ws.readyState){return[Promise.resolve(),PHPWASM.noop]}return PHPWASM.awaitEvent(ws,"open")},awaitClose:function(ws){if([ws.CLOSING,ws.CLOSED].includes(ws.readyState)){return[Promise.resolve(),PHPWASM.noop]}return PHPWASM.awaitEvent(ws,"close")},awaitError:function(ws){if([ws.CLOSING,ws.CLOSED].includes(ws.readyState)){return[Promise.resolve(),PHPWASM.noop]}return PHPWASM.awaitEvent(ws,"error")},awaitEvent:function(ws,event){let resolve;const listener=()=>{resolve()};const promise=new Promise((function(_resolve){resolve=_resolve;ws.once(event,listener)}));const cancel=()=>{ws.removeListener(event,listener);setTimeout(resolve)};return[promise,cancel]},noop:function(){},spawnProcess:function(command,args,options){if(Module["spawnProcess"]){const spawnedPromise=Module["spawnProcess"](command,args,options);return Promise.resolve(spawnedPromise).then((function(spawned){if(!spawned||!spawned.on){throw new Error("spawnProcess() must return an EventEmitter but returned a different type.")}return spawned}))}if(ENVIRONMENT_IS_NODE){return require("child_process").spawn(command,args,{...options,shell:true,stdio:["pipe","pipe","pipe"],timeout:100})}const e=new Error("popen(), proc_open() etc. are unsupported in the browser. Call php.setSpawnHandler() "+"and provide a callback to handle spawning processes, or disable a popen(), proc_open() "+"and similar functions via php.ini.");e.code="SPAWN_UNSUPPORTED";throw e},shutdownSocket:function(socketd,how){const sock=getSocketFromFD(socketd);const peer=Object.values(sock.peers)[0];if(!peer){return-1}try{peer.socket.close();SOCKFS.websocket_sock_ops.removePeer(sock,peer);return 0}catch(e){console.log("Socket shutdown error",e);return-1}}};function _js_create_input_device(deviceId){let dataBuffer=[];let dataCallback;const filename="proc_id_"+deviceId;const device=FS.createDevice("/dev",filename,(function(){}),(function(byte){try{dataBuffer.push(byte);if(dataCallback){dataCallback(new Uint8Array(dataBuffer));dataBuffer=[]}}catch(e){console.error(e);throw e}}));const devicePath="/dev/"+filename;PHPWASM.input_devices[deviceId]={devicePath:devicePath,onData:function(cb){dataCallback=cb;dataBuffer.forEach((function(data){cb(data)}));dataBuffer.length=0}};return allocateUTF8OnStack(devicePath)}function _js_fd_read(fd,iov,iovcnt,pnum){if(Asyncify.state===Asyncify.State.Normal){var returnCode;var stream;let num=0;try{stream=SYSCALLS.getStreamFromFD(fd);const num=doReadv(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError")){throw e}if(e.errno!==6||!(stream?.fd in PHPWASM.child_proc_by_fd)){HEAPU32[pnum>>2]=0;return returnCode}}}return Asyncify.handleSleep((function(wakeUp){var retries=0;var interval=50;var timeout=5e3;var maxRetries=timeout/interval;function poll(){var returnCode;var stream;let num;try{stream=SYSCALLS.getStreamFromFD(fd);num=doReadv(stream,iov,iovcnt);returnCode=0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError")){console.error(e);throw e}returnCode=e.errno}const success=returnCode===0;const failure=++retries>maxRetries||!(fd in PHPWASM.child_proc_by_fd)||PHPWASM.child_proc_by_fd[fd]?.exited||FS.isClosed(stream);if(success){HEAPU32[pnum>>2]=num;wakeUp(0)}else if(failure){HEAPU32[pnum>>2]=0;wakeUp(returnCode===6?0:returnCode)}else{setTimeout(poll,interval)}}poll()}))}function _js_module_onMessage(data,bufPtr){if(typeof Asyncify==="undefined"){return}if(Module["onMessage"]){const dataStr=UTF8ToString(data);return Asyncify.handleSleep((wakeUp=>{Module["onMessage"](dataStr).then((response=>{const responseBytes=typeof response==="string"?(new TextEncoder).encode(response):response;const responseSize=responseBytes.byteLength;const responsePtr=_malloc(responseSize+1);HEAPU8.set(responseBytes,responsePtr);HEAPU8[responsePtr+responseSize]=0;HEAPU8[bufPtr]=responsePtr;HEAPU8[bufPtr+1]=responsePtr>>8;HEAPU8[bufPtr+2]=responsePtr>>16;HEAPU8[bufPtr+3]=responsePtr>>24;wakeUp(responseSize)})).catch((e=>{console.error(e);wakeUp(0)}))}))}}function _js_open_process(command,argsPtr,argsLength,descriptorsPtr,descriptorsLength,cwdPtr,cwdLength,envPtr,envLength){if(!command){return 1}const cmdstr=UTF8ToString(command);if(!cmdstr.length){return 0}let argsArray=[];if(argsLength){for(var i=0;i>2]))}}const cwdstr=cwdPtr?UTF8ToString(cwdPtr):null;let envObject=null;if(envLength){envObject={};for(var i=0;i>2]);const splitAt=envEntry.indexOf("=");if(splitAt===-1){continue}const key=envEntry.substring(0,splitAt);const value=envEntry.substring(splitAt+1);envObject[key]=value}}var std={};for(var i=0;i>2];std[HEAPU32[descriptorPtr>>2]]={child:HEAPU32[descriptorPtr+4>>2],parent:HEAPU32[descriptorPtr+8>>2]}}return Asyncify.handleSleep((async wakeUp=>{let cp;try{const options={};if(cwdstr!==null){options.cwd=cwdstr}if(envObject!==null){options.env=envObject}cp=PHPWASM.spawnProcess(cmdstr,argsArray,options);if(cp instanceof Promise){cp=await cp}}catch(e){if(e.code==="SPAWN_UNSUPPORTED"){wakeUp(1);return}console.error(e);wakeUp(1);throw e}const ProcInfo={pid:cp.pid,exited:false,stdinFd:std[0]?.child,stdinIsDevice:std[0]?.child in PHPWASM.input_devices,stdoutChildFd:std[1]?.child,stdoutParentFd:std[1]?.parent,stderrChildFd:std[2]?.child,stderrParentFd:std[2]?.parent,stdout:new PHPWASM.EventEmitter,stderr:new PHPWASM.EventEmitter};if(ProcInfo.stdoutChildFd)PHPWASM.child_proc_by_fd[ProcInfo.stdoutChildFd]=ProcInfo;if(ProcInfo.stderrChildFd)PHPWASM.child_proc_by_fd[ProcInfo.stderrChildFd]=ProcInfo;if(ProcInfo.stdoutParentFd)PHPWASM.child_proc_by_fd[ProcInfo.stdoutParentFd]=ProcInfo;if(ProcInfo.stderrParentFd)PHPWASM.child_proc_by_fd[ProcInfo.stderrParentFd]=ProcInfo;PHPWASM.child_proc_by_pid[ProcInfo.pid]=ProcInfo;cp.on("exit",(function(code){ProcInfo.exitCode=code;ProcInfo.exited=true;ProcInfo.stdout.emit("data");ProcInfo.stderr.emit("data")}));if(ProcInfo.stdoutChildFd){const stdoutStream=SYSCALLS.getStreamFromFD(ProcInfo.stdoutChildFd);let stdoutAt=0;cp.stdout.on("data",(function(data){ProcInfo.stdout.emit("data",data);stdoutStream.stream_ops.write(stdoutStream,data,0,data.length,stdoutAt);stdoutAt+=data.length}))}if(ProcInfo.stderrChildFd){const stderrStream=SYSCALLS.getStreamFromFD(ProcInfo.stderrChildFd);let stderrAt=0;cp.stderr.on("data",(function(data){ProcInfo.stderr.emit("data",data);stderrStream.stream_ops.write(stderrStream,data,0,data.length,stderrAt);stderrAt+=data.length}))}try{await new Promise(((resolve,reject)=>{cp.on("spawn",resolve);cp.on("error",reject)}))}catch(e){console.error(e);wakeUp(1);return}if(ProcInfo.stdinIsDevice){PHPWASM.input_devices[ProcInfo.stdinFd].onData((function(data){if(!data)return;const dataStr=new TextDecoder("utf-8").decode(data);cp.stdin.write(dataStr)}));wakeUp(ProcInfo.pid);return}if(ProcInfo.stdinFd){const stdinStream=SYSCALLS.getStreamFromFD(ProcInfo.stdinFd);if(stdinStream.node){const CHUNK_SIZE=1024;const buffer=new Uint8Array(CHUNK_SIZE);let offset=0;while(true){const bytesRead=stdinStream.stream_ops.read(stdinStream,buffer,0,CHUNK_SIZE,offset);if(bytesRead===null||bytesRead===0){break}try{cp.stdin.write(buffer.subarray(0,bytesRead))}catch(e){console.error(e);return 1}if(bytesRead{let cp;try{cp=PHPWASM.spawnProcess(cmdstr,[]);if(cp instanceof Promise){cp=await cp}}catch(e){console.error(e);if(e.code==="SPAWN_UNSUPPORTED"){return 1}throw e}const outByteArrays=[];cp.stdout.on("data",(function(data){outByteArrays.push(data)}));const outputPath="/tmp/popen_output";cp.on("exit",(function(exitCode){const outBytes=new Uint8Array(outByteArrays.reduce(((acc,curr)=>acc+curr.length),0));let offset=0;for(const byteArray of outByteArrays){outBytes.set(byteArray,offset);offset+=byteArray.length}FS.writeFile(outputPath,outBytes);HEAPU8[exitCodePtr]=exitCode;wakeUp(allocateUTF8OnStack(outputPath))}))}))}function _js_process_status(pid,exitCodePtr){if(!PHPWASM.child_proc_by_pid[pid]){return-1}if(PHPWASM.child_proc_by_pid[pid].exited){HEAPU32[exitCodePtr>>2]=PHPWASM.child_proc_by_pid[pid].exitCode;return 1}return 0}function _js_waitpid(pid,exitCodePtr){if(!PHPWASM.child_proc_by_pid[pid]){return-1}return Asyncify.handleSleep((wakeUp=>{const poll=function(){if(PHPWASM.child_proc_by_pid[pid]?.exited){HEAPU32[exitCodePtr>>2]=PHPWASM.child_proc_by_pid[pid].exitCode;wakeUp(pid)}else{setTimeout(poll,50)}};poll()}))}var arraySum=(array,index)=>{var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum};var MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];var addDays=(date,days)=>{var newDate=new Date(date.getTime());while(days>0){var leap=isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var _strftime=(s,maxsize,format,tm)=>{var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}return thisDate.getFullYear()}return thisDate.getFullYear()-1}var EXPANSION_RULES_2={"%a":date=>WEEKDAYS[date.tm_wday].substring(0,3),"%A":date=>WEEKDAYS[date.tm_wday],"%b":date=>MONTHS[date.tm_mon].substring(0,3),"%B":date=>MONTHS[date.tm_mon],"%C":date=>{var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":date=>leadingNulls(date.tm_mday,2),"%e":date=>leadingSomething(date.tm_mday,2," "),"%g":date=>getWeekBasedYear(date).toString().substring(2),"%G":date=>getWeekBasedYear(date),"%H":date=>leadingNulls(date.tm_hour,2),"%I":date=>{var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":date=>leadingNulls(date.tm_mday+arraySum(isLeapYear(date.tm_year+1900)?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,date.tm_mon-1),3),"%m":date=>leadingNulls(date.tm_mon+1,2),"%M":date=>leadingNulls(date.tm_min,2),"%n":()=>"\n","%p":date=>{if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}return"PM"},"%S":date=>leadingNulls(date.tm_sec,2),"%t":()=>"\t","%u":date=>date.tm_wday||7,"%U":date=>{var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":date=>{var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":date=>date.tm_wday,"%W":date=>{var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":date=>(date.tm_year+1900).toString().substring(2),"%Y":date=>date.tm_year+1900,"%z":date=>{var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":date=>date.tm_zone,"%%":()=>"%"};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1};var _strptime=(buf,format,tm)=>{var pattern=UTF8ToString(format);var SPECIAL_CHARS="\\!@#$^&*()+=-[]/{}|:<>?,.";for(var i=0,ii=SPECIAL_CHARS.length;i=0;i=pattern.indexOf("%")){capture.push(pattern[i+1]);pattern=pattern.replace(new RegExp("\\%"+pattern[i+1],"g"),"")}var matches=new RegExp("^"+pattern,"i").exec(UTF8ToString(buf));function initDate(){function fixup(value,min,max){return typeof value!="number"||isNaN(value)?min:value>=min?value<=max?value:max:min}return{year:fixup(HEAP32[tm+20>>2]+1900,1970,9999),month:fixup(HEAP32[tm+16>>2],0,11),day:fixup(HEAP32[tm+12>>2],1,31),hour:fixup(HEAP32[tm+8>>2],0,23),min:fixup(HEAP32[tm+4>>2],0,59),sec:fixup(HEAP32[tm>>2],0,59)}}if(matches){var date=initDate();var value;var getMatch=symbol=>{var pos=capture.indexOf(symbol);if(pos>=0){return matches[pos+1]}return};if(value=getMatch("S")){date.sec=jstoi_q(value)}if(value=getMatch("M")){date.min=jstoi_q(value)}if(value=getMatch("H")){date.hour=jstoi_q(value)}else if(value=getMatch("I")){var hour=jstoi_q(value);if(value=getMatch("p")){hour+=value.toUpperCase()[0]==="P"?12:0}date.hour=hour}if(value=getMatch("Y")){date.year=jstoi_q(value)}else if(value=getMatch("y")){var year=jstoi_q(value);if(value=getMatch("C")){year+=jstoi_q(value)*100}else{year+=year<69?2e3:1900}date.year=year}if(value=getMatch("m")){date.month=jstoi_q(value)-1}else if(value=getMatch("b")){date.month=MONTH_NUMBERS[value.substring(0,3).toUpperCase()]||0}if(value=getMatch("d")){date.day=jstoi_q(value)}else if(value=getMatch("j")){var day=jstoi_q(value);var leapYear=isLeapYear(date.year);for(var month=0;month<12;++month){var daysUntilMonth=arraySum(leapYear?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,month-1);if(day<=daysUntilMonth+(leapYear?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[month]){date.day=day-daysUntilMonth}}}else if(value=getMatch("a")){var weekDay=value.substring(0,3).toUpperCase();if(value=getMatch("U")){var weekDayNumber=DAY_NUMBERS_SUN_FIRST[weekDay];var weekNumber=jstoi_q(value);var janFirst=new Date(date.year,0,1);var endDate;if(janFirst.getDay()===0){endDate=addDays(janFirst,weekDayNumber+7*(weekNumber-1))}else{endDate=addDays(janFirst,7-janFirst.getDay()+weekDayNumber+7*(weekNumber-1))}date.day=endDate.getDate();date.month=endDate.getMonth()}else if(value=getMatch("W")){var weekDayNumber=DAY_NUMBERS_MON_FIRST[weekDay];var weekNumber=jstoi_q(value);var janFirst=new Date(date.year,0,1);var endDate;if(janFirst.getDay()===1){endDate=addDays(janFirst,weekDayNumber+7*(weekNumber-1))}else{endDate=addDays(janFirst,7-janFirst.getDay()+1+weekDayNumber+7*(weekNumber-1))}date.day=endDate.getDate();date.month=endDate.getMonth()}}var fullDate=new Date(date.year,date.month,date.day,date.hour,date.min,date.sec,0);HEAP32[tm>>2]=fullDate.getSeconds();HEAP32[tm+4>>2]=fullDate.getMinutes();HEAP32[tm+8>>2]=fullDate.getHours();HEAP32[tm+12>>2]=fullDate.getDate();HEAP32[tm+16>>2]=fullDate.getMonth();HEAP32[tm+20>>2]=fullDate.getFullYear()-1900;HEAP32[tm+24>>2]=fullDate.getDay();HEAP32[tm+28>>2]=arraySum(isLeapYear(fullDate.getFullYear())?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,fullDate.getMonth()-1)+fullDate.getDate()-1;HEAP32[tm+32>>2]=0;return buf+intArrayFromString(matches[0]).length-1}return 0};function _wasm_poll_socket(socketd,events,timeout){if(typeof Asyncify==="undefined"){return 0}const POLLIN=1;const POLLPRI=2;const POLLOUT=4;const POLLERR=8;const POLLHUP=16;const POLLNVAL=32;return Asyncify.handleSleep((wakeUp=>{const polls=[];if(socketd in PHPWASM.child_proc_by_fd){const procInfo=PHPWASM.child_proc_by_fd[socketd];if(procInfo.exited){wakeUp(0);return}polls.push(PHPWASM.awaitEvent(procInfo.stdout,"data"))}else{const sock=getSocketFromFD(socketd);if(!sock){wakeUp(0);return}const lookingFor=new Set;if(events&POLLIN||events&POLLPRI){if(sock.server){for(const client of sock.pending){if((client.recv_queue||[]).length>0){wakeUp(1);return}}}else if((sock.recv_queue||[]).length>0){wakeUp(1);return}}const webSockets=PHPWASM.getAllWebSockets(sock);if(!webSockets.length){wakeUp(0);return}for(const ws of webSockets){if(events&POLLIN||events&POLLPRI){polls.push(PHPWASM.awaitData(ws));lookingFor.add("POLLIN")}if(events&POLLOUT){polls.push(PHPWASM.awaitConnection(ws));lookingFor.add("POLLOUT")}if(events&POLLHUP){polls.push(PHPWASM.awaitClose(ws));lookingFor.add("POLLHUP")}if(events&POLLERR||events&POLLNVAL){polls.push(PHPWASM.awaitError(ws));lookingFor.add("POLLERR")}}}if(polls.length===0){console.warn("Unsupported poll event "+events+", defaulting to setTimeout().");setTimeout((function(){wakeUp(0)}),timeout);return}const promises=polls.map((([promise])=>promise));const clearPolling=()=>polls.forEach((([,clear])=>clear()));let awaken=false;let timeoutId;Promise.race(promises).then((function(results){if(!awaken){awaken=true;wakeUp(1);if(timeoutId){clearTimeout(timeoutId)}clearPolling()}}));if(timeout!==-1){timeoutId=setTimeout((function(){if(!awaken){awaken=true;wakeUp(0);clearPolling()}}),timeout)}}))}function _wasm_setsockopt(socketd,level,optionName,optionValuePtr,optionLen){const optionValue=HEAPU8[optionValuePtr];const SOL_SOCKET=1;const SO_KEEPALIVE=9;const IPPROTO_TCP=6;const TCP_NODELAY=1;const isSupported=level===SOL_SOCKET&&optionName===SO_KEEPALIVE||level===IPPROTO_TCP&&optionName===TCP_NODELAY;if(!isSupported){console.warn(`Unsupported socket option: ${level}, ${optionName}, ${optionValue}`);return-1}const ws=PHPWASM.getAllWebSockets(socketd)[0];if(!ws){return-1}ws.setSocketOpt(level,optionName,optionValuePtr);return 0}function runAndAbortIfError(func){try{return func()}catch(e){abort(e)}}var Asyncify={instrumentWasmImports:function(imports){var importPatterns=[/^_dlopen_js$/,/^invoke_i$/,/^invoke_ii$/,/^invoke_iii$/,/^invoke_iiii$/,/^invoke_iiiii$/,/^invoke_iiiiii$/,/^invoke_iiiiiii$/,/^invoke_iiiiiiii$/,/^invoke_iiiiiiiiii$/,/^invoke_v$/,/^invoke_vi$/,/^invoke_vii$/,/^invoke_viidii$/,/^invoke_viii$/,/^invoke_viiii$/,/^invoke_viiiii$/,/^invoke_viiiiii$/,/^invoke_viiiiiii$/,/^invoke_viiiiiiiii$/,/^js_open_process$/,/^js_popen_to_file$/,/^js_fd_read$/,/^js_module_onMessage$/,/^js_waitpid$/,/^wasm_poll_socket$/,/^wasm_shutdown$/,/^fd_sync$/,/^__wasi_fd_sync$/,/^__asyncjs__.*$/,/^emscripten_promise_await$/,/^emscripten_idb_load$/,/^emscripten_idb_store$/,/^emscripten_idb_delete$/,/^emscripten_idb_exists$/,/^emscripten_idb_load_blob$/,/^emscripten_idb_store_blob$/,/^emscripten_sleep$/,/^emscripten_wget_data$/,/^emscripten_scan_registers$/,/^emscripten_lazy_load_code$/,/^_load_secondary_module$/,/^emscripten_fiber_swap$/,/^SDL_Delay$/];for(var x in imports){(function(x){var original=imports[x];var sig=original.sig;if(typeof original=="function"){var isAsyncifyImport=original.isAsync||importPatterns.some((pattern=>!!x.match(pattern)))}})(x)}},instrumentWasmExports:function(exports){var ret={};for(var x in exports){(function(x){var original=exports[x];if(typeof original=="function"){ret[x]=function(){Asyncify.exportCallStack.push(x);try{return original.apply(null,arguments)}finally{if(!ABORT){var y=Asyncify.exportCallStack.pop();assert(y===x);Asyncify.maybeStopUnwind()}}}}else{ret[x]=original}})(x)}return ret},State:{Normal:0,Unwinding:1,Rewinding:2,Disabled:3},state:0,StackSize:4096,currData:null,handleSleepReturnValue:0,exportCallStack:[],callStackNameToId:{},callStackIdToName:{},callStackId:0,asyncPromiseHandlers:null,sleepCallbacks:[],getCallStackId:function(funcName){var id=Asyncify.callStackNameToId[funcName];if(id===undefined){id=Asyncify.callStackId++;Asyncify.callStackNameToId[funcName]=id;Asyncify.callStackIdToName[id]=funcName}return id},maybeStopUnwind:function(){if(Asyncify.currData&&Asyncify.state===Asyncify.State.Unwinding&&Asyncify.exportCallStack.length===0){Asyncify.state=Asyncify.State.Normal;runtimeKeepalivePush();runAndAbortIfError(_asyncify_stop_unwind);if(typeof Fibers!="undefined"){Fibers.trampoline()}}},whenDone:function(){return new Promise(((resolve,reject)=>{Asyncify.asyncPromiseHandlers={resolve:resolve,reject:reject}}))},allocateData:function(){var ptr=_malloc(12+Asyncify.StackSize);Asyncify.setDataHeader(ptr,ptr+12,Asyncify.StackSize);Asyncify.setDataRewindFunc(ptr);return ptr},setDataHeader:function(ptr,stack,stackSize){HEAP32[ptr>>2]=stack;HEAP32[ptr+4>>2]=stack+stackSize},setDataRewindFunc:function(ptr){var bottomOfCallStack=Asyncify.exportCallStack[0];var rewindId=Asyncify.getCallStackId(bottomOfCallStack);HEAP32[ptr+8>>2]=rewindId},getDataRewindFunc:function(ptr){var id=HEAP32[ptr+8>>2];var name=Asyncify.callStackIdToName[id];var func=Module["asm"][name];return func},doRewind:function(ptr){var start=Asyncify.getDataRewindFunc(ptr);runtimeKeepalivePop();return start()},handleSleep:function(startAsync){if(ABORT)return;if(Asyncify.state===Asyncify.State.Normal){var reachedCallback=false;var reachedAfterCallback=false;startAsync(((handleSleepReturnValue=0)=>{if(ABORT)return;Asyncify.handleSleepReturnValue=handleSleepReturnValue;reachedCallback=true;if(!reachedAfterCallback){return}Asyncify.state=Asyncify.State.Rewinding;runAndAbortIfError((()=>_asyncify_start_rewind(Asyncify.currData)));if(typeof Browser!="undefined"&&Browser.mainLoop.func){Browser.mainLoop.resume()}var asyncWasmReturnValue,isError=false;try{asyncWasmReturnValue=Asyncify.doRewind(Asyncify.currData)}catch(err){asyncWasmReturnValue=err;isError=true}var handled=false;if(!Asyncify.currData){var asyncPromiseHandlers=Asyncify.asyncPromiseHandlers;if(asyncPromiseHandlers){Asyncify.asyncPromiseHandlers=null;(isError?asyncPromiseHandlers.reject:asyncPromiseHandlers.resolve)(asyncWasmReturnValue);handled=true}}if(isError&&!handled){throw asyncWasmReturnValue}}));reachedAfterCallback=true;if(!reachedCallback){Asyncify.state=Asyncify.State.Unwinding;Asyncify.currData=Asyncify.allocateData();if(typeof Browser!="undefined"&&Browser.mainLoop.func){Browser.mainLoop.pause()}runAndAbortIfError((()=>_asyncify_start_unwind(Asyncify.currData)))}}else if(Asyncify.state===Asyncify.State.Rewinding){Asyncify.state=Asyncify.State.Normal;runAndAbortIfError(_asyncify_stop_rewind);_free(Asyncify.currData);Asyncify.currData=null;Asyncify.sleepCallbacks.forEach((func=>callUserCallback(func)))}else{abort(`invalid state: ${Asyncify.state}`)}return Asyncify.handleSleepReturnValue},handleAsync:function(startAsync){return Asyncify.handleSleep((wakeUp=>{startAsync().then(wakeUp)}))}};function getCFunc(ident){var func=Module["_"+ident];return func}var ccall=function(ident,returnType,argTypes,args,opts){var toC={"string":str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},"array":arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); /** * Emscripten resolves `localhost` to a random IP address. Let's * make it always resolve to 127.0.0.1. diff --git a/packages/php-wasm/web/src/lib/index.ts b/packages/php-wasm/web/src/lib/index.ts index 780062297a..cab6a78de2 100644 --- a/packages/php-wasm/web/src/lib/index.ts +++ b/packages/php-wasm/web/src/lib/index.ts @@ -2,7 +2,7 @@ export * from './api'; export type { WithAPIState as WithIsReady } from './api'; export type { PHPWebLoaderOptions } from './web-php'; -export { WebPHP } from './web-php'; +export { CAPem, WebPHP } from './web-php'; export { WebPHPEndpoint } from './web-php-endpoint'; export { getPHPLoaderModule } from './get-php-loader-module'; export { registerServiceWorker } from './register-service-worker'; diff --git a/packages/php-wasm/web/src/lib/web-php.ts b/packages/php-wasm/web/src/lib/web-php.ts index 27b976a236..2ab0d495c3 100644 --- a/packages/php-wasm/web/src/lib/web-php.ts +++ b/packages/php-wasm/web/src/lib/web-php.ts @@ -8,6 +8,8 @@ import { } from '@php-wasm/universal'; import { EmscriptenDownloadMonitor } from '@php-wasm/progress'; import { getPHPLoaderModule } from './get-php-loader-module'; +import * as forge from 'node-forge'; +import { Certificate } from 'crypto'; export interface PHPWebLoaderOptions { emscriptenOptions?: EmscriptenOptions; @@ -28,6 +30,7 @@ const fakeWebsocket = () => { decorator: (WebSocketConstructor: any) => { return class FakeWebsocketConstructor extends WebSocketConstructor { constructor() { + console.log('Called constructor()!'); try { super(); } catch (e) { @@ -36,6 +39,7 @@ const fakeWebsocket = () => { } send() { + console.log('Called send()!'); return null; } }; @@ -44,6 +48,560 @@ const fakeWebsocket = () => { }; }; +async function generateKeys() { + const keyPair = await crypto.subtle.generateKey( + { + name: 'ECDH', + namedCurve: 'P-256', + }, + true, + ['deriveKey'] + ); + return keyPair; +} + +function createCertificate({ commonName }) { + // create certificate + var pki = forge.pki; + var keys = pki.rsa.generateKeyPair(2048); + var cert = pki.createCertificate(); + cert.publicKey = keys.publicKey; + // alternatively set public key from a csr + //cert.publicKey = csr.publicKey; + // NOTE: serialNumber is the hex encoded value of an ASN.1 INTEGER. + // Conforming CAs should ensure serialNumber is: + // - no more than 20 octets + // - non-negative (prefix a '00' if your value starts with a '1' bit) + cert.serialNumber = '01'; + cert.validity.notBefore = new Date(); + cert.validity.notAfter = new Date(); + cert.validity.notAfter.setFullYear( + cert.validity.notBefore.getFullYear() + 1 + ); + var attrs = [ + { + name: 'commonName', + value: commonName, + }, + { + name: 'countryName', + value: 'US', + }, + { + shortName: 'ST', + value: 'Virginia', + }, + { + name: 'localityName', + value: 'Blacksburg', + }, + { + name: 'organizationName', + value: 'Test', + }, + { + shortName: 'OU', + value: 'Test', + }, + ]; + cert.setSubject(attrs); + // alternatively set subject from a csr + //cert.setSubject(csr.subject.attributes); + cert.setIssuer(attrs); + cert.setExtensions([ + { + name: 'basicConstraints', + cA: true, + }, + { + name: 'keyUsage', + keyCertSign: true, + digitalSignature: true, + nonRepudiation: true, + keyEncipherment: true, + dataEncipherment: true, + }, + { + name: 'extKeyUsage', + serverAuth: true, + clientAuth: true, + codeSigning: true, + emailProtection: true, + timeStamping: true, + }, + { + name: 'nsCertType', + client: true, + server: true, + email: true, + objsign: true, + sslCA: true, + emailCA: true, + objCA: true, + }, + { + name: 'subjectAltName', + altNames: [ + { + type: 6, // URI + value: '*.org', + }, + { + type: 7, // IP + ip: '127.0.0.1', + }, + ], + }, + { + name: 'subjectKeyIdentifier', + }, + ]); + // FIXME: add subjectKeyIdentifier extension + // FIXME: add authorityKeyIdentifier extension + cert.publicKey = keys.publicKey; + + // self-sign certificate + cert.sign(keys.privateKey); + + // console.log('certificate created for \"' + forge.pki.certificateToPem(cert) + '\": \n' + forge.pki.privateKeyToPem(keys.privateKey)); + return { certificate: cert, privateKey: keys.privateKey }; +} + +// Introduce artificial delay to test the race +// condition when initializing the Playground client. +// for (let i = 0; i < 2; i++) { +// createCertificate(); +// } + +// @TODO: Create these certificates in FetchWebsocketConstructor based on the requested host +const { certificate, privateKey } = createCertificate({ + commonName: 'downloads.wordpress.org', //wsUrl.searchParams.get('host') || '' +}); +const CAPair = { certificate, privateKey }; +// const CAPair = createCertificate({ +// commonName: '' +// }); +export const CAPem = forge.pki.certificateToPem(CAPair.certificate); +/** + * Websocket that buffers the received bytes and translates them into + * a fetch() call. + */ +const fetchingWebsocket = (phpModuleArgs: EmscriptenOptions = {}) => { + return { + websocket: { + ...(phpModuleArgs['websocket'] || {}), + url: (_: any, host: string, port: string) => { + const query = new URLSearchParams({ + host, + port, + }).toString(); + return `ws://playground.internal/?${query}`; + }, + subprotocol: 'binary', + decorator: () => { + return class FetchWebsocketConstructor { + CONNECTING = 0; + OPEN = 1; + CLOSING = 2; + CLOSED = 3; + readyState = this.CONNECTING; + binaryType = 'blob'; + bufferedAmount = 0; + extensions = ''; + protocol = 'ws'; + host = ''; + port = 0; + listeners = new Map(); + sslServer: any; + isPlaintext: boolean | null = null; + + constructor(public url: string, public options: string[]) { + const wsUrl = new URL(url); + this.host = wsUrl.searchParams.get('host')!; + this.port = parseInt( + wsUrl.searchParams.get('port')!, + 10 + ); + + const ws = this; + try { + this.sslServer = forge.tls.createConnection({ + server: true, + caStore: forge.pki.createCaStore([ + CAPair.certificate, + ]), + sessionCache: {}, + // supported cipher suites in order of preference + cipherSuites: [ + forge.tls.CipherSuites + .TLS_RSA_WITH_AES_128_CBC_SHA, + forge.tls.CipherSuites + .TLS_RSA_WITH_AES_256_CBC_SHA, + ], + // require a client-side certificate if you want + verifyClient: false, + verify: function ( + connection, + verified, + depth, + certs + ) { + console.log('Verify '); + if (depth === 0) { + var cn = + certs[0].subject.getField( + 'CN' + ).value; + if (cn !== 'the-client') { + verified = { + alert: forge.tls.Alert + .Description + .bad_certificate, + message: + 'Certificate common name does not match expected client.', + }; + } + } + return verified; + }, + connected: function (connection) { + console.log( + 'Sending an encrypted message back to the client!' + ); + // send message to client + + console.log({ connection }); + + // connection.prepare(forge.util.encodeUtf8( + // `HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nHello World!` + // )); + + /* NOTE: experimental, start heartbeat retransmission timer + myHeartbeatTimer = setInterval(function() { + connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); + }, 5*60*1000);*/ + }, + getCertificate: function (connection, hint) { + console.log('====> getCertificate'); + // return certificate; + // This should return Pem, I think + return forge.pki.certificateToPem( + certificate + ); + }, + getPrivateKey: function (connection, cert) { + console.log('====> getPrivateKey'); + // return privateKey; + // This should return Pem, I think + return forge.pki.privateKeyToPem( + privateKey + ); + }, + tlsDataReady: function (connection) { + console.log('TLS data ready to be sent'); + console.log({ connection }); + const byteString = + connection.tlsData.getBytes(); + const byteArray = new Uint8Array( + byteString.length + ); + for ( + let i = 0; + i < byteString.length; + i++ + ) { + byteArray[i] = byteString.charCodeAt(i); + } + // TLS data (encrypted) is ready to be sent to the client + ws.emit('message', { data: byteArray }); + // if you were communicating with the client above you'd do: + // client.process(connection.tlsData.getBytes()); + }, + dataReady: function (connection) { + // clear data from the client is ready + const receivedData = forge.util.decodeUtf8( + connection.data.getBytes() + ); + if (receivedData === '') { + return; + } + console.log( + 'Clear data received: ' + receivedData + ); + + // @TODO: stream data from multiple dataReady calls in case the + // client, say, uploads a large file + setTimeout(() => { + httpRequestToFetch( + ws.host, + ws.port, + receivedData, + (data) => + connection.prepare( + uint8ArrayToBinaryString( + new Uint8Array(data) + ) + ), + () => connection.close() + ); + }); + console.log({ connection }); + + // close connection + // connection.close(); + }, + /* NOTE: experimental + heartbeatReceived: function(connection, payload) { + // restart retransmission timer, look at payload + clearInterval(myHeartbeatTimer); + myHeartbeatTimer = setInterval(function() { + connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); + }, 5*60*1000); + payload.getBytes(); + },*/ + closed: function (connection) { + console.log('disconnected'); + }, + error: function (connection, error) { + console.log(connection); + console.log('uh oh', error); + }, + }); + } catch (e) { + console.error(e); + } + setTimeout(() => { + this.readyState = this.OPEN; + this.emit('open'); + }); + } + + on(eventName: string, callback: (e: any) => void) { + this.addEventListener(eventName, callback); + } + + once(eventName: string, callback: (e: any) => void) { + const wrapper = (e: any) => { + callback(e); + this.removeEventListener(eventName, wrapper); + }; + this.addEventListener(eventName, wrapper); + } + + addEventListener( + eventName: string, + callback: (e: any) => void + ) { + // console.log("Adding listener for ", eventName, " event"); + if (!this.listeners.has(eventName)) { + this.listeners.set(eventName, new Set()); + } + this.listeners.get(eventName).add(callback); + } + + removeListener( + eventName: string, + callback: (e: any) => void + ) { + this.removeEventListener(eventName, callback); + } + + removeEventListener( + eventName: string, + callback: (e: any) => void + ) { + const listeners = this.listeners.get(eventName); + if (listeners) { + listeners.delete(callback); + } + } + + emit(eventName: string, data: any = {}) { + // console.log("dispatching ", eventName, " event"); + if (eventName === 'message') { + this.onmessage(data); + } else if (eventName === 'close') { + this.onclose(data); + } else if (eventName === 'error') { + this.onerror(data); + } else if (eventName === 'open') { + this.onopen(data); + } + const listeners = this.listeners.get(eventName); + if (listeners) { + for (const listener of listeners) { + listener(eventName, data); + } + } + } + + onclose(data: any) {} + onerror(data: any) {} + onmessage(data: any) {} + onopen(data: any) {} + + send(data: ArrayBuffer) { + console.log('Send called with ', data); + try { + if (this.isPlaintext === null) { + // If it's a HTTP request, we can just fetch it + // @TODO: This is very naive. Let's find a more robust way of detecting if + // it's a HTTP request + const string = new TextDecoder().decode(data); + const firstLine = string.split('\n')[0]; + const [, , version] = firstLine.split(' '); + this.isPlaintext = version?.startsWith('HTTP'); + } + if (this.isPlaintext) { + this.close(); + // httpRequestToFetch( + // this.host, + // this.port, + // new TextDecoder().decode(data), + // (data) => this.emit('message', { data }), + // () => this.close() + // ); + // console.log('fetch() sent'); + return; + } else { + // If it's a HTTPS request, we'll pretend to be the server + // and negotiate a secure connection + console.log(new TextDecoder().decode(data)); + this.sslServer.process( + uint8ArrayToBinaryString( + new Uint8Array(data) + ) + ); + } + return null; + } catch (e) { + console.log('Failed to fetch'); + console.error(e); + } + } + + close() { + console.log('Called close()!'); + this.readyState = this.CLOSING; + this.emit('close'); + this.readyState = this.CLOSED; + } + }; + }, + }, + }; +}; + +function httpRequestToFetch( + host: string, + port: number, + httpRequest: string, + onData: (data: ArrayBuffer) => void, + onDone: () => void +) { + const firstLine = httpRequest.split('\n')[0]; + const [method, path] = firstLine.split(' '); + + const headers = new Headers(); + for (const line of httpRequest.split('\r\n').slice(1)) { + if (line === '') { + break; + } + const [name, value] = line.split(': '); + console.log({ name, value }); + headers.set(name, value); + } + // This is a naive implementation that doesn't handle + // PHP writing arbitrary Host headers to IP addresses, + // but it's the best we can do in the browser. + const protocol = port === 443 ? 'https' : 'http'; + // @TODO: Decide which host to use. The header is less reliable, + // but in some cases it's more useful. E.g. the Host header + // may be `localhost` when `host` is 127.0.0.1, and, to + // run the fetch() request, we need to use the former since + // the latter may not respond to requests. Similarly, + // PHP may run requests to arbitrary IP addresses with + // the Host header set to a domain name, and we need to + // pass a valid domain to fetch(). + const hostname = headers.get('Host') + ? headers.get('Host') + : [80, 443].includes(port) + ? host + : `${host}:${port}`; + const url = new URL(path, protocol + '://' + hostname).toString(); + console.log({ httpRequest, method, url }); + + return fetch(url, { + method, + headers, + }) + .then((response) => { + console.log('====> Got fetch() response!', response); + const reader = response.body?.getReader(); + if (reader) { + const responseHeader = new TextEncoder().encode( + `HTTP/1.1 ${response.status} ${response.statusText}\r\n${[ + ...response.headers, + ] + .map(([name, value]) => `${name}: ${value}`) + .join('\r\n')}\r\n\r\n` + ); + + // @TODO: calling onData() and waiting for more reader chunks + // passes the control back to PHP.wasm and never yields + // the control back to JavaScript. It's likely a polling + // issue, or perhaps something specific to a Symfony HTTP + // client. Either way, PHP blocks the thread and the + // read().then() callback is never called. + // We should find a way to yield the control back to + // JavaScript after each onData() call. + // + // One clue is PHP runs out of memory when onData() blocks + // the event loop. Then it fails with a regular PHP fatal error + // message. Perhaps there's an infinite loop somewhere that + // fails to correctly poll and increases the memory usage indefinitely. + const buffer = [responseHeader.buffer]; + const read = () => { + console.log('Attempt to read the response stream'); + reader + .read() + .then(({ done, value }) => { + // console.log("got some data", value); + if (done) { + // @TODO let's stream the chunks as they + // arrive without buffering them + for (const chunk of buffer) { + onData(chunk); + } + onDone(); + return; + } + buffer.push(value.buffer); + read(); + }) + .catch((e) => { + console.error(e); + }); + }; + read(); + } + }) + .catch((e) => { + console.log('Could not fetch ', url); + console.error(e); + throw e; + }); +} + +function uint8ArrayToBinaryString(bytes: Uint8Array) { + const binary = []; + const len = bytes.byteLength; + for (let i = 0; i < len; i++) { + binary.push(String.fromCharCode(bytes[i])); + } + return binary.join(''); +} + export class WebPHP extends BasePHP { /** * Creates a new PHP instance. @@ -81,7 +639,7 @@ export class WebPHP extends BasePHP { }); return await loadPHPRuntime(phpLoaderModule, { ...(options.emscriptenOptions || {}), - ...fakeWebsocket(), + ...fetchingWebsocket(), }); } } diff --git a/packages/playground/remote/src/lib/worker-thread.ts b/packages/playground/remote/src/lib/worker-thread.ts index cba1108ba7..fb5b25315f 100644 --- a/packages/playground/remote/src/lib/worker-thread.ts +++ b/packages/playground/remote/src/lib/worker-thread.ts @@ -1,4 +1,4 @@ -import { WebPHP, WebPHPEndpoint, exposeAPI } from '@php-wasm/web'; +import { CAPem, WebPHP, WebPHPEndpoint, exposeAPI } from '@php-wasm/web'; import { EmscriptenDownloadMonitor } from '@php-wasm/progress'; import { setURLScope } from '@php-wasm/scopes'; import { DOCROOT, wordPressSiteUrl } from './config'; @@ -240,6 +240,10 @@ try { if (startupOptions.sapiName) { await php.setSapiName(startupOptions.sapiName); } + php.setPhpIniEntry('allow_url_fopen', 'On'); + php.setPhpIniEntry('openssl.cafile', '/tmp/ca-bundle.crt'); + // @TODO: Do not import the CA bundle like this. + php.writeFile('/tmp/ca-bundle.crt', CAPem); const docroot = php.documentRoot; // If WordPress isn't already installed, download and extract it from From 15007c8552730e594d90156c81c6c9d2d60099da Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Sat, 16 Mar 2024 11:14:15 +0100 Subject: [PATCH 2/3] Move TLS logic into a new module. --- packages/php-wasm/web/src/lib/tls-proxy.ts | 456 ++++++++++++++++++++ packages/php-wasm/web/src/lib/web-php.ts | 460 +-------------------- 2 files changed, 459 insertions(+), 457 deletions(-) create mode 100644 packages/php-wasm/web/src/lib/tls-proxy.ts diff --git a/packages/php-wasm/web/src/lib/tls-proxy.ts b/packages/php-wasm/web/src/lib/tls-proxy.ts new file mode 100644 index 0000000000..e693d4c622 --- /dev/null +++ b/packages/php-wasm/web/src/lib/tls-proxy.ts @@ -0,0 +1,456 @@ +import * as forge from 'node-forge'; +import { Certificate } from 'crypto'; +import { EmscriptenOptions } from '@php-wasm/universal'; + +export async function generateKeys() { + const keyPair = await crypto.subtle.generateKey( + { + name: 'ECDH', + namedCurve: 'P-256', + }, + true, + ['deriveKey'] + ); + return keyPair; +} + +export function createCertificate({ commonName }) { + // create certificate + var pki = forge.pki; + var keys = pki.rsa.generateKeyPair(2048); + var cert = pki.createCertificate(); + cert.publicKey = keys.publicKey; + // alternatively set public key from a csr + //cert.publicKey = csr.publicKey; + // NOTE: serialNumber is the hex encoded value of an ASN.1 INTEGER. + // Conforming CAs should ensure serialNumber is: + // - no more than 20 octets + // - non-negative (prefix a '00' if your value starts with a '1' bit) + cert.serialNumber = '01'; + cert.validity.notBefore = new Date(); + cert.validity.notAfter = new Date(); + cert.validity.notAfter.setFullYear( + cert.validity.notBefore.getFullYear() + 1 + ); + var attrs = [ + { + name: 'commonName', + value: commonName, + }, + { + name: 'countryName', + value: 'US', + }, + { + shortName: 'ST', + value: 'Virginia', + }, + { + name: 'localityName', + value: 'Blacksburg', + }, + { + name: 'organizationName', + value: 'Test', + }, + { + shortName: 'OU', + value: 'Test', + }, + ]; + cert.setSubject(attrs); + // alternatively set subject from a csr + //cert.setSubject(csr.subject.attributes); + cert.setIssuer(attrs); + cert.setExtensions([ + { + name: 'basicConstraints', + cA: true, + }, + { + name: 'keyUsage', + keyCertSign: true, + digitalSignature: true, + nonRepudiation: true, + keyEncipherment: true, + dataEncipherment: true, + }, + { + name: 'extKeyUsage', + serverAuth: true, + clientAuth: true, + codeSigning: true, + emailProtection: true, + timeStamping: true, + }, + { + name: 'nsCertType', + client: true, + server: true, + email: true, + objsign: true, + sslCA: true, + emailCA: true, + objCA: true, + }, + { + name: 'subjectAltName', + altNames: [ + { + type: 6, // URI + value: '*.org', + }, + { + type: 7, // IP + ip: '127.0.0.1', + }, + ], + }, + { + name: 'subjectKeyIdentifier', + }, + ]); + // FIXME: add subjectKeyIdentifier extension + // FIXME: add authorityKeyIdentifier extension + cert.publicKey = keys.publicKey; + + // self-sign certificate + cert.sign(keys.privateKey); + + // console.log('certificate created for \"' + forge.pki.certificateToPem(cert) + '\": \n' + forge.pki.privateKeyToPem(keys.privateKey)); + return { certificate: cert, privateKey: keys.privateKey }; +} + +// Introduce artificial delay to test the race +// condition when initializing the Playground client. +// for (let i = 0; i < 2; i++) { +// createCertificate(); +// } + +// @TODO: Create these certificates in FetchWebsocketConstructor based on the requested host +const { certificate, privateKey } = createCertificate({ + commonName: 'downloads.wordpress.org', //wsUrl.searchParams.get('host') || '' +}); +const CAPair = { certificate, privateKey }; +// const CAPair = createCertificate({ +// commonName: '' +// }); +export const CAPem = forge.pki.certificateToPem(CAPair.certificate); +/** + * Websocket that buffers the received bytes and translates them into + * a fetch() call. + */ +export const fetchingWebsocket = (phpModuleArgs: EmscriptenOptions = {}) => { + return { + websocket: { + ...(phpModuleArgs['websocket'] || {}), + url: (_: any, host: string, port: string) => { + const query = new URLSearchParams({ + host, + port, + }).toString(); + return `ws://playground.internal/?${query}`; + }, + subprotocol: 'binary', + decorator: () => { + return class FetchWebsocketConstructor { + CONNECTING = 0; + OPEN = 1; + CLOSING = 2; + CLOSED = 3; + readyState = this.CONNECTING; + binaryType = 'blob'; + bufferedAmount = 0; + extensions = ''; + protocol = 'ws'; + host = ''; + port = 0; + listeners = new Map(); + sslServer: any; + isPlaintext: boolean | null = null; + + constructor(public url: string, public options: string[]) { + const wsUrl = new URL(url); + this.host = wsUrl.searchParams.get('host')!; + this.port = parseInt( + wsUrl.searchParams.get('port')!, + 10 + ); + + const ws = this; + try { + this.sslServer = forge.tls.createConnection({ + server: true, + caStore: forge.pki.createCaStore([ + CAPair.certificate, + ]), + sessionCache: {}, + // supported cipher suites in order of preference + cipherSuites: [ + forge.tls.CipherSuites + .TLS_RSA_WITH_AES_128_CBC_SHA, + forge.tls.CipherSuites + .TLS_RSA_WITH_AES_256_CBC_SHA, + ], + // require a client-side certificate if you want + verifyClient: false, + verify: function ( + connection, + verified, + depth, + certs + ) { + console.log('Verify '); + if (depth === 0) { + var cn = + certs[0].subject.getField( + 'CN' + ).value; + if (cn !== 'the-client') { + verified = { + alert: forge.tls.Alert + .Description + .bad_certificate, + message: + 'Certificate common name does not match expected client.', + }; + } + } + return verified; + }, + connected: function (connection) { + console.log( + 'Sending an encrypted message back to the client!' + ); + // send message to client + + console.log({ connection }); + + // connection.prepare(forge.util.encodeUtf8( + // `HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nHello World!` + // )); + + /* NOTE: experimental, start heartbeat retransmission timer + myHeartbeatTimer = setInterval(function() { + connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); + }, 5*60*1000);*/ + }, + getCertificate: function (connection, hint) { + console.log('====> getCertificate'); + // return certificate; + // This should return Pem, I think + return forge.pki.certificateToPem( + certificate + ); + }, + getPrivateKey: function (connection, cert) { + console.log('====> getPrivateKey'); + // return privateKey; + // This should return Pem, I think + return forge.pki.privateKeyToPem( + privateKey + ); + }, + tlsDataReady: function (connection) { + console.log('TLS data ready to be sent'); + console.log({ connection }); + const byteString = + connection.tlsData.getBytes(); + const byteArray = new Uint8Array( + byteString.length + ); + for ( + let i = 0; + i < byteString.length; + i++ + ) { + byteArray[i] = byteString.charCodeAt(i); + } + // TLS data (encrypted) is ready to be sent to the client + ws.emit('message', { data: byteArray }); + // if you were communicating with the client above you'd do: + // client.process(connection.tlsData.getBytes()); + }, + dataReady: function (connection) { + // clear data from the client is ready + const receivedData = forge.util.decodeUtf8( + connection.data.getBytes() + ); + if (receivedData === '') { + return; + } + console.log( + 'Clear data received: ' + receivedData + ); + + // @TODO: stream data from multiple dataReady calls in case the + // client, say, uploads a large file + setTimeout(() => { + httpRequestToFetch( + ws.host, + ws.port, + receivedData, + (data) => + connection.prepare( + uint8ArrayToBinaryString( + new Uint8Array(data) + ) + ), + () => connection.close() + ); + }); + console.log({ connection }); + + // close connection + // connection.close(); + }, + /* NOTE: experimental + heartbeatReceived: function(connection, payload) { + // restart retransmission timer, look at payload + clearInterval(myHeartbeatTimer); + myHeartbeatTimer = setInterval(function() { + connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); + }, 5*60*1000); + payload.getBytes(); + },*/ + closed: function (connection) { + console.log('disconnected'); + }, + error: function (connection, error) { + console.log(connection); + console.log('uh oh', error); + }, + }); + } catch (e) { + console.error(e); + } + setTimeout(() => { + this.readyState = this.OPEN; + this.emit('open'); + }); + } + + on(eventName: string, callback: (e: any) => void) { + this.addEventListener(eventName, callback); + } + + once(eventName: string, callback: (e: any) => void) { + const wrapper = (e: any) => { + callback(e); + this.removeEventListener(eventName, wrapper); + }; + this.addEventListener(eventName, wrapper); + } + + addEventListener( + eventName: string, + callback: (e: any) => void + ) { + // console.log("Adding listener for ", eventName, " event"); + if (!this.listeners.has(eventName)) { + this.listeners.set(eventName, new Set()); + } + this.listeners.get(eventName).add(callback); + } + + removeListener( + eventName: string, + callback: (e: any) => void + ) { + this.removeEventListener(eventName, callback); + } + + removeEventListener( + eventName: string, + callback: (e: any) => void + ) { + const listeners = this.listeners.get(eventName); + if (listeners) { + listeners.delete(callback); + } + } + + emit(eventName: string, data: any = {}) { + // console.log("dispatching ", eventName, " event"); + if (eventName === 'message') { + this.onmessage(data); + } else if (eventName === 'close') { + this.onclose(data); + } else if (eventName === 'error') { + this.onerror(data); + } else if (eventName === 'open') { + this.onopen(data); + } + const listeners = this.listeners.get(eventName); + if (listeners) { + for (const listener of listeners) { + listener(eventName, data); + } + } + } + + onclose(data: any) {} + onerror(data: any) {} + onmessage(data: any) {} + onopen(data: any) {} + + send(data: ArrayBuffer) { + console.log('Send called with ', data); + try { + if (this.isPlaintext === null) { + // If it's a HTTP request, we can just fetch it + // @TODO: This is very naive. Let's find a more robust way of detecting if + // it's a HTTP request + const string = new TextDecoder().decode(data); + const firstLine = string.split('\n')[0]; + const [, , version] = firstLine.split(' '); + this.isPlaintext = version?.startsWith('HTTP'); + } + if (this.isPlaintext) { + this.close(); + // httpRequestToFetch( + // this.host, + // this.port, + // new TextDecoder().decode(data), + // (data) => this.emit('message', { data }), + // () => this.close() + // ); + // console.log('fetch() sent'); + return; + } else { + // If it's a HTTPS request, we'll pretend to be the server + // and negotiate a secure connection + console.log(new TextDecoder().decode(data)); + this.sslServer.process( + uint8ArrayToBinaryString( + new Uint8Array(data) + ) + ); + } + return null; + } catch (e) { + console.log('Failed to fetch'); + console.error(e); + } + } + + close() { + console.log('Called close()!'); + this.readyState = this.CLOSING; + this.emit('close'); + this.readyState = this.CLOSED; + } + }; + }, + }, + }; +}; + +function uint8ArrayToBinaryString(bytes: Uint8Array) { + const binary = []; + const len = bytes.byteLength; + for (let i = 0; i < len; i++) { + binary.push(String.fromCharCode(bytes[i])); + } + return binary.join(''); +} diff --git a/packages/php-wasm/web/src/lib/web-php.ts b/packages/php-wasm/web/src/lib/web-php.ts index 2ab0d495c3..3d4d310419 100644 --- a/packages/php-wasm/web/src/lib/web-php.ts +++ b/packages/php-wasm/web/src/lib/web-php.ts @@ -8,8 +8,7 @@ import { } from '@php-wasm/universal'; import { EmscriptenDownloadMonitor } from '@php-wasm/progress'; import { getPHPLoaderModule } from './get-php-loader-module'; -import * as forge from 'node-forge'; -import { Certificate } from 'crypto'; +import * as tls from './tls-proxy'; export interface PHPWebLoaderOptions { emscriptenOptions?: EmscriptenOptions; @@ -48,451 +47,7 @@ const fakeWebsocket = () => { }; }; -async function generateKeys() { - const keyPair = await crypto.subtle.generateKey( - { - name: 'ECDH', - namedCurve: 'P-256', - }, - true, - ['deriveKey'] - ); - return keyPair; -} - -function createCertificate({ commonName }) { - // create certificate - var pki = forge.pki; - var keys = pki.rsa.generateKeyPair(2048); - var cert = pki.createCertificate(); - cert.publicKey = keys.publicKey; - // alternatively set public key from a csr - //cert.publicKey = csr.publicKey; - // NOTE: serialNumber is the hex encoded value of an ASN.1 INTEGER. - // Conforming CAs should ensure serialNumber is: - // - no more than 20 octets - // - non-negative (prefix a '00' if your value starts with a '1' bit) - cert.serialNumber = '01'; - cert.validity.notBefore = new Date(); - cert.validity.notAfter = new Date(); - cert.validity.notAfter.setFullYear( - cert.validity.notBefore.getFullYear() + 1 - ); - var attrs = [ - { - name: 'commonName', - value: commonName, - }, - { - name: 'countryName', - value: 'US', - }, - { - shortName: 'ST', - value: 'Virginia', - }, - { - name: 'localityName', - value: 'Blacksburg', - }, - { - name: 'organizationName', - value: 'Test', - }, - { - shortName: 'OU', - value: 'Test', - }, - ]; - cert.setSubject(attrs); - // alternatively set subject from a csr - //cert.setSubject(csr.subject.attributes); - cert.setIssuer(attrs); - cert.setExtensions([ - { - name: 'basicConstraints', - cA: true, - }, - { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true, - }, - { - name: 'extKeyUsage', - serverAuth: true, - clientAuth: true, - codeSigning: true, - emailProtection: true, - timeStamping: true, - }, - { - name: 'nsCertType', - client: true, - server: true, - email: true, - objsign: true, - sslCA: true, - emailCA: true, - objCA: true, - }, - { - name: 'subjectAltName', - altNames: [ - { - type: 6, // URI - value: '*.org', - }, - { - type: 7, // IP - ip: '127.0.0.1', - }, - ], - }, - { - name: 'subjectKeyIdentifier', - }, - ]); - // FIXME: add subjectKeyIdentifier extension - // FIXME: add authorityKeyIdentifier extension - cert.publicKey = keys.publicKey; - - // self-sign certificate - cert.sign(keys.privateKey); - - // console.log('certificate created for \"' + forge.pki.certificateToPem(cert) + '\": \n' + forge.pki.privateKeyToPem(keys.privateKey)); - return { certificate: cert, privateKey: keys.privateKey }; -} - -// Introduce artificial delay to test the race -// condition when initializing the Playground client. -// for (let i = 0; i < 2; i++) { -// createCertificate(); -// } - -// @TODO: Create these certificates in FetchWebsocketConstructor based on the requested host -const { certificate, privateKey } = createCertificate({ - commonName: 'downloads.wordpress.org', //wsUrl.searchParams.get('host') || '' -}); -const CAPair = { certificate, privateKey }; -// const CAPair = createCertificate({ -// commonName: '' -// }); -export const CAPem = forge.pki.certificateToPem(CAPair.certificate); -/** - * Websocket that buffers the received bytes and translates them into - * a fetch() call. - */ -const fetchingWebsocket = (phpModuleArgs: EmscriptenOptions = {}) => { - return { - websocket: { - ...(phpModuleArgs['websocket'] || {}), - url: (_: any, host: string, port: string) => { - const query = new URLSearchParams({ - host, - port, - }).toString(); - return `ws://playground.internal/?${query}`; - }, - subprotocol: 'binary', - decorator: () => { - return class FetchWebsocketConstructor { - CONNECTING = 0; - OPEN = 1; - CLOSING = 2; - CLOSED = 3; - readyState = this.CONNECTING; - binaryType = 'blob'; - bufferedAmount = 0; - extensions = ''; - protocol = 'ws'; - host = ''; - port = 0; - listeners = new Map(); - sslServer: any; - isPlaintext: boolean | null = null; - - constructor(public url: string, public options: string[]) { - const wsUrl = new URL(url); - this.host = wsUrl.searchParams.get('host')!; - this.port = parseInt( - wsUrl.searchParams.get('port')!, - 10 - ); - - const ws = this; - try { - this.sslServer = forge.tls.createConnection({ - server: true, - caStore: forge.pki.createCaStore([ - CAPair.certificate, - ]), - sessionCache: {}, - // supported cipher suites in order of preference - cipherSuites: [ - forge.tls.CipherSuites - .TLS_RSA_WITH_AES_128_CBC_SHA, - forge.tls.CipherSuites - .TLS_RSA_WITH_AES_256_CBC_SHA, - ], - // require a client-side certificate if you want - verifyClient: false, - verify: function ( - connection, - verified, - depth, - certs - ) { - console.log('Verify '); - if (depth === 0) { - var cn = - certs[0].subject.getField( - 'CN' - ).value; - if (cn !== 'the-client') { - verified = { - alert: forge.tls.Alert - .Description - .bad_certificate, - message: - 'Certificate common name does not match expected client.', - }; - } - } - return verified; - }, - connected: function (connection) { - console.log( - 'Sending an encrypted message back to the client!' - ); - // send message to client - - console.log({ connection }); - - // connection.prepare(forge.util.encodeUtf8( - // `HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nHello World!` - // )); - - /* NOTE: experimental, start heartbeat retransmission timer - myHeartbeatTimer = setInterval(function() { - connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); - }, 5*60*1000);*/ - }, - getCertificate: function (connection, hint) { - console.log('====> getCertificate'); - // return certificate; - // This should return Pem, I think - return forge.pki.certificateToPem( - certificate - ); - }, - getPrivateKey: function (connection, cert) { - console.log('====> getPrivateKey'); - // return privateKey; - // This should return Pem, I think - return forge.pki.privateKeyToPem( - privateKey - ); - }, - tlsDataReady: function (connection) { - console.log('TLS data ready to be sent'); - console.log({ connection }); - const byteString = - connection.tlsData.getBytes(); - const byteArray = new Uint8Array( - byteString.length - ); - for ( - let i = 0; - i < byteString.length; - i++ - ) { - byteArray[i] = byteString.charCodeAt(i); - } - // TLS data (encrypted) is ready to be sent to the client - ws.emit('message', { data: byteArray }); - // if you were communicating with the client above you'd do: - // client.process(connection.tlsData.getBytes()); - }, - dataReady: function (connection) { - // clear data from the client is ready - const receivedData = forge.util.decodeUtf8( - connection.data.getBytes() - ); - if (receivedData === '') { - return; - } - console.log( - 'Clear data received: ' + receivedData - ); - - // @TODO: stream data from multiple dataReady calls in case the - // client, say, uploads a large file - setTimeout(() => { - httpRequestToFetch( - ws.host, - ws.port, - receivedData, - (data) => - connection.prepare( - uint8ArrayToBinaryString( - new Uint8Array(data) - ) - ), - () => connection.close() - ); - }); - console.log({ connection }); - - // close connection - // connection.close(); - }, - /* NOTE: experimental - heartbeatReceived: function(connection, payload) { - // restart retransmission timer, look at payload - clearInterval(myHeartbeatTimer); - myHeartbeatTimer = setInterval(function() { - connection.prepareHeartbeatRequest(forge.util.createBuffer('1234')); - }, 5*60*1000); - payload.getBytes(); - },*/ - closed: function (connection) { - console.log('disconnected'); - }, - error: function (connection, error) { - console.log(connection); - console.log('uh oh', error); - }, - }); - } catch (e) { - console.error(e); - } - setTimeout(() => { - this.readyState = this.OPEN; - this.emit('open'); - }); - } - - on(eventName: string, callback: (e: any) => void) { - this.addEventListener(eventName, callback); - } - - once(eventName: string, callback: (e: any) => void) { - const wrapper = (e: any) => { - callback(e); - this.removeEventListener(eventName, wrapper); - }; - this.addEventListener(eventName, wrapper); - } - - addEventListener( - eventName: string, - callback: (e: any) => void - ) { - // console.log("Adding listener for ", eventName, " event"); - if (!this.listeners.has(eventName)) { - this.listeners.set(eventName, new Set()); - } - this.listeners.get(eventName).add(callback); - } - - removeListener( - eventName: string, - callback: (e: any) => void - ) { - this.removeEventListener(eventName, callback); - } - - removeEventListener( - eventName: string, - callback: (e: any) => void - ) { - const listeners = this.listeners.get(eventName); - if (listeners) { - listeners.delete(callback); - } - } - - emit(eventName: string, data: any = {}) { - // console.log("dispatching ", eventName, " event"); - if (eventName === 'message') { - this.onmessage(data); - } else if (eventName === 'close') { - this.onclose(data); - } else if (eventName === 'error') { - this.onerror(data); - } else if (eventName === 'open') { - this.onopen(data); - } - const listeners = this.listeners.get(eventName); - if (listeners) { - for (const listener of listeners) { - listener(eventName, data); - } - } - } - - onclose(data: any) {} - onerror(data: any) {} - onmessage(data: any) {} - onopen(data: any) {} - - send(data: ArrayBuffer) { - console.log('Send called with ', data); - try { - if (this.isPlaintext === null) { - // If it's a HTTP request, we can just fetch it - // @TODO: This is very naive. Let's find a more robust way of detecting if - // it's a HTTP request - const string = new TextDecoder().decode(data); - const firstLine = string.split('\n')[0]; - const [, , version] = firstLine.split(' '); - this.isPlaintext = version?.startsWith('HTTP'); - } - if (this.isPlaintext) { - this.close(); - // httpRequestToFetch( - // this.host, - // this.port, - // new TextDecoder().decode(data), - // (data) => this.emit('message', { data }), - // () => this.close() - // ); - // console.log('fetch() sent'); - return; - } else { - // If it's a HTTPS request, we'll pretend to be the server - // and negotiate a secure connection - console.log(new TextDecoder().decode(data)); - this.sslServer.process( - uint8ArrayToBinaryString( - new Uint8Array(data) - ) - ); - } - return null; - } catch (e) { - console.log('Failed to fetch'); - console.error(e); - } - } - - close() { - console.log('Called close()!'); - this.readyState = this.CLOSING; - this.emit('close'); - this.readyState = this.CLOSED; - } - }; - }, - }, - }; -}; - -function httpRequestToFetch( +export function httpRequestToFetch( host: string, port: number, httpRequest: string, @@ -593,15 +148,6 @@ function httpRequestToFetch( }); } -function uint8ArrayToBinaryString(bytes: Uint8Array) { - const binary = []; - const len = bytes.byteLength; - for (let i = 0; i < len; i++) { - binary.push(String.fromCharCode(bytes[i])); - } - return binary.join(''); -} - export class WebPHP extends BasePHP { /** * Creates a new PHP instance. @@ -639,7 +185,7 @@ export class WebPHP extends BasePHP { }); return await loadPHPRuntime(phpLoaderModule, { ...(options.emscriptenOptions || {}), - ...fetchingWebsocket(), + ...tls.fetchingWebsocket(), }); } } From 0e8f8db02a69331fc00bc4e4d431171cfed65112 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Sat, 16 Mar 2024 11:28:52 +0100 Subject: [PATCH 3/3] Move another file, decode as latin1 --- packages/php-wasm/web/src/lib/tls-proxy.ts | 126 ++++++++++++++++++++- packages/php-wasm/web/src/lib/web-php.ts | 101 ----------------- 2 files changed, 122 insertions(+), 105 deletions(-) diff --git a/packages/php-wasm/web/src/lib/tls-proxy.ts b/packages/php-wasm/web/src/lib/tls-proxy.ts index e693d4c622..6c59dd48be 100644 --- a/packages/php-wasm/web/src/lib/tls-proxy.ts +++ b/packages/php-wasm/web/src/lib/tls-proxy.ts @@ -14,6 +14,14 @@ export async function generateKeys() { return keyPair; } +/** + * Creates a self-signed certificate for trusting all connections. + * + * Actual certificate integrity will be verified by the browser on the other + * end of the fake WebSocket. This is necessary to man-in-the-middle sockets + * with TLS data, because they might start as an open stream but establish a + * secure handshake after opening. + */ export function createCertificate({ commonName }) { // create certificate var pki = forge.pki; @@ -136,6 +144,108 @@ const CAPair = { certificate, privateKey }; // commonName: '' // }); export const CAPem = forge.pki.certificateToPem(CAPair.certificate); + +export function httpRequestToFetch( + host: string, + port: number, + httpRequest: string, + onData: (data: ArrayBuffer) => void, + onDone: () => void +) { + const firstLine = httpRequest.split('\n')[0]; + const [method, path] = firstLine.split(' '); + + const headers = new Headers(); + for (const line of httpRequest.split('\r\n').slice(1)) { + if (line === '') { + break; + } + const [name, value] = line.split(': '); + console.log({ name, value }); + headers.set(name, value); + } + // This is a naive implementation that doesn't handle + // PHP writing arbitrary Host headers to IP addresses, + // but it's the best we can do in the browser. + const protocol = port === 443 ? 'https' : 'http'; + // @TODO: Decide which host to use. The header is less reliable, + // but in some cases it's more useful. E.g. the Host header + // may be `localhost` when `host` is 127.0.0.1, and, to + // run the fetch() request, we need to use the former since + // the latter may not respond to requests. Similarly, + // PHP may run requests to arbitrary IP addresses with + // the Host header set to a domain name, and we need to + // pass a valid domain to fetch(). + const hostname = headers.get('Host') + ? headers.get('Host') + : [80, 443].includes(port) + ? host + : `${host}:${port}`; + const url = new URL(path, protocol + '://' + hostname).toString(); + console.log({ httpRequest, method, url }); + + return fetch(url, { + method, + headers, + }) + .then((response) => { + console.log('====> Got fetch() response!', response); + const reader = response.body?.getReader(); + if (reader) { + const responseHeader = new TextEncoder().encode( + `HTTP/1.1 ${response.status} ${response.statusText}\r\n${[ + ...response.headers, + ] + .map(([name, value]) => `${name}: ${value}`) + .join('\r\n')}\r\n\r\n` + ); + + // @TODO: calling onData() and waiting for more reader chunks + // passes the control back to PHP.wasm and never yields + // the control back to JavaScript. It's likely a polling + // issue, or perhaps something specific to a Symfony HTTP + // client. Either way, PHP blocks the thread and the + // read().then() callback is never called. + // We should find a way to yield the control back to + // JavaScript after each onData() call. + // + // One clue is PHP runs out of memory when onData() blocks + // the event loop. Then it fails with a regular PHP fatal error + // message. Perhaps there's an infinite loop somewhere that + // fails to correctly poll and increases the memory usage indefinitely. + const buffer = [responseHeader.buffer]; + const read = () => { + console.log('Attempt to read the response stream'); + reader + .read() + .then(({ done, value }) => { + // console.log("got some data", value); + if (done) { + // @TODO let's stream the chunks as they + // arrive without buffering them + for (const chunk of buffer) { + onData(chunk); + } + onDone(); + return; + } + buffer.push(value.buffer); + read(); + }) + .catch((e) => { + console.error(e); + }); + }; + read(); + } + }) + .catch((e) => { + console.log('Could not fetch ', url); + console.error(e); + throw e; + }); +} + /** * Websocket that buffers the received bytes and translates them into * a fetch() call. @@ -401,10 +511,18 @@ export const fetchingWebsocket = (phpModuleArgs: EmscriptenOptions = {}) => { // If it's a HTTP request, we can just fetch it // @TODO: This is very naive. Let's find a more robust way of detecting if // it's a HTTP request - const string = new TextDecoder().decode(data); - const firstLine = string.split('\n')[0]; - const [, , version] = firstLine.split(' '); - this.isPlaintext = version?.startsWith('HTTP'); + try { + // Throw a TypeError instead of replacing indecipherable octects with `�`. + const string = new TextDecoder('latin1', { + fatal: true, + }).decode(data); + const firstLine = string.split('\n')[0]; + const [, , version] = firstLine.split(' '); + this.isPlaintext = + version?.startsWith('HTTP'); + } catch (e) { + this.isPlaintext = false; + } } if (this.isPlaintext) { this.close(); diff --git a/packages/php-wasm/web/src/lib/web-php.ts b/packages/php-wasm/web/src/lib/web-php.ts index 3d4d310419..ceffa4212f 100644 --- a/packages/php-wasm/web/src/lib/web-php.ts +++ b/packages/php-wasm/web/src/lib/web-php.ts @@ -47,107 +47,6 @@ const fakeWebsocket = () => { }; }; -export function httpRequestToFetch( - host: string, - port: number, - httpRequest: string, - onData: (data: ArrayBuffer) => void, - onDone: () => void -) { - const firstLine = httpRequest.split('\n')[0]; - const [method, path] = firstLine.split(' '); - - const headers = new Headers(); - for (const line of httpRequest.split('\r\n').slice(1)) { - if (line === '') { - break; - } - const [name, value] = line.split(': '); - console.log({ name, value }); - headers.set(name, value); - } - // This is a naive implementation that doesn't handle - // PHP writing arbitrary Host headers to IP addresses, - // but it's the best we can do in the browser. - const protocol = port === 443 ? 'https' : 'http'; - // @TODO: Decide which host to use. The header is less reliable, - // but in some cases it's more useful. E.g. the Host header - // may be `localhost` when `host` is 127.0.0.1, and, to - // run the fetch() request, we need to use the former since - // the latter may not respond to requests. Similarly, - // PHP may run requests to arbitrary IP addresses with - // the Host header set to a domain name, and we need to - // pass a valid domain to fetch(). - const hostname = headers.get('Host') - ? headers.get('Host') - : [80, 443].includes(port) - ? host - : `${host}:${port}`; - const url = new URL(path, protocol + '://' + hostname).toString(); - console.log({ httpRequest, method, url }); - - return fetch(url, { - method, - headers, - }) - .then((response) => { - console.log('====> Got fetch() response!', response); - const reader = response.body?.getReader(); - if (reader) { - const responseHeader = new TextEncoder().encode( - `HTTP/1.1 ${response.status} ${response.statusText}\r\n${[ - ...response.headers, - ] - .map(([name, value]) => `${name}: ${value}`) - .join('\r\n')}\r\n\r\n` - ); - - // @TODO: calling onData() and waiting for more reader chunks - // passes the control back to PHP.wasm and never yields - // the control back to JavaScript. It's likely a polling - // issue, or perhaps something specific to a Symfony HTTP - // client. Either way, PHP blocks the thread and the - // read().then() callback is never called. - // We should find a way to yield the control back to - // JavaScript after each onData() call. - // - // One clue is PHP runs out of memory when onData() blocks - // the event loop. Then it fails with a regular PHP fatal error - // message. Perhaps there's an infinite loop somewhere that - // fails to correctly poll and increases the memory usage indefinitely. - const buffer = [responseHeader.buffer]; - const read = () => { - console.log('Attempt to read the response stream'); - reader - .read() - .then(({ done, value }) => { - // console.log("got some data", value); - if (done) { - // @TODO let's stream the chunks as they - // arrive without buffering them - for (const chunk of buffer) { - onData(chunk); - } - onDone(); - return; - } - buffer.push(value.buffer); - read(); - }) - .catch((e) => { - console.error(e); - }); - }; - read(); - } - }) - .catch((e) => { - console.log('Could not fetch ', url); - console.error(e); - throw e; - }); -} - export class WebPHP extends BasePHP { /** * Creates a new PHP instance.