From 2361e1bfc10cd91f7873214cd0c8f33f358820dd Mon Sep 17 00:00:00 2001 From: dave caruso Date: Mon, 25 Mar 2024 11:08:45 -0700 Subject: [PATCH 01/27] awa --- src/cli/run_command.zig | 4 +- src/install/windows-shim/BinLinkingShim.zig | 2 + src/install/windows-shim/bun_shim_impl.zig | 45 +++++++++++++++------ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index ee21120203255..782036855755f 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -1675,7 +1675,8 @@ pub const BunXFastPath = struct { var environment_buffer: bun.WPathBuffer = undefined; /// If this returns, it implies the fast path cannot be taken - fn tryLaunch(ctx: Command.Context, path_to_use: [:0]u16, env: *DotEnv.Loader, passthrough: []const []const u8) void { + fn tryLaunch(ctx_const: Command.Context, path_to_use: [:0]u16, env: *DotEnv.Loader, passthrough: []const []const u8) void { + var ctx = ctx_const; std.debug.assert(bun.isSliceInBufferT(u16, path_to_use, &BunXFastPath.direct_launch_buffer)); var command_line = BunXFastPath.direct_launch_buffer[path_to_use.len..]; @@ -1700,6 +1701,7 @@ pub const BunXFastPath = struct { const result = bun.strings.convertUTF8toUTF16InBuffer(command_line[1 + i ..], str); i += result.len + 1; } + ctx.passthrough = passthrough; const run_ctx = shim_impl.FromBunRunContext{ .handle = handle, diff --git a/src/install/windows-shim/BinLinkingShim.zig b/src/install/windows-shim/BinLinkingShim.zig index a229f791730eb..028ee03fac589 100644 --- a/src/install/windows-shim/BinLinkingShim.zig +++ b/src/install/windows-shim/BinLinkingShim.zig @@ -41,6 +41,8 @@ pub const VersionFlag = enum(u13) { /// automatic fallback path where if "node" is asked for, but not present, /// it will retry the spawn with "bun". v4 = 5477, + /// Fixed bugs where passing arguments did not always work. + v5 = 5478, _, }; diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index b5699703c45ae..57ffd34ee1396 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -36,6 +36,8 @@ //! //! The compiled binary is 12800 bytes and is `@embedFile`d into Bun itself. //! When this file is updated, the new binary should be compiled and BinLinkingShim.VersionFlag.current should be updated. +//! +//! Questions about this file should be directed at @paperdave. const builtin = @import("builtin"); const dbg = builtin.mode == .Debug; @@ -128,7 +130,7 @@ fn debug(comptime fmt: []const u8, args: anytype) void { if (!is_standalone) { bunDebugMessage(fmt, args); } else { - std.log.debug(if (fmt[fmt.len - 1] == '\n') fmt else fmt ++ "\n", args); + std.log.debug(fmt, args); } } @@ -485,7 +487,10 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { if (dbg) debug("left = {d}, at {}, after {}\n", .{ left, ptr[0], ptr[1] }); // if this is false, potential out of bounds memory access - std.debug.assert(@intFromPtr(ptr) - left * @sizeOf(std.meta.Child(@TypeOf(ptr))) >= @intFromPtr(buf1_u16)); + if (dbg) + std.debug.assert( + @intFromPtr(ptr) - left * @sizeOf(std.meta.Child(@TypeOf(ptr))) >= @intFromPtr(buf1_u16), + ); // we start our search right before the . as we know the extension is '.bunx' std.debug.assert(ptr[1] == '.'); @@ -502,7 +507,8 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { return mode.fail(.NoDirname); } ptr -= 1; - std.debug.assert(@intFromPtr(ptr) >= @intFromPtr(buf1_u16)); + if (dbg) + std.debug.assert(@intFromPtr(ptr) >= @intFromPtr(buf1_u16)); } // inlined loop to do this again, because the completion case is different // using `inline for` caused comptime issues that made the code much harder to read @@ -517,7 +523,8 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { return mode.fail(.NoDirname); } ptr -= 1; - std.debug.assert(@intFromPtr(ptr) >= @intFromPtr(buf1_u16)); + if (dbg) + std.debug.assert(@intFromPtr(ptr) >= @intFromPtr(buf1_u16)); } @compileError("unreachable"); }; @@ -667,7 +674,7 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // BUF1: '\??\C:\Users\dave\project\node_modules\my-cli\src\app.js"#node #####!!!!!!!!!!' // ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^ read_ptr const len = (@intFromPtr(read_ptr) - @intFromPtr(buf1_u8) - shebang_arg_len_u8) / 2 - nt_object_prefix.len - "\"\x00".len; - const launch_slice = buf1_u16[nt_object_prefix.len..][0..len :'"']; + const launch_slice = buf1_u16[nt_object_prefix.len..][0..len :'"']; // assert we slice at the " bun_ctx.direct_launch_with_bun_js( launch_slice, bun_ctx.cli_context, @@ -678,6 +685,7 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // Copy the shebang bin path // BUF1: '\??\C:\Users\dave\project\node_modules\my-cli\src\app.js"#node #####!!!!!!!!!!' // ^~~~^ + // ^ read_ptr // BUF2: 'node !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' read_ptr = @ptrFromInt(@intFromPtr(read_ptr) - shebang_arg_len_u8); @memcpy(buf2_u8, @as([*]u8, @ptrCast(read_ptr))[0..shebang_arg_len_u8]); @@ -687,29 +695,40 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // Copy the filename in. There is no leading " but there is a trailing " // BUF1: '\??\C:\Users\dave\project\node_modules\my-cli\src\app.js"#node #####!!!!!!!!!!' - // ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^ read_ptr + // ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^ read_ptr // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js"!!!!!!!!!!!!!!!!!!!!' - const length_of_filename_u8 = @intFromPtr(read_ptr) - @intFromPtr(buf1_u8) - shebang_arg_len_u8; + const length_of_filename_u8 = @intFromPtr(read_ptr) - + @intFromPtr(buf1_u8) - nt_object_prefix.len - + (2 * "\x00n".len); // the 'n' refers to the first char of the shebang. + const filename = buf1_u8[2 * nt_object_prefix.len ..][0..length_of_filename_u8]; + if (dbg) + debug("filename and quote: '{}'\n", .{fmt16(@alignCast(std.mem.bytesAsSlice(u16, filename)))}); + @memcpy( buf2_u8[shebang_arg_len_u8 + 2 * "\"".len ..][0..length_of_filename_u8], - buf1_u8[2 * nt_object_prefix.len ..][0..length_of_filename_u8], + filename, ); - read_ptr = @ptrFromInt(@intFromPtr(buf2_u8) + length_of_filename_u8 + 2 * ("\"".len + nt_object_prefix.len)); + // the pointer is now going to act as a write pointer for remaining data. + // note that it points into buf2 now, not buf1. this will write arguments and the null terminator + // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js"!!!!!!!!!!!!!!!!!!!!' + // ^ write_ptr + const advance = length_of_filename_u8 + shebang_arg_len_u8 + 2 * "\"".len; + var write_ptr: [*]u8 = @ptrFromInt(@intFromPtr(buf2_u8) + advance); if (user_arguments_u8.len > 0) { // Copy the user arguments in: // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js" --flags!!!!!!!!!!!' // ^~~~~X^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ - // | |filename_len where the user args go + // | |filename_len write_ptr // | the quote // shebang_arg_len - @memcpy(@as([*]u8, @ptrCast(read_ptr)), user_arguments_u8); - read_ptr = @ptrFromInt(@intFromPtr(read_ptr) + user_arguments_u8.len); + @memcpy(@as([*]u8, @ptrCast(write_ptr)), user_arguments_u8); + write_ptr = @ptrFromInt(@intFromPtr(write_ptr) + user_arguments_u8.len); } // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js" --flags#!!!!!!!!!!' // ^ null terminator - @as(*align(1) u16, @ptrCast(read_ptr)).* = 0; + @as(*align(1) u16, @ptrCast(write_ptr)).* = 0; break :spawn_command_line @ptrCast(buf2_u16); }, From 4b35db51923e9723814a5e2ba3c83a5caa068649 Mon Sep 17 00:00:00 2001 From: dave caruso Date: Mon, 25 Mar 2024 11:09:16 -0700 Subject: [PATCH 02/27] update v5 --- src/install/windows-shim/BinLinkingShim.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/install/windows-shim/BinLinkingShim.zig b/src/install/windows-shim/BinLinkingShim.zig index 028ee03fac589..30eec10c93f6c 100644 --- a/src/install/windows-shim/BinLinkingShim.zig +++ b/src/install/windows-shim/BinLinkingShim.zig @@ -30,7 +30,7 @@ shebang: ?Shebang, /// These arbitrary numbers will probably not show up in the other fields. /// This will reveal off-by-one mistakes. pub const VersionFlag = enum(u13) { - pub const current = .v4; + pub const current = .v5; v1 = 5474, /// Fix bug where paths were not joined correctly From 12104a39006d309df7e74a307394535bf9b8c597 Mon Sep 17 00:00:00 2001 From: dave caruso Date: Mon, 25 Mar 2024 11:26:26 -0700 Subject: [PATCH 03/27] a --- src/install/windows-shim/bun_shim_impl.exe | Bin 10752 -> 13312 bytes src/install/windows-shim/bun_shim_impl.zig | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/install/windows-shim/bun_shim_impl.exe b/src/install/windows-shim/bun_shim_impl.exe index ce5a5eb726f47169bad9e73d95544d4464d5c025..57ec9a4a8dfa6bd031d689620162667facbf8063 100755 GIT binary patch delta 5025 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 T;Enb-3se{v*+LQoWjOj@-@UhE delta 2853 zcmbtWe^3{YveGQ0R`dWoxUY|9ipgA#2>)z6*3o~uxDvY z=8hgWac8?T;K?tJ(AKHvBK^}gTt-fXxvTz@2-_gUU0nWUcUq>$JwIfN`5_~}NjZs7fDYZ)Px z24~rs*0Yh2)`5bDj4+p({k9Dj%R$SGqukfC>=@-SiE*0C&#~W!VGYO%DjxiVtF(mP z&mx36#$>8li%KD;TFpU8Yqfj$A-Pl3cD0IHum|9|gH(T2*xd(>6OE)AZzG{Y3adei(R^LwJ11W7yTA+>6MWdmkh`u1!;tX@PU#($p9LaMJCuUNyO z9!c*PPCy{(Zwbf2hgGtIc-4QJ7vZexF+yT|e~pEZXpE0mfxAAOcD=#*U6DBpA8|t9 zah@0T=h+hdPeev~>k+XrSRh8mZ}}r5?j0P19;%+1YV$wJujxk!Lija=R;9xv#P>JC z2i0l(jy6@#20xbclegZD$1%PmS5Cp{ZU4LvF*42ZKYV17bsdYvtS?Jyz0m1aCBY}@ zBT_x&l$$t}9_CQ?KTu5)diXstKG!XT$|bc|D3Me}u&a$isq?(Y8S^+N%;`+5J{PN3 zma~<=!(3=D39lphguVG16t?k0%I4c{^?GFTMpelxSXcCCP!ze3Tr=-k`RF+S|9HR9 z*hjFJko{b^SMb3>uh1FHk<^>?QT20CyWo#*u0Oq&S9Si@uB+4ZO#ew+aIaSwo_fSC|^=8Ms+23PIQck zx?8X^$NfccEIK|ABV$(7->ZInHIGTO?K7e}CZ4%wSGv_$t?stx(273?zs;)E(8m!m z6d9lKIzFZ91xcOts*~oA)7VZ#;n*~)?wH0gnGtpAVGC7f%^;?~rT1>OBwE2oZzBrp zg!(zv6rod8ubVrdB69z}dI?jejG9sHM~Rvb$MKk>I6vcVp*4;!Q0?jD6xHj6R`Yw9 znpZaG;D&+2&@-n2u~EbpqXf^@r&$TPi32)d7PNfG9SMSFEfko!fEEJyRglK_oTnwJK>?h*k&uS9J3mo zwpF!5xERBi_`{9D2K9m|V$Xzc*-kzK1J?;w9Eo?Iq5A#A!S1O0eT?z$397n zNOI4Nq$@(*)T#x2{}C^DO^nQCD3wp@*0rv8aMp;|afQ!SgmSkUKsF(zPSOHG!_+CNeK(UvXOwzL+dwt9Ktohp?fg3;PGw5m6fxGV> z3wR+JVw9bXhN%&%9av4H7Zo4XLd#R}N=@zpK%;&$ZumVD!$VKWsG&UbT}U>0N=+>83mUTLI5UYyJ&Ryp(Ic+vu||xktB*RJ*aF+@!uxw z*dBsVOxUqq4sa_mvoZ-TBtT&j>}TMEg=cU}p1_5g;bcJ;FM4_j-mwJNF2PUy54>r~ zeAyCQv~G!@a0$)_HgZ?jR`0zTkG~9xf{ubZLB9e05%g=&CC~_{2Q&d{0m=B)kV)dF zW3W2^=!zoz8qGh)@c+Pmm1-8rjze~Q<3K@vXfh@JEX8M2JQEu1$xHDhBIKJXyd}l! zQrw^7hf@4-iqG5KBhFUx{|6d8zy5Jc<`24`%g)Bf=qsx*#>zGt-zY8Q)((10b2wu~ zXf+Qdtbmr1@_*%)c^nh diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index 57ffd34ee1396..2c171f6854fda 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -34,7 +34,7 @@ //! Prior Art: //! - https://github.com/ScoopInstaller/Shim/blob/master/src/shim.cs //! -//! The compiled binary is 12800 bytes and is `@embedFile`d into Bun itself. +//! The compiled binary is 13312 bytes and is `@embedFile`d into Bun itself. //! When this file is updated, the new binary should be compiled and BinLinkingShim.VersionFlag.current should be updated. //! //! Questions about this file should be directed at @paperdave. From 442cd23c2586de170ae70de4fff44c1f05bb7129 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 18:27:41 +0000 Subject: [PATCH 04/27] [autofix.ci] apply automated fixes --- src/cli/run_command.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index 782036855755f..9b3ebb92ca1ef 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -1676,7 +1676,7 @@ pub const BunXFastPath = struct { /// If this returns, it implies the fast path cannot be taken fn tryLaunch(ctx_const: Command.Context, path_to_use: [:0]u16, env: *DotEnv.Loader, passthrough: []const []const u8) void { - var ctx = ctx_const; + var ctx = ctx_const; std.debug.assert(bun.isSliceInBufferT(u16, path_to_use, &BunXFastPath.direct_launch_buffer)); var command_line = BunXFastPath.direct_launch_buffer[path_to_use.len..]; From 76e117f815dcc760658071b8c2ac73eaf0e4476a Mon Sep 17 00:00:00 2001 From: dave caruso Date: Mon, 25 Mar 2024 12:36:05 -0700 Subject: [PATCH 05/27] tarball --- .../packages/bunx-bins/bunx-bins-1.0.0.tgz | Bin 0 -> 152891 bytes .../registry/packages/bunx-bins/package.json | 51 ++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 test/cli/install/registry/packages/bunx-bins/bunx-bins-1.0.0.tgz create mode 100644 test/cli/install/registry/packages/bunx-bins/package.json diff --git a/test/cli/install/registry/packages/bunx-bins/bunx-bins-1.0.0.tgz b/test/cli/install/registry/packages/bunx-bins/bunx-bins-1.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..f44a5ae1899688aa02b958bf02f2df6ae70f2c72 GIT binary patch literal 152891 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 Y0Pkvy)cG(9?*R zk+LwxYB4Zy4>nnbTBgT;YW+d@*ACDFvP&>rmaq~;az7r|>wK!YEjR<9J~x6NRkA+y zj%W8NzTS=f!H?GG?!s5tmrDOw9-2%b5|5Q4Lf4gQ2wzv4UIL}*MN!I@2~brnwuhUY zG>Ciu=-byAsLLOJ(IM@=cH6+Qp5fQjKSG;4j~Vhup4L@rik~@eF&m9uL`Fw{SM4TQH5idF_ba zA*jdBw;3Y>H;8AS>L>F}r<9bW9Fh4~lahL(NJ!%4$eW9cu$jK(s7*=2gOsFx0`HF6 z_*c*3%6#=GEZU-Euf)H41g;jRI-qDTJU@j>gv6balD#N`!M9eWH~Za9uDceW z6zd8iW>pCG75KY5q(~7C+eu!@YfXqI44A(#ZLkt?&GOC4K;-XS< zhg2SsoSh(?b@EMU>;=*zT6%g}QbcI!j~SEn;)7E8=;QLFrML)X`>|{s6^%#&I2}@j`0r6BERIO!Lywy$>jXUp+xNs@)TO&9svj(cZp!&bL}MF%+m?6| zdg9>WQ^!O8iLJTcKB?Cw9)Mf>w=gO~4O(eeBUYG4ZRLkIEkX)AT-ng(sN{DaK@)>0 znb$av)tiohsL4C`pJ9e#9Uxmdd{wU{d#xbRV)RSFWjCkd|AgW4jf2#27HCrVju%>? z2mDUef9m-lGbQi*6uR=4srzSW@n@z${OZ{Xa&M3VY-1g+!XO64zA=CSEe1u?;Is`u zE&gfaN5qBdOmCG8G6wbgl0J6vJBrT*7cBkVzl*I+;bM;tVf>Lfb5A05@O$x32*~@R zA$Tial;qyK8%zTV0a48J?hIUB3dgJ?GI>=4I_t zsFfyh`fd$sP;kF)c&G!V9vx&={?L(6l9x#srx4S2hm`y)uf7t+! zJWpQ;L-Zd7(z?YTguf>AtseKE0GQN21vGg4QD}?b(+LpqpUy`@dU`#2!Qsfz&&@aR zG>-Y{3xobofmwQ=zQhYde#FD?`Ll1smJ9n3hFCXRbUzYOhM^vOK7@Z_XcLPU<34rn zdLI_^LKkw@AB3@=3&a;r!a3+4UWXGDz?&hhaHg1l;@fT0v=_?9_dSm4KL8K|M(iKd zVZ&|8@E6Uee*&2O7q=19K?9)PwE6DcG9P1C!Tb3bqX;`n(gCY&?CK!jI%@{9e$f39 zv@QPtcJWpwXdivrc)h^8cjrFM13i$5s5Ej%iEH=*2t=$afudAT|UQ^xt!oFo^Z! zmqU8(WhY$Wi(Yt9keDB!7b)YTA%<#yT^|8FR1puOdJP-$@Z;+{aaN-^s}z#ys?R9L{)zS8>AEpY?p0*ih5%D_ zOVH484uOn)$nWu{u{DiS>w^s8pc0B3Rl@J_r_11L^&D-K#1D|z1~ZuZ>L38{blzPk z2R&VonDeVa4M-|Nvo?^uHvbAz(O_V+sXY7HM968DSg)T#9H*ab8moT>{}$|u!KCW18rQCHiGq+1qH=0MZupM54KEfU2hOu%jMQugWP&O^eYoZPg35K)H4+}yo2k!M*dME0!s%@0kI??f+$Wo%NFV6YKF^z@ z@5+V!Ak~q4K++9py00F>V97}{#^1VA6H zG3Ir{{B+D6qgYNruY(?R9QDs9K*vnpPffYuX&aO|1Z9vV(YxOJQU9z<>z_}M z{)q=DbPUIe?T)KV10-+qzEz@p;!j20G`!`Xl~{ivs=uAoW1z z5kN@Iky-;d)`BWo>r?BhRkd$%+98NQRthB!!M`>rC6|;YWCB3$-PpiH-X&|bzLddZ z&^B%Oc&shZ@81P9b=P{J)E7nk!$2vA*LP42Wz-97owZ!4C*oE~#H|`;kzq4oc4->X zOBw2mM6+-;WVZ2czXMpxR_|VP4+B&_h&m>^LV7X%?Lj0?7NuJm&UlN#U-H|sx}M|E zRj_d)2j$DAU8EfC<0#g5v@yk=QVIZ5pfQAgD#AWgCaqi;X_7i%u$m$m9fyCl2URhk zNO0LL>|%!I^vCi7goH?3 z?O$M3LO>g%+IL%L(d@=4p1-TQ9-cMU%j8>z`XLw8yv@o(f-|C{E;Q(B9}|oyr#_-$ zt;z`Q*wcx~DQfr1#)Fy%T^qd5Q~@wrP#&`8hXhpNwmjm2myIcM?ka#!*{XO1Dgr#p zefdK@POA3YF%!`b?psp!Z;+$Zs`SKQe>N2WT^iCHi`$ktKdA5xNXejpIwpRviWbPx^srqy8vTALN2A}*oU3Dc z7CE|_z5O`_XMVi`a~8jyIVpNGy~`rCx8X0W7a#oVfEtD|*Y|TImBvo~pyVe+=AcIn zEIgo;?820eg#mxpTD8_HL*WLk@Xiv9AmQJ&Hi({F%w(U9lBZ+!Tp5pQqC$k3!?U z_j1|ggRwhV1$|nLYD}7}pfC2;F2bKkY$a3xpZ}ab2Sgd2;H($ysuoZ@M>E!|F<{tVr1`n(3Z! zx{MzDoPM#AWrPkrw&Foa2}yV{A{oPc^E;dtDZL0IH<>3e=v0wbX(`9D?-Y00iid2* zPJ!R)!R#&P+Z3S~W-*}zOt+$HGmd_* zIO&w;ao?m1r=_G?^A}u4$A#7LZi>!zinA3?)Cx4Kc^n%=o;IZgILk;9Xgq)kz!Q}T zTcKxDzLu$|c`^DKEjdf8^H;R?)@jko?4{`H8(fEwL4^f~-j(#NzDE}B9>i7^^TltRf5 zYH4iyv^kBj=HFrp9ZY5Hx|YnmG9ppZk~ObC{+%{5N+bglzIl|uQ43|GixpP<$gV@u8grNMyFnHrklY`7k=5SOS^lw#peA^bIh*P z^2J$7M5*|oSnQRYXE{tq16Z;+t37l;($1et3DiXilWabv%?J6XO6V{LVzAvn1IAK zYL8XEqJh<|fz_>nH9(QmrVWmt0?b4q^#1dD(_FHbdIK~^quJOy|7kj;Necs|ny7#n zzA;Cm8%&%iO$!*MX_2Fp2_bl9bDGXpdtCz#k`T1@ zcWnQ83>T*cg&4i~R}EYJqWWyZUm0H~SdKt6)KyhOb|BSm{fRag@_d?}5@Tsr@`A zRxXg0`!EmD!zE>sF=gRSV(i~MN&OJsK3q}+Q-EhZ7<35q_kqM{1UMo71~I0E=$f|% z<534d()iDMD7!3cQi_T>Ce>JxMe(4IIa&{RLHd7J21Nq?O^Bcgh)SD{I|?rZ{&_cM zAcBrc>IX&UUPp z-kV&D{uf#3^3SX2X~-RfD-RxXNZb)ye#jiOaULmoL@ta#TS|~r60}eAK;2>Z2b?R2 z%|I^$HZH=NV$FPzZpx|*;SrWi!H$KYgR0Cr8NwFZpg{~+4FkbaqB;QI49gre(v62_ z`B50N%(aR69U^xajiC(uZnv246`gHoMQ3M9NuqYedUjOC97-J`%ctmmBYx0 zl^D8pDsfr)kez3q5cpR=!ShhiN8f`nkHWv8g^)H3|5X0fG59$MDlx2B8#e}>ZR0+X zxd_JED6()z$<{JP2#li^xgl9O!5yV&l{RA=V2#r4-6U|z_?Am4hp)Z_<%wMyxg&zicprNh{|=s^zE+VwuE&^RyH2_#=NXP!((z5# za8t#jhk@rY@kq0#iZ7gj(_m*aP>RV&3n(@?;M|857(8D+UMxluR&z=;whPL8l5!dp zCzzvgntE++h6E)6lkzG5>YoAf37ikB;sJ$!5GW$txp7+H-!XX93BMgSt`BCVUEpAb zy)qYP({T&~q2ny%S%ElUGFOQv00`okz>V6B?V@r*QU}UtcE)M`xPve|w!&dqd6%X) zJvqIJV|Ij)`%t`8 z)8QacyzHgmu05~@aAIw)c~3~?BT`|Hz`p>ZOaNvYZI1+gcZi0;gdQnBET6A0krgKU zPzUgN+(o|ms%VbL#<*j?Xb#K9K8G0v3e&rKU7Y;swfFsw>tyAwk~$PbHtN!%;KsN_ z$K{q0_fDU|^!k&a0 z)FJc`uNq3eBSk*O$R~%jvu)C`9q)&=`gu(p|jYcs}#%a{5jfY-_D$#Np(8xNr%4IK0#eaZl zkQGhfIe%UW3ZsEE9Pwd71hC1<&spZ2cBXYueBtKTP>3JX6p=&`0gCB23|2oU9fwMg z($nZOaMOZqWb9?NsDCnL`pn7f;fqSUsHQ52;G8UXYUZv@JgN7N%j*zQ~OF7{2YYGgLP4_a6<*U`xb4r9F1YU_=s=4l_U~Wy4$6t{217!IBli@z! zhU(!s6tjPshP_KGwu=?pJG~g+LcwS^Gz@q7Hk1tqZN_fC`MX)xci%?BS?m#t1CrSz znFBW53qqEFi-XcCfNVwMrx2B`>{!5>aR^9%<(h29m-$ypm?nXY5q z$tBeo2?S>k&=s+0S+}<tz}kw%mnP=V=H+S6mup1I_1eZMDXe`yUoG< z2(R~gKyV~Y3dYJ?CNe`E$Dx{2He)Am@l^6V+X3FptX^Z_VtVfimlAdqL>Iy6#xnkh6J2mMVKLeHKyJ+FA$9iwNqGm@ub_0w${Er8XKjsGlvC_N zY2X_WRP{Rm2s8JeF;LDp-Mg)PMB`BbgAbL6VNJ^K;G&odu+Th`)B4&{9^m$c=>-w9MY^WT-6e*%n=x#OhGF_l@O zP&o(Dv=iP+Tv*I+!z)~r=wK8SOdaST11olG-6X|GZ}t*#z|A#-QLWK(7s7(WSMe`r zM}uk*ls^fLf5qZ^GeM@r@*%mfZ_|^RdMj%v7Zm7Zm?#;E5@mx@R2%nK-@qvlKwVDk z%4h@w@*NN{DpHU(ERx-LFbE<={r#Bw;YyBW5Hw^f0Z6@GW*sE?{~6+46O8i8 z!Z7cAE}Ii#~%3TshP!joTZ!FTJ#bb?3ZABkrs4Z<keW7t@vFqY~vXO@E56K6S{14H-K6wg0t(CgyAqR755=xaC4_fM>w^Ef_y7H#?6{0>~z z`0)M?v_ah(@DHz>^DVe`x((!A?d;3M zfAp8l%l~gVzXe(X4RK#~#te7HcP%AzpaC4e4rT?2%%)3Z^z4l3)6mr|2QV(TacaDo z#1AaH6w1y7c5(^xx6PCVEWr0r97ePb)0N+ZUO54C)ats$0rO}^-<&SNIZ!V}V(Gc8 zdL!u;_HoNG*Z~WiISE5F+B16r0A)5~cOn;e7J?Ya5JOfM2jt19)%p?`e}PxZ608C& zQApZzDJ8k8Q(|#Q;?Vo`I^e%F-ivTNbY9kfexpaX92pCAp83cw#ZoxZJgo#yHNIbl zNhPmFM1`T<>F{m%Eyi+;!Yd4W>JgmB>i6S_1m_@UG4)uCo^x^%(`CDN$s(C=$c5V%Vnb{3E$qZm{Gq^}gYNa8k-pIK^x+B|+w0FTU0FGhB8 zWnvj%jNOc$IngvA@^ntmLg&C@i>vBNOyCiO6|-*$Kw-kIlBIxXi5zo~aEmPx=I`ar z>YtVwLkR)EsDDuqldyjmKv&iNIgJ=oe_6stYn}Ra0fqyG7eQo_iKUqP;49dxpi^Cl zqLQ<3af3Ps1BgZiwQm7*wP9J~FdimYOsX-G=@Eq#^=G<6`27WaD!?RFX=DeO^?ym^ zLgrv%(`4`F@_Rs878^tGB?nObQsQ>(p^ef?sGvqW-3zgcR+m_VlqiY;ZZm`^I!TBC zfzg>dDw!kuhbk~X2QG&)BuIL5(9DDrQJGzmMSildm*N@0aDq4tE$2vBXmsO%tSsLJ z4Qa83-{V2)RE^DIy-q=?!3vzQf$I|A!`GTrTRR`h)d--VX$7f-glJJg!wbRETqraQ z@vtfv`>L)@1_alw*9p!c&Q}$OwYnF_F}WpeHHBqkkJT7RpuFRi zSs0xyExCS#784kOMOVLRJ_bPV$7CY=rw*TQrx1$>DpLBQK( z4W9WF`Xt@2JXmOb6{0z`uW<%KT}4b5(|Ci_fW@`V!sKlHfj(;KE-1%EiY$5SH!Z+Z z#{R-|BMlV{aU3jbLhSO%?BM8lX>NK&A-i(4#U+6c^T+ye1&Bsd3-AZ=4f+6<*`o1vuxX>2EfhQyBSl2b<= zXw!lAGGC|DnQuBXd^eBsB?M^Ek>x~^X^@nX_|ZJ<@UWr+vE5jHB-UO3wT~Wl63WbP z=FV+P8|z4CKi6J+?X}lld;Md{uTy5BPy|?^Q1cavxO$;^Y$+5lhmk@NgG?-;o;6yk z4t_188v95c=$C2vrur?_qQIKkq4ST=Il7i`&-eHXrYc-*nfQY8p3jo96%z6QBqIv8 zO^S!H`M*CNMw+*)uOc4CU;Wp_!+<38h9sp^l3%wDb1$vct>=J8aYkG-@?@b-nRheNG_NVCrkc(POITzGjy31Y>Ai?S9 zQ0EWPsLtYVforjxT0^@kZ)mxGr=N5P^W;pPg2zi%QN5R}U8eY|d(i+I#Z`Hu2sBr! zbvD;YDHqhuRd(1J7b}{<#iD9CqPl+u;Ei}(SBY_D`6vzqopFZvqMo}9)7wj3AH8I4 zneQ{b-m&*+6iL4La~37}M*-T1Y2I!gMGip_VRG`Mp!SgR!$cTePtl3&A*~wF{HF{s2zZg$4f&Lcq16c0A?wUg^0IP-JS&jG(gs3G=|YBmFAD% zMicUIo(pkgy(1fW@D$&ZHGo_h^RK&n^6*)t7wh*Xn{|_^Y2}w#Nh=J7o&Fm`Pk0W5h4{W2%rUP?^1k?wWyw^;4Cvy(q!^|!VnJ~RXY3JI-_FL ziW&nmfdarIHhCiE>3f;sUkKryJK@OUu*;9=vnNP|QuDLHcwGa|%QE z4PwpMNg6!(+yI8`4-DM}M~?Nu5k~<-G#3fMx-hdJBf&~)&bk>+KQHM`fxs(b5I>YR zh%^q6u0$J7v}<8T)JW_&8`JF3U5``*?(xmFA@E{BIf*Mo^YimocxNi2*-e3R!|tXm z@u;z)%2%`Pqc(^ZLeMT$vdAqEwA9G8AA+EL#S*laP7<_S(vC^(B4Ml9{W~71h>CWN zr{|PoGBn6wB-r7H3Jkur174dzGefG*kYL$rt&4 zu=y3i86`yT#m=ynqo>!O*5=R>Z6^Mfk4dOuI~FnwSgr$DMw`YTsV3&QQQ7$j`k+*V zq0>Q~z{y1dFj>DyAy@|~3W@;fU==TUeWN)CY!k{%eAWtCbO!)m65_;AkX&&%-jcEa z5gy<;l^W>_nuV>GVWNDhaF85OKfeA;!fCP6lFWIFqTB7;V$$-Y?)Rh5ig(n%#<`;s z!xG4FmW*qg#kBm4+(>e4-Ar1SBj6u@8}FM3Qes<^SKnP1tj|fj(M$EcAZi;qzNX~- zwdE?wuD2#laBI2swD{M5Nx#sVOPzYEDc32>=To6UUUS`!yr4qCz{qL8>eGv`v~u4* zwBsfSobeRxyr)2Zcmp0M1A~~f#?mZ71k5C_uzqMu=K_RS>ldvq>pyp%MGV`r-W=Ia zt@${0Vmf2}S6Nr7hBJ%er(LuvsshGK%XDV!)S7GZR$}ky{B<9}!iNBtu8J@g zzP`FtPW}n)gI7UXFE9~8v3{WV(C|CsVh)&?{!?nLvEtB zmRZBXROZIDpCX=?xEE7s-MFSCf9V|M%C6jX1(kvs^w4?e{0$=z>j#-5ETKLinJ3AA zU`o+M|EA>)J?TV~7lF^xL^of_qxy({&27q#M|Lb^kX)Yd85yeD1JGm(%1PTAj_JNx zm%>p1z;F0D0EHGCs3{`3U}g6EZd!SkQnn!NVx6*>r?b$W2jwu`OTxWBP5 zXIg-;;$>(X->-hE>6NUcvc{MP_ffbU6hB7+~&xzgPnZuo>X`rfg{>#k8-?NIoY9k)?aoqn__vqv#00cbjz zp7JZ7DH7|+r_NO}u03ZwFPHZOcHLG%OAvZvClNilNN%ra+}GUMVGs_0Vl39)mK_KG z)N!EZOTrF1dMn6&)6UzRP~?Hd<)^s=J4SX55DFb_$tM3m(zV8gYeRceA(bT@H8d(n zfjv0dJ0;6hdKgjm?Y)(?LFn^^tO)WRdv8vgS7?tNCq)oKJs>C!=8#|kWcCeN2lQ5| zJbIr?>Ra>mIo>$OvsC#~U-gS&w4|P9xAeNKnrc~ykDjQW#=*snV>j1by|c0+21U=WW=}$N zr|1 zbujR)RH$hHt9WuL+WN&dnNkdAE1WCOzF7assm(2A%CbQ^L*Dsy zSL~ceB=o`f{zYJYK(@RiWf+lc7lxXMn&La<+GOjE%b4o8P)Iw_I~Z zH7V?oOv`^Q&zg&_@dLNV2z9-S^S}oM#~$gVmhiUB?d;*RYzw{JFtg?%G%nYiu$y+t zfPlpzc8zbV1Tmg7QF-j0KoTq{Uxilm+)&=LD6=@bSXmnBGx&$a~Xnvjw)Eh7RXLud#k3|Up%BtX4aBF z#H@3NT$7l!Q{iMaIGludQ_4*8>mi&hp zHIHAZO>4y%t2fI!>*5d(X+MKc zhX$j#hnu$y^j2aGpq0Q{26FL_K9{4&1A6NUqR1SEs{k#cy3sv}7PKtjJlH>@(X8ef z$MCOM(`iRSdZc26X@oZM1iW$=O~457DWgq;JOLjC2@-%%Mdy2}ch@tHHYfr*5+S;) zD-IAV8bd}ZSksa66B(+94=am$R3<}5inJp$HIBO(x_y5J$Cc;p44${ik5OGTQ{7v- z(*b!;Ja#hJS1}k@c6^UyFU{1D**jB;*rQ^mp5q>v&mUj5_~XKy0cr$KJbHzHI+Ft| z3q0B^IXYlpY8)bRjL%y)f7d)$MR$fAnC4%5e~$Po=de-{{&#W&@c~M=N$CK(uA=J` z*{;tcA;n@L+i%2^Ek-BNSLz{Ld0TmB^1-KrUKYL3bof@?UCPeY+>Hpk+JHU#c5>UX z_D1v8JizE$8rMN~ym3YoTWun)8qMEgi&E9QFFA);u8N~(Cv))a@dhMBFxFxx`QGn|#nfhxokniQAjUPfCbQEIJb`FM zmcmmP<>LF>vi^re;Y;<_FBGw)10D=+FkQk|I=fVJl*k;Tx{h>e&ambTX^ybAAO!9j z;P;7z)s6eA#UV8-X0%(WmUj=!?m=U)ad1=PSalukA>%-8i6s@%e_+4uL1+EJz`vvh zh&HrjL*J!-?xTJlNIuLn&`6y-0UJ|`F$2c|T^}Y&(&W3#ca;ra{lVIBst0S2$KFAO zRuAvTXmtV}NAtE3*EcPV61vq#!Cf&U zTDkZZ(wa%U24IAV<+Nti8B5+O*36wVp@^DFMGOi(yz;1>jeVq!Ml<4=m1a|QM$~iw zNY#Bi1|tXyFhvE4&>|-Ek12Q$^&dfdOe4UGCMg=qj+v~@RHed}rg5jWfU{N{#tDB# zz-=5P#$4=P)P?FB$KFqXJQgW+9wR|IH%HIL7f zXyyh@+d23X^&igBhm?t3^FW`kb6X%~DlNiXdqKjWJxEMK!$hqMFSPNd1XTu_munr?qM}`68Dr$<({KY3+}o8 zLfrH5_vIdL&(%YMdrIDqduE_5S?;;X;+~R!C--Fa&j*;Mt7+6?39yhwMQBa`hxmus z$34V8M6uXO=AXuJDR$%GVNxZrUFkxxo)n$PCgOj?-Fa z(pTL#%g$ni)MMyJz=5ZoViaOOC;BwdG$;E0{tt=1d+(dvqZ{*jWa0=}UgC!{P2(xj zaz-w$TYz1c3BSpR#m$@09TMr>AyWBN-!1n1esu}8Zyzt=Yno-1WUFQ(%(P_wVW5ymj+- z&dcka(BU$Jg<}%#RK#r!G^ubjSW1QI77{lux)gPjQstX#XCa(7SOFd^*5N|=6RMQ@ zFk$s!o)kKFK27e!{TJrBZ`IvNdp@PYZ|(f!%maJTideAr7qAO!c44i{^E`w5kt?n{ z!+gswJFzarpqGFnzW6=5n)tS@xX$WK%2K1mt zt?`RU_;j0cCmFAT=0YdKjUbTN_+Fn0O%^ZL56z6*71eg=X}sAHyT zkIBt%*o1Z!I?^dR^~(rRFUIPn5o2wZ)hxbkgjHsM)T|*e>rR~Il5R`ArUgX|q5B|7 zueRhP%n(c^QnETpo(vFA4H0p`?u|o>T}BTZ#IVs>bX4qeen#chlA;R9DpXWuxGk%q z3jH(+{Zx_nSXUOKG>|nr264;tJd0f5TzU0HYZ3rXLO_o8-xrtngcvly3Zoy9|7QRL zr8Gz7mcvw(nV4xrgwxLg+1qYoCmwmtTHuZXnPX4bD^Bs^t6Bnb^FNBn0)ChL3Nif3 z@{4pIA~5ZVBbuvUF%vTG(HB_(%$FD1o++>?WidrEUw~sUqm#PILKZZD`RGRfDi;mx zMY^%9yf_KNu1W=7g#8TL8L|cKc{V7srVyj3@ff@hBul;c+X5!ot_Ql)d;M}Ar}7_xO{aUm#?R8=;f=a z4-3KD=)=N4hCV!y*9Sy8pRh>!7l;sW>>eBXLG)xrUx zi1eYJ>-e#{>)ozM&&h^4kI6^6kA{DHir4w&Gz8R$cZhw|N$w9E1?td|PFL$P%#~&3 z)w~!O2b$gz;eHNUj&T6W5{R%LvFLSSqVnG$LQDc43%WC+JCFW0 ztlAIp9sBhpANj5W>&B#)4nsF~$xHU(2dJKd(Ej|@q!^6||9E1mL*BPHDUK1UqT%mg zZj4#>zF+oO_P&Go0p_hPXi=m*QuaX+&Yk98hxaYYJ}4TusT{Y(9T9*SKYCyCF9Drp zzPtEt-&OakQd~)gD9uJ9<00K~0R8kHv#sw@jWN|eSif2|21T&Vs~*E+CjBPT;G?-> z*B5#02X!M}Uwx$W2+p_HU!KFS7n$hCM^CHbY7(4YHeJQqn7Y59oI^L`5(IGlK|_Hj|f9E9h&(OyXRF5pH8`;c zN6&TG|1QLKxfEd$p*r*rP|7EXQfk||`qAX@BDZ2*J$@^0Pzc`8eTCotZh;L(Ioit4 zdJ_JOm(uc!%YQQw@_TGWVJ#(i@j<|ePzlLvNJ|RcN?A9_Pap{4i@+#qA9yc}vKPzE z0O&28J$@%Zf&StS%4(SGz-lJu6%G~LyjY5{7Dk)>@Tk!_{yZT*zUVimSdw(DY4Bk+!9@8CDfe~XfT&d)2_+Xt6-@cZr+zh>Y>O1BN~2A59_Vbb=e zY+qP<@=wyf@WJMTcgvLdFkut(fw3NFK73=#h33O=&NCnU`SanPE$=fQuGk{x!=+o! zoe$Hti1{$_L~cF|KOyGB;1jv|aPo=woe!5EdLlO;nA69Wze?|BzsSF@2w2=70r&HK z3DYm(sl5NEZeKg~yFX+8AKE;H|2r-Ik6QfSO$qj%m;e74rPw=#|9_m}e_#eC< zUryz&%t-gypW1wWss85?Z_4)WpB{f}e1X2yJ65vM9t=E`^3%@Z8q!l+;`L>?2uVMM za9_r+40pjfGFanG`CWFuL7HZWiZViGqS!koZ|b_pX7 zt{UT#bKujdFt#W$++g+Fqh@b0z2&mRd8AV09b3Hd3Y>t4oc`>6i%`a)oeDmw;Pf|% zleA8p_*y$AR6}O z_xQ^QzSQ0B3@82-<{sooOhdfMk!vm-}D#}k55T!-o6=f z%RGcNc25%#`YnCEwlCxfhUJ-3lG1}w6#f+L>KgT8SzG|jx%T+}*Q?zuX;XTbeIz!(47W#_z z)B9QUepV4ZQ2Sk5sFnOU4Ug0KaXKES^J4)X3;3}RkA?hr5gsq%#~FB>p?b|CjkY;I zO*}5;1_8V9^*IvW?bB`kyM4>1`JKa>(V?Y!9vK!Om_GS3m7I zgyH-S(=Kuq)1&=Nals`)lgN89b>g^M^;*O4JXHa?`FU_pjw$M^MEcw1-79CNHJ_Fy z>fXL(Wl@^Opdmr*HKVR1u?dn|-W|%z*zju-e0aU)Ya~maWTMdv{|E?|=C2cYoZ!c^ zcs$FGXYhE2AII@H&W~ew9OK7PJdW}s7dAqqZurTU?w=H*I)A>=k~7eM@%W?}mgq@O zn$Pz#im?T7z}s;hAgwB{vxqnvvKH;XqE-ZetpLD*1BETLq+nX*bURFM{wl`I@qN6>z z;shvR^w$3Ly`mKXT1bmloUHw6%C@qzy=QrQ?N84ZeY^*G=3G_YK0e1)UL?1=8S@>; zzn{j_z}!IXz}flBW}mJru++q1N*{K z`{)X@JrVVTOe+cxtwEPyGio0xmfA<=WWqUS@lQYhIn=!m*0T;^@+!Zm%mtv%-3s>@ z#2)>Xn$d;ecpQ8MhNMF?@p^F`8`bXvC`)8y^ly1YF_ z{|>v2aUdcY#}G7Km(p(I_qy~pkau+Hpk|~2kE2UNfJO4y$5rW=-tt=g8rr+o?@j8Og`g+IbnD>>`_H-v{r*eTn}c>C29(^!k?E zYt`O{;@UWV0W}ivH=6I3O;*jDzJv3J536N|HTW~yN0N6^`3>vTmUR6F)qX0mnkdg_ zEiOlZR2BJ&FTtER5rWh4K{zsXxSc&vOZIzO!ixOEHjh1k3w8TF_Jhv2R@EUt9iZh_ zmjdEyx?0lEbw4!BmtZb@V_OzrMn%l=V7XH&C1-4`_eWg_&VXN_Q91p%P zNVMuy9jm(vK0Jffjr$s^<=yWFYr?5GN1pb+xykXaT6IkJet1G)*^E~=?r#Xzn5iC0 znfAWD$uW`Mm#|GtmY1Z@4-VP|`!&1~ObtzIe0;jo+4#hlCtdJJzmLiIMNMjJQPF;$! zuDVn>I3&J&qJ8wsrZ_o#w7m_-hY?$_@A1ptz#l{`_vd^ce!qhDZ4dWhzxGD(#N${0 z8s0M*kB9CRIM6)KFKY)HY-?UGuKmU1MZBMRI9&S=k5^n4&Zfjh=hXsK@$1^1^%X0_ zwSA8lRlZ88iYOHo9WLObQ%ZOFta4lJE_y5Kp{CRhthEU%08(va-y#yT{CXAbE2iO) zRc>_@@O7(@je95dnxX6=tlVlZ0C4%^^Lu93JItB@Bx7jtCcG+&qb6c%#}pi6I3p@ zDz^!wuW=g~#X4Rk%2`%@x!EJ}J!J6(cr@;2zuYo?8YuGl`8`*E`L98duN5^EUPDjq z-~Iuv4Nq@y*P4$Pktj4D4R#8CnS7K`Uk-Pw;}?7{w``*-c7ldx=Ac^8kh=$KEd zXfYQe|CrIRcb<=6BnkM`y$b}(=H+p{`k%j9fV{$Hj4b)iBo&| zPO)7j-iZkpATf~Q#6FzkpgVC;AGRf46+!wCqepoOfmKCJ7(rgQ>^dkK;IhY+>~C$E zD&q9JpV>6aTK*hsF$bK7EdMbU5>$EWAyDPQ%p`m(m{jefs4L@40MlS+=4IG&GGNk) z8Z37MEYJmcJ`H^<`q~Fq^wXywwhzqPHwy6godU}Rk7qI^u6#p?7J7OIe^5Xr6a1aL z^14^P$=2|(;=kDa4dIaYMy4dI49>{~UFIio^Cqn6`RPb%9EYS}Qwtt0YL!+@)_?CK z&g-4ZL_ED>C1oOY!>1vGT{r=i z-ID)y->f^mqaWUQLvn-L=(eV|bvVA}FO;SZU_D{}wZR`bZBp7zpKS?m{Jhmhvv;P; z9!_`xnUNBZOtb(U12P7OuWdTOxZI<`eGGdq?-^{G5HlB!T&u7y!dq9|iF=TjYe&R8 zCa+s*#L$=FE(Bbu`4&eY!rjv_*){uiai4JN7!wT!qJr4juS0!S6aj* z!^%x!ifQ9wRo}Y*iuN>(qvD1uP@vqhmaTrl!lQpB{Iv0F{XuGEJudrE!x6yl8qjYQ zuEs`{#=wcT%c@9yp}RR;KZDYs<|+4WzGA9hLHrEb z-r%_^M5?`F6i>pxW&KrewZki0ho5olG^;}Fi_P)Hx^WOda`N_`VBlxN2X(1OmEc06 z(pCo^D)RP$V4!U{rb-j4bVw)d5YY*KHhc=;KegWB;|Lr!=V&nSi{Wni$s?sm`5GPs z+KWdT)#se3mcQSwk`^NGKI@r7WsGTahAmh-%{i<(59#({YB>6SX|C^@Gost0^##rG zZ116twPoWQb7;i1}IT2c{^F1-mh>P_`G@-P0pUrI?#_2+#rhWyHX zZ}==~yt@5s1?+9jbworRZQSaJXmtmYMcc=&@VEEV_UY8VaBuqvZJ&}+j?TKGa1)il zdz}?+pyY~4_Ghf@Z7<9#f^^t;0DC8h#Dl@w^{IUjqi&-M0#O7b;=dwrg75o?Bt#+# zLGjjnUh%ykv0W@qJ0twE#Oy6nMD!w;6u^V6QSmLivn z!#7K98iUz}MBz7F#xas*0IEpCmuJll5QMgB2*QWkAO`~??WXFM_(s)gq}ewQ0ee^D zCP>o>;hHec*=Lg!q};Ta?ZfSlG!wbb-O^M4Z3I5rgrfpTBLRTopv}fe$-0vh5#FCz zCRkyNC4q#U3T_sBIu%pw9WJAb0WuoB-9p~+PKDzzHwt-2sZ6xnwB#M?mT8~TLJMBu zXl(%m9mMcDP_d;)ZhkmJPLQZ>0iqTRSi)`JBJW#^gEd+zYza9^A$wb~QE@@OdD|9| zSX)eDE!an54zlfGA=?mps{UFcw_L(dnYe)M?Uj^Rzmn=w%3@O7C561Bw0AYvooG7; z&#Y4b**{ylg>=Q#sWFF8tN@ zk%}Su4AAE&{WIxbhiV+?fAu1M-%r{743Ykl_~CdKGyPx151pK1q~bvTk1n#X>DN1u zt+&7Er%aAk_y=Sb%hp5fN7a` zKZR0vGH|j$#ANdMC4okWPpk}OJ)W`w%{fleUAK3mqL9Qug!?^ZgC65`;FOj9R&$>5 z*x%HCnUUJn^0szY(OJ1U#pg(AT)SnF&KSg!NQDiyUY5}9VUN9!zKrN)CxO0)siE7) z7!IB>G4~6wcmapHO~Ba$BL43sYlNS)dhw)1gJ-NI{p?gxX@zIP_Dyv{a8~ zjN>8%oRT~X+L%EFJ}OVqs77O|8Pa-;8uG% z1Bsopo@+*k2#Q$MG{?Ln5(0`Y7+q7S+m9y~XrvDoflKTo$(b2I?er!D!`jMtwdk%G z1WSIO6zv+x%I_|l)f7t6zx6hj(5~`QG@z6Z8MLwkYFV4+osa+`zF;g{_0bDe-CRB& zRg=&bP1wq?rR`^mZA`^#(H?7A!Vo+#&6-YP>8i*qW)+#`ts=AFRb-aH3b82Wph7#( z2NgPHJ?*zyO9%5y*55G0IeP1J{DzWjwa{?|vp_2Od4I59Gv8b2G4^TBeI6sInZH}8 zi0z+Nc4*f^3wIHLdpi;RuT$|o4Ioh!hUWK5NqJ*HQ6K>;zHQ}rmHDlY!%dtN=ypXw zL@(Bj4dwH7qq3Y2gx-=h^MtH6y@s=SHjOm$fj&IuPnIf1r*6=mcbJ32^wW37$0Sur zHAXdifc7j0JO)YV6fiP%d3%KZjgf9h8II6LKO&0A+xL^))de=@>$r|rihG^3m-5Kl z+v(pSG_FEtgi+vvo~7T80_qdcg3=*H{{B8^+#~ImzmIE?sx+=Jz~@2D7{r}OUFyJx zGp$M{ZGrZqg^V?C_LVyQntfQG{#6_^9iUvA^gET(dZc5T(WA}zjd~f?jKWhuGBr<> zdZd#cW7IRJi-9$PeM+UNfVDS!OLcpjYES7>uR3Qx@H<<9-0D3{#f__TVj}b;eVy(q zFIMFj-(Kk3HVu%L^5*}^=Z-X)Lms08!G$$5N&os6d!)GPyJfxRn|0Scq%^CoHH( z4y^f-wbf%Ek8hS|P$3qvf5*ZE=2SY6t9auRnL`88dh*sZ)!wce&rOC~PxN2|7x?*U zze?JsW&}J7B5OX9nYEZkdU>^G=bO2fKS|=}toB4bfL`uzxR+WZH{&;t{XiDgQa9?$ zmvj212`C2wMpAJcQoIwJ*4~SD{M-`B8Bxh?VpPyOxB@>_pi$W^_p+{YQf^+7tK@-9 zB@c2X4SaqRH;IU`=m|80!?$ z=*C+f*}eZB-z|1}H53f=rj9AbVcnio_{zHbw-XU%_!t6Z^bQBA5i=ri^!s{Azq7tFl;n`+-Edg@%5(0Jp2Mjp|bm|8v&t@DcH)}QzS4w_CeB-bUw+= z1zOQ*g<23&y)gza^*Bu<#I7`?yZ|fa7G8C4 zfi2nRG5R$`4vMn~Ly#%C`50@XafF>~_#Dn#UdJsSUH)a8yqh*#OQMZ|0S+~uNWHGb z-T_tG;JFm|Me2y#`3_Am>L!92%Ih&R6->vl$qB%;BRZ{}yE&`|nBu$Nqbn6bmQg2{T%+vKQCZUGkocj`=(%>uR&W z%%Rbj^5i@!?x<vTkF&6B{DU`I^f(ELKjHl(MEFMh3Qz%iG$ji;{Bl z92Du?r#ts6O()oj>3oCL$0J?9Gavqyun)Qts_Yt2GA9E^G<#a8`znn+v{tw5>Rm-r zh&5T+)#bMTrsp}K-x|-d!n(?3{3C0y^gF(H1*k{ZJ#mAved>x>74-Cjl}=?qj$Jeh z^Dx@G!rfg*y1Ifuwa;Y7zN+ihN!gF*XYUu;k7u(dKYFBxx`=;W$)Y3OM>_dmXJQ0M z>5;Bi>0bx^LoHF8H6TKFd7gg|Y+$qM4>9oaF-t{p9w2(Uj6-68JO+uRG{z0d>p$i( z&S=JI&H1Xw*-ksy`pcVpmdQ9l<&J(E^4vOIWBmIpFf9%N8v%3_T+ zoUV7p|9D!^WT2hIG}8L9>J^<&>(BiMd1}d05We*bMef$s zMI_=qt;Hl*jc(l-P@P@Y(XMgII%l=+g1US^hKjBN3b`x^Wcii6#vj6Qm?# zebFV-s7d!7hJuVVRF*1D$XoWXTgbamNHt&OTA>Td-}_&acQi!y2VO*1?6K@nCOSaV zUuDu{#Dc;I@ybgAoBe>cAYJ$2tn{y5g%}{3J&b5hxCr}%P{72cEWPTG$gM3nR`=z+ zOfFiJ=W76s&)k27qbJ*s(b~WHEa0o-^4}cF0&fZX?_&8otr>>RvM)n_%WM=n0N)(v zu*Z4KV^1|)+f{g%r+}7?gK{(6PhEBd(*>YC3J|w)53@pl2%bTid~yq}baWNUocA@k z`4{NTvif1Hv3lT2Lfd^Af_zBvOYg#~IBYN0`$?Ig)zp2UYtaQu>VUoO*}w zepLZQe%jQe0Vr~CD)F9>s5w;uU3MS!NFB<~#jN|;Y1_EtbVn+HU4-m91S~KF;S)cNGIJRB*J_Alv?koJ^T^GQ+6R#i3mWQ~x zlkUrn+*kNu_ATu3r1D-rN4-)h5`YQ4lK~T^wr6U2A0R)iglxZ=>AI<=h~X_&BMV!Y z__wCX{@mkJzTdU^gZg*JHlN48+k*9b@o&G5WhEqVbc$7{h51(G3^7Ky({%d1y|VnX z2<^1<^9w9KPE_Qyke~{jk-aF-+eaB~U5JIF2xHz~qQb#GbpK~KUU+Rep-K9&47 z)a92Vu`!qLPKkJ@J94zci182|Kho)L@vkrBSR_XW&Iymg{)T?rUK}4!z4aw7=`)m! z{DjXYobukA{awy0WhI%>{E@yye8p}LU}$v_Pc(ATZP50^3vSE zuQF!vPv!YPU6hLjknf)Zu6Ph@3)Rp%CwIE5Wdj&c^^+lgFWEblF*0z!msxPX7&M)< zXd?#3_)o(5CC2FHuemx@do0Tsyl5}g_U{+=U;*_@i+OdPWw-xho!Gyxq#s*px3pui zX2gTFBc}txmQOs=M?BI6E52`uq^abXsz3EMLGZ?Wu`H=EF5QY~9Yo0mX zW1S_T)m10fmH>(_Z8AIpV0OVSZYheGjUIa}c}+u^;_Z_Vl!sDyq!{r_8}o}>;vm}| zdzXjUw5*$`>jzFE42QZQi(Q{$kCLWyM-kdDf?+`ug(G&7IownB8enwGx=F#+?S3tF z%(LLox%?eFm%kCg)TgS#L6 z;#6-basT9;m9hV#?hAx_`qREI-Sej>zs^6tYy1B!$M>B-z43i=ioVoX1^apZ5^4+U z-!+XJ5UZNxJrSy5z$NdV31`xe>%O@~l;+7hw#=G#yS!VUCTVFu(9qu1q)^R1MDccp zt<()brqBL-j{hnHUDlVZ%H8)w4Kgl$;!9Fp*s>nGE{hG>~d!xHKUVn{y%iNoE-@OuT=j#{f#vxBtU`=mQ=Gq%N zNZKc-!~8BqsF}sKES`vUA5k>&iYMjW1v8ud^|QAWTw*ouousTeLThKL(ttDGzcMiS zLNLvToMA)6PJ*MO$G0?1%c^FWy3_QO#q_dxCYn!i<6XYWIUe5^B)#hBnr~@R+*8%P z=IeS@L^Hz5FDiBUj*u$fK^s(D0w#{C1PE!c@9$4X6$_u7?}y3FSkG{KtP4)d&9EG0 z3@?qi5;k3P0>gf~@tS5Iaybq+T;nmildfFkCr?#u?N>53sv=wBU2M#RgI{{_x+@i9 z%-N$1cMH4@I9j)*4ziV}TQBpg_CZfeSl+T3rgn+A^2NSIviC6B{5l1ivxtY)Yss`&W6Jh+k{t-m&i@O|V@~Wm$zNt3%oSSN)8>4F>!H`^1a!gqNGHz`UH`;Ud9$0 z_$)2IJ)2G^Ux!{7Rm;rez8wAw?oB+}9=36C3%1$v!4xiT_6&Cd9294)W$6n*e&pP5U;He$|lt%TS|vrMx?a2po_!^b z7<$?AA$T971#o%ohD$%O=TNY=EEN|9M!o_tlo*^yr&qZge!-t_STUv%(z3*6TQ{Gx z3zROee}Z9a!K|}!8Ka0uh5HZ<#GQYsyfA$x-?IqTE=u{m$7i_graiLCJ5soceSZBM z5RSeVxNy`YMTMC}kTG+?;eRMj|BDD)hucj}qZk<=3eF|2WQ6%p24UWB56~z?tn9eD z0Hcbyq{MsL+28pe!UQRdGI$*f+pLRV4HsFXmto;mVBw#Gh2NsbhF+!2pI8Z_D9mt< zC?fomuqp%W>0%{k9fbYO5p_nKW?9TkluUY)vA0R$*20}d>h;s$d$}M&8i4AISsCdUq)?MW`x}C!;s2%JX4iLClwfw_7`O$n+|-i$K=@7YF;Csj$lt zncS(C>mjoFnv0cMID?A|FOKfS#q{3gh>7_SVBI-=9wno<3WY??E0r?2uTHoIo>R?=Ii z-{ZS#NHGp*_8!GCAvfdvAFfdH6L0}_8!5%NF%1``g!3Kv8r3wVdbL=B!JLADrqsA@ ze@z+QU+p#q;8di`?l;}eH0=O1`pfJoTPweIpE#ndbJc4>ROv`F7yn$F*UQDYu$LHrT z-o=ULX<3D)8mC1)^6s#_q@&Rs0E}^uVsrrSXOJx^2ZOagOLfCnpog|I^6oBPS~PLI zb=1+7p>fNz*46I;0BYf3f^oE#r0DyA!KYE9pjIH9nxIl^PB3!+Gxz7N?trsxn{j)#1jU4M{(F-;}i^{o&}vE zVzO#KBsYJbeMW#@e^Ub=tVI~?i=;y}>C!HEHh9h72Ln4(KoG$gbpr!pIEr(_0L(7} zKg0vfFuejii!=Dhr9vnE{pvYvso zWlN+)EU)i9%O}xs-PotGI``JC+TN^7qS-%P+uz2>&V4grvC{2_Jb*t9>t#oYWeOGf z2PQUnc5zM_qoOQ7GLPbUTWA-E(J3z=lYi>9|Mm$Q>y)N!VSvZ71qiQ zl3EGIE=5NwxcJiKPN0wUT=$}wB_XY~NV#b#ZT)AJ!$AceBuC9jfI{cDC+vIU&(WT+ z`mH}bdjjunb4yk6E5SbMOLj-)SEU%ht*XpAr)mV0o!60gxXwyFEf--K>sH89Wv;!^ z3b71y`MiBuRb=f)#o_36H1ZNFBBZq@;0qzQw6G$Mn9Ccf_(~CX`H})sryt%sFkJ*) zuH>N0_cN|3d)m*c_O7f$={@wtj5Yrt`{Igm(2gMpzGHe0){gM%u3)}fDHN84E1 zoUgS)Fwe>lz6`oej=nsVJ}*qB&;A^Jt|g6AW$}5nP&`Wzr;4(yt!xUwE6|7~et8a6 zZWL6x8v52^R?qyKI4}xpt<{PsLT>S9NwfhZ+6yhEX>22C^pNsG6UQtQ9wwFRzOXZo zMiUXVICQ5^w}W{Ea$yVmb;J;!TIKlE)LOIx&|***ZN+N}h&FSe4cUqt>_FX-q=*3m zm9h$Iw{W1A<_QNYXvXM9K3<duhoYt+YX*6eg$2M`)9ERsX>o& z25rn!6{@QyX`9@ma>zhXvN-TwJ}f9*<&u>XVbKK=u4&!F-C!N zShsfr(5cHpoIePk9A2*vx{bDAKyX5U^cas64%YmXG&MLT@4Urh?*KT0_JVaAu81;r ztFrr0FmUQLG(zqvm9E=kGzHcas%g^kvuZDq%xoy)sRc~8+!gn-5J^_v&t-8+Cy(do zrh@XF*^2}NuUMlvw;Yl-3s*1uNe+4>Q?Clw-MI5(!bjs{e6~a!uaSE4q5z$PNRR0Y z!gW=OZwrg38(7%|IC)O_&=;5(K}^SwO%hVr?s=Rs7i|Dp*lG5d+;Y+yL6>AEj#HPNOZ+i;$wU_ut3^X7XffS`4pWwEs<~zBrmr*Nee#-XfaH1Ov(u8X#08RS0-LQ zqT?GO3|jW+d2fE~{Q20a7DH+d0EC-ep7@}a)OU^aF4ag80eDZf;I&l>4r#wZd&h;D zi_VfwF$Su4JF)la(W=Iw-o!~hxW##AK;BkR?v@x+kII>RJ{#7hc;8o zx1VXC{n(g&3iWNHx}+# zj2pdtu0M*S{{1>Pow~(m{LrjZT{znJEZDc^s}P>KHH-wUvcrksfct5wUVA0@2FK*q zv3@DUQQu-JB3af@!c2p=suaa#Jn&3u?i@Y;jQl;Ek&`kk=xQIej>(sPF>hNX?@@~M zR%zGb40(eAn)EK8k#2*#^i$Hy>GUdhRjf`ZZoQQ>EiTTf4pzuN8dE5Lq@Ar*G-zIl zAF&NO4AkH&v#ezHUz}NfMm9moUrSqJ=m4cTB{5m6OJPM6)^IP5Vn_$PyJ^(?v=srh z#xO~*gAf`>1u(F2+O5;t2IWqiFVSSV*wXB%5UkRq_L6Fc5({Wk^{*`1E#D1ZmUDCH zg7lF6Opk$AEPC9m?7EpmdKO96?43!Zxf#0~KSuGd?6g(D+WS#Bo@exHmqn9u#Ujd; zM3kFhxZlXWgp(4B<#iOx>$<)4u#*_P?k}9-Nr`-0=U|O)c!st~tT0b{yK^D*o{TbY zt1ua~nXz_v-7LJGvm1q*d7}_mdnvDqlZugB{s)w6Yk5rm_|-p5uT6qpO&NMQm0cAX zdco7r?43vSs>skw{!Wt(t{g-&Vynbvam>K9T9BbtG101mQD^*{h*rr5_U5f;>plxa zno)&lwB`=5h}CV>C78wPcEyx#S6JOHBQCiF)TH_w3Nxg{Nl>w+{5QOp-4`U^$odbf zRWbQ#zqiwt1{*p3lfJ^fp8-E@)rzz#Ki~EaV>hc;`PBu)w!6)2>Q`T-xt%DQWwX6{ z9((Hx>#3jp-x!%ltB#=N`+8bok06inns7`q4nq_@pqlR#GLVw*uO*MXlAX~y5N zrnP?i8O`_kbjxtVRjSuKqo#kYdE3rt-u-8^G;J~Xh_5TT3@XvWyM21)vb%lt3y(Yf z;{05tRd%6=1Zujbb>+{_wDdGwp;0NCci$P+>p$Z$f;jH(O3sDMe^B#nC{N>Qky>?l z?L4(92og-a9x^2Va-7nXSMMpUz7C)Mx2IM6)6=TAY$(58^PZ6!uBeuGA9JPwu08R2b^34Q+QGk6-MzIZ93--)74ADS7ws^tf6}PaoI}tdulQ#J91@hUqiLqtnK^D>N}2S(*E@E>SWML z`aF{Eq@^RWxXmIVJ#J+ZffB0MRj&FQo?>=X+10S>nA{9$S3SIck=(qQ z?@Y1_;!5Z!$EY_W-V-y>(&biPDy+V!*VAw9XQ?~E6K8GyyR*H49yU#LjB1VvXF6zZ zd}P+If_)8lgy?b8ti7st|A<;eNgLk4d|9qn(WGgZo114zCs*!0u{ihJs#TNYvDeyD zvwq?-^k?hUbVtJ}Ocwkm2m8K~nxNmy>uI%bq={@(WOcO0c=6OoNjR zyn+4AigG#-qG4P{oN-f96TnBxMn0ZZy(P~&3nQ> zseL@m%eGsS@tfNx#3XQSKRam}F57V0!WG2*adc;6aPaQNa#dK?`d$7|G?ylE6{q6zaiV!|}hglVOfZbYx@Xn0Gl8pMqU zS`UN&U{B3`y2jYX4Ftl#J0Rh_+gq14*OP8QE8+>&VR{^I5^Iil-=1M?*Mvp6>`ZE$h~d3xxlA#YxNd+WCMeam^^{`7ZH#)P0fhh79S2;k`nC-Qvz_u?u8K08(kKJvMatic5?|A#6y@I{ z%qy9MzehrkV*m+9az*A9HIgmr`EBg#)2csp27PrKDJoLql%pj4o;stMqx5_L?SXBl zwel&eY7f$(GZRMTQ|OE84HQv-w5o%0%Wj&Nq-`j}!5Q`XoxaNJRNt~~BuHs1`~34@ zfmIoL-`-mJVomD}zY>%lLO>TpU2z<#F>d&kYMw3C()%^XyB=deuSz$>bck>W`v+=T z1>@J1Tw)abi)^epOG{J;NBj?{URs=H)EEW-T4#60NwdYZcs%5fx86iU-PEs1 zF|fQYMd+vI^~SQMH*o1plLm;hHqcul2c@Dew=Qe?9Y^T|Rd~fS>ggA1HoZB8sOFUC z`Q~OmJJsnIk>~fhJX=Jb-&=V`vU#>zc}A=}XDCnWw&o|&)>%!|PE{H- z<~H%oIIo{nd)g&^96nV3luB3P&I&7;5kc`5ykU0@>$-5&;W8Y#I_AfJ(#<3Z)_p}HXlDLr;Mt4<*?0pap0Em%T zf2A=P3}~q~4v;w99jtvQ)fMbRuta;C%XrOvuh?aDI^&AGrz@3Gi~!#;q|I7VUiGAs zj!0tw5v3j3hZXDLq|10+-kwy9LyGxUv0~rnsye;yb;Mz(Qcz}8k+++QgPuB5spPyo zd5{jFI9N&QuDq2Cd&g+cFY5rxLPYqGi0j@*zjY{5!0qS=2JYh6_yDbGc^sZ`_=9Dh zI!+%Wq#rVH%0W$P({W>a0?~nPQ_J=#-V+nRw;=Hrd-o3CRX2q;+Q**EqaG8SGPVj-#Z)!M<;& z2Jkg(Kjbnx%w(}~in%U9+It??Ey!O#z<=Eq+m&Sb&uttc4mqtDhZXZ}VvzlAT9bZ5 z{Ns!hGYa-|>@!ZKhLRtete+D9bzA&*wZ(smv2Rjguc5HR;6N}WF(5+3*bfj7x*P|B zeM?dd7E@@@VoDv4YIfqa&g>2EDgJ=>-uF4DAA0RSTkxJgv0T@>*?*0=8a{LK6YxVa zLZtBX?fp)-?{m^{)NRCqeb=W3;PV^odo*QI+8K2$E*7xgQr`$YPrkpn-+Zq`^7|^+ z(L^-+ON>u(nN4KbEto+OG;yVkhuor*E2q~eMc2SU3!#+j9}xXW=!NrxL^lAqGZ+oO({VidvI z0H+OX^I1`(w_eJKI|i)Ba82v>7}5Thp!DT#nh$)_pMhc#4+9=ypF(k< zR36O-&CCZQo&Nb8&7 z=RnJ#-%^*IG_k0XiYii+qtlOAIiqezfY>7r_6VJWhs6Bx89*_y+wXqj51|?pkHq_b zT=RYmg8aChS=!&1f}RiF%IBX+_QEZ&7k=uEDfU7zjC>z~Zn3*DDY zwikk-bl-;O9@KryU@UaQSg6BTn8$Cox2_cSLU&6~Ly49#81ARdO5lu!4F($wI}>lu z77$pA?({uh`5<;FFaX}^TgkS=YPkE_ zTZEZg=<(H;b3`#!ty)&DuDuqAeH`2MLEvC7gs<5Yn_^=BcZJMNA?nFOWp}CTI(+)y znx^RFw;HWUxbq8RMAu zt;M{34ssD3!cW*Ycps=6Z%?sjY-pSwz2;__Qeh5%h|*wH+zMNwtPF|K4EA4gl+vCmoc0%HAWK;WlfD+MR?7GG0n1O z_3&`E@!taqX?}U8#^b`&_~ifP_C@sr+4!F;vVCCtV(0=k{^z!^W&3^Xi@2t9Fc|o9 z>L4vDPn^N6se^1^TnhUl@Aq+M{~Y^bkFYQDSZDwOc^9O=kbUt9Yi2!R&8#P^nf1i` zPb#inOsZyA=5bqdLFRF5a}dCqUVqlU*lpPt3ukcSDmKuz;23QkEc;?KYhOG*Lv_68 zaUAnFx~Vf$?TbIo*%yC8q#Mzzj$y)pZL0?BF9ZM2eWE5qpL7WJ#V@DkwLZHQoDX}B zN{iL+X_3&_%$S+S#x`Eylh;g^cha`!xuC4M@mI7?v8C}IpX*kb8=Lu*u(?^7&n!!$ zni}F2^AlEJq5At&shjPKjO~`QFJ^v@Bl=o{Q!@hm(C=#9wzatwB|pz5AB2miZI({D zw{AbGRSm9d7x|5EmM?N6suL+KGvv*y&ap2(yA2&zTI-*B!`-@!ZH%36d z{0=ERjwp3v+cxBCUHQ~0G~H#;wtOE7dj`@8_AbYe+gJ%>9=LF5J~!#EP)N6fw5c*0vxd5af}BO)OVfi%45*sY+}A^{;*T zD1!B|cOS4DP?DgK5S2U-cUh5;Ae#qdzjMyqyDtdR>i7G;U)#XlJ9i#uX3or$let`~Qi)CUm2R*LCUVxD3#n=oci1ZEVh9vK!^{dvk=PrHpxz%T<$vague zX%O|e+t>p!omik3C}zf!;mki_nRXe(j3==^xZenM5_AW-+W(>bMkm{EoMp?nPOxp+ z!YJ!3Z~$6BrN1HSW&J+-4P#z4Y?$&Y%l~7O+RgGmVGyUhiW|E^XqP#!-z+v6b*IZ4 zkn&HaPP(CnI-V)7Nn|cgTyZuO!resH(gD<`wh1a%jqQpXiuD_|)KDi^V|&$LL-NYL zqFIftQG;!0MCM(OdyBp-9yb^9N;6Bcg*7pFp)NqSy;v_NeVW4bxWCBKorKdtOf0qog|n>A)Wm4#_du8BAu_ps9wEqi9&vHlv{1&DD+!Z!`Xcwi#>WYWh&* z%*KYEjPDs6#%waG_fOxDvB{)9G)>IdM7ydXhgo-^yxl(m(z99Zsts(woA7QHakDUB zioO$JIy#AobL?vrLTNn2sF{O z)>hg8ba%{VdVO!Ry0qgb0?m&13N!r>TbL=~>}Y7B>F*d#QcjBe00nbEN$I8nbiSg%|R|g%~@5pTo))};t$yTH`h$-t#qTQ@> zm4DVF<&npl=s7Uww1;JXMUM8pDF33z_IazxbEck;(%k?=Mi7s2_rR11J2|rO}{I)qcX~xlBZnGrZmXTu|ZRa-IlRez_@SYFK*Xg-8 zrX?FA>bpq|?09D2khI&HZqx2$N?RRhp5eA(rqL3BOqRIqQe6G-MlsInUR9b(wRDV7 z{W&_UrkpgDQ0+&z9Jbyh4s8%aXAO{7m@CkVm`q{9G z;$C5c&=blR@>&57ZiQb-!eH`vl|J~_|p?wu%= zC#-syE+_4rG#trHC+fz#2@M&}ardXCeopO?HWuGPSUsM*-_qa?SoXua#ob}?mYzJJ zO#`12NIL+G>x#>TV7*{V-9@R>Q*zKi1c1><7AKnBc6VFska@%MPJoc~G{mwv%oRO=|qb@y44t_Og?tGfHrH956* zo)hZTjvZ)p#nrwvXwN2zb|?tMRAblkvfDzncEOf(DwwF^el5BC(lqO%%S86xQHkOE zu^L8w&JzP6)PdV_J5&E6n`xgrFLH}}bNrJYatO24=T?!>uv^$~%`6yrK!GRFzdiHEI5EW}eifWqF(#$XSdjTL1Q{H)m3yW$#I>tt&E=|rYFav`aX zTq0jny?=rK8kThTc|&7*jI6hs%w$zDhn~>Bn$TXBGn*{9Rpi=z4F>>dMIPF$>h#q> zHNe+H7(}x_%j^slX!ggqh=tn2MuF~)4qcCcs7cv9PJ!;-2*aV}%5I}f^T|5VX-Qpv zJ?@N777Fl0`F0$})8BBCS{xtMpKrQw1CU-))&#RYjA{b) zyKzm>`A!s)JKl+Fg2w33qz?ygg87jqn2gxRE4p|=fEODSE79ssyduk2wW$r0rLsKK zybH}^Z5Y$8pz_x;DE-+w zp0hrQo3s7Jsee92(I&iy?`})#A7b9cne^_zK?0D6@cXy;-BHpGeeUz+DH!u*@CkVW z8Q?Si=ipv`CHmUX*N!P3BnT|^{VX-`Ilc_&(1Mdd$1+&$9GaQ9?4!`TmG-o=^pj>6po-4WbzkKts1 zu^;Y6{E>Edy3E^Ix%5UD<#w3nuwaLkhJ8iN3icq&H5K1GaJ$U^Co~~BNx2cSkVh5J z?yf`?zcYar7(HL^mNidF?%tywci&MjWB|n~cEEQNe7C^2(|s~ykGnS=Mi_f~mG2>kox|GpX!pIDcSO zM$%{c5b~PrKZ8^Sde7ZmO7FR=OX)r1yCS_OyNmUn^E7&OFJ1#*##4KDG4x;6_0@f5 zvbC+!+B=1NZ2wub0G-Ps_Ln#UKSEsJ-^FnKM}SV(-~!XpJ74z3_YS;G6}SPtu?*;q z?;R-A705(yhwP2-9cR$eG%{KJ)bTDu(hlz#c+bd!T9k~BRV@#wu4xdDBC^EPn7MWW+lq@QPUD-I<7*;%DkGKPQ^N5t70FuK7rZ7 z%0-hq^?0UcOR7rMz`Dg{5Z^b5pXoPbtmlD^I4e9Y{Lu6AOD|o=$Zw$_^B2fx98`KiF-icOMkZ&@G0azE!v}p=ph-a}A1X%1EP*MQJl1$<*v)U4l76pbn{A-4bO#r>rx?^j)?c@BDVdd*%R?ea=|$RUK@FB@*CZCv>g_WD4pk>o9B zLf+;)&n(-b==K}#TW(I!{*s&q}W(dtY#>zcS4G*Nb^ZOY{c0u>(B zhAOmTKjoP6tgCwE0aLTb8VapWnQkk&T+K@IEW*$?*DGnPp#c`25Rx`u9TQiEq?XiY>xsAElcdugm%b0FR7~ZOMC5{H-Ot-DR zd?ENfe<`{U(Dpf!gL*Qg3k!)koEL2L=Hhf3SlNvdnx!x7JK$)1?3DJJ^FsF2o3h#>+9LwqqI*F}YN#)RZW zh4jSalP6f+J(191xS1Gu6q|~5BC~Ur5z1W_2%xu&63XaFj z$I_~_6rb>5qY!e#thez4gc!nwyd>y+<*okv0Dx#W*);BCSq=qTqoC2_1+9 zPmsfJ#&D?KdQt>-%CzCfFjwT+t*ztGCh!gpaYdiJwNK4$aq9DSp|y7?1%#Wpr(o{r zd#@jDiI(M5aGNE4o6-+sKXgR9vBBqZ{H?3rEH;sNkbstk z+9v@8w-3>%jCu7uyW)!W=set04l^FDwN5gtn{X!t)#^b&52^E<`WSK3o4vT^$SrLE zFVY~#J#CjdF5|67STqU!aJ90edJifbFa|#oOL7Fg*p2syGVn0xt|nt`?0T`%kjtx@dVd z8n`==(J(<{zd((ikqko^HS8kO|GwTON7p8 zVZ#>V4-(afQ4=mI>gO0$eNj<6^|p**UmcTTe6)$W(%q*J{J~0uy8_9-Qs1CJQ#hn*K=kXfm zVZl5+GsKi?)D(uG_Y&xk9RQeg_VT?*4q=+;!y$ZT0l@fuvB%Z%$Z)UL{hMMh5gFw3 zp`;40Z-B|*3DjRxj5gV#_L1SR7QeQ(}9W!^O7c-uOIYH3X zmo3n5NO_V+?LR6*t-bssvhAxj)Z+d(s=UHT3*kp6QuHzqP$0jyvJsEBmpuB8vq zVkf3}KYxJK8Q86WE!El)Fmwf|em1M09ybnf2LU)gYi~k%HstJn3Yh=i+~RhJ>Td%A#yxS51}AQxDX#|$D;^W9J;~g<9Pq`0z!$95f0rPa z4Nuy={xylHH`LnRL--2hMfC?1U6t{(aU%_0tCTG0>bROeK)2FwU>J=ciwh%*tLaq} ze)ZxOiexBg)NiQSxRLbCQ2d(4vf=zr7T;c`hrBQjWW+Aj)NI@o6L)$zZuw;XRW(M~ z5*?v@dcY+6$0RJ@9aA4Uk4@`WnUtzNc+YQdJO6>1KHG{h_w#6dEf?t z^Clib(7ngmUI-#Tpr5LqW}9;}Bxx*tWd*F;9wYvo7}(m=YaPZ1KO~lXG=jlyhKjHE zB75?(+}^-bP;@zhS?r739|C^#4iEl*r`}b)tT;s?e!TkOVw2QEPK?lmK_;m)?9s|R zd|?kC^JoowbTW^outyK`s8>9O8Ih|dKabIBr_9Vc7gzg36h(j)45}(`gP}0Xmf}`1 zVXMTuY#JvtHFfPR8CbFS`_|RKUwdF_1I#t@?F5$Yr22nB0q4%tlp-&W@DLWaS0Baj7MpyTts&?+N_lBS?qP0o( zV~HyNn4tizKG;;XJG3CcX;suLw0 zHqEeUMh>#xoMF>vs?J$(&W!SnTXD{`X)?~g;)IZq=U;I`{+FJA#R(yooqxp%&@P3+ zaN!lF38i$d#GxT}qtsYFkUO+Ma67Fw#XfyrBMgpuChie89_oR9z*0YMy@|FET4_H3 z5`|j_n*lM;tvjtO=cD04Ez$?YZx|^N^v<{tdSioH2gST^P|SA@iur#XzrjOAr*{o4 zyO|-jE`nI(XTJ)cG(J#G??bHXtHX$;?wrNwa3kix)uO&`{~g$;!}z_!mN5ij%$6h0 zvW-bcYAFzno?Xw|mZ{ATwg?ZN#@tUSr6+`c#LzGX5Y(bjS%D#34k|%}N5WboVKd{y zd@<=RITIb$8J#XRyPoJ|V`Q|4gOh;}6h&f$@qQT|VPmI8PUj(|1#Y4iz(r1^4K5P@ zi28(B)Q^urJ<9v}zttZK#myfVf&YYP<2Tp;tlUfR~ipRkamX^-kipID`=D;d8b7y2yBh9at`siog}*`e$WEELX7I ztwz~vT+mO5)pr7HlxgEtFuTJ_yLcD$k&S!Vey10u#}C8ecqq5-AhCE7-d~{j*)j3g ztHXe@Vgjln0pnrOljVQ6ULxvwEvBR@m9C;Qz2r!A>==~>4 z&0fSlv0sxva6k))i;B96GxeXv|hqC#cfJU7UTWVa?oFNau zEdPQwSqNwV;Q4tO7Ap!C3<3Iomqga?sh?nfvD14C8%j1F)-J^Zg6)yBf^Dj|KT#E! zs;oyI+yirOEA*sRy3a^%yxWL(9D5VlAs-gU1ZyU!Irl^z?Wmh_iu7V2Zx1^Jo9E@l z!@RE9z?ph+uWY>MJ>WPDD?2$njd?u+sxfLp>5B5@-_ zBH}INj6;?t8d)RQL>Kb^ncXj7_>w(gJq>xKgjm6oX|*Pg&+5qdL=gkPS9N53lFumS z(;D%~Vm`izPcHN6jQHd;pPq=%WLlT@80GPK4!%-`hViv`P<*9uG|CBIbbb?sFYHfI z9S?D4btVua9E-T&(TK}Lr0r0}<#*x!Rvqaa)epw@iZl$&=!@=d6gxS(yOB>?bax}4 zQPJIve6pgu8~Nl8(%{QVRC&FV~y!`o1p+QWEDRXQBa2VdRa`h4O3*4G)| z-}-vu`ddn0e0S?hj_+=O!MN@Q7>w<1FqfRSzi~CU_2apD$}Mp?yO{pw5A`up7DL;S z)-Iikh9YP`2~ZVMiH zc}q{?9yv^Y=}^J6jXC)wc~xSkGlKu6JvT3EHG^40!21Lo*@?n?=Rfj4P7Cw49$*8* z<^5o?T!asb6o;TVW-AVh;#jCS9#R}j5@<6Z85oN4zvA%$ENjQ(#uXMUp5K&KSu_oF z#?VmS#p>78JXrmNWU?d|p7q$q-#mNZr!ijC1os(3cItmHA7TSAS60|HD(p%NyOP5$ zRoI2iz+Bi4$TF3`#LAfu<*fC_6cYHeVeXz>CdUH~S+b`hSC;ibNk)?XsmN92fpQfI zpy%XC}Mr!#ul9Ss*a)#GVg$yc}-|Fro5jn^r@F+yg zoC3ki%P``tdlccZGzK`8-gvGC11Df&8YxCHX*JS+9o8tpSKEJt#>zxVY8#p7VS>`I zCSWy52L{Nu`Vb0mp(q=0q{B&!%<7s<#vD;%YfW9ED%j-iy>v+6vp9R+z|>kyI!T~= z&8E?wWf?;4>9V1MIKm{(B_$;3i72+=oxg6VqJ#?nME!aRp zHZ7;?U5@^sT|l!+&LY&O%^7wZIYR?K;H>JXG;rHn@OB9_Ulocn6_YZjj!NO(0VdlG z3@A{Gj-Kf8U=-gs1`n9T{Q_!vIv}Jwjp8RpX`s+7294PVjM=+Qc_)qH0rTiSK?>Y% z6n7gNz5v=)c!zDw2BYXTYlEoYNZe%>KfsXS2SRqgS>0<+KV=r%jMAAxqvS6%XCF0Z zpE07%p8cl0HuLB%BPzxVBp9Wm0CO)SGipB(M5h_;lYw{epjmy&n10wSo<)AG zDM$l}jiV14r4zRUB#4;^0H)q$oAPtiv!wk5ib6m>pdbKh{cHeL-=%*PRTu`$tnCfM zW3V&;Ys$HW(Oh(4k^sPM=PyjsKU{qvODFRWlOos zl-GR$_>mY;1wsHek(8uL$NnZ$ZLWpfI_piz|22&Lr961@RVQ1=;OEs6>lzsM>dhbo6j zKO;Cy++Vwm;z8)#Sw`({vu_AE4y;xOlR0b~FgxJ+J;06e;nEyFXS zB{GDEEfNiHAHl=R!U)W$tuyC2T#nxd>rfH5)RtvbOMnHg_AE;HqRu6%fic*L7r8|T z5(c{fb+dj}ST_1JPzNcv-!)AN+FhmnsC`bt+V3}Eiv^(eO$Chx7-7NgnA)c=+9aqC zQT-31I!LVlK5{_)_d!huj4+C&BTzn3#vKY{K*@dp$JGar3- zSTOF`78b7#uS)szX>~g%C(HNxzEH^8n#k4sFUj+%xta-TbR=-KuPD;fSxWhSz+jAD z;iB@vyo4nvmP_|T*SV!LM3wIDxYFGnRl2F+(v{fVEhPbXK7|Ki*xmarb~ejh>yi-| zTdaB~D^{yBx>yb;D^{cP++zL387bDA&e&qnw_L3MabCDsF@;IPS-Zcu9)OLnWk4tV zLN3G_eDAkRurdEbrEQ_)Vh6Zd;GtqXNZA&D4B1Wi7AwL>r6)rwh_Sx}W9_G}vG)*! z5-(npL-7!XnN(*SW}*wz<6wnJmJ8GAV1-c)T9^ZlNMU~G7`!mM9I=I=B80~WyJknm zVk)b94{^rA71yFA)G8e_;EfmN-jV&V zhqdV|Hr&v0d!#0ah;a6FVC~NA0YK9A#k=)`xBz zU_18Dx8uFhc}ewl1&NR=St+mXJy6hIwCu*}-owZLTD1H&Is3y12I441@H@~Bq`jgT z5U<2SWG!^vJMB27oJS|hVHhQ{4JR) z81P0aA6=Cx-s`_7By+yG{*+Ld4i9>Na{t@szdwobnUTc74YEz9>vi9xMYc&_!y;P` zS!C;qvdDHc)*{;_!kdhtK2Zq^$$u}SZ0|&jvUMs(*?d3i35D2gL)+X?Sa2XDWIF^k zSw@j>3y(z;YSJ-H7&v6zHU*m0Pa-cE=$`~5bf`+TbS$&grHQl;GoUjC+7?YHHI~gn zv!0FuufZmi^Huf&SLx0ms->+Y8@u)*v^3lP5AY(~8##R)psg`tM$M4tF(Px-nr{Y> zNhEuRwZdDPXbA{UedykNR;0V`g|(&q(W_%Q3}l}Qt9!4z`mv(r=}1UBE0^Eo?#=bU zBLT^rHt|5=a$R-rtH0|kTyDfA@K4_Xie^jwqnGFa%Ea8z5coDqi%fwK?y_1nGAznHB+8w@+#kV!rPb}S z)atkKmeNEI_gFe35t%E{huuT3=N?1ul`up1>LAD&a~~WK%sr0dGwS|omNHp|PW-%R z`4xEm`39uq@R5UA9;GaEB?}>I)0AZ^uymdn-_FXVmtfq>2~P_=ECfKUyaUVlGAnic zGTf?5{lnYxy+^q&!-v&Z z#clUMceW)NJc%l)FIf#3Ov~|Dy=r#zu7sw`vGd+$#GKwOK%4s+TXfgkM61btCvy|> zX1+~y8(1KV-Qri@#PIKZi>_Hqbgg}M>}0P}otd`$5}NEQmuD$<&JjU?@SA`+?z5!c z9Zo+LdffEYBiwz(sY}A1XhnV_;}TM@Ltm_EmnHQoa9i!kcz<7GZRM&Z6gEPOS4blo zptpN>;p~jnO@kiKHiO2W`UmTg^zJYAK@V<17W;Ghwy<|gaff?9RKMG@m#R)vB;HA! zFBcz`2mte*>0B|Kd&7?RByi&iIG4=VG5xUxilI;iEnj`#e_7{$=c|9$`RZ5w|1tB` zYtQWWAjK$TYg-E-AWbwar1EXb+ z6Eq^}@Kv=viilney}0^||I&+pS9&q@^nVP!z{TO5q#=J-xH6`>sq1y++q5Bpd*eIF zg6LtkPZx=^lTBiTg>(1JNosmM!qY|TA1XV){-N(8)8cxa=^w)PKcRoJ zJ)(R_pUu<~MN|+Scun3>(cq5CUiiXl$|YS(CA|=RxpYkEo7O+X{Zsmfro9%ce<;JZ z_yMCvLSZeb-vzj<{qB}5NYguYq{5uI;7q!=yktfVgO zUYUmyo!A0JOc{;4cX1ayy{`72uH9uR7^{ce<>P^K-3^`aG^{_EZkc?_s)%&U%!ZbI z2y(*&oh?Mm`*U!nxwe~%{MjJfj`};L2Rp4@W@9ePg^fbH`P#9Jm z0z>wJR{)d$C~j~&i@olDlpJz9OWJ6#BAXumF80GB(n}k;xR~s=G`ja&>R>VH2X`mL z|ByCy+vc@Eow~~}do%+I<`BDlH$oBIdn}#){kUG-1F-r_T<|{P?k?HOgkdeP#42fp z=X273)L-HTKOE;yz|mE-276ImKAJRq$m)%vbsKpI%dZqNT|#sUGD(<<)VXYAt-X94 z$_Zqnoo4TjR1_Zd1V*8`(tVlO7Xv9tcwr)tgu|su-8mKIOIN2ti6tm}`FIuX2|^R| zVyAEBc3Sav`jZFZ4=iXM)HUBrdv?d>*RhrL{IEtmqz4Q6mb{kh_?BFmD$GWzP=r=6}(b?Dv`@iq29w+Nv%o0yt4^*nU7j4R~xi8r4J9-VH%>JLTYVZ37aB!6g(FtvX z7b_JBXW(PPT$gZlP0rJ@c*ATuo6|~2Z!NNhtBTyrXaAgtO>c*%!Pju7tgnlCczs37 z&;uMRL{#gQ+a!lH`>t6QR_(Q$(*EMk7;RpXPs7qmzS~&ZNXW6J)D3#zqlr9Kolia2vUX)l8zYPz~Cr%1TE z1Xcb6f7w(vg%EnpD|oQkgtpo-5fC9@t;+5MB4ojn-S?3QIjvF=-dQtvcBI>h8u8(h z9{m~3dYxD?@ucr(InT$5bthJ5Y63V{kMKPY zF(I`PQU`{DBkk1?gUV+8uh~JP_D_ewulLbpclZ5li!_=Z_E2~ag?HUgYtra&pn@&e zwfKNqKbqd`ZSg%iyu}aihL4+DCObcFYMC6rUYi%uDEexl!rlWb0VHA+4*oP(sSl_> z+HVo-gwb8gOr&GfxZ8<@!1$&@8B7~AIY`2i&Dl<4cB4r=ECdgmMju!@3J4s5MmyH{1A$n5eo^@7|E~9f_~`qt_X7Cf2p`%O ze>67!>H04nf>{Le|2Zry8>-YYjEo(KjA0BJYhDf^!qv4-@ux%r+rp%$Cer$pDL}MP{2NWXguc zpF^)};C}u~GRsqE%xmOCyz%RQfhk>pNq2$WNvj9E=#OV|$_m116r}>MQEE%6NZu6k z!t!%vFaL^~&xIA}D?tzBQvQrl+)siU9Vr!=i{k95nbj>Td-&JXhTQ!qh0+M+sJz6# z0u92CQvtM)7kt)osIn?=f5jJOvANtIn6DQbSUD?_%wj{?9pR;Z6<}bQUV#tmer*T} z=f4Tf7oId_*VlU2<|~MSHLBD$36}7{#Vf2ERT69Lga)VhmG%7JpgJC0P1c2@DgAS8 z9WSCj;lwdb@CBxr>8c@^5H&efiW?c;^^`5|i` zfQIekUCW_9W@wEs3}QXB&m6tzWu>l2GKiisJzw2}6@0$ix-$ zgUB2DR%8%QSfucTvlloA(H}QiE%Sb;+>Cg?G_}n8snjy>hlKrag{0#XCI{1o*BPk? z-mix-drS$H00BOF|B1eVAN%qPLG+Qn*d5A3&Xn%MS#K&X(ztbRlEfi)=X|}mr@8~D zLGBGFO@~~~R$@9MteT5hwKo-#X3jn(WbZ@WS@pEr@)q5cMy2qmt_mma8ad=oG;g7{ zE!?{jM)%O9hJM^SvQ?`4)C2_`-NUV`#u62LZYnro(tgI(R-@I>f)7pF<6NzZiPYY_ z@`Xf|pA_%Ot7G4 zM}4;yhmfFaJzUMh@;0R8D>RDln{88O%ZV!Yh}|Z!*OccsiCse8F;v1@aS2A%)*Hor zM)3ew!xWmf0i948b-R~c&g>_%{0R&e0z#Gs02fctMJH|Z-||i3>$K_sf}QVj^nAJ7 zr1hXyCALYD%L4s7SOcW){aqr!+~Ye^B;)IO!dEjYQ+SayU@^AGB=!q1D_WiFQ3}t4 zYBWTYMvL&-yK9IoBE~vfLRD-#lpN9DKLh2roE2EWGF+(SrY?lMp~zH7EG-pOpHo4L zh9&=GKe@UH&EuR=N5%sxpB-Jl^kKTPkAU;#(pIr;pDdaGpUie4{C{9p70!k5-7tjN z=Z7G#AOee+X9On&2XV1cB;&-WJ%h0YuEu?a#sl!efg8`CW?^iahq#(2l{5>({OCnv z#~H(KD2K|pi*+5IU8Jd&UWLcWCn{Hr=7}^FG@7#Q<%M*C6wi(e%WrZDVJ-;O>e*7$ zw;|B)Oia^Uut^^e#?)i{1+wi8W!T`W^0;;t8)m&t%5v-G9ju zcXLKd>B+OIjN|U+;^XcH%Y-*EM0US}?zZBO-EF%%)J%A6h3dL?1oYbTbmGm9`f*nV zkNI1QGk^cQtcxOG!A%K&4NzF>8ejN9;Jh~KeCKDA@nMxpj^7@>|~Ryrml zRu4>198QzBF`TAtV>nf9J3mf)WSsU4iqq3kIPFt#+MhOIfZQ@}-TftP?&dk4(!LcQ z^LJbJkc1V}5s=ypkqQ5p@r3=)leooLdbg0`uOsjtzvp>bpbK}+5bA#139~q%JwBk_ zu5L^8A_}>)sW?E_Of6_s&iw(!JDy8a5q?+xG-VSW;a?)#$0dQbzT%|kAi|pu;i(uv z2waWLNmnblpW!6_W;KRDGa~FluI2;qOG@p(gU;V-AgL&gNA^eZk4);;++3(`VD}^} zNq0U+2Y0D6>Ak?~?kWx+;N9{ZJGi^)IXbvI0?*j%$!!^XExz#(udjIQIC4XM`-)rK zeI*?b-so-u%yt#mVF5UT4Os3gaRP^^x~_qa`;HZ-9)Ff{{|F&}O73E}y9?R@!w(g| z2W~sYYrwEB#N=Y>;^YH5GD817@B24B?;H7_BOma8g`WRv>xJmKxb-XOdF$4Tqvyg_ zM$cz&W%Rsg>-p*VsQqV}5B#maP$LenXTye{0-qi4?u`m5-C>v<^noGg*;7 zLQ0;#Ri@lP&56#}$#lD!S!}R)=~S}gqUd+>Z{q0pfQr%Y(`>bzbmE!8==TTbq2Kms z`u)K(7ogw2d4|#NUp;d!{r=fAjDB06iO}y=&oKJE;+Y8jUi{1j>38OR&qV0AEU2*; zg+2<&zt|yD>pG;?MBh=I!%IDHQ2IRmlK;}@e^>fEv;RLx-uV3V;Cox*=s}ZA59(!l za3@6Ad0u*enk#n3(Sv6cdLTL&9XKY_fjWf_gq~t_p#Q0J=|JEqMh8B7DnbViKgH-k z%Tp0Lu>UEU4m84=<52O0-2@A00@4Gd1&uJOyGj)9EcNB5&f&@i9q%`#4?5nn+`Vl3 zJ9d;uw!iJ+C9e~Pmsu^Dbal&$V7v-wKGjDZHfFq=w2rv(KFg*VM&sRV)2FlX4)j6@ z9*V4{O`{#lCP$5TrKiy-mq)%)>xmlg)^;^^*3W1+!)c51nc(zb~{K?2dJ#ZCi z1P&G0&Dr%_?d2h+{*Y%(8&|6h$pkd&pdj0UbDiY78M_%#PqYS&6jAB+*pfg!8|c)U zSstE*+ukwcb7y#ZLrcXFU)vCvkL2?%B%i49+F-jI=%-YGrzeMaYdfQ#641{ESNm%~ zKX+nhHgkF>PCJU8d8D5W#)AF0QD)XQ2ZkV|0xxzEQIjKYoh1YP)a1bE&sq>gFBZz; zL@*YZjVRm-gTaY2C<(EZp=wNcmp=e8N9>-FMw?G0JHbSwyeJA#2Ea2v`W2H4g{RK< z*BelI6I#eY`G6;xNGW`xemBf&&W1TTB}CuR=$F;LK5(Nkyz{MKYM`*%fd{aHIK+he zU0#zoD_NYI#`1?L0)S*~U}91u#2IOVI5$I_HAWWg!1`g$urrE#pX%rF?3E z-Q9a&L|`6iHey#9it(PvuwNyT8Nw{z4t7lgoTQA+lyigCj?#1^0y)ZfIaSObZ@>uwM)9q1lZ{Wd&$JM^_Qk1pxa*yLyzUUdR zT8;brFu~!QbcE||8Z8D?!C2R^>pM_sd^kst7Ob8j{BRc)Mpavjhe z2au3Nl!rzYzRx)TwziIYqt4ZSQ_vfdxHr5Feph>LS2%}P)x6X;OrPtZd|6_>HXIyv z9?U&%BaORjCB&4fsuCyh%Cc2@TZ)$7ku0MY{1AD~40)qul%d{ehO$xo&VdNZa#Ilo zPWDk4%i?$XBN)pKhXTSlMA(m|_L0OPIGhYw?0m{#OG)G3RB%;j;RGLq_S?%|KKDT`*A?I0K?;B>(2XP(+o3*EO!W z7KjbaI506b;He-W3kVs6TyMnF);upeK$S6d9aij#UoZv3lYpls<%CZD&Ao(L1i3bY z!E?3ygWm7~EUb7L7WuqJgRa5AnHsuaV$YZG@DN;|n6 zF9Yb1Bp_0s?~3H|su~MTXobvQokVa8&o~E>1*K7ygYYB-TaF3&68a?-h zDW?KS))IwqD+X8fKz_vrQ+6{uzcLjxn+gsH+V{DdcZpd#AV^;n3brYi=tVC(_4&97 zE$^c2OUSyrh$x>>38r@f#(bZc>^dD(``WR;9aygnHSXScCVSDht-8R zCT9^)-{h7Xa{Tkj-h+b|yRor?Ee4%)&FwIf(e6yqB0Zi<;1Q|+MzVw4Wl%fT>e13p zAC3`VOi+S zbfc^Nr3AAa%yxUQz`&3qoKcWGjntIu)w`JffAoHc&+9bk9MBUS#%eDT z9_X@fdHE`D5uoKQ=&swnFuLpb0S|N%%$e3BRqd4qHrC`EO}I7*;r>jOBP5J&G&cC5 zZx)(x~EC0H29<^QI}G`XFwc3kYpX?bnkBGfFMiv`Ytm{~28Wl7m6Q6E|U z278Mv1*p$i^0z``d7S9P1*IRLbRp;H3&iw zY9XhM_`a3B6sg#6|vq5yROcI|x3Hqw14 z+HC)AQ~=<#PX-&Q1Dy=o6*dXhAix3v--N47=syktwVS{?2lE?60Mh(@)P=kX9jPx^SLdOYntavd%wF8=f(Brej?e3N#U$)@=>t{?2Q1M>Ue0n|JM+`ogmnANT}S{qcx2A@f+Gop>r zhGS;n)L`}G=q<4-H!BSMudy}lL~jdljNJ!6u?`|HrJx(BsIE~91GDiz!Jscuz~@eyz7 zE31VxI&@KybK@{xac&t_tvI(1lVoRlO|lX`;>wk%?ltBuA0%105>Bu{5DG5TJWXdC(+nCCF z7uHgg%wnC{#)pik)0FHZkUdUp8<;y7s!3je(5V?lFViqJz2^)|pm)izM8cpZnO>%3 z3QnJsOu^|T$%!&nO;GLafK{$$7V6A8ZEr2R8LDX_yBMvD;_;~&hUnBJqb(pz8la?? zCNSBSU;|*xtd_9oW$A#yF~juh$0U=%w7T*WMr-d-ZrxF=E0!Padqa3iGB}|8`t?vs zawecNft-oxOeCiUof>i`p)-k`L(n;doI}w$6wQSgp{s23uTe)DK~vxjR76lX%Vtv9 zXW8Z?z}PpUJ;fGooT{_|5U0QKEWJ%P4$ynfjUjrExe;IKV+!asr+|FZO$8JyU0-lk zsNRK;jk<0bpU8m{K3C$h-P+zd%T}Uly~9?P(8{d+jT3^+Ch?#UJS^)2Jd>sw;gSHo z!=Vzbf^J{==cxaw=5;36r*w)k9g7b`yJT3%XfuWYyEE38B!{34%Kgy2hAtcDufz$O z+wO@GxsaZX%?GP|F@7E<~RL=o}#DS#+Ky=NWXKA!k22`^njd&OUPX zqO+Hr1gr;8UH;tt3z*_OMSqb@ZtRS@WGx#GogJu)f3qsKp-iP+YlKG~aXlXT`+!i1 z9U5MG?9lX1kl)cA`a>iWC4~HMnMJ43+R+Lib02lch@WN47`14VdjOyTrn8K?J>^|y z)Lm6mUCkCGxVt++gFC_9-JOHG!@*s@1P$))?(P~qxN~rKJ2;oWajW)vnVOoKs{Jsl zx_fnJHwsWYSLdam+ey`<%1BiCq4x@zr76%UnG9QwZa!n~%L7`sB^$BIdGrfweaHBa zI+@b<`g=RTjE>^YbvcuNRl{&kAgFD^aKLB12C;ZAuS>H+ zzu;JoStO^5%Cpa|``#y1?-I6jX|0IdRPAeB0Y)i~1|f4X?nw4(Cu3YHYmv+K^7^hO zsb(gfjOn=7Esr(2e-1C@a}x_yi=OhzMj2(p&-V4N1hEnwb)_YTIgW(nPp8hx%KUB8 zwQCc>yuM{+hA9gQ^tJ@pTsr?^=l3m%mMfG(_9u=K2)*CQ>)H<}B_NhP{H zi?L#|{C`aeetGC}HiQ>C9HQ}lFzVvqN)34crLm`u47V`Q4JXNtUToxyg6ES|2x?g^ z+JJWiGkSJ_Bi~oTs$reu>X1w`{A#m)39{yJn6*@}t*22|U9)1fl_m3cWt%wg zl_MRcUGwZU`03K z=E1HI>F!id3x9OY4e9QDO~%AXk4QfaR2_qDxwICgD$e6wy`gXe7G8m8`z6AHT2LWg zlAIzXi!qPr#S@EZi-%ABL~5QSVmKeUo4rT;-yQ&haZ|$s*(JILBk#2KKL3ND$UBYV z;D^>dLa)^#L8nQzA8H-9fa_YJYD4rtP2|PKrXWD&?v?q+G0(>lvKCf>1C+Q2X8)No zS)})L;#~$__*P_krty@93W{|P%dT=6X%BZn+_hiXNq|ExH6CquSHurj@85o6^zw5pTnq2~+t0+d?$BEvbA=IXM!abT=Vqn^ zi%;Db671V9!sG2Ya2u}_habBLQEdC>Dqpfo0W}5!i6_Jg#&U)qqnL2Tr*t{S27|0h zSB`T=TG|~bbKbgdow}!c_*Rg~JI<~yndfdr_sKH@)Gtefy3}gYzwpk~ZjDa3pOT&1 zQjF~vI;tAHCK`fblVjirwQ{a5d#N~@2p9J!-P(LvND!l=DdXig%XqXA4aPbyM=Q%8 z+WO#4Rn$O**r~3nh~b5=jr<$gd-qRMD)&#_{jtI7T$Lv)-0IDQ1QlsY@9O6Zf9p3O zdc|+lUUoG9m48uPc#bMlWLED;qN19C(khF&K(dqhy`@|kr&`WLM!PfgJ0`7weV0<2<-(7M8MqVlm=YKc4w2n;%!;c zRNTlhYmw<>d=#51^T>rOTa9-TEI_{vpNTc?mC4Z}PtC9Fu2t7hV}bL7UXBBVYB#y> z?IGsx=`vTId|MaV0IZ>k_D2L2t^L4UkE`fUM-;!T7goWMhYu4jL)9+!K4`}&v)CT} zFsH8U%Sf(*1OW)NziB;rR6r;=x(X0;n33s>A;zBcbS5MbsLTRYC419{KmYrUdh!My zTlfxI{_vGl=bl4oHyCBmX&0(8K6q&gNj~fTjYOHU3uP)?^Iy_cGUC!~5n{Ul#1R^f zYdQfRxNkkGqjTi~a+iA?+tG|EhpM%fIJq4G>!Hti7|~-*}N|E z-c{9q?hpF=nAqdRgJ5IB?)!bP)D#haPsp{5MyH8n+jKcujq%IqF-knhh^?(eMyB>3 zJmY>n&L1(M&Jdj2KrIQxc5fJleGUfm9*be}@Sy?`(d6CDzs5yd^mrFq?bh0cdDaSn zRv1IqGt}V*LH}|L#+<^?a8nvX(EFZy6^-h4Wfir%YDUfkMK1Jip`SB+Q?Bmp#PStY z6aDr-<^(aum^JvANbx0l&d5x3%Rdl@fm`k)(_0sw5rs#EDtAPt0FWcnuDaax<|-iHCttLUM|qFa7TE&$7lx8U zw?L$_Wf#B;IG_`0dR8&%sqc@Z8%)fyVS&5AKw#l04MdAS=EnP}^NN3)VeZYM?vX0H zub>x6J}p1eaD=$}59E;v%w>`Ml#w85CT<*}FB)iFHJo_)Mp0=%J~@aD!%EJ;W5B5Uug2$L$Gz zgJ_9HfvyuMTjgr{0{fMP5SD*FLj9TKy1RpnV#Z>Ksj5V*Hz|T@p&LWivCoi<#jw4l zH`&*YE8X|52-|AL2GweI6W%2C>3Gv#*^hLds@VI|dpq!1b2|Vh{2BKLFSdQg;oZO( zk5OiYNxlkg>62xAAgPr7J4BQ732QQaRe=M1YrZ?au4#pi#%81`6$5FBWw`?*nPRM> zY4$>jO*34@tICV5O{u&6&kDFc-w!JHknhqSTehF<$9=;k!SlWb#W13gq$ry{b)y2& zBR>&CjJlUFM8dmdJwLJO7TK6G@<;6cT)_WwXUMnL%s7<<>e93Lc#ZKWeGQ=#G#;QO zwTG}^zdbcsLl`dmsIXnAjiowZ@pCiX5GJ zvw3c(?dg$Tj)!C4FH<|cPgZ_*GaU%xU~wi2P5fKWk%Z@P$guHQXUU%_A6n#xI7AhI|Zr>k&`zreqDz`4#_kna8eakLq2;3}Dw6q<$}gSqPSfgtI+L`Y+1q-E*-1eiZ%|3@Iuj&oeH`4)MXU9hPt=<7z+KLJ8kh< z+hpFl)pkkX2pk%&OQuPf^3~wq-6Z02ha%DLxY1ulwjB=R^j}U5+e#i=2I~V+Op+V( zj-iBopKDWABuDKRqYtObcNq_b!t<4{UN>$oXnm@_6vd?3HdJZlS~sQ~t(UN;;_4A+ zz}#wly?}0`<<5ITai;jDfJ>WF(e6_CAY2Q7gCU1co!ZNPM-P|_d`55o~<=AE95 zrt#k+7I|%m0l@<9?212zNZFkQ z86^?E_3g-2?-eb{dpmSj(-736z^mD%sM?K2akOn?P1oj9#s-oMKjMaW~KD*fs>F=*V+{lQ#PlD`^dTs|!okTMQsor>|Rj z`}LUnjm3xg5ERBVAtwVnpaeXZQ(-TeX=en_g2pInqY5CSY}bQ*@)lgNy?n@jbJWT^ zy%MAs3dfx5;7V)*A0YasHes^18aoliz6hHwOUXl3CtsAph{EIc&JK#{%MjfE%<2Rq zvI_ejQKe8ugRLNL^Wg&}U}ueeq4vs&9(GH+E}`iDx}*_|JuqrK)Z{JjVbUBW2fgpjE0N6u^F|o&ng^hK<{D6QbGs|Zey6y%+u5GzwYEa&E-oU>1_Wm=W;VZXX_U(~;&)I2DaYg``U`x^) z%`KNr#xece&8&7iqyni!BL z-d#DBjSPdcVS_Th%FGX9v*$tJ@>G|sjY1oCuttxqe)M)eXyBH=(SF;0oB`V(0#v>n>0&Z6| ztgI)+76xT-+kz9+{paw7x!TBoM8i~e%boZZ#!}gKz$ep3@Z4u-FWAX0cjqZ^@`Ln2 zdpmz=%`?6)w~$t9yY~3eqP3829xR_mht&gzVKM#?C!aK&Ish3Mk91~NHjzMayT+7@ zn*s5sgYUAw+v_L@Rd56pX?u6QQ1QI;tIVnPgP2O83(i5VDmRXnfKFQbd*wui75J)YkMI=AL9>&*az6M=J9!qe!dpv5V`OX>s0(FYUo!xY3#J+q>>Gwjq9L7`b5H zha~x3b!J#G+ligmM?PT;ufI%0lg-pV=oga5)bqC{@Kw(nK zCMagnWDaP4<6y`3i(b(gr*Zy+X;`6ew|e)#@YaW6jQ&z#$!BeeXQ!CkK)Uh3!reI6 zXp)qAE?1!vQ@%`IsoPjO$smu;mxJ|F>tx43m%{;5K9oeewPru=FQofeR`8yKts3fx zMFw?S{@S`U8DVBs#?!v*gnL9eayhPu0HjyqW4t1gO{t~=@3qwG@3 zLyb>(2uKUnqpWnSLpJa9%vB<^%YWv2^!{*+>FIYX7^^GZ=jcuXJ>ZF>oD8 ztu~hSX7&{lq9eu&O4ToyVg5nzG1JXB*tNSMs|(k;DG9 zL;hfH#s44#vGEAJTr$ph}LOt%9!-vV8$gw0RR(cZ^ra(te0@Q=|n2j)rtdjdRq z2Og7pE%o17d97`?-+KjG(+F@~Hw`8t*gUhmh)-;LL*+mSgwwu=qxCi3Ku^Hs^7LhI zjO{81gF~<1#8B5!;ttINk0Y>9@U<8_P^}UV4kCy%4^U1)Ek$l_TO})bIggJ22_mM)uM?H=2`K1e1Vov>yXgPb= zek5-hflu3W!xOkH^b;8$)hEkr|RXX^XaS;|pn2sOvD zm$6vjuUmb}-o$+{`m>-$z|r_s)u-}x>C5N&RdH<|ML6J2xmZbNfeM8nql$!EfEoy$ zni4QpOpu-$L(KJZ%Ppx+>S>39b z?(^Dyz56lZKMc}7Ap6w*c?me{J#7OUpL`~NXmecHAD5q4iFaqLso_pi0j{rJc1Sg49ug&b>Ls4%yhc`>`~wGW$W_4&I*x+0sXi(A8?}5v{)qbw`Rf||+gE}Znc9*y8C^oefrPFAhy%$>j+u}KE#aclTw@zmS<~`e2VBt% z#OUvkPS(?JX5J`7HE_s&%k2~p#SHa$YPnkfyfTXe-T6QEbW(Y~E9rW#Wd7`Fbp4!t zyaPdej-4Up{+b#8z(Y+v@!Ad^%@o=i%6J2;ihrcW{(dK9O*R0;o5AufDK`tib)TG- z9)1SjfdRaMH~h`V=NPLE@|BL&AjkQ^##C*mEBxG*miKj(YZ5B_IUyxFJnG*BvJJU& z!d&D`Dp;J1Iv|Sfz3X_4xvGD&4fT&wuGLbp2Cn8#fm)9)vyBZg`{?K7%OHNEKq043 zyib&msLv0d4~)ETg3l8ouyhj+-|KytKl}e(T{kv>=!q9mbx%JRFqBbS&V|{9?ZdA+ z@2k%3DhE@@d?(9>KEcEzBg znPI}WF?Yp}lG{B#2xL-Z$o}nKEv3Ra79tC_db=+NHt z%d+qxZ=d~sxor66`=D)M|85NTS|qDVje<{Rnwcn8UN3 z;@1!=jgTODc2gY6pFe@2zn0L+xNKZFU4HOtqs3z}(E1Mq#U2(=_-nGU2&S%|8LwMN zqvos7Vg3%s%+LJ?z$Zt>hD8XK6#FAXg)1u&@I6p9h)xBY3K17+_l66=^70l9v&GU5grvA_BZ5kaDqs$$Y)?N6~ZmjEgB*`A~GT(A}Wn0GR-htVpXVYgYmAWE1ifR)VkJ(>o}843twL~z%M~icYS7wZ z+jqCER2kp1o$zJT=sFsAjBCmoh*<4bFVZc-&V_FtbeO~X&^`DhFowv=C|{N+&Bgyd zop08wS!}{v7%RDC(>|5lkZCT^R*M!L{X0KNASvx(v5z>norc{WdyHp@&BRmWuJ)(x zH^!fIxo**!80wQ1I>ipXZ|6Uq&6d=2Mq-^k=jh;58CJ}z@b1l#2e~>HZlSYfl+EdY zCohh+P$yhcqh(kGZX})Ki-6^-eoZz5kYMR{G=AoUwkebNn&EHs@4uXnedV zXPf$dToR{py0T-1qHp4{@gOmp=KJgJz;+ra?d5}69wiC*Q)GTkkL>Agj^^FKUO%95 zQmH`sKBZ`WCvhh3^PA)!z8bk1`3EPrK7WC1sst;2M6&r`d>YLh5klfhr5(K*a-^az z9X_!pXU7x|b%r#B#<(AEl1yfc<+fAKKz9i*VX0E9(P`{K0s24P1(UL`W11(?lc| z5BM5LQIO*|eEu#{795z*)lpW`E|OO-Q&q}hN(#sPw#Vy>{S|>M3oz{9`-7dg&7E~i zEq~aWrJ-+S*NdpX7~VLo(JR>;^(>$W^dpva9CSY;G?t6jqHJj^B(-jeHF)wm$QFU+O3jG5 zb!!bmNLuQI$-uXFZyJuUskbnocnmpRERFt34iejCW`aa~O7v z6K9r;W*{6&iS|7a|WvmG@RvbAWpK&m2v^(&m&s z!`#!g!?Vujly^K+oUIA^_f9*eqtt}c5shA_WYEUfdi@f8mvyy8AZbYl;-d7jUhGkO zbIKX`MQ`FUMR&3EhA+`k4tUKsaSLie)Yc2Ps&34>;?>&mK4W}6W2l%~ZXW@ryn9+_ zAH0RDZuGj2kEFyjuhcP$Demkyqz;Xd>hJKSmHeP?DHD4EG2V?cb3|HY#@@EAa_^m5H;7=PWPI6&92C?B(y&rcC66F&9Ac0_ctqB5*X0<8V3F$X1qhD_++GvKDhl` zVnP)V{xQX!`tB;MUB#kbdwYX#CurnU6i{ewfcb%Urj0?gmzu4a4{D@O5xunZP+MQM z6=-mXi=#PDzWWuO%l_ga`&1>JpEG4^n5nT)d)@6>Da^pYuWdce(j~rl$5x*^Q8j1D z5_S61VXoCz3`HBwzzbR^oG7QPw5_9?mZ;~&7__po87{3aGZM?E+gTRuBmtsjB8*U# zf1pes<5Lej`mV0uII+$V0Q%rG*`Tfnwe}5Nd6Z7P5C4S_vrlB`>qN`cIb7XnPcIw><2qaid-y&qofF3WgCF}a(L7#$@uw5#1ClN*k5 z+NOe_Mrq;Cg3sX+U-7{BEAr=OZ07f=#i^Jk&jmDTSdX9Hx-WOM4y8uz0?xiX%%7W_ z*)2%T*+!rm))oMwq`~0t;*x-NBbf{Ni|(CS2op60>@#uu@UZ%arcRxp{j zb~@(cwF@#p{6#hP$hI3^R^O!t0xxhjuySHt%|oJLpp`{QyWk!T`FnDD(z943BAc8B)} zw|Qi0-1`~mmqfkRQW+s2^s1#{un&AHU8C6CBwX-W7^@v`E);h16SO)wdA2-svZNI+=k8Ho54q>QbTI)3t;OTu=({_8{X+4-Ju54rJ zwJtr`PgFPeB{>RkXviEae;;A>QcFI^s%NkJ1m4oCP0ty;?kN>z-EZ!VM;DQn1azti zk*#!xk>b9NPrNE}Z<;kA0is9cU*+;Iup%A;)U>R-bJK)8#xBf#*AWmKT|UbDoGagG z#}tlg?H}DrE}N!J9E2v2tKFVdjxWwQ#I$SfO(v53!FKO`=OzWh7$DQGamICkno!*L zm#~~le=yPNDm|RAmc#`U$O`XbjM2lWuF;@&;;ruF(j?Lx%F=t%aq*&T^5bUX`R*t; zX=?ZIz#`q7bl#h(QRx$;o(o!zEBb9wD)9P}+hx*AusaiBd50JF(cILsMz;A3ejFro z==F|)xZZ3;%}Ee_D>&xE08K!yZ2>z!{etczxsXtyr?zO`Io@6EMgQUI^gb(>crW@r z>Aws%eI9ON2vqwti@mlFe|eCgx&mS8ik9iaYY{5zFw(#TcRgk`fwDUjNA22|!VSwt zET7Y7$-+J)=KhA_wVnfvwZ29MARQyHfaz;7Vkg??))}Iku&xn6lmL-H;(XK{-{zo|DE5Vt}$zC4zh5qId3 zS<6oXx18Lh`(pH;5Y5Lz|NZNF>NN6Xwm?Zu^yo&X=l6of$x6B2cTyXhhCVV98UYnQ zMxy5|l2nogGfE^By90=-N3Ti`sZ$wwJpuJoKUeRR z0Nh(0UdfDq&W^~cmi)`3Q;2M*XAEk1h25SH{iYsRkDO}a+Otwe|74o!vcy$ZpJCV; z3PH8iSBZ@_)4#v{{S({F@a}gx?CEg$D(+Br@E+^|_pTAKlnBsReTQGnc36nJ>`Zw* zZ6z6{@lWxUklj0tq$teiHTaSgFmO)wQ?4^-O`cvOPk3s)J2uju$zhPPMGZio^335 z*Oi<8C#$dQ%DF*g0rY<4cbDrA(R&q<4HRnX&n0L!p~V;v^JHLMr=9>ojN3Q!=KD2C z4J#i4B#zi@UjMMu0!y_kDTTigZU;9=%pUlxPKP9o%yel#E5U`c78<$MPLp8&c=Iw~ za?0{_8^`5g^ZlU)-r^rEL07Zgwnq)5&}jdy*RC_jbY9|UWi%2n&m()O6H9j{@z&MR z&kFepna+~xmxAP!Q&VNLfANjoNvj%z>5$ePeAe=@x&Y*{qIbu+R>a*Xj;zL>Jicg_ zr;kP;Kk{YQ2$4g zXnYx3MrE7)tCZoOUMXmESb{^z!UlS;36E`8= zkWc~2yCK7UYj_^ir_59}++}>g?gF~y$Dd*e%~3F`uD%YIGdq|Ytnj&uC+k$~Rmz@G z38cMfu`ecu7ESbEFFo5sFZ%JExcA4V9g(RR?vo3?xJ%fdT4^{vayu?PwYGKT*gEK+ z_=0;`6gF*YKx6UtGx4Yv!f6l1@o$AC@57wA>ja5cz6K{BVW-DFb6JY>-6VD&_H(0a z^4bczd3=+ldiwe=9)(7kcT^glCluXl7KyK6bQPf?(Il`2IWSF~&fOr{*SdbYZ_Ud!G^mStqw zbaSFDE(laEAPuy1+dC{7h4XitA-=Tj>d8;snAo8q5#}*N*wj|s(^T})zj-pp0=Ts` z*898YZd9;VMA;E;<_b=q&!wIg8K3m;euQ+6X>@Y42Xvd=CLQR~WRpC{s=6+kc&tft zcG*$xwHtQ7Mjoi6z=>NPZSYQk%$eh8v(;D>RnEv4-{#`iIwOX(_@#kw@A0vfuqdv* z%D~vrdgI@F`aQ9&)~{K`abVu&7#juPug;tIa;_|z=F+vw@+P^hV4_#P%)PrJj^pRB zfGG5aC%J)Uiz{CY_vW0EAhMBz~Pn(z4PO>J{=l<3erp|CQ(++bhV*JK{{H%|xXleebyPpYx?!?Byj~ zw}0_?`Y*0*X^W*z>qbD&k9U7ASQU%RKEFd%&?Y7c&A*d0pYO#)W)n=bU)?1ET*-;& z`jYGn0ErM-v@GtfAFFu=g-vkBQ>JZG)s|nIkW}ME! z!OVQ8i9@GV&Gsj!vVNtt%dt>3y#8r!Aj8m!#ZeY3taWWNZFO~_BL#f0m1-rkgtg~V zGgQ-H^<9y6=zZQQYMkjHbZWhq74*)I@a!QmeSf}x3<-`S(k$dVp9rB(pk*j}D60Xi z|D3Kd+f2eeysoCGIN!-fT2mFgQu-V0;22^Se0bdrqdrnm+wNJS=k=Yc{fecdEk|R5 zkN~dd>f`<8n}%{7$FvQp+I)CE--n}2Az;R<)VAF5fce3&#?F^9>U84_W*BLnNJ5D{ z)sxyh*KCeu5Kc^(qt(eMn6>SBpqt@Ko+Or|#BIpq;se?XDX)DW{B#;JA7Ny*M0)bQuWlemaz_(B?^DHgsXWyyMpZH1ed7`u8xO z{Az#aigs!hxTJRPl0TZ?j28{H#k)J*;L3FpBYp1bJk{W+KsuETL@)mxEu;}?h(zEJ zSbKRJ)Oqka3k2cV;f1Lix-wD8EZ8k&VI8-w{r7`qSxx35rtLW^I zV^ONOTYm#;zdEr+++@rLkS+S*?L{#CD3Bd3o9@B?3VM6GT*R!1 zatwpc_B+M!k2)pJxnFh)r8)PK09u;uNzY@^c)GV)%{BTLPo-GBIMw>szP&Whr_XY9 zaFwpreuctiV|ZJwslDrqpJ=w9@U3!wpv2?=M+I$2Wt;yg*|xfi*A8}cf?f@tZim1?=cNkhhH3?D$0ptp`ms!Bvis%(BtHA^c1d8 zhL6#w$(_RbQMPqNfnu~u;k?RPvG+W86k*A<9?f;;Gm?j;IlrV-*fBKR#^J8BR|lhU z_C5M-V| zi3?_C&2JU?*l6!Hu~lABlBxUi4Ye`xc$Y@bL-}+s>hVcm+aaa;pp9Qe78GO&<~9}a z^~C<^{r<8qjBNcLM)?(+a-_meO2Q6dklr!n{ zd~Jj~0WD#Uy_^|Cj>3FY+Z(GK^^R+;Hq-m#&A#IK>utV@OMTf_C)u3*yPoA?c8_=X zMqGTfPgTN3BR^#W-NmFNC+<(>+1wzh6dIjuI&R+oGD$iJx1D8Dv86uw9hnH4Vf3bdgs z0mD|jY#-yHId7j+q71y3q7WZBoO5o?iI)l(&>M9j>*3)7R)}KJQRy0m-q6_dJ<_` z+RY!KI)%m=t2_IybMAY1uPqia^>H2r$NSZI5>4gCtjy0yjR=p2{+DCxb$WpcdH{!U z1fWsuXkdg*=0at=@`;;X9o1c&)2~p0P)HW4x2@xxj}KKKr+J|NnIC#yyUibMze{4Z z;dUUCzQl$8=K%S%{{p?TB88MaGSnZ(5kg_<$Le=WjxY3ICWKL3^tJw7taFP!^FoF; z&c+((TWT_&&TaQxxGtw3yJo z+;$=d`+AtZWjFF-SH;(RP$6D>252QOU3?g;W7=;%kP{L3>( zhd+Jle_BIe?O{M84fqMaR7Hj~RRapGaRS0F?_Zf5q+``_GZROQqlHE-V?G6ZNIC2H zpuwV%Aw7el;k^Hvr&Y{^0q0>u4%;yNQfUT42SQojyZQfFO0y4<{uc&C3)N@$tokG+ zL}GhIhWhAmDt1v8UT4?Gywb`K>0_TJTBCk7SU+vo*ST)t^%%;~UgnQDWl08kv9qp1 zdrz^^m5Bl{+C=aTybICQv>J>x$tQRIz^stmiX3Ye4%U2QME7fk@0fgpZ5X=9_pv8D zPB{=cT|6Y`dt!?&1LL|Ax_l$e%7k3DoC!zLrs?yWHAwSgz}ek}G+uAa_y_Elk})a> zG3jtl6OurV+TaoIx3EfMwngbB3>hod!75YDhI8UC7U^8S5=l+wHEy$o8zIy0uPsas z>8M1-UF?J+n>IouvU-CA4c|vlGJ}JJl_AkUq)e~v|#9=7qkXOnCNcH|*6e_CF zHnaw!8=AMoCh82R(^YuGu-`*ZroX5?G+7=8E)YqEe zhM$m~FX@6a8i_=&P#N-VK6vUbm-O&AO1O*s=b`+h10W^e55;g+y_}ifVb&rPLpf*t z;J1$97oRVkO^?XEe!AhE>)vtS3taOuBE8|(RKW*na##(fUt?RRdEv5`Yz8Nxz4Xni z2iJMr(EmJQhTIK0RsK3Oj;c))h~>p0b_}XT???g$<;S&%yga^cbDa@ajpK^VH39lQ z^7sWFor4lnGeYhssQ>leNTXj@bKE2Mq5@l3zR6D1=DAx?9uG4{7V-;4+BWF1(%tD> zKhr@q2-QXYcmUQ}*&tgl;B8OOKp=s9;5^=&5VU98=0VD}Xz71r3r*n_ahlh~yD9k~-jW+R(t-McJFNC-Ho)9{%5KBXoA+@jTp{-X^ zUi`kuZ~JY?>{?4&wl>{SytmpO@Bjfz6@l^W<%naR1(2E)=y4P42>1*3A5AgQ@7m8(UkH!7;s^NPP%~{ zUSU-SeVbQtiis?ch{VKcNS^+c;^Lkx?TnC~;k~&iqmd|6`g>#b^ViSa>nG znnaAeLKJ(bWVBy(Ph4f@D-;bzJkN57$r_Uo_0}-4?{yW}_Oj=HjSqz2Lp4jVgqrCjWh6}hHk0EJ8Suw*n~K*HB%li?w9*0NG3Ad~ zaFFAy-Hl~=g&Kr4@!CIf0O3bW*+mZgjmGSqa4tw!~baaW_ z)@^Rxeha0&HW}q?W34AK5a#}t<7n{B(=iYZ^7H+lkPfOS)AziaG5_l=bv&=zB^7JX zKJ<`%7KGrDa%c}}WFPG#C-%iNMg`X!KA{aysB0|b8gew8ZtgnkQZ=r?(>O{FsULg* zOwWEB%5ns82*=fk_-!PTNy$Fyd2KJj{uN``-8)hq_({Kuy$KX9h44uI@gSHi0}yogwnDt6^+Z+*=AAp_8MAoYgZ6U= zcb-d+wl~dO;*-0eTWUxV>U;M^*ToD+2p5ZAtP`WLUsDLdufs~zqf_c% zdmXoeVKg}U)`jlA=-2JZRkHA<7WGgN>gjhnG01?#heDBl?pYitFqyiYFd49BlL zfk0T?Nk{mJ?jw};gDy<+*YnNq&p6|2GDzVxS^L?gwV=l2z%VMK^iy4|J@QxTt+$d ztKy?7lMO*SiJ;LDjQFGANd4A^whY{M5K)Ynt>NSd+A-^11x7jRWxDVw#+-oy1eD{0ol)>Ldk`C5|I!D|Q$ z(_N?ky}$6>Gl(dQTO~`)q#5u@IU2Ve)zTm1&nH@B#hsY6I1)bIh-OPk7Cv&;p*42P zEQ{A%l$u9?<$V4mJv}N}xl^u;zPsCOg!-}Ux>0mvMkK7TG@b1H$hHp;1|qk(%%h+xYRH7 zc1k5?)WpbXyA4YwEXCzf)UQdj=j6lGp}DDk2FPUxGkCYDRp$k~AIOQb0BOU;q~*_( zeli-Co0-1cTluoGbEqcQXj|4zQT=&wiJN6Zd^8bb(yux(k!XRK|9ih^t??sTjsat| z>_E@|cZ36b9g6QP-CW*uMiXa3f4_&WVQznQW!Ohw*hxwwv$8C6#TuBahDJH2SoO zxe~<13nwTz?#lD5kgv#v-fyp8Z1{a!jL_L&kqvvAwmZ>KQfm{-SbJjdWMr5-lo_H4 z(tnn@80PK<4-`_vtmhmn?sWX+8W|E^`Gqn7jA5a_c6yw)p<>0D@lac_=kpv5of4A> zk66^wq${*_OQgiF8W?Lf-Zxzp9x9p!{Vg@9OzMQ9lt$zlcv?{&vwWlcIK0^FsVm91 zr+i|DM!?QfF*t`sucgTS;gb13?m&Y))T@cq`ISWWL0JJjerJrkur56TXA`bCI008R zMl_yvTU3?mI5Teq0V~p<>$kO6kPqHt$*J1&-)tXU(6wS(mbHGhGVC-1BU(T@qck^J zl?iW^h>G>ryd8)K3(jGL2-9M;)n;Ad7>awl5X?At9%YcIJN8a%)^Wg(r4Cu3b;7RF z%QX0)h0{3#7SDcRb@7{lH?S`YX=ahYV087r(WSGH?D$H&byOoPFI77tAXiNBKhuDp z>!BPoC_g!i5yV&KViGe4T}UTz50vj=JHiE=r{xqkOQ`tBYZP~YkNo@7;+ zYkwiW{z~I{g{XxA@K1B-z?=tI>Cm$2~x+5^>R1`&gYvn%y%yEOr*> z@%i?n`S-+SI1&9S5<`a}eHCv_AmJMR8NE5v+|x$e#gs>-eIQS3r71zIX8-K;h8WRn zQzO*RbC{!qdy2TQmq z?z*$k`>3`7BO5p6DzWMGfV~`;66HBXF8y<}0VL>~$)tsTc2YmnwbshU*aQ zd%UWRah-gwkN+em2pH~J6B*?x`n%{SRm}<$^g}1naoaB83E^Cx&kSv@n|wmOjxMM98WI9^#6uS=(@Z1*gWpRj@wR?Vrgy7#L-x&2=N84c$0 zi*L~I6G&yql{he&auQvk%uup#kl<@|YF- z10P74E)dO%RFXiE&R+cU<)&Z(pL-<>@e#NHNtl>IqNJ-i7yAYbQ?+B&Ts=vU={+la z(~Dmq#vo5j<(I!@MQ$)KX<7qYZPE;`-uw*ijTZXhO42oaQgOE7=_HQHzx`kkfItA{ z?MfKIAIa!6&|Xb0iuL6K&2^5!{Nf0Hg3_R`SQ;0sW|GMb5*a)$YpxP%y{XnT8<5Fl z(0GtUoW}l@aDV-{zy93c0Pb%f`!`s~{S|S4x%k0c{9rDAFc&|ViyzFz=OS|PNJ7%# z9kLYM!4}zp`~xx$!pyA9(WEZyB;b3IKi=>z+qG;rliDiM)3kg&*P{lVJdx?Ze-Wn9 zGHSkpefbGVpQP!)=f?C^X}Jg$2ShzwC)b+hB5;3c908YY9Gk7#El)_$F&Sp1H|Q!j z<1|T0dWLjA^-{6#*{R^J7+oh%-37X-RAhpvNdJ)1KC?Z~nDsv`)AZRQ40MBIF0qseiIxLJFT z9LLztdTIl-Y6ozdjZdu67vMMIE+X~`8OZ9_NSyWncLM_T!hA?{paeY=r|YwiCs>P zV&Yy;Z2owF6Rew9-w6OEY(B((Jdw18ttYV!r;zbt(-OOc9IiJ=d}2k@0r07NZMvBK$sef$vB$}Ah)qkZ3%R#AP28@;9$Nu$iS;M;i!T74vUMPK&;~NE zekNm0>?U%wBJLt$FYf>l5_c)F267$Low&1!U9yYRnYh;zYuHT=)}L7WJ!GB`w=1z< z?gN<3=0mLdAZb5wYl*$}Ex;}|PhzKh&4bg#okQ$-ay(_zZsNf@a@gM_`4c;8GY_g0 zcQ&yPw(+0|aYF$QipkN6xLNy&kq7OFJD1pnMLh6h-Ne>B&4cd5?Mm!ya;R8;VvQvv zU*awzw&8gmOe1bSv2o;>P2BOses+=M%f=_xSMfh`W^7=^{H=P24%eHj>!EM&jlZtLbP5 zyNFv$tR}<`idi?YgG240gt+60y-bb=Y(B)^k=emh)=jLUlO0sQ&8~4f7!Ym;O^7?5 zSo_X);6>c7#I7cXA91fIc2f*#3vm|_`!LoH-XU)2X9ok7Bri5Cv3toeinxo3Z8X#l zCJ;BD*nQ-f#`?4FRMIZiP3$9;9V}<_NwWi<+733e`HQk5chgw z(?;7t1aWJL-8hECBkm$%v$IJXiJP@9@7aNtxLt{jAjc>+A7ZG&lnY$);ywDQDM zc{0;JL8y#D?DMY#U|4zgVMd=K_JB99JykA!q}rY~9RdXILj zcZTU5`)r6vAQT8qz9gLZu<1;K+ZediFHRv`Od3owHHQ+Xz)&$zL_{rbdz1V){hB1qJzG`h}YOf+fAk=(b?dbUair9s7n%XI>IBD=)G$)ruz zu|GTU=-|;ZAt^y2N%ClC9V?2|;zg_^j*79AYFoL|PcX&AxPMWa(N zIyP98Ad(9e<&Ee<(rHcqmmGmw(^sCLx6JJo(G7n%^2?R5ZV&rIic0ddjyhbfQqf17nC=R`!Px~J6^Bq0JSDc zqawlKwi}dAW=A49?bKQk2OlDsmVqOOt6})a+GcxT#I#=8?=ZMr{bU-8gQfUUa*u z#}XvwCEtsC{=()WsL;7KqFUwXr?45Vl18vUu6k`t*+@}J6fsRSj7??^rw8Eb8a#8FrG3AB%H~ z?b8oENwWRX)!dI(XR2UvkVs;=16nRqf-uk`LXzz>vW<<#vSlKUO1316LW6{Ig^2MO zJ^KH{=YOW#vo~MHYd`;!ymbFB3c&mSf8z5$G6gF6_>Y9(r+@$I^)LF5EdJN8f1&uL z`+uRIzaOsue_;K~aYg*UUH{^LX#I;sfiJKB09^n7$oiMtKK+aF-2bm%|B`=d{o6eM z>`QJ1HTns5X&2YY&8P4Zkwe97pPtl~S6l8BOu&+_1Z#VSB#sBX) z|C^TnNM-VWF9bb?&n#M6@NG>w;Bu6#@n`?z@4?Xv;d@t5Fg^_CoS~6+l Date: Mon, 25 Mar 2024 13:23:25 -0700 Subject: [PATCH 06/27] a --- .../packages/bunx-bins/bunx-bins-1.0.0.tgz | Bin 152891 -> 152970 bytes .../registry/packages/bunx-bins/package.json | 16 +++++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/test/cli/install/registry/packages/bunx-bins/bunx-bins-1.0.0.tgz b/test/cli/install/registry/packages/bunx-bins/bunx-bins-1.0.0.tgz index f44a5ae1899688aa02b958bf02f2df6ae70f2c72..4f99c67740cbae7f77d3853c199c053906efa94a 100644 GIT binary patch delta 14009 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%0DGrPesUng=-iN`9`v)4-Nq6#xEey4_NfQOY8N2 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

@HOaq0b7uvzMlS98Yy#KDbZ9J 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 Date: Mon, 25 Mar 2024 12:50:31 -0700 Subject: [PATCH 07/27] a --- .../registry/bun-install-registry.test.ts | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/test/cli/install/registry/bun-install-registry.test.ts b/test/cli/install/registry/bun-install-registry.test.ts index a3bfb09a96ae3..c15b3855ebb77 100644 --- a/test/cli/install/registry/bun-install-registry.test.ts +++ b/test/cli/install/registry/bun-install-registry.test.ts @@ -1,5 +1,5 @@ import { file, spawn } from "bun"; -import { bunExe, bunEnv as env, toBeValidBin, toHaveBins } from "harness"; +import { bunExe, bunEnv as env, isWindows, toBeValidBin, toHaveBins } from "harness"; import { join } from "path"; import { mkdtempSync, realpathSync } from "fs"; import { rm, writeFile, mkdir, exists, cp } from "fs/promises"; @@ -51,7 +51,7 @@ registry = "http://localhost:${port}/" }); afterEach(async () => { - await rm(packageDir, { force: true, recursive: true }); + 0 && (await rm(packageDir, { force: true, recursive: true })); }); describe.each(["--production", "without --production"])("%s", flag => { @@ -6616,3 +6616,40 @@ describe("yarn tests", () => { expect(await exited).toBe(0); }); }); + +test.if(isWindows)("bin linking shim should work", async () => { + await writeFile( + join(packageDir, "package.json"), + JSON.stringify({ + name: "foo", + version: "1.0.0", + dependencies: { + "bunx-bins": "*", + }, + }), + ); + console.log(packageDir); + + var { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "install", "--dev"], + cwd: packageDir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env, + }); + + var err = await new Response(stderr).text(); + var out = await new Response(stdout).text(); + console.log(err); + expect(err).toContain("Saved lockfile"); + expect(err).not.toContain("error:"); + expect(err).not.toContain("panic:"); + expect(err).not.toContain("not found"); + expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([ + "", + " + bunx-bins@1.0.0", + "", + expect.stringContaining("1 package installed"), + ]); +}); From 4fae44bc2c2b5ec30b29363302293711a81ca157 Mon Sep 17 00:00:00 2001 From: dave caruso Date: Mon, 25 Mar 2024 17:01:20 -0700 Subject: [PATCH 08/27] blah --- docs/installation.md | 4 +- src/bun.js/WebKit | 2 +- src/cli/run_command.zig | 8 +- src/cli/uninstall.ps1 | 9 +- src/install/windows-shim/BinLinkingShim.zig | 12 +- src/install/windows-shim/bun_shim_impl.exe | Bin 13312 -> 12800 bytes src/install/windows-shim/bun_shim_impl.zig | 128 ++++++++++-------- src/output.zig | 12 +- test/cli/install/bunx.test.ts | 7 +- .../registry/bun-install-registry.test.ts | 55 +++++++- 10 files changed, 154 insertions(+), 83 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index bada2d86b071a..cac2b33c38e5d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -232,8 +232,8 @@ If you need to remove Bun from your system, use the following commands. $ rm -rf ~/.bun # for macOS, Linux, and WSL ``` -```bash#Windows -$ Remove-Item ~\.bun -Recurse +```powershell#Windows +powershell -c ~\.bun\uninstall.ps1 ``` ```bash#NPM diff --git a/src/bun.js/WebKit b/src/bun.js/WebKit index c3712c13dcdc0..64b2fa7da7c07 160000 --- a/src/bun.js/WebKit +++ b/src/bun.js/WebKit @@ -1 +1 @@ -Subproject commit c3712c13dcdc091cfe4c7cb8f2c1fd16472e6f92 +Subproject commit 64b2fa7da7c077a3ac7f258d45281f25ac2ef250 diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index 9b3ebb92ca1ef..f47e75e909018 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -456,19 +456,20 @@ pub const RunCommand = struct { // wrapper exe. we build the full exe path even though we could do // a relative lookup, because in the case we do find it, we have to // generate this full path anyways. + // if (Environment.isWindows and bun.strings.hasSuffixComptime(executable, ".exe")) { std.debug.assert(std.fs.path.isAbsolute(executable)); - + // Using @constCast is safe because we know that // `direct_launch_buffer` is the data destination that assumption is // backed by the immediate assertion. var wpath = @constCast(bun.strings.toNTPath(&BunXFastPath.direct_launch_buffer, executable)); std.debug.assert(bun.isSliceInBufferT(u16, wpath, &BunXFastPath.direct_launch_buffer)); - + std.debug.assert(wpath.len > bun.windows.nt_object_prefix.len + ".exe".len); wpath.len += ".bunx".len - ".exe".len; @memcpy(wpath[wpath.len - "bunx".len ..], comptime bun.strings.w("bunx")); - + BunXFastPath.tryLaunch(ctx, wpath, env, passthrough); } @@ -1507,6 +1508,7 @@ pub const RunCommand = struct { // Run absolute/relative path if ((script_name_to_search.len > 1 and script_name_to_search[0] == '/') or + (Environment.isWindows and script_name_to_search > 3 and std.ascii.isAlphabetic(script_name_to_search[0]) and script_name_to_search[1] == ':') or (script_name_to_search.len > 2 and script_name_to_search[0] == '.' and script_name_to_search[1] == '/')) { Run.boot(ctx, ctx.allocator.dupe(u8, script_name_to_search) catch unreachable) catch |err| { diff --git a/src/cli/uninstall.ps1 b/src/cli/uninstall.ps1 index df74be1872f7d..7fca554a9f449 100644 --- a/src/cli/uninstall.ps1 +++ b/src/cli/uninstall.ps1 @@ -12,7 +12,8 @@ $ErrorActionPreference = "Stop" function Write-Env { param([String]$Key, [String]$Value) - $EnvRegisterKey = Get-Item -Path 'HKCU:Environment' + $RegisterKey = Get-Item -Path 'HKCU:' + $EnvRegisterKey = $RegisterKey.OpenSubKey('Environment', $true) if ($null -eq $Value) { $EnvRegisterKey.DeleteValue($Key) } else { @@ -30,7 +31,8 @@ function Write-Env { function Get-Env { param([String] $Key) - $RegisterKey = Get-Item -Path 'HKCU:Environment' + $RegisterKey = Get-Item -Path 'HKCU:' + $EnvRegisterKey = $RegisterKey.OpenSubKey('Environment') $EnvRegisterKey.GetValue($Key, $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) } @@ -94,8 +96,9 @@ try { $Path = $Path -split ';' $Path = $Path | Where-Object { $_ -ne "${PSScriptRoot}\bin" } Write-Env -Key 'Path' -Value ($Path -join ';') -} catch { +} catch { Write-Host "Could not remove ${PSScriptRoot}\bin from PATH." + Write-Error $_ if ($PauseOnError) { pause } exit 1 } diff --git a/src/install/windows-shim/BinLinkingShim.zig b/src/install/windows-shim/BinLinkingShim.zig index 30eec10c93f6c..81dac390eba31 100644 --- a/src/install/windows-shim/BinLinkingShim.zig +++ b/src/install/windows-shim/BinLinkingShim.zig @@ -84,14 +84,14 @@ fn wU8(comptime s: []const u8) []const u8 { pub const Shebang = struct { launcher: []const u8, utf16_len: u32, - is_bun: bool, + is_node_or_bun: bool, - pub fn init(launcher: []const u8, is_bun: bool) !Shebang { + pub fn init(launcher: []const u8, is_node_or_bun: bool) !Shebang { return .{ .launcher = launcher, // TODO(@paperdave): what if this is invalid utf8? .utf16_len = @intCast(bun.simdutf.length.utf16.from.utf8(launcher)), - .is_bun = is_bun, + .is_node_or_bun = is_node_or_bun, }; } @@ -202,8 +202,8 @@ pub const Shebang = struct { if (eqlComptime(first, "/usr/bin/env") or eqlComptime(first, "/bin/env")) { const rest = tokenizer.rest(); const program = tokenizer.next() orelse return parseFromBinPath(bin_path); - const is_bun = eqlComptime(program, "bun") or eqlComptime(program, "node"); - return try Shebang.init(rest, is_bun); + const is_node_or_bun = eqlComptime(program, "bun") or eqlComptime(program, "node"); + return try Shebang.init(rest, is_node_or_bun); } return try Shebang.init(line, false); @@ -237,7 +237,7 @@ pub fn encodeInto(options: @This(), buf: []u8) !void { wbuf[1] = 0; wbuf = wbuf[2..]; - const is_node_or_bun = if (options.shebang) |s| s.is_bun else false; + const is_node_or_bun = if (options.shebang) |s| s.is_node_or_bun else false; var flags = Flags{ .has_shebang = options.shebang != null, .is_node_or_bun = is_node_or_bun, diff --git a/src/install/windows-shim/bun_shim_impl.exe b/src/install/windows-shim/bun_shim_impl.exe index 57ec9a4a8dfa6bd031d689620162667facbf8063..78cbc16faac42d25aaf4faab83471d1dda9eb81a 100755 GIT binary patch delta 1049 zcmZ9Ie`s4(6vyv*d+D=To0p_X+XZJ!c~d&YEwWj4?bKSwecJ=Y6%B2+bh8be4iwwS z&_NQKpwINd+?oAr;6MH&?w^{C!ITog5eMp|qjsWyD9X64ovT&4Ziv_OUZ!9#-1F;x z?>V1)bECQ86S?LwpOR*G)-vm08IdP0m<^x_4EQ*{TjCRI(R zZ!^=+AJzW07bbpM%ir4m5n~ziiPej0hNr6qBbjH!!ky#VU%BH(l4XM2zQyeotJG(V zie{ZL%Q@?*xLZkARgJNQD+DXd4P^Ss(22Hc+Ew$j8|`}GO<>Hf>~;Koj|8kogMgo9wxN3E-Ss=J$X-hTidx@Es#*I?G5kULyIs8}uCJ-nRlxn)2ic1x zDONIVV#&ptSX0JR`uR%FFA9Cnv!aEZn03)gmT~NYq$PePVYSZ~l7#7%xzle9iPP>Z zS0y^UXwt}$Ktw5_>X5J~5cAZ^`*WW-kj+ zMh`9`Rw;1d^kSWhaP!~MHKH{-C8FW~5ec8wQnF7jA1DfnE4s<3KpGi#n9HyiV@v_;v1V-i{DB2%@r|CZdcbzR=E zE|0Ct!*_BVXi2DxZH!^4H5T6|q;ie*vxPc zNP>B|NBTf}TwyQ@f?q`NgIOsmxQsDUT{lOOA=?)f88=L)R_kolUQb@;-;ZVAcH!Oo z`ufCKOv%*WHv0E@GK zLX)D*uR_hS2_|um<7a5Vb8r6iN`Lx!NV&qA;;;#G2xYog9 zUfrDH=7gRJX?@}il~L|n`z?J=TIm|3t%^x%F1)Esy@TP>oXzhS|fxs}!;0F1-a zIvqrD%)jk1RpW~pDNCdB%xwIIVow0 zi*%v+kk&29l^y0*o7OG9rm#&#&_?}Ql3oy1L`d5$!UV*5DpkCZm{S}nK_!Oa@}U1j zGpSAI@s%{G>CDn0Ix$|pIx$8rjah`1VB~z1>B~v}mnCcP7C|okN z)JFX!Qw>DORFCK+&^XR5_k$+7!C;6nE%BwJLbqChr>19s;mV2{^;b%gxic-cxwF~r z6`uf<YlV{PL#ZY}iUC3h!`W>8U zGG9AtZ-dY9D}NXLgeLtR z5Xbjx+F?ufSj|Def!g*@49DWdE7!|K7iM xHed2%LH{S$q#XN8%KoeL6r_Cpx|BO^N_m9hEfZ3j#0wNJ(0L}?IPctx4*@-89n=5- diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index 2c171f6854fda..06f40b309a828 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -56,11 +56,9 @@ const Flags = @import("./BinLinkingShim.zig").Flags; pub inline fn wliteral(comptime str: []const u8) []const u16 { if (!@inComptime()) @compileError("strings.w() must be called in a comptime context"); comptime var output: [str.len]u16 = undefined; - for (str, 0..) |c, i| { output[i] = c; } - const Static = struct { pub const literal: []const u16 = output[0..output.len]; }; @@ -179,7 +177,7 @@ const FailReason = enum { .CouldNotDirectLaunch => if (!is_standalone) "bin metadata is corrupt (invalid utf16)" else - // Unreachable is ok because Direct Launch is not supported in standalone mode + // unreachable is ok because Direct Launch is not supported in standalone mode unreachable, }; } @@ -194,7 +192,9 @@ const FailReason = enum { try writer.writeAll("error: "); switch (reason) { inline else => |r| { - if (is_standalone and r == .CouldNotDirectLaunch) unreachable; + if (is_standalone and r == .CouldNotDirectLaunch) + // unreachable is ok because Direct Launch is not supported in standalone mode + unreachable; const template = comptime getFormatTemplate(r) ++ "\n\n"; @@ -346,8 +346,8 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { assert(@intFromPtr(cmd_line_u16.ptr) % 2 == 0); // alignment assumption if (dbg) { - debug("CommandLine: {}\n", .{fmt16(cmd_line_u16[0 .. cmd_line_b_len / 2])}); - debug("ImagePathName: {}\n", .{fmt16(image_path_u16[0 .. image_path_b_len / 2])}); + debug("CommandLine: {}", .{fmt16(cmd_line_u16[0 .. cmd_line_b_len / 2])}); + debug("ImagePathName: {}", .{fmt16(image_path_u16[0 .. image_path_b_len / 2])}); } var buf1: [w.PATH_MAX_WIDE + "\"\" ".len]u16 = undefined; @@ -394,8 +394,8 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { .MaximumLength = path_len_bytes, .Buffer = buf1_u16, }; - if (dbg) debug("NtCreateFile({s})\n", .{fmt16(unicodeStringToU16(nt_name))}); - if (dbg) debug("NtCreateFile({any})\n", .{(unicodeStringToU16(nt_name))}); + if (dbg) debug("NtCreateFile({s})", .{fmt16(unicodeStringToU16(nt_name))}); + if (dbg) debug("NtCreateFile({any})", .{(unicodeStringToU16(nt_name))}); var attr = w.OBJECT_ATTRIBUTES{ .Length = @sizeOf(w.OBJECT_ATTRIBUTES), .RootDirectory = null, @@ -407,8 +407,8 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // NtCreateFile will fail for absolute paths if we do not pass an OBJECT name // so we need the prefix here. This is an extra sanity check. if (dbg) { - std.debug.assert(std.mem.startsWith(u16, unicodeStringToU16(nt_name), &nt_object_prefix)); - std.debug.assert(std.mem.endsWith(u16, unicodeStringToU16(nt_name), comptime wliteral(".bunx"))); + assert(std.mem.startsWith(u16, unicodeStringToU16(nt_name), &nt_object_prefix)); + assert(std.mem.endsWith(u16, unicodeStringToU16(nt_name), comptime wliteral(".bunx"))); } const rc = nt.NtCreateFile( &metadata_handle, @@ -424,7 +424,7 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { 0, ); if (rc != .SUCCESS) { - if (dbg) debug("error opening: {s}\n", .{@tagName(rc)}); + if (dbg) debug("error opening: {s}", .{@tagName(rc)}); if (rc == .OBJECT_NAME_NOT_FOUND) mode.fail(.ShimNotFound); mode.fail(.CouldNotOpenShim); @@ -464,11 +464,11 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { break :find_args cmd_line_u8[0..0]; }; - if (dbg) debug("UserArgs: '{s}' ({d} bytes)\n", .{ user_arguments_u8, user_arguments_u8.len }); + if (dbg) debug("UserArgs: '{s}' ({d} bytes)", .{ user_arguments_u8, user_arguments_u8.len }); - std.debug.assert(user_arguments_u8.len % 2 == 0); - std.debug.assert(user_arguments_u8.len != 2); - std.debug.assert(user_arguments_u8.len == 0 or user_arguments_u8[0] == ' '); + assert(user_arguments_u8.len % 2 == 0); + assert(user_arguments_u8.len != 2); + assert(user_arguments_u8.len == 0 or user_arguments_u8[0] == ' '); // Read the metadata file into the memory right after the image path. // @@ -484,18 +484,18 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { var read_ptr: [*]u16 = brk: { var left = image_path_b_len / 2 - (if (is_standalone) ".exe".len else ".bunx".len) - 1; var ptr: [*]u16 = buf1_u16[nt_object_prefix.len + left ..]; - if (dbg) debug("left = {d}, at {}, after {}\n", .{ left, ptr[0], ptr[1] }); + if (dbg) debug("left = {d}, at {}, after {}", .{ left, ptr[0], ptr[1] }); // if this is false, potential out of bounds memory access if (dbg) - std.debug.assert( + assert( @intFromPtr(ptr) - left * @sizeOf(std.meta.Child(@TypeOf(ptr))) >= @intFromPtr(buf1_u16), ); // we start our search right before the . as we know the extension is '.bunx' - std.debug.assert(ptr[1] == '.'); + assert(ptr[1] == '.'); while (true) { - if (dbg) debug("1 - {}\n", .{std.unicode.fmtUtf16le(ptr[0..1])}); + if (dbg) debug("1 - {}", .{std.unicode.fmtUtf16le(ptr[0..1])}); if (ptr[0] == '\\') { left -= 1; // ptr is of type [*]u16, which means -= operates on number of ITEMS, not BYTES @@ -508,12 +508,12 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { } ptr -= 1; if (dbg) - std.debug.assert(@intFromPtr(ptr) >= @intFromPtr(buf1_u16)); + assert(@intFromPtr(ptr) >= @intFromPtr(buf1_u16)); } // inlined loop to do this again, because the completion case is different // using `inline for` caused comptime issues that made the code much harder to read while (true) { - if (dbg) debug("2 - {}\n", .{std.unicode.fmtUtf16le(ptr[0..1])}); + if (dbg) debug("2 - {}", .{std.unicode.fmtUtf16le(ptr[0..1])}); if (ptr[0] == '\\') { // ptr is at the position marked S, so move forward one *character* break :brk ptr + 1; @@ -524,17 +524,17 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { } ptr -= 1; if (dbg) - std.debug.assert(@intFromPtr(ptr) >= @intFromPtr(buf1_u16)); + assert(@intFromPtr(ptr) >= @intFromPtr(buf1_u16)); } - @compileError("unreachable"); + @compileError("unreachable - the loop breaks this entire block"); }; - std.debug.assert(read_ptr[0] != '\\'); - std.debug.assert((read_ptr - 1)[0] == '\\'); + assert(read_ptr[0] != '\\'); + assert((read_ptr - 1)[0] == '\\'); const read_max_len = buf1.len * 2 - (@intFromPtr(read_ptr) - @intFromPtr(buf1_u16)); - if (dbg) debug("read_ptr = buf1 + {d}\n", .{(@intFromPtr(read_ptr) - @intFromPtr(buf1_u16))}); - if (dbg) debug("max_read_len = {d}\n", .{read_max_len}); + if (dbg) debug("read_ptr = buf1 + {d}", .{(@intFromPtr(read_ptr) - @intFromPtr(buf1_u16))}); + if (dbg) debug("max_read_len = {d}", .{read_max_len}); // Do the read! // @@ -556,25 +556,25 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // In the context of this program, I don't think that is possible, but I will handle it read_max_len, else => |rc| { - if (dbg) debug("error reading: {s}\n", .{@tagName(rc)}); + if (dbg) debug("error reading: {s}", .{@tagName(rc)}); return mode.fail(.CouldNotReadShim); }, }; _ = nt.NtClose(metadata_handle); - if (dbg) debug("BufferAfterRead: '{}'\n", .{fmt16(buf1_u16[0 .. ((@intFromPtr(read_ptr) - @intFromPtr(buf1_u8)) + read_len) / 2])}); + if (dbg) debug("BufferAfterRead: '{}'", .{fmt16(buf1_u16[0 .. ((@intFromPtr(read_ptr) - @intFromPtr(buf1_u8)) + read_len) / 2])}); read_ptr = @ptrFromInt(@intFromPtr(read_ptr) + read_len - @sizeOf(Flags)); const flags: Flags = @as(*align(1) Flags, @ptrCast(read_ptr)).*; if (dbg) { const flags_u16: u16 = @as(*align(1) u16, @ptrCast(read_ptr)).*; - debug("FlagsInt: {d}\n", .{flags_u16}); + debug("FlagsInt: {d}", .{flags_u16}); - debug("Flags:\n", .{}); + debug("Flags:", .{}); inline for (comptime std.meta.fieldNames(Flags)) |name| { - debug(" {s}: {}\n", .{ name, @field(flags, name) }); + debug(" {s}: {}", .{ name, @field(flags, name) }); } } @@ -642,8 +642,8 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { const shebang_bin_path_len_bytes = shebang_metadata.bin_path_len_bytes; if (dbg) { - debug("bin_path_len_bytes: {}\n", .{shebang_metadata.bin_path_len_bytes}); - debug("args_len_bytes: {}\n", .{shebang_metadata.args_len_bytes}); + debug("bin_path_len_bytes: {}", .{shebang_metadata.bin_path_len_bytes}); + debug("args_len_bytes: {}", .{shebang_metadata.args_len_bytes}); } // magic number related to how BinLinkingShim.zig writes the metadata @@ -655,7 +655,7 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { (@as(u64, shebang_arg_len_u8) +| @as(u64, shebang_bin_path_len_bytes)) + validation_length_offset != read_len) { if (dbg) - debug("read_len: {}\n", .{read_len}); + debug("read_len: {}", .{read_len}); return mode.fail(.InvalidShimBounds); } @@ -670,7 +670,7 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // // This optimization can save an additional ~10-20ms depending on the machine // as we do not have to launch a second process. - if (dbg) debug("direct_launch_with_bun_js\n", .{}); + if (dbg) debug("direct_launch_with_bun_js", .{}); // BUF1: '\??\C:\Users\dave\project\node_modules\my-cli\src\app.js"#node #####!!!!!!!!!!' // ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^ read_ptr const len = (@intFromPtr(read_ptr) - @intFromPtr(buf1_u8) - shebang_arg_len_u8) / 2 - nt_object_prefix.len - "\"\x00".len; @@ -698,11 +698,14 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^ read_ptr // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js"!!!!!!!!!!!!!!!!!!!!' const length_of_filename_u8 = @intFromPtr(read_ptr) - - @intFromPtr(buf1_u8) - nt_object_prefix.len - - (2 * "\x00n".len); // the 'n' refers to the first char of the shebang. + @intFromPtr(buf1_u8) - 2 * nt_object_prefix.len - 2 * "\x00".len; const filename = buf1_u8[2 * nt_object_prefix.len ..][0..length_of_filename_u8]; - if (dbg) - debug("filename and quote: '{}'\n", .{fmt16(@alignCast(std.mem.bytesAsSlice(u16, filename)))}); + if (dbg) { + const sliced = std.mem.bytesAsSlice(u16, filename); + debug("filename and quote: '{}'", .{fmt16(@alignCast(sliced))}); + debug("last char of above is '{}'", .{sliced[sliced.len - 1]}); + assert(sliced[sliced.len - 1] == '\"'); + } @memcpy( buf2_u8[shebang_arg_len_u8 + 2 * "\"".len ..][0..length_of_filename_u8], @@ -712,8 +715,12 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // note that it points into buf2 now, not buf1. this will write arguments and the null terminator // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js"!!!!!!!!!!!!!!!!!!!!' // ^ write_ptr - const advance = length_of_filename_u8 + shebang_arg_len_u8 + 2 * "\"".len; - var write_ptr: [*]u8 = @ptrFromInt(@intFromPtr(buf2_u8) + advance); + if (dbg) { + debug("advance = {} + {} + {}\n", .{ shebang_arg_len_u8, "\"".len, length_of_filename_u8 }); + } + const advance = shebang_arg_len_u8 + 2 * "\"".len + length_of_filename_u8; + var write_ptr: [*]u16 = @ptrFromInt(@intFromPtr(buf2_u8) + advance); + assert((write_ptr - 1)[0] == '"'); if (user_arguments_u8.len > 0) { // Copy the user arguments in: @@ -728,12 +735,18 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js" --flags#!!!!!!!!!!' // ^ null terminator - @as(*align(1) u16, @ptrCast(write_ptr)).* = 0; + write_ptr[0] = 0; break :spawn_command_line @ptrCast(buf2_u16); }, }; + if (!is_standalone) { + // Prepare stdio for the child process, as after this we are going to immediatly exit. + bun.Output.Source.Stdio.restore(); + bun.C.windows_enable_stdio_inheritance(); + } + // I attempted to use lower level methods for this, but it really seems // too difficult and not worth the stability risks. // @@ -778,8 +791,8 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { null, null, 1, // true - if (is_standalone) 0 else w.CREATE_UNICODE_ENVIRONMENT, - if (is_standalone) null else @constCast(bun_ctx.environment), + 0, + null, null, &startup_info, &process, @@ -787,8 +800,8 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { if (did_process_spawn == 0) { const spawn_err = k32.GetLastError(); if (dbg) { - debug("CreateProcessW failed: {s}\n", .{@tagName(spawn_err)}); - debug("attempt number: {d}\n", .{attempt_number}); + debug("CreateProcessW failed: {s}", .{@tagName(spawn_err)}); + debug("attempt number: {d}", .{attempt_number}); } return switch (spawn_err) { .FILE_NOT_FOUND => if (flags.has_shebang) { @@ -868,14 +881,15 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { var exit_code: w.DWORD = 255; _ = k32.GetExitCodeProcess(process.hProcess, &exit_code); + if (dbg) debug("exit_code: {d}", .{exit_code}); _ = nt.NtClose(process.hProcess); _ = nt.NtClose(process.hThread); nt.RtlExitUserProcess(exit_code); - @compileError("unreachable"); + @compileError("unreachable - RtlExitUserProcess does not return"); } - @compileError("unreachable"); + @compileError("unreachable - above loop should not exit"); } pub const FromBunRunContext = struct { @@ -907,8 +921,8 @@ pub const FromBunRunContext = struct { /// this returns void, to which the caller should still try invoking the exe directly. This /// is to handle version mismatches where bun.exe's decoder is too new than the .bunx file. pub fn tryStartupFromBunJS(context: FromBunRunContext) void { - std.debug.assert(!std.mem.startsWith(u16, context.base_path, &nt_object_prefix)); - comptime std.debug.assert(!is_standalone); + assert(!std.mem.startsWith(u16, context.base_path, &nt_object_prefix)); + comptime assert(!is_standalone); launcher(.launch, context); } @@ -941,16 +955,16 @@ pub const ReadWithoutLaunchResult = union { /// The cost of spawning is about 5-12ms, and the unicode conversions are way /// faster than that, so this is a huge win. pub fn readWithoutLaunch(context: FromBunShellContext) ReadWithoutLaunchResult { - std.debug.assert(!std.mem.startsWith(u16, context.base_path, &nt_object_prefix)); - comptime std.debug.assert(!is_standalone); + assert(!std.mem.startsWith(u16, context.base_path, &nt_object_prefix)); + comptime assert(!is_standalone); return launcher(.read_without_launch, context); } /// Main function for `bun_shim_impl.exe` pub inline fn main() noreturn { - comptime std.debug.assert(is_standalone); - comptime std.debug.assert(builtin.single_threaded); - comptime std.debug.assert(!builtin.link_libc); - comptime std.debug.assert(!builtin.link_libcpp); + comptime assert(is_standalone); + comptime assert(builtin.single_threaded); + comptime assert(!builtin.link_libc); + comptime assert(!builtin.link_libcpp); launcher(.launch, {}); } diff --git a/src/output.zig b/src/output.zig index 41b01dbb58100..fc4152187eb32 100644 --- a/src/output.zig +++ b/src/output.zig @@ -241,9 +241,9 @@ pub const Source = struct { const stdout = bun.sys.File.from(std.io.getStdOut()); const stderr = bun.sys.File.from(std.io.getStdErr()); - var output_source = Output.Source.init(stdout, stderr); - output_source.set(); + Output.Source.init(stdout, stderr) + .set(); if (comptime Environment.isDebug) { initScopedDebugWriterAtStartup(); @@ -259,8 +259,8 @@ pub const Source = struct { } }; - pub fn set(_source: *Source) void { - source = _source.*; + pub fn set(new_source: *const Source) void { + source = new_source.*; source_set = true; if (!stdout_stream_set) { @@ -288,8 +288,8 @@ pub const Source = struct { enable_ansi_colors = enable_ansi_colors_stdout or enable_ansi_colors_stderr; } - stdout_stream = _source.stream; - stderr_stream = _source.error_stream; + stdout_stream = new_source.stream; + stderr_stream = new_source.error_stream; } } }; diff --git a/test/cli/install/bunx.test.ts b/test/cli/install/bunx.test.ts index 61574d4eb80dc..b96d787da3da6 100644 --- a/test/cli/install/bunx.test.ts +++ b/test/cli/install/bunx.test.ts @@ -29,9 +29,10 @@ it("should choose the tagged versions instead of the PATH versions when a tag is const results = await Promise.all(processes.map(p => p.exited)); expect(results).toEqual([0, 0, 0]); - const outputs = (await Promise.all(processes.map(p => new Response(p.stdout).text()))).map(a => - a.substring(0, a.indexOf("\n")), - ); + const outputs = (await Promise.all(processes.map(p => new Response(p.stdout).text()))).map(a => { + console.log(a); + return a.substring(0, a.indexOf("\n")); + }); expect(outputs).toEqual(["SemVer 7.5.0", "SemVer 7.5.1", "SemVer 7.5.2"]); }); diff --git a/test/cli/install/registry/bun-install-registry.test.ts b/test/cli/install/registry/bun-install-registry.test.ts index c15b3855ebb77..03803394fb0a0 100644 --- a/test/cli/install/registry/bun-install-registry.test.ts +++ b/test/cli/install/registry/bun-install-registry.test.ts @@ -1,12 +1,13 @@ import { file, spawn } from "bun"; import { bunExe, bunEnv as env, isWindows, toBeValidBin, toHaveBins } from "harness"; import { join } from "path"; -import { mkdtempSync, realpathSync } from "fs"; +import { mkdtempSync, realpathSync, copyFileSync, mkdirSync } from "fs"; import { rm, writeFile, mkdir, exists, cp } from "fs/promises"; import { readdirSorted } from "../dummy.registry"; import { tmpdir } from "os"; import { fork, ChildProcess } from "child_process"; import { beforeAll, afterAll, beforeEach, afterEach, test, expect, describe } from "bun:test"; +import { f } from "js/bun/http/js-sink-sourmap-fixture/index.mjs"; expect.extend({ toBeValidBin, @@ -6617,7 +6618,11 @@ describe("yarn tests", () => { }); }); -test.if(isWindows)("bin linking shim should work", async () => { +// This test is to verify that BinLinkingShim.zig creates correct shim files as +// well as bun_shim_impl.exe works in various edge cases. There are many fast +// paths for many many cases. +test.if(isWindows)("windows bin linking shim should work", async () => { + expect(process.platform).toBe("win32"); // extra check await writeFile( join(packageDir, "package.json"), JSON.stringify({ @@ -6652,4 +6657,50 @@ test.if(isWindows)("bin linking shim should work", async () => { "", expect.stringContaining("1 package installed"), ]); + + const temp_bin_dir = join(packageDir, "temp"); + mkdirSync(temp_bin_dir); + + for (let i = 1; i <= 7; i++) { + const target = join(temp_bin_dir, "a".repeat(i) + ".exe"); + copyFileSync(bunExe(), target); + } + + const PATH = process.env.PATH + ";" + temp_bin_dir; + + const bins = [ + { bin: "bin1", name: "bin1" }, + { bin: "bin2", name: "bin2" }, + { bin: "bin3", name: "bin3" }, + { bin: "bin4", name: "bin4" }, + { bin: "bin5", name: "bin5" }, + { bin: "bin6", name: "bin6" }, + { bin: "bin7", name: "bin7" }, + { bin: "bin-node", name: "bin-node" }, + { bin: "bin-bun", name: "bin-bun" }, + { bin: "bin-py", name: "bin-py" }, + { bin: "native", name: "exe" }, + { bin: "uses-native", name: "exe" }, + ]; + + for (const { bin, name } of bins) { + // `bun run ${bin} arg1 arg2` + var { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "run", bin, "arg1", "arg2"], + cwd: packageDir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env: { + ...env, + PATH, + }, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err.trim()).toBe(""); + const out = await new Response(stdout).text(); + expect(out.trim()).toBe(`i am ${name} arg1 arg2`); + expect(await exited).toBe(0); + } }); From e3ea26c1f23779471f0d5488b1ac40dc4f812433 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 00:03:25 +0000 Subject: [PATCH 09/27] [autofix.ci] apply automated fixes --- src/cli/run_command.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index f47e75e909018..ab7cf2ee8fddc 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -459,17 +459,17 @@ pub const RunCommand = struct { // if (Environment.isWindows and bun.strings.hasSuffixComptime(executable, ".exe")) { std.debug.assert(std.fs.path.isAbsolute(executable)); - + // Using @constCast is safe because we know that // `direct_launch_buffer` is the data destination that assumption is // backed by the immediate assertion. var wpath = @constCast(bun.strings.toNTPath(&BunXFastPath.direct_launch_buffer, executable)); std.debug.assert(bun.isSliceInBufferT(u16, wpath, &BunXFastPath.direct_launch_buffer)); - + std.debug.assert(wpath.len > bun.windows.nt_object_prefix.len + ".exe".len); wpath.len += ".bunx".len - ".exe".len; @memcpy(wpath[wpath.len - "bunx".len ..], comptime bun.strings.w("bunx")); - + BunXFastPath.tryLaunch(ctx, wpath, env, passthrough); } From 2ef978a729440d3552f460005fe7c1707313609a Mon Sep 17 00:00:00 2001 From: dave caruso Date: Mon, 25 Mar 2024 17:02:30 -0700 Subject: [PATCH 10/27] bump --- .../packages/bunx-bins/bunx-bins-1.0.0.tgz | Bin 152970 -> 152267 bytes .../registry/packages/bunx-bins/package.json | 13 +++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/test/cli/install/registry/packages/bunx-bins/bunx-bins-1.0.0.tgz b/test/cli/install/registry/packages/bunx-bins/bunx-bins-1.0.0.tgz index 4f99c67740cbae7f77d3853c199c053906efa94a..b33009b1371cc664828c57687f226d4c5935e822 100644 GIT binary patch delta 13563 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 diff --git a/test/cli/install/registry/packages/bunx-bins/package.json b/test/cli/install/registry/packages/bunx-bins/package.json index f0adefd5840e8..ffdfd47cda49d 100644 --- a/test/cli/install/registry/packages/bunx-bins/package.json +++ b/test/cli/install/registry/packages/bunx-bins/package.json @@ -7,6 +7,7 @@ "bin": { "bin-node": "bin-node.js", "bin-bun": "bin-bun.ts", + "bin-bun-run": "bin-bun-run.ts", "bin-py": "bin-py.py", "bin1": "bin1.ts", "bin2": "bin2.ts", @@ -23,17 +24,17 @@ "_nodeVersion": "21.7.1", "_npmVersion": "10.5.0", "dist": { - "integrity": "sha512-/9hHaZuimeMyfSmQZPnrk8mP5QsLJDMpkBKiGZ0qRgCfXWfp0HH649pyqI3+wqWmsx08gv4EjZGV6qmeqooTzA==", - "shasum": "7837a6c1c921bed2653833976abecd97753a25bf", + "integrity": "sha512-BJf8PSFHafYTaZ76t2c0C1KXAv0xKdqJNKxZ9APbCzbEhT9ilvfLFYsbkXjOySGBDuWg0Pb/dEc6gb6WLvJMoQ==", + "shasum": "c23382ce43a04a94035050ac736f04179a8639ff", "tarball": "http://localhost:4873/bunx-bins/-/bunx-bins-1.0.0.tgz" }, "contributors": [] } }, "time": { - "modified": "2024-03-25T20:21:25.444Z", - "created": "2024-03-25T20:21:25.444Z", - "1.0.0": "2024-03-25T20:21:25.444Z" + "modified": "2024-03-26T00:02:03.432Z", + "created": "2024-03-26T00:02:03.432Z", + "1.0.0": "2024-03-26T00:02:03.432Z" }, "users": {}, "dist-tags": { @@ -43,7 +44,7 @@ "_distfiles": {}, "_attachments": { "bunx-bins-1.0.0.tgz": { - "shasum": "7837a6c1c921bed2653833976abecd97753a25bf", + "shasum": "c23382ce43a04a94035050ac736f04179a8639ff", "version": "1.0.0" } }, From 3c6b5b3f9bdbd0f584a85776da8657a08c3cd4c1 Mon Sep 17 00:00:00 2001 From: dave caruso Date: Mon, 25 Mar 2024 18:16:06 -0700 Subject: [PATCH 11/27] wah --- src/cli/run_command.zig | 3 +- src/install/windows-shim/bun_shim_impl.zig | 5 +- src/output.zig | 5 +- .../registry/bun-install-registry.test.ts | 93 +++++++++++++++--- .../packages/bunx-bins/bunx-bins-1.0.0.tgz | Bin 152267 -> 152275 bytes .../registry/packages/bunx-bins/package.json | 3 +- test/js/bun/util/highlighter.test.ts | 2 +- 7 files changed, 88 insertions(+), 23 deletions(-) diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index ab7cf2ee8fddc..6256c3fd320e5 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -1508,7 +1508,7 @@ pub const RunCommand = struct { // Run absolute/relative path if ((script_name_to_search.len > 1 and script_name_to_search[0] == '/') or - (Environment.isWindows and script_name_to_search > 3 and std.ascii.isAlphabetic(script_name_to_search[0]) and script_name_to_search[1] == ':') or + (Environment.isWindows and script_name_to_search.len > 3 and std.ascii.isAlphabetic(script_name_to_search[0]) and script_name_to_search[1] == ':') or (script_name_to_search.len > 2 and script_name_to_search[0] == '.' and script_name_to_search[1] == '/')) { Run.boot(ctx, ctx.allocator.dupe(u8, script_name_to_search) catch unreachable) catch |err| { @@ -1527,7 +1527,6 @@ pub const RunCommand = struct { if (script_name_to_search.len == 1 and script_name_to_search[0] == '-') { // read from stdin - var stack_fallback = std.heap.stackFallback(2048, bun.default_allocator); var list = std.ArrayList(u8).init(stack_fallback.get()); errdefer list.deinit(); diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index 06f40b309a828..8bd5ea502d086 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -698,7 +698,7 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^ read_ptr // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js"!!!!!!!!!!!!!!!!!!!!' const length_of_filename_u8 = @intFromPtr(read_ptr) - - @intFromPtr(buf1_u8) - 2 * nt_object_prefix.len - 2 * "\x00".len; + @intFromPtr(buf1_u8) - 2 * (nt_object_prefix.len - "\x00".len); const filename = buf1_u8[2 * nt_object_prefix.len ..][0..length_of_filename_u8]; if (dbg) { const sliced = std.mem.bytesAsSlice(u16, filename); @@ -742,7 +742,8 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { }; if (!is_standalone) { - // Prepare stdio for the child process, as after this we are going to immediatly exit. + // Prepare stdio for the child process, as after this we are going to *immediatly* exit + // it is likely that the c-runtime's atexit will not be called as we end the process ourselves. bun.Output.Source.Stdio.restore(); bun.C.windows_enable_stdio_inheritance(); } diff --git a/src/output.zig b/src/output.zig index fc4152187eb32..341a7fea91ef3 100644 --- a/src/output.zig +++ b/src/output.zig @@ -208,6 +208,7 @@ pub const Source = struct { _ = SetConsoleCP(CP_UTF8); const ENABLE_VIRTUAL_TERMINAL_INPUT = 0x200; + const ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002; const ENABLE_PROCESSED_OUTPUT = 0x0001; var mode: w.DWORD = undefined; @@ -220,13 +221,13 @@ pub const Source = struct { if (w.kernel32.GetConsoleMode(stdout, &mode) != 0) { console_mode[1] = mode; bun_stdio_tty[1] = 1; - _ = SetConsoleMode(stdout, ENABLE_PROCESSED_OUTPUT | w.ENABLE_VIRTUAL_TERMINAL_PROCESSING | 0); + _ = SetConsoleMode(stdout, ENABLE_PROCESSED_OUTPUT | w.ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_WRAP_AT_EOL_OUTPUT | mode); } if (w.kernel32.GetConsoleMode(stderr, &mode) != 0) { console_mode[2] = mode; bun_stdio_tty[2] = 1; - _ = SetConsoleMode(stderr, ENABLE_PROCESSED_OUTPUT | w.ENABLE_VIRTUAL_TERMINAL_PROCESSING | 0); + _ = SetConsoleMode(stderr, ENABLE_PROCESSED_OUTPUT | w.ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_WRAP_AT_EOL_OUTPUT | mode); } } }; diff --git a/test/cli/install/registry/bun-install-registry.test.ts b/test/cli/install/registry/bun-install-registry.test.ts index 03803394fb0a0..817c67c77f8f8 100644 --- a/test/cli/install/registry/bun-install-registry.test.ts +++ b/test/cli/install/registry/bun-install-registry.test.ts @@ -197,8 +197,8 @@ describe.each(["--production", "without --production"])("%s", flag => { name: "basic-1", version: "1.0.0", }))().then( - async () => await rm(join(packageDir, "node_modules", "basic-1"), { recursive: true, force: true }), - ), + async () => await rm(join(packageDir, "node_modules", "basic-1"), { recursive: true, force: true }), + ), (async () => (hash = Bun.hash(await file(join(packageDir, "bun.lockb")).arrayBuffer())))(), ]); @@ -4678,14 +4678,14 @@ for (const forceWaiterThread of [false, true]) { out = await Bun.readableStreamToText(stdout); expected = withRm ? [ - "", - " + uses-what-bin@1.0.0", - "", - expect.stringContaining("1 package installed"), - "", - " Blocked 1 postinstall. Run `bun pm untrusted` for details.", - "", - ] + "", + " + uses-what-bin@1.0.0", + "", + expect.stringContaining("1 package installed"), + "", + " Blocked 1 postinstall. Run `bun pm untrusted` for details.", + "", + ] : ["", expect.stringContaining("Checked 3 installs across 4 packages (no changes)")]; expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual(expected); @@ -6666,6 +6666,8 @@ test.if(isWindows)("windows bin linking shim should work", async () => { copyFileSync(bunExe(), target); } + copyFileSync(join(packageDir, "node_modules\\bunx-bins\\native.exe"), join(temp_bin_dir, "native.exe")); + const PATH = process.env.PATH + ";" + temp_bin_dir; const bins = [ @@ -6680,11 +6682,11 @@ test.if(isWindows)("windows bin linking shim should work", async () => { { bin: "bin-bun", name: "bin-bun" }, { bin: "bin-py", name: "bin-py" }, { bin: "native", name: "exe" }, - { bin: "uses-native", name: "exe" }, + { bin: "uses-native", name: `exe ${packageDir}\\node_modules\\bunx-bins\\uses-native.ts` }, ]; + // `bun run ${bin} arg1 arg2` for (const { bin, name } of bins) { - // `bun run ${bin} arg1 arg2` var { stdout, stderr, exited } = spawn({ cmd: [bunExe(), "run", bin, "arg1", "arg2"], cwd: packageDir, @@ -6693,7 +6695,7 @@ test.if(isWindows)("windows bin linking shim should work", async () => { stderr: "pipe", env: { ...env, - PATH, + Path: PATH, }, }); expect(stderr).toBeDefined(); @@ -6703,4 +6705,67 @@ test.if(isWindows)("windows bin linking shim should work", async () => { expect(out.trim()).toBe(`i am ${name} arg1 arg2`); expect(await exited).toBe(0); } -}); + + // `bun --bun run ${bin} arg1 arg2` + for (const { bin, name } of bins) { + var { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "--bun", "run", bin, "arg1", "arg2"], + cwd: packageDir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env: { + ...env, + Path: PATH, + }, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err.trim()).toBe(""); + const out = await new Response(stdout).text(); + expect(out.trim()).toBe(`i am ${name} arg1 arg2`); + expect(await exited).toBe(0); + } + + // `bun --bun x ${bin} arg1 arg2` + for (const { bin, name } of bins) { + var { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "--bun", "x", bin, "arg1", "arg2"], + cwd: packageDir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env: { + ...env, + Path: PATH, + }, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err.trim()).toBe(""); + const out = await new Response(stdout).text(); + expect(out.trim()).toBe(`i am ${name} arg1 arg2`); + expect(await exited).toBe(0); + } + + // `${bin} arg1 arg2` + for (const { bin, name } of bins) { + var { stdout, stderr, exited } = spawn({ + cmd: [join(packageDir, 'node_modules', '.bin', bin + ".exe"), "arg1", "arg2"], + cwd: packageDir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env: { + ...env, + Path: PATH, + }, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err.trim()).toBe(""); + const out = await new Response(stdout).text(); + expect(out.trim()).toBe(`i am ${name} arg1 arg2`); + expect(await exited).toBe(0); + } +}, 60_000); diff --git a/test/cli/install/registry/packages/bunx-bins/bunx-bins-1.0.0.tgz b/test/cli/install/registry/packages/bunx-bins/bunx-bins-1.0.0.tgz index b33009b1371cc664828c57687f226d4c5935e822..7a49c5da0d6659918165445810779e3b0141b090 100644 GIT binary patch delta 12999 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 diff --git a/test/cli/install/registry/packages/bunx-bins/package.json b/test/cli/install/registry/packages/bunx-bins/package.json index ffdfd47cda49d..689eb6a10720a 100644 --- a/test/cli/install/registry/packages/bunx-bins/package.json +++ b/test/cli/install/registry/packages/bunx-bins/package.json @@ -24,8 +24,7 @@ "_nodeVersion": "21.7.1", "_npmVersion": "10.5.0", "dist": { - "integrity": "sha512-BJf8PSFHafYTaZ76t2c0C1KXAv0xKdqJNKxZ9APbCzbEhT9ilvfLFYsbkXjOySGBDuWg0Pb/dEc6gb6WLvJMoQ==", - "shasum": "c23382ce43a04a94035050ac736f04179a8639ff", + "shasum": "1809cf2217354265981106f91617b87381abad75", "tarball": "http://localhost:4873/bunx-bins/-/bunx-bins-1.0.0.tgz" }, "contributors": [] diff --git a/test/js/bun/util/highlighter.test.ts b/test/js/bun/util/highlighter.test.ts index af3b7abb2f5a6..422d6bfe50ff0 100644 --- a/test/js/bun/util/highlighter.test.ts +++ b/test/js/bun/util/highlighter.test.ts @@ -1,5 +1,5 @@ import { test, expect } from "bun:test"; -import { readFileSync, writeFileSync } from "fs"; + // @ts-expect-error const highlighter: (code: string) => string = globalThis[Symbol.for("Bun.lazy")]("unstable_syntaxHighlight"); From 8bd46306dda3ea13879a7808db44f670bc7c9fff Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 01:17:49 +0000 Subject: [PATCH 12/27] [autofix.ci] apply automated fixes --- src/install/windows-shim/bun_shim_impl.zig | 2 +- .../registry/bun-install-registry.test.ts | 300 +++++++++--------- 2 files changed, 153 insertions(+), 149 deletions(-) diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index 8bd5ea502d086..b11b828ac4d49 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -698,7 +698,7 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^ read_ptr // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js"!!!!!!!!!!!!!!!!!!!!' const length_of_filename_u8 = @intFromPtr(read_ptr) - - @intFromPtr(buf1_u8) - 2 * (nt_object_prefix.len - "\x00".len); + @intFromPtr(buf1_u8) - 2 * (nt_object_prefix.len - "\x00".len); const filename = buf1_u8[2 * nt_object_prefix.len ..][0..length_of_filename_u8]; if (dbg) { const sliced = std.mem.bytesAsSlice(u16, filename); diff --git a/test/cli/install/registry/bun-install-registry.test.ts b/test/cli/install/registry/bun-install-registry.test.ts index 817c67c77f8f8..af22b87fa4934 100644 --- a/test/cli/install/registry/bun-install-registry.test.ts +++ b/test/cli/install/registry/bun-install-registry.test.ts @@ -197,8 +197,8 @@ describe.each(["--production", "without --production"])("%s", flag => { name: "basic-1", version: "1.0.0", }))().then( - async () => await rm(join(packageDir, "node_modules", "basic-1"), { recursive: true, force: true }), - ), + async () => await rm(join(packageDir, "node_modules", "basic-1"), { recursive: true, force: true }), + ), (async () => (hash = Bun.hash(await file(join(packageDir, "bun.lockb")).arrayBuffer())))(), ]); @@ -4678,14 +4678,14 @@ for (const forceWaiterThread of [false, true]) { out = await Bun.readableStreamToText(stdout); expected = withRm ? [ - "", - " + uses-what-bin@1.0.0", - "", - expect.stringContaining("1 package installed"), - "", - " Blocked 1 postinstall. Run `bun pm untrusted` for details.", - "", - ] + "", + " + uses-what-bin@1.0.0", + "", + expect.stringContaining("1 package installed"), + "", + " Blocked 1 postinstall. Run `bun pm untrusted` for details.", + "", + ] : ["", expect.stringContaining("Checked 3 installs across 4 packages (no changes)")]; expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual(expected); @@ -6621,151 +6621,155 @@ describe("yarn tests", () => { // This test is to verify that BinLinkingShim.zig creates correct shim files as // well as bun_shim_impl.exe works in various edge cases. There are many fast // paths for many many cases. -test.if(isWindows)("windows bin linking shim should work", async () => { - expect(process.platform).toBe("win32"); // extra check - await writeFile( - join(packageDir, "package.json"), - JSON.stringify({ - name: "foo", - version: "1.0.0", - dependencies: { - "bunx-bins": "*", - }, - }), - ); - console.log(packageDir); - - var { stdout, stderr, exited } = spawn({ - cmd: [bunExe(), "install", "--dev"], - cwd: packageDir, - stdout: "pipe", - stdin: "pipe", - stderr: "pipe", - env, - }); - - var err = await new Response(stderr).text(); - var out = await new Response(stdout).text(); - console.log(err); - expect(err).toContain("Saved lockfile"); - expect(err).not.toContain("error:"); - expect(err).not.toContain("panic:"); - expect(err).not.toContain("not found"); - expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([ - "", - " + bunx-bins@1.0.0", - "", - expect.stringContaining("1 package installed"), - ]); - - const temp_bin_dir = join(packageDir, "temp"); - mkdirSync(temp_bin_dir); - - for (let i = 1; i <= 7; i++) { - const target = join(temp_bin_dir, "a".repeat(i) + ".exe"); - copyFileSync(bunExe(), target); - } - - copyFileSync(join(packageDir, "node_modules\\bunx-bins\\native.exe"), join(temp_bin_dir, "native.exe")); - - const PATH = process.env.PATH + ";" + temp_bin_dir; - - const bins = [ - { bin: "bin1", name: "bin1" }, - { bin: "bin2", name: "bin2" }, - { bin: "bin3", name: "bin3" }, - { bin: "bin4", name: "bin4" }, - { bin: "bin5", name: "bin5" }, - { bin: "bin6", name: "bin6" }, - { bin: "bin7", name: "bin7" }, - { bin: "bin-node", name: "bin-node" }, - { bin: "bin-bun", name: "bin-bun" }, - { bin: "bin-py", name: "bin-py" }, - { bin: "native", name: "exe" }, - { bin: "uses-native", name: `exe ${packageDir}\\node_modules\\bunx-bins\\uses-native.ts` }, - ]; +test.if(isWindows)( + "windows bin linking shim should work", + async () => { + expect(process.platform).toBe("win32"); // extra check + await writeFile( + join(packageDir, "package.json"), + JSON.stringify({ + name: "foo", + version: "1.0.0", + dependencies: { + "bunx-bins": "*", + }, + }), + ); + console.log(packageDir); - // `bun run ${bin} arg1 arg2` - for (const { bin, name } of bins) { var { stdout, stderr, exited } = spawn({ - cmd: [bunExe(), "run", bin, "arg1", "arg2"], + cmd: [bunExe(), "install", "--dev"], cwd: packageDir, stdout: "pipe", stdin: "pipe", stderr: "pipe", - env: { - ...env, - Path: PATH, - }, + env, }); - expect(stderr).toBeDefined(); - const err = await new Response(stderr).text(); - expect(err.trim()).toBe(""); - const out = await new Response(stdout).text(); - expect(out.trim()).toBe(`i am ${name} arg1 arg2`); - expect(await exited).toBe(0); - } - // `bun --bun run ${bin} arg1 arg2` - for (const { bin, name } of bins) { - var { stdout, stderr, exited } = spawn({ - cmd: [bunExe(), "--bun", "run", bin, "arg1", "arg2"], - cwd: packageDir, - stdout: "pipe", - stdin: "pipe", - stderr: "pipe", - env: { - ...env, - Path: PATH, - }, - }); - expect(stderr).toBeDefined(); - const err = await new Response(stderr).text(); - expect(err.trim()).toBe(""); - const out = await new Response(stdout).text(); - expect(out.trim()).toBe(`i am ${name} arg1 arg2`); - expect(await exited).toBe(0); - } + var err = await new Response(stderr).text(); + var out = await new Response(stdout).text(); + console.log(err); + expect(err).toContain("Saved lockfile"); + expect(err).not.toContain("error:"); + expect(err).not.toContain("panic:"); + expect(err).not.toContain("not found"); + expect(out.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([ + "", + " + bunx-bins@1.0.0", + "", + expect.stringContaining("1 package installed"), + ]); - // `bun --bun x ${bin} arg1 arg2` - for (const { bin, name } of bins) { - var { stdout, stderr, exited } = spawn({ - cmd: [bunExe(), "--bun", "x", bin, "arg1", "arg2"], - cwd: packageDir, - stdout: "pipe", - stdin: "pipe", - stderr: "pipe", - env: { - ...env, - Path: PATH, - }, - }); - expect(stderr).toBeDefined(); - const err = await new Response(stderr).text(); - expect(err.trim()).toBe(""); - const out = await new Response(stdout).text(); - expect(out.trim()).toBe(`i am ${name} arg1 arg2`); - expect(await exited).toBe(0); - } + const temp_bin_dir = join(packageDir, "temp"); + mkdirSync(temp_bin_dir); - // `${bin} arg1 arg2` - for (const { bin, name } of bins) { - var { stdout, stderr, exited } = spawn({ - cmd: [join(packageDir, 'node_modules', '.bin', bin + ".exe"), "arg1", "arg2"], - cwd: packageDir, - stdout: "pipe", - stdin: "pipe", - stderr: "pipe", - env: { - ...env, - Path: PATH, - }, - }); - expect(stderr).toBeDefined(); - const err = await new Response(stderr).text(); - expect(err.trim()).toBe(""); - const out = await new Response(stdout).text(); - expect(out.trim()).toBe(`i am ${name} arg1 arg2`); - expect(await exited).toBe(0); - } -}, 60_000); + for (let i = 1; i <= 7; i++) { + const target = join(temp_bin_dir, "a".repeat(i) + ".exe"); + copyFileSync(bunExe(), target); + } + + copyFileSync(join(packageDir, "node_modules\\bunx-bins\\native.exe"), join(temp_bin_dir, "native.exe")); + + const PATH = process.env.PATH + ";" + temp_bin_dir; + + const bins = [ + { bin: "bin1", name: "bin1" }, + { bin: "bin2", name: "bin2" }, + { bin: "bin3", name: "bin3" }, + { bin: "bin4", name: "bin4" }, + { bin: "bin5", name: "bin5" }, + { bin: "bin6", name: "bin6" }, + { bin: "bin7", name: "bin7" }, + { bin: "bin-node", name: "bin-node" }, + { bin: "bin-bun", name: "bin-bun" }, + { bin: "bin-py", name: "bin-py" }, + { bin: "native", name: "exe" }, + { bin: "uses-native", name: `exe ${packageDir}\\node_modules\\bunx-bins\\uses-native.ts` }, + ]; + + // `bun run ${bin} arg1 arg2` + for (const { bin, name } of bins) { + var { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "run", bin, "arg1", "arg2"], + cwd: packageDir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env: { + ...env, + Path: PATH, + }, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err.trim()).toBe(""); + const out = await new Response(stdout).text(); + expect(out.trim()).toBe(`i am ${name} arg1 arg2`); + expect(await exited).toBe(0); + } + + // `bun --bun run ${bin} arg1 arg2` + for (const { bin, name } of bins) { + var { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "--bun", "run", bin, "arg1", "arg2"], + cwd: packageDir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env: { + ...env, + Path: PATH, + }, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err.trim()).toBe(""); + const out = await new Response(stdout).text(); + expect(out.trim()).toBe(`i am ${name} arg1 arg2`); + expect(await exited).toBe(0); + } + + // `bun --bun x ${bin} arg1 arg2` + for (const { bin, name } of bins) { + var { stdout, stderr, exited } = spawn({ + cmd: [bunExe(), "--bun", "x", bin, "arg1", "arg2"], + cwd: packageDir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env: { + ...env, + Path: PATH, + }, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err.trim()).toBe(""); + const out = await new Response(stdout).text(); + expect(out.trim()).toBe(`i am ${name} arg1 arg2`); + expect(await exited).toBe(0); + } + + // `${bin} arg1 arg2` + for (const { bin, name } of bins) { + var { stdout, stderr, exited } = spawn({ + cmd: [join(packageDir, "node_modules", ".bin", bin + ".exe"), "arg1", "arg2"], + cwd: packageDir, + stdout: "pipe", + stdin: "pipe", + stderr: "pipe", + env: { + ...env, + Path: PATH, + }, + }); + expect(stderr).toBeDefined(); + const err = await new Response(stderr).text(); + expect(err.trim()).toBe(""); + const out = await new Response(stdout).text(); + expect(out.trim()).toBe(`i am ${name} arg1 arg2`); + expect(await exited).toBe(0); + } + }, + 60_000, +); From 776e5c7bfe138953514d01a900469c0db23865ef Mon Sep 17 00:00:00 2001 From: dave caruso Date: Mon, 25 Mar 2024 18:41:36 -0700 Subject: [PATCH 13/27] farther --- test/cli/install/bunx.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/cli/install/bunx.test.ts b/test/cli/install/bunx.test.ts index b96d787da3da6..f213a76b41131 100644 --- a/test/cli/install/bunx.test.ts +++ b/test/cli/install/bunx.test.ts @@ -29,10 +29,9 @@ it("should choose the tagged versions instead of the PATH versions when a tag is const results = await Promise.all(processes.map(p => p.exited)); expect(results).toEqual([0, 0, 0]); - const outputs = (await Promise.all(processes.map(p => new Response(p.stdout).text()))).map(a => { - console.log(a); - return a.substring(0, a.indexOf("\n")); - }); + const outputs = (await Promise.all(processes.map(p => new Response(p.stdout).text()))).map(a => + a.substring(0, a.indexOf("\n")) + ); expect(outputs).toEqual(["SemVer 7.5.0", "SemVer 7.5.1", "SemVer 7.5.2"]); }); From c34b6d5ec7890d36f1d86e4aa871cbafc636886c Mon Sep 17 00:00:00 2001 From: dave caruso Date: Mon, 25 Mar 2024 18:48:46 -0700 Subject: [PATCH 14/27] a --- src/install/extract_tarball.zig | 1 + test/cli/install/bunx.test.ts | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/install/extract_tarball.zig b/src/install/extract_tarball.zig index 1f9be3a47a0b7..b96feb2efc627 100644 --- a/src/install/extract_tarball.zig +++ b/src/install/extract_tarball.zig @@ -528,6 +528,7 @@ fn makeOpenDirAccessMaskW(self: std.fs.Dir, sub_path_w: [*:0]const u16, access_m // and the directory is trying to be opened for iteration. .ACCESS_DENIED => return error.AccessDenied, .INVALID_PARAMETER => return error.BadPathName, + .SHARING_VIOLATION => return error.FileNotFound, else => return w.unexpectedStatus(rc), } } diff --git a/test/cli/install/bunx.test.ts b/test/cli/install/bunx.test.ts index f213a76b41131..fa19a69845691 100644 --- a/test/cli/install/bunx.test.ts +++ b/test/cli/install/bunx.test.ts @@ -1,6 +1,6 @@ import { spawn } from "bun"; import { afterEach, beforeEach, expect, it } from "bun:test"; -import { bunExe, bunEnv as env } from "harness"; +import { bunExe, bunEnv as env, isWindows } from "harness"; import { mkdtemp, realpath, rm, writeFile } from "fs/promises"; import { tmpdir } from "os"; import { join } from "path"; @@ -95,7 +95,6 @@ it("should output usage if no arguments are passed", async () => { }); it("should work for @scoped packages", async () => { - await rm(join(await realpath(tmpdir()), "@withfig"), { force: true, recursive: true }); // without cache const withoutCache = spawn({ cmd: [bunExe(), "x", "@withfig/autocomplete-tools", "--help"], @@ -112,7 +111,7 @@ it("should work for @scoped packages", async () => { expect(err).not.toContain("panic:"); expect(withoutCache.stdout).toBeDefined(); let out = await new Response(withoutCache.stdout).text(); - expect(out.trim()).toContain("Usage: @withfig/autocomplete-tool"); + expect(out.trim()).toContain("Usage: @withfig/autocomplete-tools"); expect(await withoutCache.exited).toBe(0); // cached @@ -131,7 +130,7 @@ it("should work for @scoped packages", async () => { expect(err).not.toContain("panic:"); expect(cached.stdout).toBeDefined(); out = await new Response(cached.stdout).text(); - expect(out.trim()).toContain("Usage: @withfig/autocomplete-tool"); + expect(out.trim()).toContain("Usage: @withfig/autocomplete-tools"); expect(await cached.exited).toBe(0); }); @@ -182,7 +181,7 @@ it("should work for github repository", async () => { expect(err).not.toContain("panic:"); expect(withoutCache.stdout).toBeDefined(); let out = await new Response(withoutCache.stdout).text(); - expect(out.trim()).toContain("Usage: cowsay"); + expect(out.trim()).toContain("Usage: " + (isWindows ? 'cli.js' : 'cowsay')); expect(await withoutCache.exited).toBe(0); // cached @@ -201,7 +200,7 @@ it("should work for github repository", async () => { expect(err).not.toContain("panic:"); expect(cached.stdout).toBeDefined(); out = await new Response(cached.stdout).text(); - expect(out.trim()).toContain("Usage: cowsay"); + expect(out.trim()).toContain("Usage: " + (isWindows ? 'cli.js' : 'cowsay')); expect(await cached.exited).toBe(0); }); From cdd4253baf0fe3d575fdd19d954d135b87409105 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 01:56:37 +0000 Subject: [PATCH 15/27] [autofix.ci] apply automated fixes --- test/cli/install/bunx.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/cli/install/bunx.test.ts b/test/cli/install/bunx.test.ts index fa19a69845691..30929477db772 100644 --- a/test/cli/install/bunx.test.ts +++ b/test/cli/install/bunx.test.ts @@ -29,8 +29,8 @@ it("should choose the tagged versions instead of the PATH versions when a tag is const results = await Promise.all(processes.map(p => p.exited)); expect(results).toEqual([0, 0, 0]); - const outputs = (await Promise.all(processes.map(p => new Response(p.stdout).text()))).map(a => - a.substring(0, a.indexOf("\n")) + const outputs = (await Promise.all(processes.map(p => new Response(p.stdout).text()))).map(a => + a.substring(0, a.indexOf("\n")), ); expect(outputs).toEqual(["SemVer 7.5.0", "SemVer 7.5.1", "SemVer 7.5.2"]); }); @@ -181,7 +181,7 @@ it("should work for github repository", async () => { expect(err).not.toContain("panic:"); expect(withoutCache.stdout).toBeDefined(); let out = await new Response(withoutCache.stdout).text(); - expect(out.trim()).toContain("Usage: " + (isWindows ? 'cli.js' : 'cowsay')); + expect(out.trim()).toContain("Usage: " + (isWindows ? "cli.js" : "cowsay")); expect(await withoutCache.exited).toBe(0); // cached @@ -200,7 +200,7 @@ it("should work for github repository", async () => { expect(err).not.toContain("panic:"); expect(cached.stdout).toBeDefined(); out = await new Response(cached.stdout).text(); - expect(out.trim()).toContain("Usage: " + (isWindows ? 'cli.js' : 'cowsay')); + expect(out.trim()).toContain("Usage: " + (isWindows ? "cli.js" : "cowsay")); expect(await cached.exited).toBe(0); }); From 578b40b6d233057c6416d2f08a0915deab0b03cc Mon Sep 17 00:00:00 2001 From: dave caruso Date: Tue, 26 Mar 2024 17:56:57 -0700 Subject: [PATCH 16/27] im confused --- src/cli/run_command.zig | 7 ++++--- src/feature_flags.zig | 2 ++ src/install/extract_tarball.zig | 6 +++--- src/install/windows-shim/bun_shim_impl.zig | 11 +++++++---- test/cli/install/bunx.test.ts | 16 ++++++++++++---- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index 6256c3fd320e5..03b0b4ee8104b 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -456,8 +456,7 @@ pub const RunCommand = struct { // wrapper exe. we build the full exe path even though we could do // a relative lookup, because in the case we do find it, we have to // generate this full path anyways. - // - if (Environment.isWindows and bun.strings.hasSuffixComptime(executable, ".exe")) { + if (Environment.isWindows and bun.FeatureFlags.windows_bunx_fast_path and bun.strings.hasSuffixComptime(executable, ".exe")) { std.debug.assert(std.fs.path.isAbsolute(executable)); // Using @constCast is safe because we know that @@ -1555,7 +1554,7 @@ pub const RunCommand = struct { return true; } - if (Environment.isWindows) try_bunx_file: { + if (Environment.isWindows and bun.FeatureFlags.windows_bunx_fast_path) try_bunx_file: { // Attempt to find a ".bunx" file on disk, and run it, skipping the // wrapper exe. we build the full exe path even though we could do // a relative lookup, because in the case we do find it, we have to @@ -1677,6 +1676,8 @@ pub const BunXFastPath = struct { /// If this returns, it implies the fast path cannot be taken fn tryLaunch(ctx_const: Command.Context, path_to_use: [:0]u16, env: *DotEnv.Loader, passthrough: []const []const u8) void { + if (!bun.FeatureFlags.windows_bunx_fast_path) return; + var ctx = ctx_const; std.debug.assert(bun.isSliceInBufferT(u16, path_to_use, &BunXFastPath.direct_launch_buffer)); var command_line = BunXFastPath.direct_launch_buffer[path_to_use.len..]; diff --git a/src/feature_flags.zig b/src/feature_flags.zig index 27a173f8b2d9b..66ceb74096bff 100644 --- a/src/feature_flags.zig +++ b/src/feature_flags.zig @@ -164,4 +164,6 @@ pub const disable_auto_js_to_ts_in_node_modules = true; pub const runtime_transpiler_cache = true; +pub const windows_bunx_fast_path = true; + pub const breaking_changes_1_1_0 = false; diff --git a/src/install/extract_tarball.zig b/src/install/extract_tarball.zig index b96feb2efc627..59d782e4528c4 100644 --- a/src/install/extract_tarball.zig +++ b/src/install/extract_tarball.zig @@ -451,7 +451,7 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD /// Opens the dir if the path already exists and is a directory. /// This function is not atomic, and if it returns an error, the file system may /// have been modified regardless. -fn makeOpenPathAccessMaskW(self: std.fs.Dir, sub_path: []const u8, access_mask: u32, no_follow: bool) std.os.OpenError!std.fs.Dir { +fn makeOpenPathAccessMaskW(self: std.fs.Dir, sub_path: []const u8, access_mask: u32, no_follow: bool) !std.fs.Dir { var it = try std.fs.path.componentIterator(sub_path); // If there are no components in the path, then create a dummy component with the full path. var component = it.last() orelse std.fs.path.NativeUtf8ComponentIterator.Component{ @@ -483,7 +483,7 @@ const MakeOpenDirAccessMaskWOptions = struct { create_disposition: u32, }; -fn makeOpenDirAccessMaskW(self: std.fs.Dir, sub_path_w: [*:0]const u16, access_mask: u32, flags: MakeOpenDirAccessMaskWOptions) std.os.OpenError!std.fs.Dir { +fn makeOpenDirAccessMaskW(self: std.fs.Dir, sub_path_w: [*:0]const u16, access_mask: u32, flags: MakeOpenDirAccessMaskWOptions) !std.fs.Dir { var result = std.fs.Dir{ .fd = undefined, }; @@ -528,7 +528,7 @@ fn makeOpenDirAccessMaskW(self: std.fs.Dir, sub_path_w: [*:0]const u16, access_m // and the directory is trying to be opened for iteration. .ACCESS_DENIED => return error.AccessDenied, .INVALID_PARAMETER => return error.BadPathName, - .SHARING_VIOLATION => return error.FileNotFound, + .SHARING_VIOLATION => return error.SharingViolation, else => return w.unexpectedStatus(rc), } } diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index b11b828ac4d49..acb6e5556b566 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -698,7 +698,7 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { // ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ^ read_ptr // BUF2: 'node "C:\Users\dave\project\node_modules\my-cli\src\app.js"!!!!!!!!!!!!!!!!!!!!' const length_of_filename_u8 = @intFromPtr(read_ptr) - - @intFromPtr(buf1_u8) - 2 * (nt_object_prefix.len - "\x00".len); + @intFromPtr(buf1_u8) - 2 * (nt_object_prefix.len + "\x00".len); const filename = buf1_u8[2 * nt_object_prefix.len ..][0..length_of_filename_u8]; if (dbg) { const sliced = std.mem.bytesAsSlice(u16, filename); @@ -778,9 +778,10 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { .wShowWindow = 0, .cbReserved2 = 0, .lpReserved2 = null, - .hStdInput = ProcessParameters.hStdInput, - .hStdOutput = ProcessParameters.hStdOutput, - .hStdError = ProcessParameters.hStdError, + // The standard handles outside of standalone may be tampered with. + .hStdInput = if(is_standalone) ProcessParameters.hStdInput else bun.win32.STDERR_FD.cast(), + .hStdOutput = if(is_standalone) ProcessParameters.hStdOutput else bun.win32.STDOUT_FD.cast(), + .hStdError = if(is_standalone) ProcessParameters.hStdError else bun.win32.STDIN_FD.cast(), }; inline for (.{ 0, 1 }) |attempt_number| iteration: { @@ -924,6 +925,7 @@ pub const FromBunRunContext = struct { pub fn tryStartupFromBunJS(context: FromBunRunContext) void { assert(!std.mem.startsWith(u16, context.base_path, &nt_object_prefix)); comptime assert(!is_standalone); + comptime assert(bun.FeatureFlags.windows_bunx_fast_path); launcher(.launch, context); } @@ -958,6 +960,7 @@ pub const ReadWithoutLaunchResult = union { pub fn readWithoutLaunch(context: FromBunShellContext) ReadWithoutLaunchResult { assert(!std.mem.startsWith(u16, context.base_path, &nt_object_prefix)); comptime assert(!is_standalone); + comptime assert(bun.FeatureFlags.windows_bunx_fast_path); return launcher(.read_without_launch, context); } diff --git a/test/cli/install/bunx.test.ts b/test/cli/install/bunx.test.ts index 30929477db772..b3a7cb1ceb3fa 100644 --- a/test/cli/install/bunx.test.ts +++ b/test/cli/install/bunx.test.ts @@ -5,11 +5,19 @@ import { mkdtemp, realpath, rm, writeFile } from "fs/promises"; import { tmpdir } from "os"; import { join } from "path"; import { readdirSorted } from "./dummy.registry"; +import { readdirSync } from "js/node/fs/export-star-from"; let x_dir: string; beforeEach(async () => { x_dir = await realpath(await mkdtemp(join(tmpdir(), "bun-x.test"))); + + const tmp = isWindows ? tmpdir() : '/tmp'; + readdirSync(tmp).forEach(file => { + if (file.startsWith('bunx-')) { + rm(join(tmp, file), { recursive: true, force: true }); + } + }); }); afterEach(async () => { await rm(x_dir, { force: true, recursive: true }); @@ -97,7 +105,7 @@ it("should output usage if no arguments are passed", async () => { it("should work for @scoped packages", async () => { // without cache const withoutCache = spawn({ - cmd: [bunExe(), "x", "@withfig/autocomplete-tools", "--help"], + cmd: [bunExe(), "--bun","x", "@withfig/autocomplete-tools", "--help"], cwd: x_dir, stdout: "pipe", stdin: "pipe", @@ -116,7 +124,7 @@ it("should work for @scoped packages", async () => { // cached const cached = spawn({ - cmd: [bunExe(), "x", "@withfig/autocomplete-tools", "--help"], + cmd: [bunExe(), "--bun","x", "@withfig/autocomplete-tools", "--help"], cwd: x_dir, stdout: "pipe", stdin: "pipe", @@ -130,6 +138,7 @@ it("should work for @scoped packages", async () => { expect(err).not.toContain("panic:"); expect(cached.stdout).toBeDefined(); out = await new Response(cached.stdout).text(); + console.log({ out,err }); expect(out.trim()).toContain("Usage: @withfig/autocomplete-tools"); expect(await cached.exited).toBe(0); }); @@ -164,7 +173,6 @@ console.log( }); it("should work for github repository", async () => { - await rm(join(await realpath(tmpdir()), "github:piuccio"), { force: true, recursive: true }); // without cache const withoutCache = spawn({ cmd: [bunExe(), "x", "github:piuccio/cowsay", "--help"], @@ -205,7 +213,6 @@ it("should work for github repository", async () => { }); it("should work for github repository with committish", async () => { - await rm(join(await realpath(tmpdir()), "github:piuccio"), { force: true, recursive: true }); const withoutCache = spawn({ cmd: [bunExe(), "x", "github:piuccio/cowsay#HEAD", "hello bun!"], cwd: x_dir, @@ -221,6 +228,7 @@ it("should work for github repository with committish", async () => { expect(err).not.toContain("panic:"); expect(withoutCache.stdout).toBeDefined(); let out = await new Response(withoutCache.stdout).text(); + if (!out) console.log(err); expect(out.trim()).toContain("hello bun!"); expect(await withoutCache.exited).toBe(0); From 9b41644d434e892aa16eb41bca295d3f351af828 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 00:58:09 +0000 Subject: [PATCH 17/27] [autofix.ci] apply automated fixes --- src/install/windows-shim/bun_shim_impl.zig | 6 +++--- test/cli/install/bunx.test.ts | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index acb6e5556b566..3b430de29a84e 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -779,9 +779,9 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { .cbReserved2 = 0, .lpReserved2 = null, // The standard handles outside of standalone may be tampered with. - .hStdInput = if(is_standalone) ProcessParameters.hStdInput else bun.win32.STDERR_FD.cast(), - .hStdOutput = if(is_standalone) ProcessParameters.hStdOutput else bun.win32.STDOUT_FD.cast(), - .hStdError = if(is_standalone) ProcessParameters.hStdError else bun.win32.STDIN_FD.cast(), + .hStdInput = if (is_standalone) ProcessParameters.hStdInput else bun.win32.STDERR_FD.cast(), + .hStdOutput = if (is_standalone) ProcessParameters.hStdOutput else bun.win32.STDOUT_FD.cast(), + .hStdError = if (is_standalone) ProcessParameters.hStdError else bun.win32.STDIN_FD.cast(), }; inline for (.{ 0, 1 }) |attempt_number| iteration: { diff --git a/test/cli/install/bunx.test.ts b/test/cli/install/bunx.test.ts index b3a7cb1ceb3fa..640c4dfb681f0 100644 --- a/test/cli/install/bunx.test.ts +++ b/test/cli/install/bunx.test.ts @@ -12,9 +12,9 @@ let x_dir: string; beforeEach(async () => { x_dir = await realpath(await mkdtemp(join(tmpdir(), "bun-x.test"))); - const tmp = isWindows ? tmpdir() : '/tmp'; + const tmp = isWindows ? tmpdir() : "/tmp"; readdirSync(tmp).forEach(file => { - if (file.startsWith('bunx-')) { + if (file.startsWith("bunx-")) { rm(join(tmp, file), { recursive: true, force: true }); } }); @@ -105,7 +105,7 @@ it("should output usage if no arguments are passed", async () => { it("should work for @scoped packages", async () => { // without cache const withoutCache = spawn({ - cmd: [bunExe(), "--bun","x", "@withfig/autocomplete-tools", "--help"], + cmd: [bunExe(), "--bun", "x", "@withfig/autocomplete-tools", "--help"], cwd: x_dir, stdout: "pipe", stdin: "pipe", @@ -124,7 +124,7 @@ it("should work for @scoped packages", async () => { // cached const cached = spawn({ - cmd: [bunExe(), "--bun","x", "@withfig/autocomplete-tools", "--help"], + cmd: [bunExe(), "--bun", "x", "@withfig/autocomplete-tools", "--help"], cwd: x_dir, stdout: "pipe", stdin: "pipe", @@ -138,7 +138,7 @@ it("should work for @scoped packages", async () => { expect(err).not.toContain("panic:"); expect(cached.stdout).toBeDefined(); out = await new Response(cached.stdout).text(); - console.log({ out,err }); + console.log({ out, err }); expect(out.trim()).toContain("Usage: @withfig/autocomplete-tools"); expect(await cached.exited).toBe(0); }); From d6b54fe430abf39dcdbceed1c14b12eae49acd82 Mon Sep 17 00:00:00 2001 From: sequencerr <45060278+sequencerr@users.noreply.github.com> Date: Mon, 25 Mar 2024 22:26:47 +0100 Subject: [PATCH 18/27] Fix typo (#9623) --- docs/project/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/project/contributing.md b/docs/project/contributing.md index 8df91bcca2820..7a150c6086659 100644 --- a/docs/project/contributing.md +++ b/docs/project/contributing.md @@ -150,7 +150,7 @@ $ cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug $ ninja -C build # 'bun run build' runs just this ``` -Advanced uses can pass CMake flags to customize the build. +Advanced users can pass CMake flags to customize the build. ## VSCode From a6bada65c66be931f8787d9073f7a8bec79ab8f4 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Mon, 25 Mar 2024 14:37:20 -0700 Subject: [PATCH 19/27] Fix crash in Bun.escapeHTML (#9619) Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> --- src/string_immutable.zig | 12 ++++++------ test/js/bun/util/escapeHTML.test.js | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/string_immutable.zig b/src/string_immutable.zig index 9f6237bc3387f..9fd5f5792e2c0 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -2493,8 +2493,8 @@ pub fn elementLengthLatin1IntoUTF16(comptime Type: type, latin1_: Type) usize { pub fn escapeHTMLForLatin1Input(allocator: std.mem.Allocator, latin1: []const u8) !Escaped(u8) { const Scalar = struct { - pub const lengths: [std.math.maxInt(u8)]u4 = brk: { - var values: [std.math.maxInt(u8)]u4 = undefined; + pub const lengths: [std.math.maxInt(u8) + 1]u4 = brk: { + var values: [std.math.maxInt(u8) + 1]u4 = undefined; for (values, 0..) |_, i| { switch (i) { '"' => { @@ -2833,8 +2833,8 @@ fn Escaped(comptime T: type) type { pub fn escapeHTMLForUTF16Input(allocator: std.mem.Allocator, utf16: []const u16) !Escaped(u16) { const Scalar = struct { - pub const lengths: [std.math.maxInt(u8)]u4 = brk: { - var values: [std.math.maxInt(u8)]u4 = undefined; + pub const lengths: [std.math.maxInt(u8) + 1]u4 = brk: { + var values: [std.math.maxInt(u8) + 1]u4 = undefined; for (values, 0..) |_, i| { values[i] = switch (i) { '"' => """.len, @@ -3062,7 +3062,7 @@ pub fn escapeHTMLForUTF16Input(allocator: std.mem.Allocator, utf16: []const u16) break :scan_and_allocate_lazily; }, 128...std.math.maxInt(u16) => { - const cp = utf16Codepoint([]const u16, ptr[0..2]); + const cp = utf16Codepoint([]const u16, ptr[0..if (ptr + 1 == end) 1 else 2]); ptr += @as(u16, cp.len); }, @@ -3096,7 +3096,7 @@ pub fn escapeHTMLForUTF16Input(allocator: std.mem.Allocator, utf16: []const u16) ptr += 1; }, 128...std.math.maxInt(u16) => { - const cp = utf16Codepoint([]const u16, ptr[0..2]); + const cp = utf16Codepoint([]const u16, ptr[0..if (ptr + 1 == end) 1 else 2]); buf.appendSlice(ptr[0..@as(usize, cp.len)]) catch unreachable; ptr += @as(u16, cp.len); diff --git a/test/js/bun/util/escapeHTML.test.js b/test/js/bun/util/escapeHTML.test.js index bdddf4a45db58..12d185f1fb892 100644 --- a/test/js/bun/util/escapeHTML.test.js +++ b/test/js/bun/util/escapeHTML.test.js @@ -88,4 +88,18 @@ describe("escapeHTML", () => { expect(escapeHTML(" ".repeat(32) + "😊lo")).toBe(" ".repeat(32) + "😊lo"); expect(escapeHTML(" ".repeat(32) + "lo😊")).toBe(" ".repeat(32) + "lo😊"); }); + + it("bad input doesn't crash", () => { + escapeHTML("a".repeat(512) + String.fromCodePoint(0xd800)); + + for (let i = 0; i < 768; i++) { + escapeHTML("\xff" + "a".repeat(i)); + escapeHTML(String.fromCodePoint(0xd800) + "a".repeat(i)); + escapeHTML("a".repeat(i) + String.fromCodePoint(0xd800)); + escapeHTML(String.fromCodePoint(0xd800).repeat(i)); + escapeHTML("\xff" + String.fromCodePoint(0xd800).repeat(i)); + escapeHTML("\xff".repeat(i) + String.fromCodePoint(0xd800)); + escapeHTML(String.fromCodePoint(0xd800) + "\xff".repeat(i)); + } + }); }); From 8f3600ad4d0fed2ba32c84d79ec1d2b92290f966 Mon Sep 17 00:00:00 2001 From: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> Date: Mon, 25 Mar 2024 15:17:45 -0700 Subject: [PATCH 20/27] Fixes #9610 --- src/js/node/tty.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/node/tty.ts b/src/js/node/tty.ts index 413c32dc2eced..fdd00cf230d0d 100644 --- a/src/js/node/tty.ts +++ b/src/js/node/tty.ts @@ -276,7 +276,7 @@ Object.defineProperty(WriteStream, "prototype", { }; WriteStream.prototype.moveCursor = function (dx, dy, cb) { - return (readline ??= require("node:readline")).moveCursor(this, dx, dy, cb); + return require("node:readline").moveCursor(this, dx, dy, cb); }; return Real; From 01f1016b330f653413cb6f188b5e34646b403234 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Mon, 25 Mar 2024 17:21:11 -0700 Subject: [PATCH 21/27] Implement `fs.openAsBlob` (#9628) * Implement `fs.openAsBlob` * Use a function --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> --- docs/runtime/nodejs-apis.md | 2 +- src/js/node/fs.js | 37 +++++++++++++++++++------------------ test/js/node/fs/fs.test.ts | 14 +++++++++++++- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/docs/runtime/nodejs-apis.md b/docs/runtime/nodejs-apis.md index 63075409b3a2a..92286448891c6 100644 --- a/docs/runtime/nodejs-apis.md +++ b/docs/runtime/nodejs-apis.md @@ -56,7 +56,7 @@ Some methods are not optimized yet. ### [`node:fs`](https://nodejs.org/api/fs.html) -🟡 Missing `Dir` `openAsBlob` `opendir` `opendirSync` `statfs` `statfsSync` +🟡 Missing `statfs` `statfsSync`, `opendirSync`. `Dir` is partially implemented. ### [`node:http`](https://nodejs.org/api/http.html) diff --git a/src/js/node/fs.js b/src/js/node/fs.js index caaec55eef5d4..d6033efcf7cd9 100644 --- a/src/js/node/fs.js +++ b/src/js/node/fs.js @@ -95,6 +95,10 @@ class FSWatcher extends EventEmitter { // close(); // } +function openAsBlob(path, options) { + return Promise.$resolve(Bun.file(path, options)); +} + class StatWatcher extends EventEmitter { // _handle: StatWatcherHandle; @@ -326,44 +330,39 @@ var access = function access(...args) { lutimesSync = fs.lutimesSync.bind(fs), rmSync = fs.rmSync.bind(fs), rmdirSync = fs.rmdirSync.bind(fs), - writev = (fd, buffers, position, callback) => { + writev = function writev(fd, buffers, position, callback) { if (typeof position === "function") { callback = position; position = null; } - queueMicrotask(() => { - try { - var written = fs.writevSync(fd, buffers, position); - } catch (e) { - callback(e); - } + if (!$isCallable(callback)) { + throw new TypeError("callback must be a function"); + } - callback(null, written, buffers); - }); + fs.writev(fd, buffers, position).$then(bytesWritten => callback(null, bytesWritten, buffers), callback); }, writevSync = fs.writevSync.bind(fs), - readv = (fd, buffers, position, callback) => { + readv = function readv(fd, buffers, position, callback) { if (typeof position === "function") { callback = position; position = null; } - queueMicrotask(() => { - try { - var written = fs.readvSync(fd, buffers, position); - } catch (e) { - callback(e); - } + if (!$isCallable(callback)) { + throw new TypeError("callback must be a function"); + } - callback(null, written, buffers); - }); + fs.readv(fd, buffers, position).$then(bytesRead => callback(null, bytesRead, buffers), callback); }, readvSync = fs.readvSync.bind(fs), Dirent = fs.Dirent, Stats = fs.Stats, watch = function watch(path, options, listener) { return new FSWatcher(path, options, listener); + }, + opendir = function opendir(...args) { + callbackify(promises.opendir, args); }; // TODO: make symbols a separate export somewhere @@ -1349,6 +1348,8 @@ export default { writevSync, fdatasync, fdatasyncSync, + openAsBlob, + opendir, [Symbol.for("::bunternal::")]: { ReadStreamClass, WriteStreamClass, diff --git a/test/js/node/fs/fs.test.ts b/test/js/node/fs/fs.test.ts index 5045023653e45..d8bf6b1145015 100644 --- a/test/js/node/fs/fs.test.ts +++ b/test/js/node/fs/fs.test.ts @@ -37,6 +37,7 @@ import fs, { readvSync, fstatSync, fdatasyncSync, + openAsBlob, } from "node:fs"; import _promises, { type FileHandle } from "node:fs/promises"; @@ -45,7 +46,7 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; import { ReadStream as ReadStream_, WriteStream as WriteStream_ } from "./export-from.js"; -import { ReadStream as ReadStreamStar_, WriteStream as WriteStreamStar_, fdatasync } from "./export-star-from.js"; +import { Dir, ReadStream as ReadStreamStar_, WriteStream as WriteStreamStar_, fdatasync } from "./export-star-from.js"; import { spawnSync } from "bun"; const Buffer = globalThis.Buffer || Uint8Array; @@ -59,6 +60,10 @@ function mkdirForce(path: string) { if (!existsSync(path)) mkdirSync(path, { recursive: true }); } +it("fs.openAsBlob", async () => { + expect((await openAsBlob(import.meta.path)).size).toBe(statSync(import.meta.path).size); +}); + it("writing to 1, 2 are possible", () => { expect(fs.writeSync(1, Buffer.from("\nhello-stdout-test\n"))).toBe(19); expect(fs.writeSync(2, Buffer.from("\nhello-stderr-test\n"))).toBe(19); @@ -2291,6 +2296,13 @@ describe("fs/promises", () => { it("opendir should have a path property, issue#4995", async () => { expect((await fs.promises.opendir(".")).path).toBe("."); + + const { promise, resolve } = Promise.withResolvers

(); + fs.opendir(".", (err, dir) => { + resolve(dir); + }); + + expect((await promise).path).toBe("."); }); }); From 3533d34bf9ce892857d0fa1e4adfbd33135e7478 Mon Sep 17 00:00:00 2001 From: Ashcon Partovi Date: Tue, 26 Mar 2024 10:39:33 -0700 Subject: [PATCH 22/27] Fix `bun install -g` not working on Docker Closes #8753 --- .vscode/settings.json | 21 +++++++++++++-------- dockerhub/alpine/Dockerfile | 3 +++ dockerhub/debian-slim/Dockerfile | 3 +++ dockerhub/debian/Dockerfile | 3 +++ dockerhub/distroless/Dockerfile | 3 +++ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index f830213bb0125..af077036c9a82 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -40,7 +40,7 @@ // C++ "lldb.verboseLogging": false, "cmake.configureOnOpen": false, - "C_Cpp.errorSquiggles": "enabled", + "C_Cpp.errorSquiggles": "enabled", "[cpp]": { "editor.defaultFormatter": "xaver.clang-format" }, @@ -55,7 +55,7 @@ "prettier.enable": true, "eslint.workingDirectories": ["${workspaceFolder}/packages/bun-types"], "[javascript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[javascriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" @@ -72,12 +72,12 @@ // JSON "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "esbenp.prettier-vscode" }, - + // Markdown "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode", @@ -94,12 +94,17 @@ // TOML "[toml]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "esbenp.prettier-vscode" }, // YAML "[yaml]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + + // Dockerfile + "[dockerfile]": { + "editor.formatOnSave": false }, // Files @@ -148,5 +153,5 @@ "WebKit/WebDriver": true, "WebKit/WebKitBuild": true, "WebKit/WebInspectorUI": true - }, + } } diff --git a/dockerhub/alpine/Dockerfile b/dockerhub/alpine/Dockerfile index 4051cf17d9a5a..79e10e28416b6 100644 --- a/dockerhub/alpine/Dockerfile +++ b/dockerhub/alpine/Dockerfile @@ -96,6 +96,9 @@ FROM alpine:3.18 ARG BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 ENV BUN_RUNTIME_TRANSPILER_CACHE_PATH=${BUN_RUNTIME_TRANSPILER_CACHE_PATH} +ARG BUN_INSTALL_BIN=/usr/local/bin +ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN} + COPY --from=build /usr/local/bin/bun /usr/local/bin/ COPY docker-entrypoint.sh /usr/local/bin/ diff --git a/dockerhub/debian-slim/Dockerfile b/dockerhub/debian-slim/Dockerfile index babe2d7a571a5..c26352eec5950 100644 --- a/dockerhub/debian-slim/Dockerfile +++ b/dockerhub/debian-slim/Dockerfile @@ -62,6 +62,9 @@ FROM debian:bullseye-slim ARG BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 ENV BUN_RUNTIME_TRANSPILER_CACHE_PATH=${BUN_RUNTIME_TRANSPILER_CACHE_PATH} +ARG BUN_INSTALL_BIN=/usr/local/bin +ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN} + COPY docker-entrypoint.sh /usr/local/bin COPY --from=build /usr/local/bin/bun /usr/local/bin/bun diff --git a/dockerhub/debian/Dockerfile b/dockerhub/debian/Dockerfile index f8d147cc9075b..e17da98e21008 100644 --- a/dockerhub/debian/Dockerfile +++ b/dockerhub/debian/Dockerfile @@ -63,6 +63,9 @@ COPY --from=build /usr/local/bin/bun /usr/local/bin/bun ARG BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 ENV BUN_RUNTIME_TRANSPILER_CACHE_PATH=${BUN_RUNTIME_TRANSPILER_CACHE_PATH} +ARG BUN_INSTALL_BIN=/usr/local/bin +ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN} + RUN groupadd bun \ --gid 1000 \ && useradd bun \ diff --git a/dockerhub/distroless/Dockerfile b/dockerhub/distroless/Dockerfile index adf339bdfe94e..3ee9cb34f8384 100644 --- a/dockerhub/distroless/Dockerfile +++ b/dockerhub/distroless/Dockerfile @@ -62,6 +62,9 @@ FROM gcr.io/distroless/base-nossl-debian11 ARG BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 ENV BUN_RUNTIME_TRANSPILER_CACHE_PATH=${BUN_RUNTIME_TRANSPILER_CACHE_PATH} +ARG BUN_INSTALL_BIN=/usr/local/bin +ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN} + COPY --from=build /usr/local/bin/bun /usr/local/bin/ # Temporarily use the `build`-stage image binaries to create a symlink: From 0edf86e39ec8e18eab319bf304dc7ad0da30ea42 Mon Sep 17 00:00:00 2001 From: Ashcon Partovi Date: Tue, 26 Mar 2024 10:41:28 -0700 Subject: [PATCH 23/27] Revert "Fix `bun install -g` not working on Docker" This reverts commit 20fce1a1be724b33aed397f877107f829bd5bb25. --- .vscode/settings.json | 21 ++++++++------------- dockerhub/alpine/Dockerfile | 3 --- dockerhub/debian-slim/Dockerfile | 3 --- dockerhub/debian/Dockerfile | 3 --- dockerhub/distroless/Dockerfile | 3 --- 5 files changed, 8 insertions(+), 25 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index af077036c9a82..f830213bb0125 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -40,7 +40,7 @@ // C++ "lldb.verboseLogging": false, "cmake.configureOnOpen": false, - "C_Cpp.errorSquiggles": "enabled", + "C_Cpp.errorSquiggles": "enabled", "[cpp]": { "editor.defaultFormatter": "xaver.clang-format" }, @@ -55,7 +55,7 @@ "prettier.enable": true, "eslint.workingDirectories": ["${workspaceFolder}/packages/bun-types"], "[javascript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "esbenp.prettier-vscode", }, "[javascriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" @@ -72,12 +72,12 @@ // JSON "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "esbenp.prettier-vscode", }, "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "esbenp.prettier-vscode", }, - + // Markdown "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode", @@ -94,17 +94,12 @@ // TOML "[toml]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "esbenp.prettier-vscode", }, // YAML "[yaml]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - }, - - // Dockerfile - "[dockerfile]": { - "editor.formatOnSave": false + "editor.defaultFormatter": "esbenp.prettier-vscode", }, // Files @@ -153,5 +148,5 @@ "WebKit/WebDriver": true, "WebKit/WebKitBuild": true, "WebKit/WebInspectorUI": true - } + }, } diff --git a/dockerhub/alpine/Dockerfile b/dockerhub/alpine/Dockerfile index 79e10e28416b6..4051cf17d9a5a 100644 --- a/dockerhub/alpine/Dockerfile +++ b/dockerhub/alpine/Dockerfile @@ -96,9 +96,6 @@ FROM alpine:3.18 ARG BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 ENV BUN_RUNTIME_TRANSPILER_CACHE_PATH=${BUN_RUNTIME_TRANSPILER_CACHE_PATH} -ARG BUN_INSTALL_BIN=/usr/local/bin -ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN} - COPY --from=build /usr/local/bin/bun /usr/local/bin/ COPY docker-entrypoint.sh /usr/local/bin/ diff --git a/dockerhub/debian-slim/Dockerfile b/dockerhub/debian-slim/Dockerfile index c26352eec5950..babe2d7a571a5 100644 --- a/dockerhub/debian-slim/Dockerfile +++ b/dockerhub/debian-slim/Dockerfile @@ -62,9 +62,6 @@ FROM debian:bullseye-slim ARG BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 ENV BUN_RUNTIME_TRANSPILER_CACHE_PATH=${BUN_RUNTIME_TRANSPILER_CACHE_PATH} -ARG BUN_INSTALL_BIN=/usr/local/bin -ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN} - COPY docker-entrypoint.sh /usr/local/bin COPY --from=build /usr/local/bin/bun /usr/local/bin/bun diff --git a/dockerhub/debian/Dockerfile b/dockerhub/debian/Dockerfile index e17da98e21008..f8d147cc9075b 100644 --- a/dockerhub/debian/Dockerfile +++ b/dockerhub/debian/Dockerfile @@ -63,9 +63,6 @@ COPY --from=build /usr/local/bin/bun /usr/local/bin/bun ARG BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 ENV BUN_RUNTIME_TRANSPILER_CACHE_PATH=${BUN_RUNTIME_TRANSPILER_CACHE_PATH} -ARG BUN_INSTALL_BIN=/usr/local/bin -ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN} - RUN groupadd bun \ --gid 1000 \ && useradd bun \ diff --git a/dockerhub/distroless/Dockerfile b/dockerhub/distroless/Dockerfile index 3ee9cb34f8384..adf339bdfe94e 100644 --- a/dockerhub/distroless/Dockerfile +++ b/dockerhub/distroless/Dockerfile @@ -62,9 +62,6 @@ FROM gcr.io/distroless/base-nossl-debian11 ARG BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 ENV BUN_RUNTIME_TRANSPILER_CACHE_PATH=${BUN_RUNTIME_TRANSPILER_CACHE_PATH} -ARG BUN_INSTALL_BIN=/usr/local/bin -ENV BUN_INSTALL_BIN=${BUN_INSTALL_BIN} - COPY --from=build /usr/local/bin/bun /usr/local/bin/ # Temporarily use the `build`-stage image binaries to create a symlink: From 2dabf1337e1e7833d0fe4c90d91d25ace93fb8f4 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Tue, 26 Mar 2024 13:53:58 -0700 Subject: [PATCH 24/27] what happens if nonblocking tty (#9608) Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> --- src/bun.js/bindings/c-bindings.cpp | 49 ++++++++++++++++++++++++- src/bun.js/webcore/streams.zig | 57 +++++++++++++++++++++++++----- src/c.zig | 1 + src/feature_flags.zig | 5 +++ 4 files changed, 102 insertions(+), 10 deletions(-) diff --git a/src/bun.js/bindings/c-bindings.cpp b/src/bun.js/bindings/c-bindings.cpp index bcda72ec28fe1..f77f9e6bb56c8 100644 --- a/src/bun.js/bindings/c-bindings.cpp +++ b/src/bun.js/bindings/c-bindings.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #else #include #include @@ -480,4 +481,50 @@ extern "C" void bun_initialize_process() #endif atexit(Bun__onExit); -} \ No newline at end of file +} + +#if OS(WINDOWS) +extern "C" int32_t open_as_nonblocking_tty(int32_t fd, int32_t mode) +{ + RELEASE_ASSERT_NOT_REACHED(); +} + +#else + +static bool can_open_as_nonblocking_tty(int32_t fd) +{ + int result; +#if OS(LINUX) || OS(FreeBSD) + int dummy = 0; + + result = ioctl(fd, TIOCGPTN, &dummy) != 0; +#elif OS(DARWIN) + + char dummy[256]; + + result = ioctl(fd, TIOCPTYGNAME, &dummy) != 0; + +#else + +#error "TODO" + +#endif + + return result; +} + +extern "C" int32_t open_as_nonblocking_tty(int32_t fd, int32_t mode) +{ + if (!can_open_as_nonblocking_tty(fd)) { + return -1; + } + + char pathbuf[PATH_MAX + 1]; + if (ttyname_r(fd, pathbuf, sizeof(pathbuf)) != 0) { + return -1; + } + + return open(pathbuf, mode | O_NONBLOCK | O_NOCTTY | O_CLOEXEC); +} + +#endif \ No newline at end of file diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig index 158b7a752de79..d37c4729b629e 100644 --- a/src/bun.js/webcore/streams.zig +++ b/src/bun.js/webcore/streams.zig @@ -3039,9 +3039,24 @@ pub const FileSink = struct { pub fn setup(this: *FileSink, options: *const StreamStart.FileSinkOptions) JSC.Maybe(void) { // TODO: this should be concurrent. + var isatty: ?bool = null; + var is_nonblocking_tty = false; const fd = switch (switch (options.input_path) { .path => |path| bun.sys.openA(path.slice(), options.flags(), options.mode), - .fd => |fd_| bun.sys.dupWithFlags(fd_, if (bun.FDTag.get(fd_) == .none and !this.force_sync_on_windows) std.os.O.NONBLOCK else 0), + .fd => |fd_| brk: { + if (comptime Environment.isPosix and FeatureFlags.nonblocking_stdout_and_stderr_on_posix) { + if (bun.FDTag.get(fd_) != .none) { + const rc = bun.C.open_as_nonblocking_tty(@intCast(fd_.cast()), std.os.O.WRONLY); + if (rc > -1) { + isatty = true; + is_nonblocking_tty = true; + break :brk JSC.Maybe(bun.FileDescriptor){ .result = bun.toFD(rc) }; + } + } + } + + break :brk bun.sys.dupWithFlags(fd_, if (bun.FDTag.get(fd_) == .none and !this.force_sync_on_windows) std.os.O.NONBLOCK else 0); + }, }) { .err => |err| return .{ .err = err }, .result => |fd| fd, @@ -3054,13 +3069,22 @@ pub const FileSink = struct { return .{ .err = err }; }, .result => |stat| { - this.pollable = bun.sys.isPollable(stat.mode) or std.os.isatty(fd.int()); + this.pollable = bun.sys.isPollable(stat.mode); + if (!this.pollable and isatty == null) { + isatty = std.os.isatty(fd.int()); + } + + if (isatty) |is| { + if (is) + this.pollable = true; + } + this.fd = fd; this.is_socket = std.os.S.ISSOCK(stat.mode); - this.nonblocking = this.pollable and switch (options.input_path) { + this.nonblocking = is_nonblocking_tty or (this.pollable and switch (options.input_path) { .path => true, .fd => |fd_| bun.FDTag.get(fd_) == .none, - }; + }); }, } } else if (comptime Environment.isWindows) { @@ -3402,11 +3426,20 @@ pub const FileReader = struct { pub fn openFileBlob(file: *Blob.FileStore) JSC.Maybe(OpenedFileBlob) { var this = OpenedFileBlob{ .fd = bun.invalid_fd }; var file_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + var is_nonblocking_tty = false; const fd = if (file.pathlike == .fd) - if (file.pathlike.fd.isStdio()) - file.pathlike.fd - else switch (Syscall.dupWithFlags(file.pathlike.fd, brk: { + if (file.pathlike.fd.isStdio()) brk: { + if (comptime Environment.isPosix) { + const rc = bun.C.open_as_nonblocking_tty(@intCast(file.pathlike.fd.int()), std.os.O.RDONLY); + if (rc > -1) { + is_nonblocking_tty = true; + file.is_atty = true; + break :brk bun.toFD(rc); + } + } + break :brk file.pathlike.fd; + } else switch (Syscall.dupWithFlags(file.pathlike.fd, brk: { if (comptime Environment.isPosix) { if (bun.FDTag.get(file.pathlike.fd) == .none and !(file.is_atty orelse false)) { break :brk std.os.O.NONBLOCK; @@ -3459,14 +3492,20 @@ pub const FileReader = struct { return .{ .err = Syscall.Error.fromCode(.ISDIR, .fstat) }; } - this.pollable = bun.sys.isPollable(stat.mode) or (file.is_atty orelse false); + this.pollable = bun.sys.isPollable(stat.mode) or is_nonblocking_tty or (file.is_atty orelse false); this.file_type = if (bun.S.ISFIFO(stat.mode)) .pipe else if (bun.S.ISSOCK(stat.mode)) .socket else .file; - this.nonblocking = this.pollable and !(file.is_atty orelse false); + + // pretend it's a non-blocking pipe if it's a TTY + if (is_nonblocking_tty and this.file_type != .socket) { + this.file_type = .nonblocking_pipe; + } + + this.nonblocking = is_nonblocking_tty or (this.pollable and !(file.is_atty orelse false)); if (this.nonblocking and this.file_type == .pipe) { this.file_type = .nonblocking_pipe; diff --git a/src/c.zig b/src/c.zig index 150dae475c584..5e74b804f3486 100644 --- a/src/c.zig +++ b/src/c.zig @@ -467,3 +467,4 @@ pub extern "C" fn Bun__ttySetMode(fd: c_int, mode: c_int) c_int; pub extern "C" fn bun_initialize_process() void; pub extern "C" fn bun_restore_stdio() void; +pub extern "C" fn open_as_nonblocking_tty(i32, i32) i32; diff --git a/src/feature_flags.zig b/src/feature_flags.zig index 66ceb74096bff..05902b3a76478 100644 --- a/src/feature_flags.zig +++ b/src/feature_flags.zig @@ -167,3 +167,8 @@ pub const runtime_transpiler_cache = true; pub const windows_bunx_fast_path = true; pub const breaking_changes_1_1_0 = false; + +// This causes strange bugs where writing via console.log (sync) has a different +// order than via Bun.file.writer() so we turn it off until there's a unified, +// buffered writer abstraction shared throughout Bun +pub const nonblocking_stdout_and_stderr_on_posix = false; From 1bffcd3d24a3ca8c762349f1ef8c4ac6f0829bfe Mon Sep 17 00:00:00 2001 From: dave caruso Date: Tue, 26 Mar 2024 18:24:33 -0700 Subject: [PATCH 25/27] merge --- src/install/windows-shim/bun_shim_impl.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index 3b430de29a84e..0d4aa1c644a05 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -779,9 +779,9 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { .cbReserved2 = 0, .lpReserved2 = null, // The standard handles outside of standalone may be tampered with. - .hStdInput = if (is_standalone) ProcessParameters.hStdInput else bun.win32.STDERR_FD.cast(), + .hStdInput = if (is_standalone) ProcessParameters.hStdInput else bun.win32.STDIN_FD.cast(), .hStdOutput = if (is_standalone) ProcessParameters.hStdOutput else bun.win32.STDOUT_FD.cast(), - .hStdError = if (is_standalone) ProcessParameters.hStdError else bun.win32.STDIN_FD.cast(), + .hStdError = if (is_standalone) ProcessParameters.hStdError else bun.win32.STDERR_FD.cast(), }; inline for (.{ 0, 1 }) |attempt_number| iteration: { From 0ec0b5e157d95b9d883045c6cbf85a3bf71415a3 Mon Sep 17 00:00:00 2001 From: dave caruso Date: Tue, 26 Mar 2024 19:05:43 -0700 Subject: [PATCH 26/27] a --- src/feature_flags.zig | 2 +- src/install/semver.zig | 6 ------ src/install/windows-shim/bun_shim_impl.exe | Bin 12800 -> 13312 bytes src/install/windows-shim/bun_shim_impl.zig | 6 ++++++ 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/feature_flags.zig b/src/feature_flags.zig index 05902b3a76478..f0183b07cb706 100644 --- a/src/feature_flags.zig +++ b/src/feature_flags.zig @@ -164,7 +164,7 @@ pub const disable_auto_js_to_ts_in_node_modules = true; pub const runtime_transpiler_cache = true; -pub const windows_bunx_fast_path = true; +pub const windows_bunx_fast_path = false; // Disabled to simplify fixing the bunx issue pub const breaking_changes_1_1_0 = false; diff --git a/src/install/semver.zig b/src/install/semver.zig index dff0c9ec97dc0..320837ec65a59 100644 --- a/src/install/semver.zig +++ b/src/install/semver.zig @@ -63,12 +63,6 @@ pub const String = extern struct { } } - pub fn isUndefined(this: *const String) bool { - const num: u64 = undefined; - const bytes = @as(u64, @bitCast(this.bytes)); - return @as(u63, @truncate(bytes)) == @as(u63, @truncate(num)); - } - pub const Formatter = struct { str: *const String, buf: string, diff --git a/src/install/windows-shim/bun_shim_impl.exe b/src/install/windows-shim/bun_shim_impl.exe index 78cbc16faac42d25aaf4faab83471d1dda9eb81a..bec9155b4905ed758e8414e8d768848fcaf97e34 100755 GIT binary patch delta 2579 zcmd^BZA?>F7(VCPQbgeLQIN4Y&|H|E$S69M2uf#hr{=m3b#rPJP-tp`$h0LaVYZ~L z@mg*o9yMmklEwWQ>ZThQkulSKXu;`3k}Xc-=FGBPR03*7Kqq(aDOaQ2k0r)`JIy)I zd7t-v&w0*!PSbj;yv|+T^z-jea3HM>p=oFmmxxe$%f2&u?;?ciTBbfry*PHx+eU~< zf}Rdtr^RcKjZj7Yma0luB|=wNTmf_zmq}0J7jQw_A9yZjY``2+R;M6DOyBXQcA)}n zYSPW{tZM?U!;Tih$Bu~P7Z@YTWp|0(EI44U%w%aD>yaDPq6Tms7VH?IC6a%p&Wn&- z7UzJhk6=fJ2LMH>UHAkr>=!}+Ob~&2Hy~?79uH@mP3{E(d>11gg!q*qKG`o^rPp;9 zPlE`NA@GQDmv9uYQ$i_dsWhsTgQSw#2!&iT0wH(ag#pXw*x|d!ZOtt+_t|87?U=*Y zRbvPBcK0^oJ9V%BLr7PM9){&GNIzfbhe&hC+;>B8@L5(6Z}E*}Tll>pOKh)YID~nB z{2=5IHAITKw;rY^^^TV+nlKRO%qpLS9KOc+V|G^}@rB2La}O#9;buf>g-~ae&XJ%f zG|;zV3i67Q5ekG{t4jbwe4q=~w3)8hO!sX~r((Pq-5^9ZE;jct5%fq*wr9_nsuI)p z#P_YP%-my>F7*e15rcU3JNd{>fLDgyVO76P9oAMk#37Yt5B!Z^Q^Azkr=`lM_6Y-sNZv$RjPFY4DB#j zrADC&{Dxth6t;amn9cjYg4>ruOJwW3M6pQW1D}E|N{VP2VK=&;iNqI)yuvUnO1G9u zBT77M<#;9RFJ|=vJra2LL>>__^^ytWIdIp8>mF65-G+EiHzg_Dq=OQ^F+L(0c26yJg9=UDV3q1GVicZ5Nr4JwyygN*4m;0mBTLm<@& zonJZ3C$|eDYzi2QJ>!!M$bzux0Iab$oX6(S*?isuUTPLf83)gvM6gSE1F)0%EgfuB zD3pLmw;rXu5o+{NY7?X2PM+~X4v|~}yp67iOaj+X$|t*MYwYu$U*NRx?6VX-E39vX zb2<6rp_1P@xcya10f2IY=?FFpY@tpSnlce$!&bqmvZXZ-T$12ajJ0MKS z0RyV$RO~QO{)9Ez+gj+>D_!Gr&iyhlm=CahEd22pP?OCEPJ>lu4iQ=3T*3~b4=iL) zM86$Cd6za$w0M3^h@8Qw#K6+*41C}|JafhHFX3qr0K#jch1V!w!Ws{SFVKvLa5ESn zyhd@t#N0>Zgm5uzlh0@QK^ojHmu02-ak>01ph2IsAfj()+lIJ0%=OHrKTg`1zHT!3 zHt3oN?pCjo-~#hyQ7(Ctu83dDT`Qt(@vFJcIh0SR<}S~r^$Dv|)8@k>!JKq}GV=hD zr}WOF*Amv^9c`tFi5R~}U+1f_ogU-g;W}qgKB=1PoK5SKR&sX>>3OhD%%XFW*Wjsi zcXB!RlbPO0uB7cL8MG#a;8c1nr5vxLX{mNxMYp7u<2>32<33twT#skby~c9&qUeZMA@DHVSf?jKlr%q$vN;ik@G>6y*tX@ z`I!As`4dh&Pnh?#(*6hgA5v7cc|cX;Z>s89*85epW>8gIZ>eg38aTGyR@ELLOxK|g zsp`c3w!(~qDVe9?H<$g%DTV%^^#XTvQOnd!&ydF6)i4e`tYv7JtKm3{P_bsereTGK z^%`#1aKDB}HGGgCwcj%I)HkFTW}GlCuXd5j+NzprTdiaBmQ9tejhk!Rw&yLw2l93Q E0Qy)NZvX%Q delta 2029 zcmbtVZERCj7(VCHu5)g?Yxlvd!pd?{I$^XE*boMEbmUyP7!syTC~m{88Ib^SEm?G? zt!)#o+fBfO#28}G_yctbj*ajUTxwt`Q;aaemmdj4Lr%vCW5zLt?)sjt7+7Nb;aSdo z-jC;;^PKm*&4SIr#y!D;7Ng)rsWFU-(UU?pLV0`le`{=AiBR+2Sx?g-PG5907dSaE z^I#fM{1n&_sxN)BvBB4X&{3Xuz$}1SNPF>fxU~BwE*COuv4GgP86jdnL!E}_1FwX@ zKJG!w;m?DJ8j*NJ(W=LZ)*-zHHoL^>$G0Fq+KyTw)hX3rgjTDOd4?cDT6KmOR(%L3 zar_8SQG29=fbocQ9DoZUV8;OYAlf9IA2$6g1R!@lnL$Y05EIQ2=_(yDxB@#BVDcRl z?UZx~@T7_?XsvpmnJfrZE<_sP~A` zcVQ(7_dQ5_0tOp`y0LrkQLkM{0NWXJ4&0jKEftF*kcLaR!ecg<_(9B-mww(g8pC4b zE`*65Ba6?rd`5eXUT19xL*RR-E*2qgxNXUV$CpjQ@d=3e@37UdxuVuc&2CkZJfvNb zcGC4}j*=_za?zNtwi4Z_8xZQr6rvka%pHX+lkeZ;XZRJHAB7FRvKwGx&)Y zYU_bA6hqb9On(O3BoFfE5cNJ$N0fHA)XWM*Uf-T1i|~jyZZIK~2wa3ym^=+WHSmFy zX;fC@@;7&EV&rWM^^2|6+!fi%VkSo40AEp=Vjts=x`*q-SBX|*8dcQ0Yt=E<1^w); zibt06(t#Kivip*KMC|9uw8=H_+@`^RuCLLQav>nAS2!oxf-SI|w@odE!sDxOj)ED{ z6w}b;jh=<;kanNcEUUw86({50f&UEWKSK7#L8lCtbU;}csBDJm5_8;=P2A8gnmeQ% zAaF!@^Q1A%?{We@2tkUd9g+4A(wad>G` zTw+;L++g?VjGb7pSI~u-TMK%pL+*7$h~TsOb<)1f`IDkmcF~^9%|g|SG&gIbU@fOR zvYLb?74&k}tGWIquu1#uT>#b2+eDk;SWK(3H)Ga)FgqLLYxJ<#giq1@oLa%UfbPg? z608g9<(v(|#uw;(bCdAY0=nP435V#2xlUMAM%P;!@I`vmQb&6%g>-H%!M)U<>%nK} zKyDrGpk;Y=c$B`Mw*^!B2iWh?m-9XN06mhw3BT2yU9b-a%4`Uo`)BC0OQ!h6Q+(?b z-|`=R#+1A;#h*Q1^tgbLDgGe%w4u;iwub5Y+}pa|c}v%~4Z%$4dgdKnm+$Jj3h|jE zy1o_seu(!2e$KkftY28HAG;Ca|KC=?d^iq4?9j@+v#f#Zspwz|$5WUN3_c1{IO!oY sH{~x&;kp!hQ@AUIyHogZ-M^euh5q+J^v1js-A77a!qkT6eCja#4F(&W-T(jq diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index 0d4aa1c644a05..aab9eebc35eb5 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -116,6 +116,8 @@ const k32 = struct { const GetExitCodeProcess = w.kernel32.GetExitCodeProcess; /// https://learn.microsoft.com/en-us/windows/console/getconsolemode const GetConsoleMode = w.kernel32.GetConsoleMode; + /// https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-sethandleinformation + const SetHandleInformation = w.kernel32.SetHandleInformation; /// https://learn.microsoft.com/en-us/windows/console/setconsolemode extern "kernel32" fn SetConsoleMode( hConsoleHandle: w.HANDLE, // [in] @@ -784,6 +786,10 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { .hStdError = if (is_standalone) ProcessParameters.hStdError else bun.win32.STDERR_FD.cast(), }; + _ = k32.SetHandleInformation(startup_info.hStdInput.?, w.HANDLE_FLAG_INHERIT, 1); + _ = k32.SetHandleInformation(startup_info.hStdOutput.?, w.HANDLE_FLAG_INHERIT, 1); + _ = k32.SetHandleInformation(startup_info.hStdError.?, w.HANDLE_FLAG_INHERIT, 1); + inline for (.{ 0, 1 }) |attempt_number| iteration: { if (dbg) debug("lpCommandLine: {}\n", .{fmt16(std.mem.span(spawn_command_line))}); From 3c6108dd3d318b19be71dda2a5d2099b12ee6c39 Mon Sep 17 00:00:00 2001 From: dave caruso Date: Tue, 26 Mar 2024 19:30:52 -0700 Subject: [PATCH 27/27] blah --- src/cli/run_command.zig | 3 +-- src/install/windows-shim/bun_shim_impl.exe | Bin 13312 -> 12800 bytes src/install/windows-shim/bun_shim_impl.zig | 4 ---- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index 03b0b4ee8104b..61275d392a5a1 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -1506,8 +1506,7 @@ pub const RunCommand = struct { } // Run absolute/relative path - if ((script_name_to_search.len > 1 and script_name_to_search[0] == '/') or - (Environment.isWindows and script_name_to_search.len > 3 and std.ascii.isAlphabetic(script_name_to_search[0]) and script_name_to_search[1] == ':') or + if (std.fs.path.isAbsolute(script_name_to_search) or (script_name_to_search.len > 2 and script_name_to_search[0] == '.' and script_name_to_search[1] == '/')) { Run.boot(ctx, ctx.allocator.dupe(u8, script_name_to_search) catch unreachable) catch |err| { diff --git a/src/install/windows-shim/bun_shim_impl.exe b/src/install/windows-shim/bun_shim_impl.exe index bec9155b4905ed758e8414e8d768848fcaf97e34..bec89b47e4a3980a1e96e4028e6922b29112db9a 100755 GIT binary patch delta 2029 zcmbtVZA?>F7(VA(C}YrDNB<{bD3iN+DD?Pp^jsQ1?+bd2YnF!Ny+&~E$!F6q35%Y>{NEFdSCXjNlGYm?ppn_cGg6Pr)~ZAHzHYL}`pLMzqi976~ptt!(8t3HI2 zIDQ1Es9n+_z}~2I0)Pu4V8;RZAld|-A2#(I1R!@InL$Wg7Z-D)(lt74a0j<5z~nn9 z+G*)9;3*YZ&}#JoGg=U;n1@i@KQ|T+I4|CDcVJ)Sp|GR4%GEDx-mT-l$muQBpx!IS zcEL&#>3Nv=1PnF^bz}G8qh7z50Jbac>c2h9S0WZhAq|&sM@H>#@q@VAnsLEB631fn z9)yV=CkxN*_>6X^`CK(&41w=mx>$&Ok(Nc{UcZS%ddDFaxXV_;=89S^HF;D;@{(3X z+D_M|JBzQv%f;gUnhL0AT#TK9U1i5Fvg0o~+>;){==KVtSy#CF#6o%`-5zWk*LC9f zjzrEFs$6}t`eWifh$yY?(pOv$-;o zrWgk&ZuC4{hqU^oCRrU~D>xbd4*cgh|1q+!7j(*SNhg$rfyySBZqe+K?BcpUF{e#3 z1A!yL8z+n*ewUN*K?qVrZIkSPuzVH(AH1`jDVw)$d6E{D2uIB?H51h@5ds~|4^rCZqu7+ks-OXmXb!_vp}jzSjn zHawxXfptK5LT_2pYLh~+junFgdK*|h7_NSzW!vHWM?Xv{xZ9AaXqA|R$LPV#0&!?@ zQe0w5Qrtl2nau52aFo;eS)22_r$X*cLzv)m`VG>$#PyS+RdmptCXCa~g$b=FtN=8*rEo=hO-dO6gilJ-$SbS!!vQrGU=PCAgaga=rL0 z?a!^nZM4){i$~}_>n2R;A7H;vU(NI4gY;mf8_I|Ig587EkhvCi%8W zzU4ps%t?7+l0S2-@JRu~ll%ejX?=mMbQRO}*>`lk{kE=e8HAb8^{l(PF5lC272?x} zb$v7VeGu;h{G4@`+P<*ZKK3BQ|GzDR`Dh%5*x}`SXV`)_Qqh4Fj-@aI7<}ZXaKb}q scFJFp!Zj)MrEq5occ<{tx_>#R68-Ok=*>ANJCByUf~g(P`qXLo8+EjuEdT%j delta 2579 zcmd^BZA?>F7(VCPQbgeLQIN4Y&|H|E$S69M2uf#hr{=m3b#rPJP-tp`$h0LaVYZ~L z@mg*o9yMmklEwWQ>ZThQkulSKXu;`3k}Xc-=FGBPR03*7Kqq(aDOaQ2k0r)`JIy)I zd7t-v&w0*!PSbj;yv|+T^z-jea3HM>p=oFmmxxe$%f2&u?;?ciTBbfry*PHx+eU~< zf}Rdtr^RcKjZj7Yma0luB|=wNTmf_zmq}0J7jQw_A9yZjY``2+R;M6DOyBXQcA)}n zYSPW{tZM?U!;Tih$Bu~P7Z@YTWp|0(EI44U%w%aD>yaDPq6Tms7VH?IC6a%p&Wn&- z7UzJhk6=fJ2LMH>UHAkr>=!}+Ob~&2Hy~?79uH@mP3{E(d>11gg!q*qKG`o^rPp;9 zPlE`NA@GQDmv9uYQ$i_dsWhsTgQSw#2!&iT0wH(ag#pXw*x|d!ZOtt+_t|87?U=*Y zRbvPBcK0^oJ9V%BLr7PM9){&GNIzfbhe&hC+;>B8@L5(6Z}E*}Tll>pOKh)YID~nB z{2=5IHAITKw;rY^^^TV+nlKRO%qpLS9KOc+V|G^}@rB2La}O#9;buf>g-~ae&XJ%f zG|;zV3i67Q5ekG{t4jbwe4q=~w3)8hO!sX~r((Pq-5^9ZE;jct5%fq*wr9_nsuI)p z#P_YP%-my>F7*e15rcU3JNd{>fLDgyVO76P9oAMk#37Yt5B!Z^Q^Azkr=`lM_6Y-sNZv$RjPFY4DB#j zrADC&{Dxth6t;amn9cjYg4>ruOJwW3M6pQW1D}E|N{VP2VK=&;iNqI)yuvUnO1G9u zBT77M<#;9RFJ|=vJra2LL>>__^^ytWIdIp8>mF65-G+EiHzg_Dq=OQ^F+L(0c26yJg9=UDV3q1GVicZ5Nr4JwyygN*4m;0mBTLm<@& zonJZ3C$|eDYzi2QJ>!!M$bzux0Iab$oX6(S*?isuUTPLf83)gvM6gSE1F)0%EgfuB zD3pLmw;rXu5o+{NY7?X2PM+~X4v|~}yp67iOaj+X$|t*MYwYu$U*NRx?6VX-E39vX zb2<6rp_1P@xcya10f2IY=?FFpY@tpSnlce$!&bqmvZXZ-T$12ajJ0MKS z0RyV$RO~QO{)9Ez+gj+>D_!Gr&iyhlm=CahEd22pP?OCEPJ>lu4iQ=3T*3~b4=iL) zM86$Cd6za$w0M3^h@8Qw#K6+*41C}|JafhHFX3qr0K#jch1V!w!Ws{SFVKvLa5ESn zyhd@t#N0>Zgm5uzlh0@QK^ojHmu02-ak>01ph2IsAfj()+lIJ0%=OHrKTg`1zHT!3 zHt3oN?pCjo-~#hyQ7(Ctu83dDT`Qt(@vFJcIh0SR<}S~r^$Dv|)8@k>!JKq}GV=hD zr}WOF*Amv^9c`tFi5R~}U+1f_ogU-g;W}qgKB=1PoK5SKR&sX>>3OhD%%XFW*Wjsi zcXB!RlbPO0uB7cL8MG#a;8c1nr5vxLX{mNxMYp7u<2>32<33twT#skby~c9&qUeZMA@DHVSf?jKlr%q$vN;ik@G>6y*tX@ z`I!As`4dh&Pnh?#(*6hgA5v7cc|cX;Z>s89*85epW>8gIZ>eg38aTGyR@ELLOxK|g zsp`c3w!(~qDVe9?H<$g%DTV%^^#XTvQOnd!&ydF6)i4e`tYv7JtKm3{P_bsereTGK z^%`#1aKDB}HGGgCwcj%I)HkFTW}GlCuXd5j+NzprTdiaBmQ9tejhk!Rw&yLw2l93Q E0Qy)NZvX%Q diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index aab9eebc35eb5..acbdb0b3fff9c 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -786,10 +786,6 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { .hStdError = if (is_standalone) ProcessParameters.hStdError else bun.win32.STDERR_FD.cast(), }; - _ = k32.SetHandleInformation(startup_info.hStdInput.?, w.HANDLE_FLAG_INHERIT, 1); - _ = k32.SetHandleInformation(startup_info.hStdOutput.?, w.HANDLE_FLAG_INHERIT, 1); - _ = k32.SetHandleInformation(startup_info.hStdError.?, w.HANDLE_FLAG_INHERIT, 1); - inline for (.{ 0, 1 }) |attempt_number| iteration: { if (dbg) debug("lpCommandLine: {}\n", .{fmt16(std.mem.span(spawn_command_line))});