aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.vscode/launch.json6
-rw-r--r--Makefile4
-rw-r--r--README.md35
-rw-r--r--build.zig9
-rw-r--r--examples/css-stress-test/pages/_app.tsx2
-rw-r--r--examples/hello-next/babel.js.REMOVED.git-id1
-rw-r--r--examples/hello-next/bun-framework-next/package.json3
-rw-r--r--examples/hello-next/bun-mimalloc.REMOVED.git-id1
-rw-r--r--examples/hello-next/components/subtitle.tsx1
-rw-r--r--examples/hello-next/next.config.js9
-rw-r--r--examples/hello-next/package.json6
-rw-r--r--examples/hello-next/pages/index.tsx5
-rw-r--r--examples/hello-next/styles/2.css3
-rw-r--r--examples/hello-next/styles/Home.module.css2
-rw-r--r--examples/hello-next/tsconfig.json2
-rw-r--r--examples/lotta-modules/index.js9
-rw-r--r--examples/lotta-modules/package.json1
-rw-r--r--src/api/demo/pages/index.tsx2
-rw-r--r--src/bun_queue.zig845
-rw-r--r--src/bundler.zig728
-rw-r--r--src/cli.zig93
-rw-r--r--src/feature_flags.zig2
-rw-r--r--src/fs.zig30
-rw-r--r--src/global.zig2
-rw-r--r--src/http.zig12
m---------src/javascript/jsc/WebKit0
-rw-r--r--src/js_lexer.zig52
-rw-r--r--src/js_parser/js_parser.zig8
-rw-r--r--src/lock.zig9
-rw-r--r--src/options.zig11
-rw-r--r--src/resolver/resolver.zig51
-rw-r--r--src/string_immutable.zig10
-rw-r--r--src/test/project.zig1466
33 files changed, 2867 insertions, 553 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
index dd4349d2c..763640c48 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -157,12 +157,12 @@
"program": "${workspaceFolder}/build/debug/macos-x86_64/bun",
"args": [
"bun",
- "./index.js",
+ // "./index.js",
"--origin=http://localhost:9000/",
- // "--use=./bun-framework-next",
+ "--use=./bun-framework-next",
"--platform=browser"
],
- "cwd": "${workspaceFolder}/examples/lotta-modules/",
+ "cwd": "${workspaceFolder}/examples/hello-next/",
"console": "internalConsole"
},
{
diff --git a/Makefile b/Makefile
index 5bf8204e0..a544ca01d 100644
--- a/Makefile
+++ b/Makefile
@@ -76,7 +76,9 @@ BUN_LLD_FLAGS := $(OBJ_FILES) \
src/deps/picohttpparser.o \
$(CLANG_FLAGS) \
-fpie \
-
+
+mimalloc:
+ cd src/deps/mimalloc; cmake .; make;
bun-link-lld-debug:
clang++ $(BUN_LLD_FLAGS) \
diff --git a/README.md b/README.md
index c9bd6c529..c1cc2c847 100644
--- a/README.md
+++ b/README.md
@@ -102,6 +102,41 @@ bun build ./routes --outdir=./out
Unlike many other bundlers, `Bun` only bundles `node_modules`. This is great for development, where most people add/update packages much less frequently than app code (which is also great for caching in browsers). To make that distinction clear, the filename defaults to `node_modules.bun`. We recommend storing `node_modules.bun` in your git repository. Since it's a binary file, it shouldn't clutter your git history and it will make your entire frontend development team move faster if they don't have to re-bundle dependencies.
+# Building from source
+
+Estimated: 30-60 minutes :(
+
+You'll want to start downloading two things at once:
+
+```bash
+git clone https://github.com/jarred-sumner/zig && git checkout jarred/zig-sloppy-with-small-structs
+```
+
+```bash
+git submodule update --init --recursive --progress --depth=1
+```
+
+Next, compile Zig.
+
+On a Mac, that looks like this:
+
+```bash
+cmake . -DCMAKE_PREFIX_PATH=$(brew --prefix llvm) -DZIG_STATIC_LLVM=ON -DCMAKE_BUILD_TYPE=Release && make -j 16
+```
+
+Note that `brew install zig` won't work. Bun uses a build of Zig with a couple patches.
+
+You'll want to make sure `zig` is in `$PATH`. The `zig` binary wil be in the same folder as the newly-cloned `zig` repo. If you use fish, you can run `fish_add_path (pwd)`.
+
+Now go back to the folder with `Bun`'s repository.
+
+Run:
+
+```
+zig build headers
+zig build
+```
+
# Credits
- While written in Zig instead of Go, Bun's JS transpiler & CSS lexer source code is based off of @evanw's esbuild project. @evanw did a fantastic job with esbuild.
diff --git a/build.zig b/build.zig
index 18a618517..a0363abf5 100644
--- a/build.zig
+++ b/build.zig
@@ -126,6 +126,7 @@ pub fn build(b: *std.build.Builder) void {
javascript.setMainPkgPath(b.pathFromRoot("."));
typings_exe.setMainPkgPath(b.pathFromRoot("."));
exe.setMainPkgPath(b.pathFromRoot("."));
+
// exe.want_lto = true;
if (!target.getCpuArch().isWasm()) {
b.default_step.dependOn(&exe.step);
@@ -189,6 +190,8 @@ pub fn build(b: *std.build.Builder) void {
b.default_step.dependOn(&exe.step);
var steps = [_]*std.build.LibExeObjStep{ exe, javascript, typings_exe, headers_exec };
+ // const single_threaded = b.option(bool, "single-threaded", "Build single-threaded") orelse false;
+
for (steps) |step, i| {
step.linkLibC();
step.linkLibCpp();
@@ -201,6 +204,12 @@ pub fn build(b: *std.build.Builder) void {
step.addObjectFile("src/deps/libWTF.a");
step.addObjectFile("src/deps/libbmalloc.a");
+ step.addObjectFile("src/deps/mimalloc/libmimalloc.a");
+ step.addLibPath("src/deps/mimalloc");
+ step.addIncludeDir("src/deps/mimalloc");
+
+ // step.single_threaded = single_threaded;
+
// We must link ICU statically
step.addObjectFile("/usr/local/opt/icu4c/lib/libicudata.a");
step.addObjectFile("/usr/local/opt/icu4c/lib/libicui18n.a");
diff --git a/examples/css-stress-test/pages/_app.tsx b/examples/css-stress-test/pages/_app.tsx
index 43d6a776a..47b7ffa56 100644
--- a/examples/css-stress-test/pages/_app.tsx
+++ b/examples/css-stress-test/pages/_app.tsx
@@ -1,4 +1,4 @@
-import "../src/index.css";
+// import "../src/index.css";
import App from "next/app";
diff --git a/examples/hello-next/babel.js.REMOVED.git-id b/examples/hello-next/babel.js.REMOVED.git-id
new file mode 100644
index 000000000..c6e41fc71
--- /dev/null
+++ b/examples/hello-next/babel.js.REMOVED.git-id
@@ -0,0 +1 @@
+e2e5ce1979cde7a27f105fc408e375bbc6a9d78d \ No newline at end of file
diff --git a/examples/hello-next/bun-framework-next/package.json b/examples/hello-next/bun-framework-next/package.json
index 9f12a57a3..fbe7a1d60 100644
--- a/examples/hello-next/bun-framework-next/package.json
+++ b/examples/hello-next/bun-framework-next/package.json
@@ -1,8 +1,7 @@
{
"name": "bun-framework-next",
- "version": "0.0.0-8",
+ "version": "0.0.0-9",
"description": "",
- "main": "package.json",
"framework": {
"static": "public",
"assetPrefix": "_next/",
diff --git a/examples/hello-next/bun-mimalloc.REMOVED.git-id b/examples/hello-next/bun-mimalloc.REMOVED.git-id
new file mode 100644
index 000000000..d81da2b9a
--- /dev/null
+++ b/examples/hello-next/bun-mimalloc.REMOVED.git-id
@@ -0,0 +1 @@
+1cfda0305a0e23d0aaf4459029f0b97424d0f22d \ No newline at end of file
diff --git a/examples/hello-next/components/subtitle.tsx b/examples/hello-next/components/subtitle.tsx
index 347d97a4d..1fda3db60 100644
--- a/examples/hello-next/components/subtitle.tsx
+++ b/examples/hello-next/components/subtitle.tsx
@@ -1,3 +1,4 @@
+
export default function Hey() {
return <div>!!yep</div>;
}
diff --git a/examples/hello-next/next.config.js b/examples/hello-next/next.config.js
index 0d6071006..c161436ab 100644
--- a/examples/hello-next/next.config.js
+++ b/examples/hello-next/next.config.js
@@ -1,3 +1,10 @@
module.exports = {
reactStrictMode: true,
-}
+ typescript: {
+ // !! WARN !!
+ // Dangerously allow production builds to successfully complete even if
+ // your project has type errors.
+ // !! WARN !!
+ ignoreBuildErrors: true,
+ },
+};
diff --git a/examples/hello-next/package.json b/examples/hello-next/package.json
index fd803c98a..77ce7b80e 100644
--- a/examples/hello-next/package.json
+++ b/examples/hello-next/package.json
@@ -5,9 +5,15 @@
"license": "MIT",
"dependencies": {
"next": "^11.1.0",
+ "parcel": "2.0.0-rc.0",
"path": "^0.12.7",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"whatwg-url": "^9.1.0"
+ },
+ "devDependencies": {
+ "@babel/standalone": "^7.15.3",
+ "@types/react": "^17.0.19",
+ "typescript": "^4.3.5"
}
}
diff --git a/examples/hello-next/pages/index.tsx b/examples/hello-next/pages/index.tsx
index b87c67a84..dab661672 100644
--- a/examples/hello-next/pages/index.tsx
+++ b/examples/hello-next/pages/index.tsx
@@ -3,11 +3,12 @@ import Image from "next/image";
import styles from "../styles/Home.module.css";
import Link from "next/link";
import { useRouter } from "next/router";
-
import Title from "../components/Title";
+import React from "react";
export default function Home() {
const router = useRouter();
+
return (
<div className={styles.container}>
<Head>
@@ -20,7 +21,7 @@ export default function Home() {
<main className={styles.main}>
<h1 className={styles.title}>
- Welcome to <a href="https://nextjs.org">Next.js!</a>
+ asdasdasd to <a href="https://nextjs.org">Next.js!</a>
</h1>
<p className={styles.description}>
diff --git a/examples/hello-next/styles/2.css b/examples/hello-next/styles/2.css
new file mode 100644
index 000000000..1e30d2166
--- /dev/null
+++ b/examples/hello-next/styles/2.css
@@ -0,0 +1,3 @@
+* {
+ background-color: red;
+}
diff --git a/examples/hello-next/styles/Home.module.css b/examples/hello-next/styles/Home.module.css
index 35454bb74..167d5f75b 100644
--- a/examples/hello-next/styles/Home.module.css
+++ b/examples/hello-next/styles/Home.module.css
@@ -1,3 +1,4 @@
+@import url("./2.css");
.container {
min-height: 100vh;
padding: 0 0.5rem;
@@ -7,7 +8,6 @@
align-items: center;
height: 100vh;
}
-
.main {
padding: 5rem 0;
flex: 1;
diff --git a/examples/hello-next/tsconfig.json b/examples/hello-next/tsconfig.json
index 679268d71..b423bb201 100644
--- a/examples/hello-next/tsconfig.json
+++ b/examples/hello-next/tsconfig.json
@@ -18,6 +18,6 @@
"path": ["node_modules/path-browserify"]
}
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/index.tsx"],
"exclude": ["node_modules"]
}
diff --git a/examples/lotta-modules/index.js b/examples/lotta-modules/index.js
index 12c99a7a7..4968cac4b 100644
--- a/examples/lotta-modules/index.js
+++ b/examples/lotta-modules/index.js
@@ -1,7 +1,7 @@
import "lodash/_DataView.js";
import "lodash/_Hash.js";
import "lodash/_LazyWrapper.js";
-import "lodash/_ListCache.js";
+import "lodash/_ListCache";
import "lodash/_LodashWrapper.js";
import "lodash/_Map.js";
import "lodash/_MapCache.js";
@@ -631,8 +631,11 @@ import "lodash/xorWith.js";
import "lodash/zip.js";
import "lodash/zipObject.js";
import "lodash/zipObjectDeep.js";
-import "lodash/zipWith.js";
+import "lodash/_setToString";
import "lodash";
+import "lodash/lodash";
import "underscore";
-import "three.js";
+import "three";
+
+// import "@babel/standalone/babel.js";
diff --git a/examples/lotta-modules/package.json b/examples/lotta-modules/package.json
index 6168008db..6688548da 100644
--- a/examples/lotta-modules/package.json
+++ b/examples/lotta-modules/package.json
@@ -4,6 +4,7 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
+ "@babel/standalone": "^7.15.3",
"lodash": "^4.17.21",
"three.js": "^0.77.1",
"underscore": "^1.13.1"
diff --git a/src/api/demo/pages/index.tsx b/src/api/demo/pages/index.tsx
index 6f09d0d52..4d60b4084 100644
--- a/src/api/demo/pages/index.tsx
+++ b/src/api/demo/pages/index.tsx
@@ -1,6 +1,6 @@
import Head from "next/head";
import Image from "next/image";
-// import styles from "../styles/Home.module.css";
+import styles from "../styles/Home.module.css";
import "../lib/api.ts";
export default function Home() {
diff --git a/src/bun_queue.zig b/src/bun_queue.zig
new file mode 100644
index 000000000..4c289d511
--- /dev/null
+++ b/src/bun_queue.zig
@@ -0,0 +1,845 @@
+const std = @import("std");
+const Mutex = @import("./lock.zig").Mutex;
+const Channel = @import("./sync.zig").Channel;
+const WaitGroup = @import("./sync.zig").WaitGroup;
+usingnamespace @import("./global.zig");
+const Wyhash = std.hash.Wyhash;
+const assert = std.debug.assert;
+
+const VerboseQueue = false;
+
+pub fn NewBlockQueue(comptime Value: type, comptime block_size: comptime_int, comptime block_count: usize) type {
+ return struct {
+ const BlockQueue = @This();
+ const Block = [block_size]Value;
+
+ blocks: [block_count]*Block = undefined,
+ overflow: std.ArrayList(*Block) = undefined,
+ first: Block = undefined,
+ len: std.atomic.Atomic(i32) = std.atomic.Atomic(i32).init(0),
+ allocated_blocks: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0),
+
+ write_lock: bool = false,
+ overflow_write_lock: bool = false,
+ overflow_readers: std.atomic.Atomic(u8) = std.atomic.Atomic(u8).init(0),
+ allocator: *std.mem.Allocator,
+ empty_queue: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(1),
+ rand: std.rand.DefaultPrng = std.rand.DefaultPrng.init(100),
+
+ pub fn new(this: *BlockQueue, allocator: *std.mem.Allocator) void {
+ this.* = BlockQueue{
+ .allocator = allocator,
+ .overflow = std.ArrayList(*Block).init(allocator),
+ .len = std.atomic.Atomic(i32).init(0),
+ };
+ this.blocks[0] = &this.first;
+ this.allocator = allocator;
+ }
+
+ pub fn get(this: *BlockQueue) ?Value {
+ if (this.len.fetchMax(-1, .SeqCst) <= 0) return null;
+
+ while (@atomicRmw(bool, &this.write_lock, .Xchg, true, .SeqCst)) {
+ const end = this.rand.random.uintAtMost(u8, 64);
+ var i: u8 = 0;
+ while (i < end) : (i += 1) {}
+ std.atomic.spinLoopHint();
+ }
+ defer assert(@atomicRmw(bool, &this.write_lock, .Xchg, false, .SeqCst));
+
+ if (this.len.fetchMax(-1, .SeqCst) <= 0) return null;
+ const current_len_ = this.len.fetchSub(1, .SeqCst);
+ if (current_len_ <= 0) return null;
+
+ const current_len = @intCast(u32, current_len_);
+ if (current_len == 0) {
+ return null;
+ }
+
+ const current_block = @floatToInt(u32, std.math.floor(@intToFloat(f32, (current_len - 1) / block_size)));
+ const index = (current_len - 1) % block_size;
+
+ if (comptime VerboseQueue) std.debug.print("[GET] {d}, {d}\n", .{ current_block, index });
+
+ switch (current_block) {
+ 0 => {
+ return this.first[index];
+ },
+ 1...block_count => {
+ const ptr = @atomicLoad(*Block, &this.blocks[current_block], .SeqCst);
+ return ptr[index];
+ },
+ else => {
+ const is_overflowing = current_block > block_count;
+
+ unreachable;
+ },
+ }
+ }
+
+ pub fn enqueue(this: *BlockQueue, value: Value) !void {
+ while (@atomicRmw(bool, &this.write_lock, .Xchg, true, .SeqCst)) {
+ const end = this.rand.random.uintAtMost(u8, 32);
+ var i: u8 = 0;
+ while (i < end) : (i += 1) {}
+ std.atomic.spinLoopHint();
+ }
+ defer assert(@atomicRmw(bool, &this.write_lock, .Xchg, false, .SeqCst));
+ defer {
+ const old = this.empty_queue.swap(0, .SeqCst);
+ if (old == 1) std.Thread.Futex.wake(&this.empty_queue, std.math.maxInt(u32));
+ }
+
+ const current_len = @intCast(u32, std.math.max(this.len.fetchAdd(1, .SeqCst), 0));
+ const next_len = current_len + 1;
+
+ const current_block = @floatToInt(u32, std.math.floor(@intToFloat(f32, current_len) / block_size));
+ const next_block = @floatToInt(u32, std.math.floor(@intToFloat(f32, next_len) / block_size));
+ const index = (current_len % block_size);
+ const next_index = (next_len % block_size);
+
+ if (comptime VerboseQueue) std.debug.print("\n[PUT] {d}, {d} - {d} \n", .{ current_block, index, current_len });
+
+ const allocated_block = this.allocated_blocks.load(.SeqCst);
+ const needs_new_block = next_index == 0;
+ const needs_to_allocate_block = needs_new_block and allocated_block < next_block;
+ const overflowing = current_block >= block_count;
+
+ if (needs_to_allocate_block) {
+ defer {
+ _ = this.allocated_blocks.fetchAdd(1, .SeqCst);
+ }
+ var new_list = try this.allocator.create(Block);
+ if (next_block >= block_count) {
+ const needs_lock = this.overflow.items.len + 1 >= this.overflow.capacity;
+ if (needs_lock) {
+ while (this.overflow_readers.load(.SeqCst) > 0) {
+ std.atomic.spinLoopHint();
+ }
+ @atomicStore(bool, &this.overflow_write_lock, true, .SeqCst);
+ }
+ defer {
+ if (needs_lock) {
+ @atomicStore(bool, &this.overflow_write_lock, false, .SeqCst);
+ }
+ }
+ try this.overflow.append(new_list);
+ } else {
+ @atomicStore(*Block, &this.blocks[next_block], new_list, .SeqCst);
+ }
+ }
+
+ var block_ptr = if (!overflowing)
+ @atomicLoad(*Block, &this.blocks[current_block], .SeqCst)
+ else
+ @atomicLoad(*Block, &this.overflow.items[current_block - block_count], .SeqCst);
+
+ block_ptr[index] = value;
+ if (current_len < 10) std.Thread.Futex.wake(@ptrCast(*const std.atomic.Atomic(u32), &this.len), std.math.maxInt(u32));
+ }
+ };
+}
+
+pub fn NewBunQueue(comptime Value: type) type {
+ return struct {
+ const KeyType = u32;
+ const BunQueue = @This();
+ const Queue = NewBlockQueue(Value, 64, 48);
+ // pub const Fifo = NewFifo(Value);
+
+ allocator: *std.mem.Allocator,
+ queue: Queue,
+ keys: Keys,
+ count: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0),
+
+ pub fn init(allocator: *std.mem.Allocator) !*BunQueue {
+ var bun = try allocator.create(BunQueue);
+ bun.* = BunQueue{
+ .allocator = allocator,
+ .queue = undefined,
+ .keys = Keys{
+ .offset = AtomicOffset.init(Offset.bits(.{ .used = 0, .len = 0 })),
+ .block_overflow = Keys.OverflowList.init(allocator),
+ },
+ };
+ bun.queue.new(allocator);
+
+ bun.keys.blocks[0] = &bun.keys.first_key_list;
+ return bun;
+ }
+
+ pub const Keys = struct {
+ pub const OverflowList = std.ArrayList([*]KeyType);
+ // Half a page of memory
+
+ blocks: [overflow_size][*]KeyType = undefined,
+ offset: AtomicOffset,
+ block_overflow: OverflowList,
+ block_overflow_lock: bool = false,
+ first_key_list: [block_size]KeyType = undefined,
+ mutex: Mutex = Mutex{},
+ write_lock: bool = false,
+ append_readers: u8 = 0,
+ append_lock: bool = false,
+ pending_write: KeyType = 0,
+ };
+
+ pub const Offset = packed struct {
+ used: u16,
+ len: u16,
+
+ pub const Int = std.meta.Int(.unsigned, @bitSizeOf(@This()));
+
+ pub inline fn bits(this: Offset) Int {
+ return @bitCast(Int, this);
+ }
+ };
+
+ pub const block_size = 2048 / @sizeOf(KeyType);
+ pub const overflow_size = 32;
+
+ // In one atomic load/store, get the length and offset of the keys
+ pub const AtomicOffset = std.atomic.Atomic(Offset.Int);
+
+ fn pushList(this: *BunQueue, used: u16) !void {
+
+ // this.keys.mutex.acquire();
+ // defer this.keys.mutex.release();
+
+ var block = try this.allocator.alloc(KeyType, block_size);
+
+ if (used < overflow_size) {
+ @atomicStore([*]KeyType, &this.keys.blocks[used], block.ptr, .Release);
+ } else {
+ const needs_lock = this.keys.block_overflow.items.len + 1 >= this.keys.block_overflow.capacity;
+ if (needs_lock) {
+ while (@atomicLoad(u8, &this.keys.append_readers, .SeqCst) > 0) {
+ std.atomic.spinLoopHint();
+ }
+ @atomicStore(bool, &this.keys.append_lock, true, .SeqCst);
+ }
+ defer {
+ if (needs_lock) @atomicStore(bool, &this.keys.append_lock, false, .SeqCst);
+ }
+ try this.keys.block_overflow.append(block.ptr);
+ }
+ }
+
+ inline fn contains(this: *BunQueue, key: KeyType) bool {
+ @fence(.Acquire);
+ if (@atomicLoad(KeyType, &this.keys.pending_write, .SeqCst) == key) return true;
+ // this.keys.mutex.tryAcquire()
+
+ var offset = this.getOffset();
+ std.debug.assert(&this.keys.first_key_list == this.keys.blocks[0]);
+
+ // Heuristic #1: the first files you import are probably the most common in your app
+ // e.g. "react"
+ if (offset.used != 0) {
+ for (this.keys.first_key_list) |_key| {
+ if (key == _key) return true;
+ }
+ }
+
+ if (offset.used < overflow_size) {
+ // Heuristic #2: you import files near each other
+ const block_ptr = @atomicLoad([*]KeyType, &this.keys.blocks[offset.used], .SeqCst);
+ for (block_ptr[0..offset.len]) |_key| {
+ if (key == _key) return true;
+ }
+ } else {
+ while (@atomicLoad(bool, &this.keys.append_lock, .SeqCst)) {
+ std.atomic.spinLoopHint();
+ }
+ _ = @atomicRmw(u8, &this.keys.append_readers, .Add, 1, .SeqCst);
+ defer {
+ _ = @atomicRmw(u8, &this.keys.append_readers, .Sub, 1, .SeqCst);
+ }
+ const latest = @atomicLoad([*]KeyType, &this.keys.block_overflow.items[offset.used - overflow_size], .SeqCst);
+
+ for (latest[0..offset.len]) |_key| {
+ if (key == _key) return true;
+ }
+ }
+
+ if (offset.used > 0) {
+ var j: usize = 1;
+ while (j < std.math.min(overflow_size, offset.used)) : (j += 1) {
+ const block_ptr = @atomicLoad([*]KeyType, &this.keys.blocks[j], .SeqCst);
+ for (block_ptr[0..block_size]) |_key| {
+ if (key == _key) return true;
+ }
+ }
+
+ if (offset.used > overflow_size) {
+ var end = offset.used - overflow_size;
+ j = 0;
+ while (j < end) : (j += 1) {
+ while (@atomicLoad(bool, &this.keys.append_lock, .SeqCst)) {
+ std.atomic.spinLoopHint();
+ }
+
+ _ = @atomicRmw(u8, &this.keys.append_readers, .Add, 1, .SeqCst);
+ defer {
+ _ = @atomicRmw(u8, &this.keys.append_readers, .Sub, 1, .SeqCst);
+ }
+
+ const block = @atomicLoad([*]KeyType, &this.keys.block_overflow.items[j], .SeqCst);
+ for (block[0..block_size]) |_key| {
+ if (key == _key) return true;
+ }
+ }
+ }
+ }
+
+ return @atomicLoad(KeyType, &this.keys.pending_write, .Acquire) == key;
+ }
+
+ pub inline fn getOffset(this: *BunQueue) Offset {
+ return @bitCast(Offset, this.keys.offset.load(std.atomic.Ordering.Acquire));
+ }
+
+ pub fn hasItem(this: *BunQueue, key: KeyType) bool {
+ @fence(.SeqCst);
+
+ if (this.contains(key)) return true;
+ while (@atomicRmw(bool, &this.keys.write_lock, .Xchg, true, .SeqCst)) {
+ std.atomic.spinLoopHint();
+ }
+ defer assert(@atomicRmw(bool, &this.keys.write_lock, .Xchg, false, .SeqCst));
+
+ if (@atomicRmw(KeyType, &this.keys.pending_write, .Xchg, key, .SeqCst) == key) return true;
+
+ const offset = this.getOffset();
+
+ const new_len = (offset.len + 1) % block_size;
+ const is_new_list = new_len == 0;
+ const new_offset = Offset{ .used = @intCast(u16, @boolToInt(is_new_list)) + offset.used, .len = new_len };
+
+ {
+ var latest_list = if (offset.used < overflow_size)
+ @atomicLoad([*]KeyType, &this.keys.blocks[offset.used], .SeqCst)
+ else
+ @atomicLoad([*]KeyType, &this.keys.block_overflow.items[offset.used - overflow_size], .SeqCst);
+
+ assert(@atomicRmw(KeyType, &latest_list[offset.len], .Xchg, key, .Release) != key);
+ }
+
+ // We only should need to lock when we're allocating memory
+ if (is_new_list) {
+ this.pushList(new_offset.used) catch unreachable;
+ }
+
+ this.keys.offset.store(new_offset.bits(), .Release);
+
+ return false;
+ }
+
+ inline fn _writeItem(this: *BunQueue, value: Value) !void {
+ _ = this.count.fetchAdd(1, .Release);
+ try this.queue.enqueue(value);
+ }
+
+ pub fn upsert(this: *BunQueue, key: KeyType, value: Value) !void {
+ if (!this.hasItem(key)) {
+ try this._writeItem(value);
+ }
+ }
+
+ pub fn upsertWithResult(this: *BunQueue, key: KeyType, value: Value) !bool {
+ if (!this.hasItem(key)) {
+ try this._writeItem(value);
+ return true;
+ }
+
+ return false;
+ }
+ pub inline fn next(this: *BunQueue) ?Value {
+ return this.queue.get();
+ }
+ };
+}
+
+test "BunQueue: Single-threaded" {
+ const BunQueue = NewBunQueue([]const u8);
+ const hash = Wyhash.hash;
+ const expect = std.testing.expect;
+
+ var queue = try BunQueue.init(default_allocator);
+
+ var greet = [_]string{
+ "hello", "how", "are", "you",
+ "https://", "ton.local.twitter.com", "/responsive-web-internal/", "sourcemaps",
+ "/client-web/", "loader.Typeahead.7c3b3805.js.map:", "ERR_BLOCKED_BY_CLIENT", "etch failed loading: POST ",
+ "ondemand.LottieWeb.08803c45.js", "ondemand.InlinePlayer.4990ef15.js", "ondemand.BranchSdk.bb99d145.js", "ondemand.Dropdown.011d5045.js",
+ };
+ var greeted: [greet.len]bool = undefined;
+ std.mem.set(bool, &greeted, false);
+
+ for (greet) |ing, i| {
+ const key = @truncate(u32, hash(0, ing));
+ try expect(!queue.contains(
+ key,
+ ));
+ try queue.upsert(
+ key,
+ ing,
+ );
+ try expect(queue.hasItem(
+ key,
+ ));
+ try expect(queue.getOffset().len == i + 1);
+ }
+
+ {
+ var i: usize = 0;
+ while (i < greet.len) : (i += 1) {
+ const item = (queue.next()) orelse return try std.testing.expect(false);
+ try expect(strings.containsAny(&greet, item));
+ const index = strings.indexAny(&greet, item) orelse unreachable;
+ try expect(!greeted[index]);
+ greeted[index] = true;
+ }
+ i = 0;
+ while (i < greet.len) : (i += 1) {
+ try expect(queue.next() == null);
+ }
+ i = 0;
+ while (i < greet.len) : (i += 1) {
+ try expect(greeted[i]);
+ }
+ i = 0;
+ }
+
+ const end_offset = queue.getOffset().len;
+
+ for (greet) |ing, i| {
+ const key = @truncate(u32, hash(0, ing));
+ try queue.upsert(
+ key,
+ ing,
+ );
+
+ try expect(end_offset == queue.getOffset().len);
+ }
+}
+
+test "BunQueue: Dedupes" {
+ const BunQueue = NewBunQueue([]const u8);
+ const hash = Wyhash.hash;
+ const expect = std.testing.expect;
+
+ var queue = try BunQueue.init(default_allocator);
+
+ var greet = [_]string{
+ "uniq1",
+ "uniq2",
+ "uniq3",
+ "uniq4",
+ "uniq5",
+ "uniq6",
+ "uniq7",
+ "uniq8",
+ "uniq9",
+ "uniq10",
+ "uniq11",
+ "uniq12",
+ "uniq13",
+ "uniq14",
+ "uniq15",
+ "uniq16",
+ "uniq17",
+ "uniq18",
+ "uniq19",
+ "uniq20",
+ "uniq21",
+ "uniq22",
+ "uniq23",
+ "uniq24",
+ "uniq25",
+ "uniq26",
+ "uniq27",
+ "uniq28",
+ "uniq29",
+ "uniq30",
+ } ++ [_]string{ "dup20", "dup21", "dup27", "dup2", "dup12", "dup15", "dup4", "dup12", "dup10", "dup7", "dup26", "dup22", "dup1", "dup23", "dup11", "dup8", "dup11", "dup29", "dup28", "dup25", "dup20", "dup2", "dup6", "dup16", "dup22", "dup13", "dup30", "dup9", "dup3", "dup17", "dup14", "dup18", "dup8", "dup3", "dup28", "dup30", "dup24", "dup18", "dup24", "dup5", "dup23", "dup10", "dup13", "dup26", "dup27", "dup29", "dup25", "dup4", "dup19", "dup15", "dup6", "dup17", "dup1", "dup16", "dup19", "dup7", "dup9", "dup21", "dup14", "dup5" };
+ var prng = std.rand.DefaultPrng.init(100);
+ prng.random.shuffle(string, &greet);
+ var deduped = std.BufSet.init(default_allocator);
+ var consumed = std.BufSet.init(default_allocator);
+
+ for (greet) |ing, i| {
+ const key = @truncate(u32, hash(0, ing));
+
+ const is_new = !deduped.contains(ing);
+ try deduped.insert(ing);
+ try queue.upsert(key, ing);
+ }
+
+ while (queue.next()) |i| {
+ try expect(consumed.contains(i) == false);
+ try consumed.insert(i);
+ }
+
+ try std.testing.expectEqual(consumed.count(), deduped.count());
+ try expect(deduped.count() > 0);
+}
+
+test "BunQueue: SCMP Threaded" {
+ const BunQueue = NewBunQueue([]const u8);
+ const expect = std.testing.expect;
+
+ var _queue = try BunQueue.init(default_allocator);
+
+ var greet = [_]string{
+ "uniq1",
+ "uniq2",
+ "uniq3",
+ "uniq4",
+ "uniq5",
+ "uniq6",
+ "uniq7",
+ "uniq8",
+ "uniq9",
+ "uniq10",
+ "uniq11",
+ "uniq12",
+ "uniq13",
+ "uniq14",
+ "uniq15",
+ "uniq16",
+ "uniq17",
+ "uniq18",
+ "uniq19",
+ "uniq20",
+ "uniq21",
+ "uniq22",
+ "uniq23",
+ "uniq24",
+ "uniq25",
+ "uniq26",
+ "uniq27",
+ "uniq28",
+ "uniq29",
+ "uniq30",
+ "uniq31",
+ "uniq32",
+ "uniq33",
+ "uniq34",
+ "uniq35",
+ "uniq36",
+ "uniq37",
+ "uniq38",
+ "uniq39",
+ "uniq40",
+ "uniq41",
+ "uniq42",
+ "uniq43",
+ "uniq44",
+ "uniq45",
+ "uniq46",
+ "uniq47",
+ "uniq48",
+ "uniq49",
+ "uniq50",
+ "uniq51",
+ "uniq52",
+ "uniq53",
+ "uniq54",
+ "uniq55",
+ "uniq56",
+ "uniq57",
+ "uniq58",
+ "uniq59",
+ "uniq60",
+ "uniq61",
+ "uniq62",
+ "uniq63",
+ "uniq64",
+ "uniq65",
+ "uniq66",
+ "uniq67",
+ "uniq68",
+ "uniq69",
+ "uniq70",
+ "uniq71",
+ "uniq72",
+ "uniq73",
+ "uniq74",
+ "uniq75",
+ "uniq76",
+ "uniq77",
+ "uniq78",
+ "uniq79",
+ "uniq80",
+ "uniq81",
+ "uniq82",
+ "uniq83",
+ "uniq84",
+ "uniq85",
+ "uniq86",
+ "uniq87",
+ "uniq88",
+ "uniq89",
+ "uniq90",
+ "uniq91",
+ "uniq92",
+ "uniq93",
+ "uniq94",
+ "uniq95",
+ "uniq96",
+ "uniq97",
+ "uniq98",
+ "uniq99",
+ "uniq100",
+ "uniq101",
+ "uniq102",
+ "uniq103",
+ "uniq104",
+ "uniq105",
+ "uniq106",
+ "uniq107",
+ "uniq108",
+ "uniq109",
+ "uniq110",
+ "uniq111",
+ "uniq112",
+ "uniq113",
+ "uniq114",
+ "uniq115",
+ "uniq116",
+ "uniq117",
+ "uniq118",
+ "uniq119",
+ "uniq120",
+ } ++ [_]string{ "dup1", "dup1", "dup10", "dup10", "dup11", "dup11", "dup12", "dup2", "dup20", "dup20", "dup21", "dup21", "dup22", "dup22", "dup23", "dup23", "dup12", "dup13", "dup13", "dup14", "dup14", "dup15", "dup15", "dup16", "dup16", "dup17", "dup17", "dup18", "dup18", "dup19", "dup19", "dup2", "dup2", "dup20", "dup20", "dup21", "dup21", "dup22", "dup22", "dup23", "dup23", "dup24", "dup24", "dup25", "dup3", "dup30", "dup30", "dup4", "dup4", "dup5", "dup5", "dup6", "dup23", "dup23", "dup12", "dup13", "dup13", "dup14", "dup14", "dup15", "dup15", "dup16", "dup16", "dup17", "dup17", "dup18", "dup18", "dup19", "dup19", "dup2", "dup2", "dup20", "dup20", "dup21", "dup21", "dup22", "dup22", "dup23", "dup23", "dup24", "dup24", "dup6", "dup7", "dup7", "dup8", "dup8", "dup9", "dup9", "dup25", "dup26", "dup26", "dup3", "dup30", "dup30", "dup4", "dup4", "dup5", "dup5", "dup6", "dup6", "dup7", "dup7", "dup8", "dup8", "dup9", "dup9", "dup27", "dup27", "dup28", "dup28", "dup29", "dup29", "dup3", "dup3", "dup30", "dup30", "dup4", "dup4", "dup5", "dup5", "dup6", "dup6", "dup7", "dup7", "dup8", "dup8", "dup9", "dup9" };
+ var prng = std.rand.DefaultPrng.init(100);
+ prng.random.shuffle(string, &greet);
+ var in = try default_allocator.create(std.BufSet);
+ in.* = std.BufSet.init(default_allocator);
+ for (greet) |i| {
+ try in.insert(i);
+ try _queue.upsert(@truncate(u32, std.hash.Wyhash.hash(0, i)), i);
+ }
+
+ const Worker = struct {
+ index: u8 = 0,
+
+ pub fn run(queue: *BunQueue, dedup_list: *std.BufSet, wg: *WaitGroup, mut: *Mutex) !void {
+ defer wg.done();
+ // const tasks = more_work[num];
+ // var remain = tasks;
+ while (queue.next()) |cur| {
+ mut.acquire();
+ defer mut.release();
+ try dedup_list.insert(cur);
+ }
+ }
+
+ pub fn run1(queue: *BunQueue, num: u8, dedup_list: *std.BufSet, wg: *WaitGroup, mut: *Mutex) !void {
+ defer wg.done();
+ const tasks = more_work[num];
+ var remain = tasks;
+ try queue.upsert(@truncate(u32, std.hash.Wyhash.hash(0, remain[0])), remain[0]);
+ remain = tasks[1..];
+ loop: while (true) {
+ while (queue.next()) |cur| {
+ mut.acquire();
+ try dedup_list.insert(cur);
+ mut.release();
+ }
+
+ if (remain.len > 0) {
+ try queue.upsert(@truncate(u32, std.hash.Wyhash.hash(0, remain[0])), remain[0]);
+ remain = tasks[1..];
+ var j: usize = 0;
+ while (j < 1000) : (j += 1) {}
+ continue :loop;
+ }
+
+ break :loop;
+ }
+ }
+ };
+
+ var out = try default_allocator.create(std.BufSet);
+ out.* = std.BufSet.init(default_allocator);
+
+ var waitgroup = try default_allocator.create(WaitGroup);
+ waitgroup.* = WaitGroup.init();
+
+ var worker1 = try default_allocator.create(Worker);
+ worker1.* = Worker{};
+ var worker2 = try default_allocator.create(Worker);
+ worker2.* = Worker{};
+ waitgroup.add();
+ waitgroup.add();
+ var mutex = try default_allocator.create(Mutex);
+ mutex.* = Mutex{};
+
+ var thread1 = try std.Thread.spawn(.{}, Worker.run, .{ _queue, out, waitgroup, mutex });
+ var thread2 = try std.Thread.spawn(.{}, Worker.run, .{ _queue, out, waitgroup, mutex });
+
+ waitgroup.wait();
+ thread1.join();
+ thread2.join();
+
+ try std.testing.expectEqual(out.count(), in.count());
+ var iter = in.hash_map.iterator();
+
+ while (iter.next()) |entry| {
+ try expect(in.contains(entry.key_ptr.*));
+ }
+}
+
+test "BunQueue: MPMC Threaded" {
+ const BunQueue = NewBunQueue([]const u8);
+ const expect = std.testing.expect;
+ var _queue = try BunQueue.init(default_allocator);
+
+ var in = try default_allocator.create(std.BufSet);
+ in.* = std.BufSet.init(default_allocator);
+
+ const Worker = struct {
+ index: u8 = 0,
+ const WorkerCount = 2;
+ const lodash_all = shuffle(@TypeOf(@import("./test/project.zig").lodash), @import("./test/project.zig").lodash);
+ const lodash1 = lodash_all[0 .. lodash_all.len / 3];
+ const lodash2 = lodash_all[lodash1.len..][0 .. lodash_all.len / 3];
+ const lodash3 = lodash_all[lodash1.len + lodash2.len ..];
+
+ pub fn shuffle(comptime Type: type, comptime val: Type) Type {
+ var copy = val;
+ @setEvalBranchQuota(99999);
+ var rand = std.rand.DefaultPrng.init(100);
+ rand.random.shuffle(string, &copy);
+ return copy;
+ }
+ const three_all = shuffle(@TypeOf(@import("./test/project.zig").three), @import("./test/project.zig").three);
+ const three1 = three_all[0 .. three_all.len / 3];
+ const three2 = three_all[three1.len..][0 .. three_all.len / 3];
+ const three3 = three_all[three1.len + three2.len ..];
+
+ fn run1(queue: *BunQueue, num: u8, dedup_list: *std.BufSet, wg: *WaitGroup, mut: *Mutex) !void {
+ defer wg.done();
+ const tasks = switch (num) {
+ 0 => lodash1,
+ 1 => lodash2,
+ 2 => lodash3,
+ 3 => three1,
+ 4 => three2,
+ 5 => three3,
+ else => unreachable,
+ };
+
+ var remain = tasks;
+ try queue.upsert(@truncate(u32, std.hash.Wyhash.hash(0, remain[0])), remain[0]);
+ remain = tasks[1..];
+ loop: while (true) {
+ while (queue.next()) |cur| {
+ mut.acquire();
+ defer mut.release();
+ try expect(!dedup_list.contains(cur));
+ try dedup_list.insert(cur);
+ }
+
+ if (remain.len > 0) {
+ try queue.upsert(@truncate(u32, std.hash.Wyhash.hash(0, remain[0])), remain[0]);
+ remain = remain[1..];
+ var j: usize = 0;
+ while (j < 10000) : (j += 1) {}
+ continue :loop;
+ }
+
+ break :loop;
+ }
+ }
+
+ pub fn run(queue: *BunQueue, num: u8, dedup_list: *std.BufSet, wg: *WaitGroup, mut: *Mutex) !void {
+ try run1(queue, num, dedup_list, wg, mut);
+ }
+ };
+
+ var greet = [_]string{
+ "uniq1",
+ "uniq2",
+ "uniq3",
+ "uniq4",
+ "uniq5",
+ "uniq6",
+ "uniq7",
+ "uniq8",
+ "uniq9",
+ "uniq10",
+ "uniq11",
+ "uniq12",
+ "uniq13",
+ "uniq14",
+ "uniq15",
+ "uniq16",
+ "uniq17",
+ "uniq18",
+ "uniq19",
+ "uniq20",
+ "uniq21",
+ "uniq22",
+ "uniq23",
+ "uniq24",
+ "uniq25",
+ "uniq26",
+ "uniq27",
+ "uniq28",
+ "uniq29",
+ "uniq30",
+ } ++ [_]string{ "dup1", "dup1", "dup10", "dup10", "dup11", "dup11", "dup12", "dup2", "dup20", "dup20", "dup21", "dup21", "dup22", "dup22", "dup23", "dup23", "dup12", "dup13", "dup13", "dup14", "dup14", "dup15", "dup15", "dup16", "dup16", "dup17", "dup17", "dup18", "dup18", "dup19", "dup19", "dup2", "dup2", "dup20", "dup20", "dup21", "dup21", "dup22", "dup22", "dup23", "dup23", "dup24", "dup24", "dup25", "dup3", "dup30", "dup30", "dup4", "dup4", "dup5", "dup5", "dup6", "dup23", "dup23", "dup12", "dup13", "dup13", "dup14", "dup14", "dup15", "dup15", "dup16", "dup16", "dup17", "dup17", "dup18", "dup18", "dup19", "dup19", "dup2", "dup2", "dup20", "dup20", "dup21", "dup21", "dup22", "dup22", "dup23", "dup23", "dup24", "dup24", "dup6", "dup7", "dup7", "dup8", "dup8", "dup9", "dup9", "dup25", "dup26", "dup26", "dup3", "dup30", "dup30", "dup4", "dup4", "dup5", "dup5", "dup6", "dup6", "dup7", "dup7", "dup8", "dup8", "dup9", "dup9", "dup27", "dup27", "dup28", "dup28", "dup29", "dup29", "dup3", "dup3", "dup30", "dup30", "dup4", "dup4", "dup5", "dup5", "dup6", "dup6", "dup7", "dup7", "dup8", "dup8", "dup9", "dup9" };
+
+ for (greet) |a| {
+ try in.insert(a);
+ try _queue.upsert(@truncate(u32, std.hash.Wyhash.hash(0, a)), a);
+ }
+
+ for (Worker.lodash_all) |a| {
+ try in.insert(a);
+ }
+
+ for (Worker.three_all) |a| {
+ try in.insert(a);
+ }
+
+ var out = try default_allocator.create(std.BufSet);
+ out.* = std.BufSet.init(default_allocator);
+
+ var waitgroup = try default_allocator.create(WaitGroup);
+ waitgroup.* = WaitGroup.init();
+
+ waitgroup.add();
+ waitgroup.add();
+ waitgroup.add();
+ waitgroup.add();
+ waitgroup.add();
+ waitgroup.add();
+ var mutex = try default_allocator.create(Mutex);
+ mutex.* = Mutex{};
+
+ var thread1 = try std.Thread.spawn(.{}, Worker.run, .{ _queue, 0, out, waitgroup, mutex });
+ var thread2 = try std.Thread.spawn(.{}, Worker.run, .{ _queue, 1, out, waitgroup, mutex });
+ var thread3 = try std.Thread.spawn(.{}, Worker.run, .{ _queue, 2, out, waitgroup, mutex });
+ var thread4 = try std.Thread.spawn(.{}, Worker.run, .{ _queue, 3, out, waitgroup, mutex });
+ var thread5 = try std.Thread.spawn(.{}, Worker.run, .{ _queue, 4, out, waitgroup, mutex });
+ var thread6 = try std.Thread.spawn(.{}, Worker.run, .{ _queue, 5, out, waitgroup, mutex });
+
+ waitgroup.wait();
+ thread1.join();
+ thread2.join();
+ thread3.join();
+ thread4.join();
+ thread5.join();
+ thread6.join();
+
+ try std.testing.expectEqual(out.count(), in.count());
+ var iter = in.hash_map.iterator();
+
+ while (iter.next()) |entry| {
+ try expect(out.contains(entry.key_ptr.*));
+ }
+}
diff --git a/src/bundler.zig b/src/bundler.zig
index fcfffdd15..4942c3989 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -34,149 +34,7 @@ const isPackagePath = _resolver.isPackagePath;
const Css = @import("css_scanner.zig");
const DotEnv = @import("./env_loader.zig");
const Lock = @import("./lock.zig").Lock;
-pub const ServeResult = struct {
- file: options.OutputFile,
- mime_type: MimeType,
-};
-
-pub const ClientEntryPoint = struct {
- code_buffer: [8096]u8 = undefined,
- path_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,
- source: logger.Source = undefined,
-
- pub fn isEntryPointPath(extname: string) bool {
- return strings.startsWith("entry.", extname);
- }
-
- pub fn generateEntryPointPath(outbuffer: []u8, original_path: Fs.PathName) string {
- var joined_base_and_dir_parts = [_]string{ original_path.dir, original_path.base };
- var generated_path = Fs.FileSystem.instance.absBuf(&joined_base_and_dir_parts, outbuffer);
-
- std.mem.copy(u8, outbuffer[generated_path.len..], ".entry");
- generated_path = outbuffer[0 .. generated_path.len + ".entry".len];
- std.mem.copy(u8, outbuffer[generated_path.len..], original_path.ext);
- return outbuffer[0 .. generated_path.len + original_path.ext.len];
- }
-
- pub fn decodeEntryPointPath(outbuffer: []u8, original_path: Fs.PathName) string {
- var joined_base_and_dir_parts = [_]string{ original_path.dir, original_path.base };
- var generated_path = Fs.FileSystem.instance.absBuf(&joined_base_and_dir_parts, outbuffer);
- var original_ext = original_path.ext;
- if (strings.indexOf(original_path.ext, "entry")) |entry_i| {
- original_ext = original_path.ext[entry_i + "entry".len ..];
- }
-
- std.mem.copy(u8, outbuffer[generated_path.len..], original_ext);
-
- return outbuffer[0 .. generated_path.len + original_ext.len];
- }
-
- pub fn generate(entry: *ClientEntryPoint, comptime BundlerType: type, bundler: *BundlerType, original_path: Fs.PathName, client: string) !void {
-
- // This is *extremely* naive.
- // The basic idea here is this:
- // --
- // import * as EntryPoint from 'entry-point';
- // import boot from 'framework';
- // boot(EntryPoint);
- // --
- // We go through the steps of printing the code -- only to then parse/transpile it because
- // we want it to go through the linker and the rest of the transpilation process
-
- const dir_to_use: string = original_path.dirWithTrailingSlash();
-
- const code = try std.fmt.bufPrint(
- &entry.code_buffer,
- \\var lastErrorHandler = globalThis.onerror;
- \\var loaded = {{boot: false, entry: false, onError: null}};
- \\if (!lastErrorHandler || !lastErrorHandler.__onceTag) {{
- \\ globalThis.onerror = function (evt) {{
- \\ if (this.onError && typeof this.onError == 'function') {{
- \\ this.onError(evt, loaded);
- \\ }}
- \\ console.error(evt.error);
- \\ debugger;
- \\ }};
- \\ globalThis.onerror.__onceTag = true;
- \\ globalThis.onerror.loaded = loaded;
- \\}}
- \\
- \\import boot from '{s}';
- \\loaded.boot = true;
- \\if ('setLoaded' in boot) boot.setLoaded(loaded);
- \\import * as EntryPoint from '{s}{s}';
- \\loaded.entry = true;
- \\
- \\if (!boot) {{
- \\ const now = Date.now();
- \\ debugger;
- \\ const elapsed = Date.now() - now;
- \\ if (elapsed < 1000) {{
- \\ throw new Error('Expected framework to export default a function. Instead, framework exported:', Object.keys(boot));
- \\ }}
- \\}}
- \\
- \\boot(EntryPoint, loaded);
- ,
- .{
- client,
- dir_to_use,
- original_path.filename,
- },
- );
-
- entry.source = logger.Source.initPathString(generateEntryPointPath(&entry.path_buffer, original_path), code);
- entry.source.path.namespace = "client-entry";
- }
-};
-
-pub const ServerEntryPoint = struct {
- code_buffer: [std.fs.MAX_PATH_BYTES * 2 + 500]u8 = undefined,
- output_code_buffer: [std.fs.MAX_PATH_BYTES * 8 + 500]u8 = undefined,
- source: logger.Source = undefined,
-
- pub fn generate(
- entry: *ServerEntryPoint,
- comptime BundlerType: type,
- bundler: *BundlerType,
- original_path: Fs.PathName,
- name: string,
- ) !void {
-
- // This is *extremely* naive.
- // The basic idea here is this:
- // --
- // import * as EntryPoint from 'entry-point';
- // import boot from 'framework';
- // boot(EntryPoint);
- // --
- // We go through the steps of printing the code -- only to then parse/transpile it because
- // we want it to go through the linker and the rest of the transpilation process
-
- const dir_to_use: string = original_path.dirWithTrailingSlash();
-
- const code = try std.fmt.bufPrint(
- &entry.code_buffer,
- \\//Auto-generated file
- \\import * as start from '{s}{s}';
- \\export * from '{s}{s}';
- ,
- .{
- dir_to_use,
- original_path.filename,
- dir_to_use,
- original_path.filename,
- },
- );
-
- entry.source = logger.Source.initPathString(name, code);
- entry.source.path.text = name;
- entry.source.path.namespace = "server-entry";
- }
-};
-
-pub const ResolveResults = std.AutoHashMap(u64, void);
-pub const ResolveQueue = std.fifo.LinearFifo(_resolver.Result, std.fifo.LinearFifoBufferType.Dynamic);
+const NewBunQueue = @import("./bun_queue.zig").NewBunQueue;
// How it works end-to-end
// 1. Resolve a file path from input using the resolver
@@ -184,7 +42,7 @@ pub const ResolveQueue = std.fifo.LinearFifo(_resolver.Result, std.fifo.LinearFi
// 3. If the loader is .js, .jsx, .ts, .tsx, or .json, run it through our JavaScript Parser
// IF serving via HTTP and it's parsed without errors:
// 4. If parsed without errors, generate a strong ETag & write the output to a buffer that sends to the in the Printer.
-// 7. Else, write any errors to error page
+// 4. Else, write any errors to error page (which doesn't exist yet)
// IF writing to disk AND it's parsed without errors:
// 4. Write the output to a temporary file.
// Why? Two reasons.
@@ -210,7 +68,7 @@ pub const ResolveQueue = std.fifo.LinearFifo(_resolver.Result, std.fifo.LinearFi
// buffer (react-dom.development.js is 550 KB)
// ^ This is how it used to work!
// - If we delay printing, we need to keep the AST around. Which breaks all our
-// recycling logic since that could be many many ASTs.
+// memory-saving recycling logic since that could be many many ASTs.
// 5. Once all files are written, determine the shortest common path
// 6. Move all the temporary files to their intended destinations
// IF writing to disk AND it's a file-like loader
@@ -219,22 +77,12 @@ pub const ResolveQueue = std.fifo.LinearFifo(_resolver.Result, std.fifo.LinearFi
// 5. Resolve any imports of this file to that hash(file(absolute_path))
// 6. Append to the files array with the new filename
// 7. When parsing & resolving is over, just copy the file.
-// - on macOS, ensure it does an APFS shallow clone so that doesn't use disk space
+// - on macOS, ensure it does an APFS shallow clone so that doesn't use disk space (only possible if file doesn't already exist)
+// fclonefile
// IF serving via HTTP AND it's a file-like loader:
-// 4. Hash the metadata ${absolute_path}-${fstat.mtime}-${fstat.size}
-// 5. Use a deterministic prefix so we know what file to look for without copying it
-// Example scenario:
-// GET /logo-SIU3242.png
-// 404 Not Found because there is no file named "logo-SIu3242.png"
-// Instead, we can do this:
-// GET /public/SIU3242/logo.png
-// Our server sees "/public/" and knows the next segment will be a token
-// which lets it ignore that when resolving the absolute path on disk
-// 6. Compare the current hash with the expected hash
-// 7. IF does not match, do a 301 Temporary Redirect to the new file path
-// This adds an extra network request for outdated files, but that should be uncommon.
-// 7. IF does match, serve it with that hash as a weak ETag
-// 8. This should also just work unprefixed, but that will be served Cache-Control: private, no-store
+// 4. Use os.sendfile so copying/reading the file happens in the kernel instead of in Bun.
+// This unfortunately means content hashing for HTTP server is unsupported, but metadata etags work
+// For each imported file, GOTO 1.
pub const ParseResult = struct {
source: logger.Source,
@@ -243,29 +91,6 @@ pub const ParseResult = struct {
input_fd: ?StoredFileDescriptorType = null,
};
-pub const ScanResult = struct {
- path: Fs.Path,
- is_node_module: bool = false,
- file_size: u32 = 0,
- import_record_start: u32,
- import_record_length: u32,
-
- pub const Summary = struct {
- import_records: std.ArrayList(ImportRecord),
- scan_results: std.ArrayList(ScanResult),
- pub fn list(summary: *const Summary) List {
- return List{
- .import_records = summary.import_records.items,
- .scan_results = summary.scan_results.items,
- };
- }
- pub const List = struct {
- import_records: []ImportRecord,
- scan_results: []ScanResult,
- };
- };
-};
-
pub fn NewBundler(cache_files: bool) type {
return struct {
pub const Linker = if (cache_files) linker.Linker else linker.ServeLinker;
@@ -551,62 +376,44 @@ pub fn NewBundler(cache_files: bool) type {
}
pub const GenerateNodeModuleBundle = struct {
- pub const PathMap = struct {
- const HashTable = std.StringHashMap(u32);
-
- backing: HashTable,
- mutex: Lock,
-
- pub fn init(allocator: *std.mem.Allocator) PathMap {
- return PathMap{
- .backing = HashTable.init(allocator),
- .mutex = Lock.init(),
- };
- }
-
- pub inline fn lock(this: *PathMap) void {
- this.mutex.lock();
- }
-
- pub inline fn unlock(this: *PathMap) void {
- this.mutex.unlock();
- }
-
- pub inline fn hashOf(str: string) u64 {
- return std.hash.Wyhash.hash(0, str);
- }
-
- pub inline fn getOrPut(this: *PathMap, str: string) !HashTable.GetOrPutResult {
- return this.backing.getOrPut(str);
- }
-
- pub inline fn contains(this: *PathMap, str: string) bool {
- return this.backing.contains(str);
- }
- };
-
- const BunQueue = sync.Channel(_resolver.Result, .Dynamic);
+ const BunQueue = NewBunQueue(_resolver.Result);
pub const ThreadPool = struct {
// Hardcode 512 as max number of threads for now.
workers: [512]Worker = undefined,
- workers_used: u16 = 0,
- cpu_count: u16 = 0,
- wait_group: sync.WaitGroup = sync.WaitGroup.init(),
-
+ workers_used: u32 = 0,
+ cpu_count: u32 = 0,
+ started_workers: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0),
+ stopped_workers: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0),
+ completed_count: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0),
pub fn start(this: *ThreadPool, generator: *GenerateNodeModuleBundle) !void {
- this.cpu_count = @truncate(u16, @divFloor((try std.Thread.getCpuCount()) + 1, 2));
+ this.cpu_count = @truncate(u32, @divFloor((try std.Thread.getCpuCount()) + 1, 2));
while (this.workers_used < this.cpu_count) : (this.workers_used += 1) {
- this.workers[this.workers_used].wg = &this.wait_group;
-
- this.wait_group.add();
try this.workers[this.workers_used].init(generator);
}
}
- pub fn wait(this: *ThreadPool) void {
- this.wait_group.wait();
+ pub fn wait(this: *ThreadPool, generator: *GenerateNodeModuleBundle) void {
+ while (generator.queue.count.load(.SeqCst) != generator.pool.completed_count.load(.SeqCst)) {
+ var j: usize = 0;
+ while (j < 100) : (j += 1) {}
+ std.atomic.spinLoopHint();
+ }
+
+ for (this.workers[0..this.workers_used]) |*worker| {
+ @atomicStore(bool, &worker.quit, true, .Release);
+ }
+
+ while (this.stopped_workers.load(.Acquire) != this.workers_used) {
+ var j: usize = 0;
+ while (j < 100) : (j += 1) {}
+ std.atomic.spinLoopHint();
+ }
+
+ for (this.workers[0..this.workers_used]) |*worker| {
+ worker.thread.join();
+ }
}
pub const Task = struct {
@@ -617,10 +424,13 @@ pub fn NewBundler(cache_files: bool) type {
pub const Worker = struct {
thread_id: std.Thread.Id,
thread: std.Thread,
+
allocator: *std.mem.Allocator,
- wg: *sync.WaitGroup,
generator: *GenerateNodeModuleBundle,
data: *WorkerData = undefined,
+ quit: bool = false,
+
+ has_notify_started: bool = false,
pub const WorkerData = struct {
shared_buffer: MutableString = undefined,
@@ -641,11 +451,26 @@ pub fn NewBundler(cache_files: bool) type {
worker.thread = try std.Thread.spawn(.{}, Worker.run, .{worker});
}
+ pub fn notifyStarted(this: *Worker) void {
+ if (!this.has_notify_started) {
+ this.has_notify_started = true;
+ _ = this.generator.pool.started_workers.fetchAdd(1, .Release);
+ std.Thread.Futex.wake(&this.generator.pool.started_workers, std.math.maxInt(u32));
+ }
+ }
+
pub fn run(this: *Worker) void {
- defer this.wg.done();
Output.Source.configureThread();
this.thread_id = std.Thread.getCurrentId();
- defer Output.flush();
+ if (isDebug) {
+ Output.prettyln("Thread started.\n", .{});
+ }
+ defer {
+ if (isDebug) {
+ Output.prettyln("Thread stopped.\n", .{});
+ }
+ Output.flush();
+ }
this.loop() catch |err| {
Output.prettyErrorln("<r><red>Error: {s}<r>", .{@errorName(err)});
@@ -653,20 +478,33 @@ pub fn NewBundler(cache_files: bool) type {
}
pub fn loop(this: *Worker) anyerror!void {
- // Delay initializing until we get the first thing.
- const first = (try this.generator.resolve_queue.tryReadItem()) orelse return;
+ defer {
+ _ = this.generator.pool.stopped_workers.fetchAdd(1, .Release);
+ this.notifyStarted();
+
+ std.Thread.Futex.wake(&this.generator.pool.stopped_workers, 1);
+ // std.Thread.Futex.wake(&this.generator.queue.len, std.math.maxInt(u32));
+ }
+
js_ast.Expr.Data.Store.create(this.generator.allocator);
js_ast.Stmt.Data.Store.create(this.generator.allocator);
this.data = this.generator.allocator.create(WorkerData) catch unreachable;
this.data.* = WorkerData{};
this.data.shared_buffer = try MutableString.init(this.generator.allocator, 0);
this.data.scan_pass_result = js_parser.ScanPassResult.init(this.generator.allocator);
+
defer this.data.deinit(this.generator.allocator);
- try this.generator.processFile(this, first);
+ this.notifyStarted();
+
+ while (!@atomicLoad(bool, &this.quit, .Acquire)) {
+ while (this.generator.queue.next()) |item| {
+ defer {
+ _ = this.generator.pool.completed_count.fetchAdd(1, .Release);
+ }
- while (try this.generator.resolve_queue.tryReadItem()) |item| {
- try this.generator.processFile(this, item);
+ try this.generator.processFile(this, item);
+ }
}
}
};
@@ -677,9 +515,8 @@ pub fn NewBundler(cache_files: bool) type {
package_list: std.ArrayList(Api.JavascriptBundledPackage),
header_string_buffer: MutableString,
// Just need to know if we've already enqueued this one
- resolved_paths: PathMap,
package_list_map: std.AutoHashMap(u64, u32),
- resolve_queue: *BunQueue,
+ queue: *BunQueue,
bundler: *ThisBundler,
allocator: *std.mem.Allocator,
tmpfile: std.fs.File,
@@ -689,47 +526,46 @@ pub fn NewBundler(cache_files: bool) type {
code_end_byte_offset: u32 = 0,
has_jsx: bool = false,
+ work_waiter: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0),
list_lock: Lock = Lock.init(),
pub const current_version: u32 = 1;
pub fn enqueueItem(this: *GenerateNodeModuleBundle, resolve: _resolver.Result) !void {
- var this_module_resolved_path = try this.resolved_paths.getOrPut(resolve.path_pair.primary.text);
+ const loader = this.bundler.options.loaders.get(resolve.path_pair.primary.name.ext) orelse .file;
+ if (!loader.isJavaScriptLike()) return;
- if (!this_module_resolved_path.found_existing) {
- if (resolve.isLikelyNodeModule()) {
- if (BundledModuleData.get(this, &resolve)) |module_data_| {
- this_module_resolved_path.value_ptr.* = module_data_.module_id;
- }
- }
- var result = resolve;
- result.path_pair.primary = Fs.Path.init(std.mem.span(try this.allocator.dupeZ(u8, resolve.path_pair.primary.text)));
- try this.resolve_queue.writeItem(result);
- }
+ var result = resolve;
+ result.path_pair.primary = Fs.Path.init(std.mem.span(try this.allocator.dupeZ(u8, resolve.path_pair.primary.text)));
+
+ try this.queue.upsert(result.hash(loader), result);
}
// The Bun Bundle Format
- // Your entire node_modules folder in a single compact file designed for web browsers.
- // A binary JavaScript bundle format prioritizing bundle time and serialization/deserialization time
+ // All the node_modules your app uses in a single compact file with metadata
+ // A binary JavaScript bundle format prioritizing generation time and deserialization time
pub const magic_bytes = "#!/usr/bin/env bun\n\n";
- // This makes it possible to do ./path-to-bundle on posix systems you can see the raw JS contents
+ // This makes it possible to do ./path-to-bundle on posix systems so you can see the raw JS contents
// https://en.wikipedia.org/wiki/Magic_number_(programming)#In_files
// Immediately after the magic bytes, the next character is a uint32 followed by a newline
// 0x00000000\n
// That uint32 denotes the byte offset in the file where the code for the bundle ends
// - If the value is 0, that means the file did not finish writing or there are no modules
- // - This imposes a maximum bundle size of around 4,294,967,295 bytes. If your JS is more than 4 GB, you're a
+ // - This imposes a maximum bundle size of around 4,294,967,295 bytes. If your JS is more than 4 GB, it won't work.
// The raw JavaScript is encoded as a UTF-8 string starting from the current position + 1 until the above byte offset.
// This uint32 is useful for HTTP servers to separate:
// - Which part of the bundle is the JS code?
// - Which part is the metadata?
- // Without needing to do a full pass through the file.
- // The metadata is at the bottom of the file instead of the top because the metadata is generated after the entire bundle is written.
+ // Without needing to do a full pass through the file, or necessarily care about the metadata.
+ // The metadata is at the bottom of the file instead of the top because the metadata is written after all JS code in the bundle is written.
// The rationale there is:
- // 1. We cannot prepend to a file without a pass over the entire file
- // 2. The metadata is variable-length and that format will change more often. Perhaps different bundlers will generate different metadata.
- // If you have 32 MB of JavaScript dependencies, the only time it's acceptable to do a full pass is when sending it over HTTP via sendfile()
- // So instead, we append to the file after printing each node_module
+ // 1. We cannot prepend to a file without rewriting the entire file
+ // 2. The metadata is variable-length and that format will change often.
+ // 3. We won't have all the metadata until after all JS is finished writing
+ // If you have 32 MB of JavaScript dependencies, you really want to avoid reading the code in memory.
+ // - This lets you seek to the specific position in the file.
+ // - HTTP servers should use sendfile() instead of copying the file to userspace memory.
+ // So instead, we append metadata to the file after printing each node_module
// When there are no more modules to process, we generate the metadata
// To find the metadata, you look at the byte offset: initial_header[magic_bytes.len..initial_header.len - 1]
// Then, you add that number to initial_header.len
@@ -737,12 +573,13 @@ pub fn NewBundler(cache_files: bool) type {
var buf = std.mem.zeroes([magic_bytes.len + 5]u8);
std.mem.copy(u8, &buf, magic_bytes);
var remainder = buf[magic_bytes.len..];
- // Write an invalid byte offset to be updated after the file ends
+ // Write an invalid byte offset to be updated after we finish generating the code
std.mem.writeIntNative(u32, remainder[0 .. remainder.len - 1], 0);
buf[buf.len - 1] = '\n';
break :brk buf;
};
const code_start_byte_offset: u32 = initial_header.len;
+ // The specifics of the metadata is not documented here. You can find it in src/api/schema.peechy.
pub fn appendHeaderString(generator: *GenerateNodeModuleBundle, str: string) !Api.StringPointer {
var offset = generator.header_string_buffer.list.items.len;
@@ -773,16 +610,15 @@ pub fn NewBundler(cache_files: bool) type {
var tmpfile = try tmpdir.createFileZ(tmpname, .{ .read = isDebug, .exclusive = true });
var generator = try allocator.create(GenerateNodeModuleBundle);
- var queue = try allocator.create(BunQueue);
- queue.* = BunQueue.init(allocator);
+ var queue = try BunQueue.init(allocator);
defer allocator.destroy(generator);
generator.* = GenerateNodeModuleBundle{
.module_list = std.ArrayList(Api.JavascriptBundledModule).init(allocator),
.package_list = std.ArrayList(Api.JavascriptBundledPackage).init(allocator),
.header_string_buffer = try MutableString.init(allocator, 0),
.allocator = allocator,
- .resolved_paths = PathMap.init(allocator),
- .resolve_queue = queue,
+ .queue = queue,
+ // .resolve_queue = queue,
.bundler = bundler,
.tmpfile = tmpfile,
.log = bundler.log,
@@ -821,16 +657,13 @@ pub fn NewBundler(cache_files: bool) type {
defer this.bundler.resetStore();
const entry_points = try router.getEntryPoints(allocator);
- try this.resolve_queue.buffer.ensureUnusedCapacity(entry_points.len + resolve_queue_estimate);
for (entry_points) |entry_point| {
const source_dir = bundler.fs.top_level_dir;
const resolved = try bundler.linker.resolver.resolve(source_dir, entry_point, .entry_point);
try this.enqueueItem(resolved);
}
this.bundler.resetStore();
- } else {
- try this.resolve_queue.buffer.ensureUnusedCapacity(resolve_queue_estimate);
- }
+ } else {}
for (bundler.options.entry_points) |entry_point| {
defer this.bundler.resetStore();
@@ -885,8 +718,9 @@ pub fn NewBundler(cache_files: bool) type {
}
this.bundler.resetStore();
+
try this.pool.start(this);
- this.pool.wait();
+ this.pool.wait(this);
if (this.log.errors > 0) {
// We stop here because if there are errors we don't know if the bundle is valid
@@ -1140,10 +974,6 @@ pub fn NewBundler(cache_files: bool) type {
&source,
)) orelse return;
if (ast.import_records.len > 0) {
- this.resolved_paths.lock();
- defer {
- this.resolved_paths.unlock();
- }
{
for (ast.import_records) |*import_record, record_id| {
@@ -1162,17 +992,14 @@ pub fn NewBundler(cache_files: bool) type {
const absolute_path = resolved_import.path_pair.primary.text;
- const get_or_put_result = try this.resolved_paths.getOrPut(absolute_path);
-
module_data = BundledModuleData.get(this, resolved_import) orelse continue;
import_record.module_id = module_data.module_id;
import_record.is_bundled = true;
import_record.path = Fs.Path.init(module_data.import_path);
- get_or_put_result.value_ptr.* = import_record.module_id;
-
- if (!get_or_put_result.found_existing) {
- try this.resolve_queue.writeItem(_resolved_import.*);
- }
+ try this.queue.upsert(
+ _resolved_import.hash(this.bundler.options.loaders.get(resolved_import.path_pair.primary.name.ext) orelse .file),
+ _resolved_import.*,
+ );
} else |err| {
if (comptime isDebug) {
Output.prettyErrorln("\n<r><red>{s}<r> on resolving \"{s}\" from \"{s}\"", .{
@@ -1364,6 +1191,8 @@ pub fn NewBundler(cache_files: bool) type {
Output.flush();
}
+ this.list_lock.lock();
+ defer this.list_lock.unlock();
code_offset = write_result.off;
written = write_result.len;
@@ -1373,11 +1202,6 @@ pub fn NewBundler(cache_files: bool) type {
const code_length = this.tmpfile_byte_offset - code_offset;
// std.debug.assert(code_length == written);
- this.list_lock.lock();
- defer {
- this.list_lock.unlock();
- }
-
var package_get_or_put_entry = try this.package_list_map.getOrPut(package.hash);
if (!package_get_or_put_entry.found_existing) {
@@ -1443,8 +1267,6 @@ pub fn NewBundler(cache_files: bool) type {
);
{
- this.resolved_paths.lock();
- defer this.resolved_paths.unlock();
for (scan_pass_result.import_records.items) |*import_record, i| {
if (import_record.is_internal) {
continue;
@@ -1455,22 +1277,13 @@ pub fn NewBundler(cache_files: bool) type {
continue;
}
- const resolved_import: *const _resolver.Result = _resolved_import;
-
- const get_or_put_result = try this.resolved_paths.getOrPut(resolved_import.path_pair.primary.text);
-
- if (get_or_put_result.found_existing) {
- continue;
- }
-
_resolved_import.path_pair.primary = Fs.Path.init(std.mem.span(try this.allocator.dupeZ(u8, _resolved_import.path_pair.primary.text)));
-
- // Always enqueue unwalked import paths, but if it's not a node_module, we don't care about the hash
- try this.resolve_queue.writeItem(_resolved_import.*);
-
- if (BundledModuleData.get(this, resolved_import)) |module| {
- get_or_put_result.value_ptr.* = module.module_id;
- }
+ try this.queue.upsert(
+ _resolved_import.hash(
+ this.bundler.options.loaders.get(_resolved_import.path_pair.primary.name.ext) orelse .file,
+ ),
+ _resolved_import.*,
+ );
} else |err| {
switch (err) {
error.ModuleNotFound => {
@@ -1801,74 +1614,6 @@ pub fn NewBundler(cache_files: bool) type {
return output_file;
}
- pub fn scanWithResolveResult(
- bundler: *ThisBundler,
- resolve_result: _resolver.Result,
- scan_pass_result: *js_parser.ScanPassResult,
- ) !?ScanResult {
- if (resolve_result.is_external) {
- return null;
- }
- var import_records = &scan_pass_result.import_records;
- var named_imports = &scan_pass_result.named_imports;
- errdefer js_ast.Expr.Data.Store.reset();
- errdefer js_ast.Stmt.Data.Store.reset();
-
- // Step 1. Parse & scan
- const loader = bundler.options.loaders.get(resolve_result.path_pair.primary.name.ext) orelse .file;
- var file_path = resolve_result.path_pair.primary;
- file_path.pretty = Linker.relative_paths_list.append(string, bundler.fs.relativeTo(file_path.text)) catch unreachable;
-
- switch (loader) {
- .jsx, .tsx, .js, .ts, .json => {
- const entry = bundler.resolver.caches.fs.readFile(
- bundler.fs,
- file_path.text,
- resolve_result.dirname_fd,
- !cache_files,
- null,
- ) catch return null;
-
- const source = logger.Source.initFile(Fs.File{ .path = file_path, .contents = entry.contents }, bundler.allocator) catch return null;
- const source_dir = file_path.name.dirWithTrailingSlash();
-
- var jsx = bundler.options.jsx;
- jsx.parse = loader.isJSX();
- var opts = js_parser.Parser.Options.init(jsx, loader);
-
- var result = ScanResult{
- .path = file_path,
- .file_size = @truncate(u32, source.contents.len),
- .is_node_module = resolve_result.isLikelyNodeModule(),
- .import_record_start = @truncate(u32, import_records.items.len),
- .import_record_length = 0,
- };
-
- try bundler.resolver.caches.js.scan(
- bundler.allocator,
- scan_pass_result,
- opts,
- bundler.options.define,
- bundler.log,
- &source,
- );
- result.import_record_length = @truncate(u32, import_records.items.len - result.import_record_start);
- for (import_records.items[result.import_record_start..import_records.items.len]) |*import_record, i| {
- if (bundler.linker.resolver.resolve(source_dir, import_record.path.text, import_record.kind)) |*resolved_import| {
- if (resolved_import.is_external) {
- continue;
- }
- } else |err| {}
- }
- return result;
- },
- // TODO:
- else => {
- return null;
- },
- }
- }
-
pub fn print(
bundler: *ThisBundler,
result: ParseResult,
@@ -2144,90 +1889,6 @@ pub fn NewBundler(cache_files: bool) type {
return entry;
}
- // pub fn scanDependencies(
- // allocator: *std.mem.Allocator,
- // log: *logger.Log,
- // _opts: Api.TransformOptions,
- // ) !ScanResult.Summary {
- // var opts = _opts;
- // opts.resolve = .dev;
- // var bundler = try ThisBundler.init(allocator, log, opts, null);
-
- // bundler.configureLinker();
-
- // var entry_points = try allocator.alloc(_resolver.Result, bundler.options.entry_points.len);
-
- // if (log.level == .verbose) {
- // bundler.resolver.debug_logs = try DebugLogs.init(allocator);
- // }
-
- // var rfs: *Fs.FileSystem.RealFS = &bundler.fs.fs;
-
- // var entry_point_i: usize = 0;
- // for (bundler.options.entry_points) |_entry| {
- // var entry: string = bundler.normalizeEntryPointPath(_entry);
-
- // defer {
- // js_ast.Expr.Data.Store.reset();
- // js_ast.Stmt.Data.Store.reset();
- // }
-
- // const result = bundler.resolver.resolve(bundler.fs.top_level_dir, entry, .entry_point) catch |err| {
- // Output.printError("Error resolving \"{s}\": {s}\n", .{ entry, @errorName(err) });
- // continue;
- // };
-
- // const key = result.path_pair.primary.text;
- // if (bundler.resolve_results.contains(key)) {
- // continue;
- // }
- // try bundler.resolve_results.put(key, result);
- // entry_points[entry_point_i] = result;
-
- // if (isDebug) {
- // Output.print("Resolved {s} => {s}", .{ entry, result.path_pair.primary.text });
- // }
-
- // entry_point_i += 1;
- // bundler.resolve_queue.writeItem(result) catch unreachable;
- // }
- // var scan_results = std.ArrayList(ScanResult).init(allocator);
- // var scan_pass_result = js_parser.ScanPassResult.init(allocator);
-
- // switch (bundler.options.resolve_mode) {
- // .lazy, .dev, .bundle => {
- // while (bundler.resolve_queue.readItem()) |item| {
- // js_ast.Expr.Data.Store.reset();
- // js_ast.Stmt.Data.Store.reset();
- // scan_pass_result.named_imports.clearRetainingCapacity();
- // scan_results.append(bundler.scanWithResolveResult(item, &scan_pass_result) catch continue orelse continue) catch continue;
- // }
- // },
- // else => Global.panic("Unsupported resolve mode: {s}", .{@tagName(bundler.options.resolve_mode)}),
- // }
-
- // // if (log.level == .verbose) {
- // // for (log.msgs.items) |msg| {
- // // try msg.writeFormat(std.io.getStdOut().writer());
- // // }
- // // }
-
- // if (FeatureFlags.tracing) {
- // Output.printError(
- // "\n---Tracing---\nResolve time: {d}\nParsing time: {d}\n---Tracing--\n\n",
- // .{
- // bundler.resolver.elapsed,
- // bundler.elapsed,
- // },
- // );
- // }
-
- // return ScanResult.Summary{
- // .scan_results = scan_results,
- // .import_records = scan_pass_result.import_records,
- // };
- // }
-
fn enqueueEntryPoints(bundler: *ThisBundler, entry_points: []_resolver.Result, comptime normalize_entry_point: bool) usize {
var entry_point_i: usize = 0;
@@ -2277,7 +1938,7 @@ pub fn NewBundler(cache_files: bool) type {
// 100.00 µs std.fifo.LinearFifo(resolver.Result,std.fifo.LinearFifoBufferType { .Dynamic = {}}).writeItemAssumeCapacity
if (bundler.options.resolve_mode != .lazy) {
- try bundler.resolve_queue.ensureUnusedCapacity(24);
+ try bundler.resolve_queue.ensureUnusedCapacity(3);
}
var entry_points = try allocator.alloc(_resolver.Result, bundler.options.entry_points.len);
@@ -2380,6 +2041,8 @@ pub fn NewBundler(cache_files: bool) type {
return final_result;
}
+ // pub fn processResolveQueueWithThreadPool(bundler)
+
pub fn processResolveQueue(
bundler: *ThisBundler,
comptime import_path_format: options.BundleOptions.ImportPathFormat,
@@ -2387,10 +2050,13 @@ pub fn NewBundler(cache_files: bool) type {
comptime Outstream: type,
outstream: Outstream,
) !void {
+ // var count: u8 = 0;
while (bundler.resolve_queue.readItem()) |item| {
js_ast.Expr.Data.Store.reset();
js_ast.Stmt.Data.Store.reset();
+ // defer count += 1;
+
if (comptime wrap_entry_point) {
const loader = bundler.options.loaders.get(item.path_pair.primary.name.ext) orelse .file;
@@ -2437,6 +2103,8 @@ pub fn NewBundler(cache_files: bool) type {
null,
) catch continue orelse continue;
bundler.output_files.append(output_file) catch unreachable;
+
+ // if (count >= 3) return try bundler.processResolveQueueWithThreadPool(import_path_format, wrap_entry_point, Outstream, outstream);
}
}
};
@@ -2721,3 +2389,153 @@ pub const Transformer = struct {
);
}
};
+
+pub const ServeResult = struct {
+ file: options.OutputFile,
+ mime_type: MimeType,
+};
+
+pub const ClientEntryPoint = struct {
+ code_buffer: [8096]u8 = undefined,
+ path_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,
+ source: logger.Source = undefined,
+
+ pub fn isEntryPointPath(extname: string) bool {
+ return strings.startsWith("entry.", extname);
+ }
+
+ pub fn generateEntryPointPath(outbuffer: []u8, original_path: Fs.PathName) string {
+ var joined_base_and_dir_parts = [_]string{ original_path.dir, original_path.base };
+ var generated_path = Fs.FileSystem.instance.absBuf(&joined_base_and_dir_parts, outbuffer);
+
+ std.mem.copy(u8, outbuffer[generated_path.len..], ".entry");
+ generated_path = outbuffer[0 .. generated_path.len + ".entry".len];
+ std.mem.copy(u8, outbuffer[generated_path.len..], original_path.ext);
+ return outbuffer[0 .. generated_path.len + original_path.ext.len];
+ }
+
+ pub fn decodeEntryPointPath(outbuffer: []u8, original_path: Fs.PathName) string {
+ var joined_base_and_dir_parts = [_]string{ original_path.dir, original_path.base };
+ var generated_path = Fs.FileSystem.instance.absBuf(&joined_base_and_dir_parts, outbuffer);
+ var original_ext = original_path.ext;
+ if (strings.indexOf(original_path.ext, "entry")) |entry_i| {
+ original_ext = original_path.ext[entry_i + "entry".len ..];
+ }
+
+ std.mem.copy(u8, outbuffer[generated_path.len..], original_ext);
+
+ return outbuffer[0 .. generated_path.len + original_ext.len];
+ }
+
+ pub fn generate(entry: *ClientEntryPoint, comptime BundlerType: type, bundler: *BundlerType, original_path: Fs.PathName, client: string) !void {
+
+ // This is *extremely* naive.
+ // The basic idea here is this:
+ // --
+ // import * as EntryPoint from 'entry-point';
+ // import boot from 'framework';
+ // boot(EntryPoint);
+ // --
+ // We go through the steps of printing the code -- only to then parse/transpile it because
+ // we want it to go through the linker and the rest of the transpilation process
+
+ const dir_to_use: string = original_path.dirWithTrailingSlash();
+
+ const code = try std.fmt.bufPrint(
+ &entry.code_buffer,
+ \\var lastErrorHandler = globalThis.onerror;
+ \\var loaded = {{boot: false, entry: false, onError: null}};
+ \\if (!lastErrorHandler || !lastErrorHandler.__onceTag) {{
+ \\ globalThis.onerror = function (evt) {{
+ \\ if (this.onError && typeof this.onError == 'function') {{
+ \\ this.onError(evt, loaded);
+ \\ }}
+ \\ console.error(evt.error);
+ \\ debugger;
+ \\ }};
+ \\ globalThis.onerror.__onceTag = true;
+ \\ globalThis.onerror.loaded = loaded;
+ \\}}
+ \\
+ \\import boot from '{s}';
+ \\loaded.boot = true;
+ \\if ('setLoaded' in boot) boot.setLoaded(loaded);
+ \\import * as EntryPoint from '{s}{s}';
+ \\loaded.entry = true;
+ \\
+ \\if (!boot) {{
+ \\ const now = Date.now();
+ \\ debugger;
+ \\ const elapsed = Date.now() - now;
+ \\ if (elapsed < 1000) {{
+ \\ throw new Error('Expected framework to export default a function. Instead, framework exported:', Object.keys(boot));
+ \\ }}
+ \\}}
+ \\
+ \\boot(EntryPoint, loaded);
+ ,
+ .{
+ client,
+ dir_to_use,
+ original_path.filename,
+ },
+ );
+
+ entry.source = logger.Source.initPathString(generateEntryPointPath(&entry.path_buffer, original_path), code);
+ entry.source.path.namespace = "client-entry";
+ }
+};
+
+pub const ServerEntryPoint = struct {
+ code_buffer: [std.fs.MAX_PATH_BYTES * 2 + 500]u8 = undefined,
+ output_code_buffer: [std.fs.MAX_PATH_BYTES * 8 + 500]u8 = undefined,
+ source: logger.Source = undefined,
+
+ pub fn generate(
+ entry: *ServerEntryPoint,
+ comptime BundlerType: type,
+ bundler: *BundlerType,
+ original_path: Fs.PathName,
+ name: string,
+ ) !void {
+
+ // This is *extremely* naive.
+ // The basic idea here is this:
+ // --
+ // import * as EntryPoint from 'entry-point';
+ // import boot from 'framework';
+ // boot(EntryPoint);
+ // --
+ // We go through the steps of printing the code -- only to then parse/transpile it because
+ // we want it to go through the linker and the rest of the transpilation process
+
+ const dir_to_use: string = original_path.dirWithTrailingSlash();
+
+ const code = try std.fmt.bufPrint(
+ &entry.code_buffer,
+ \\//Auto-generated file
+ \\import * as start from '{s}{s}';
+ \\export * from '{s}{s}';
+ ,
+ .{
+ dir_to_use,
+ original_path.filename,
+ dir_to_use,
+ original_path.filename,
+ },
+ );
+
+ entry.source = logger.Source.initPathString(name, code);
+ entry.source.path.text = name;
+ entry.source.path.namespace = "server-entry";
+ }
+};
+
+pub const ResolveResults = std.AutoHashMap(
+ u64,
+ void,
+);
+pub const ResolveQueue = std.fifo.LinearFifo(
+ _resolver.Result,
+ std.fifo.LinearFifoBufferType.Dynamic,
+);
diff --git a/src/cli.zig b/src/cli.zig
index 83ebea850..b1eb3fe52 100644
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -139,7 +139,7 @@ pub const Arguments = struct {
pub const ParamType = clap.Param(clap.Help);
- const params: [26]ParamType = brk: {
+ const params: [25]ParamType = brk: {
@setEvalBranchQuota(9999);
break :brk [_]ParamType{
clap.parseParam("--use <STR> Choose a framework, e.g. \"--use next\". It checks first for a package named \"bun-framework-packagename\" and then \"packagename\".") catch unreachable,
@@ -157,7 +157,7 @@ pub const Arguments = struct {
clap.parseParam("--no-summary   Don't print a summary (when generating .bun") catch unreachable,
clap.parseParam("--origin <STR> Rewrite import paths to start with --origin. Default: \"/\"") catch unreachable,
clap.parseParam("--platform <STR> \"browser\" or \"node\". Defaults to \"browser\"") catch unreachable,
- clap.parseParam("--production   [not implemented] generate production code") catch unreachable,
+ // clap.parseParam("--production   [not implemented] generate production code") catch unreachable,
clap.parseParam("--static-dir <STR> Top-level directory for .html files, fonts or anything external. Defaults to \"<cwd>/public\", to match create-react-app and Next.js") catch unreachable,
clap.parseParam("--tsconfig-override <STR> Load tsconfig from path instead of cwd/tsconfig.json") catch unreachable,
clap.parseParam("-d, --define <STR>... Substitute K:V while parsing, e.g. --define process.env.NODE_ENV:development") catch unreachable,
@@ -208,7 +208,7 @@ pub const Arguments = struct {
.loaders = loader_tuple.values,
},
- .serve = cmd == .DevCommand,
+ .serve = cmd == .DevCommand or (FeatureFlags.dev_only and cmd == .AutoCommand),
.main_fields = args.options("--main-fields"),
.generate_node_module_bundle = cmd == .BunCommand,
.inject = args.options("--inject"),
@@ -276,7 +276,7 @@ pub const Arguments = struct {
else => {},
}
- const production = args.flag("--production");
+ const production = false; //args.flag("--production");
var write = entry_points.len > 1 or output_dir != null;
if (write and output_dir == null) {
@@ -309,7 +309,7 @@ pub const Arguments = struct {
};
switch (comptime cmd) {
- .DevCommand, .BuildCommand => {
+ .AutoCommand, .DevCommand, .BuildCommand => {
if (args.option("--static-dir")) |public_dir| {
opts.router = Api.RouteConfig{ .extensions = &.{}, .dir = &.{}, .static_dir = public_dir };
}
@@ -426,20 +426,35 @@ const HelpCommand = struct {
var cwd_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const cwd = std.os.getcwd(&cwd_buf) catch unreachable;
const dirname = std.fs.path.basename(cwd);
- const fmt =
- \\> <r> <b><white>init<r> Setup Bun in \"{s}\"
- \\> <r> <b><green>dev <r><d> ./a.ts ./b.jsx<r> Start a Bun Dev Server
- \\<d>*<r> <b><cyan>build <r><d> ./a.ts ./b.jsx<r> Make JavaScript-like code runnable & bundle CSS
- \\> <r> <b><magenta>bun <r><d> ./a.ts ./b.jsx<r> Bundle dependencies of input files into a <r><magenta>.bun<r>
- \\> <r> <green>run <r><d> ./a.ts <r> Run a JavaScript-like file with Bun.js
- \\> <r> <b><blue>discord<r> Open Bun's Discord server
- \\> <r> <b><d>help <r> Print this help menu
- \\
- ;
-
- switch (reason) {
- .explicit => Output.pretty("Bun: a fast bundler & transpiler for web software.\n\n" ++ fmt, .{dirname}),
- .invalid_command => Output.prettyError("<r><red>Uh-oh<r> not sure what to do with that command.\n\n" ++ fmt, .{dirname}),
+ if (FeatureFlags.dev_only) {
+ const fmt =
+ \\> <r> <b><green>dev <r><d> ./a.ts ./b.jsx<r> Start a Bun Dev Server
+ \\> <r> <b><magenta>bun <r><d> ./a.ts ./b.jsx<r> Bundle dependencies of input files into a <r><magenta>.bun<r>
+ \\> <r> <b><blue>discord<r> Open Bun's Discord server
+ \\> <r> <b><d>help <r> Print this help menu
+ \\
+ ;
+
+ switch (reason) {
+ .explicit => Output.pretty("Bun: a fast bundler & transpiler for web software.\n\n" ++ fmt, .{}),
+ .invalid_command => Output.prettyError("<r><red>Uh-oh<r> not sure what to do with that command.\n\n" ++ fmt, .{}),
+ }
+ } else {
+ const fmt =
+ \\> <r> <b><white>init<r> Setup Bun in \"{s}\"
+ \\> <r> <b><green>dev <r><d> ./a.ts ./b.jsx<r> Start a Bun Dev Server
+ \\<d>*<r> <b><cyan>build <r><d> ./a.ts ./b.jsx<r> Make JavaScript-like code runnable & bundle CSS
+ \\> <r> <b><magenta>bun <r><d> ./a.ts ./b.jsx<r> Bundle dependencies of input files into a <r><magenta>.bun<r>
+ \\> <r> <green>run <r><d> ./a.ts <r> Run a JavaScript-like file with Bun.js
+ \\> <r> <b><blue>discord<r> Open Bun's Discord server
+ \\> <r> <b><d>help <r> Print this help menu
+ \\
+ ;
+
+ switch (reason) {
+ .explicit => Output.pretty("Bun: a fast bundler & transpiler for web software.\n\n" ++ fmt, .{dirname}),
+ .invalid_command => Output.prettyError("<r><red>Uh-oh<r> not sure what to do with that command.\n\n" ++ fmt, .{dirname}),
+ }
}
Output.flush();
@@ -506,18 +521,30 @@ pub const Command = struct {
const first_arg_name = std.mem.span(next_arg);
const RootCommandMatcher = strings.ExactSizeMatcher(8);
- return switch (RootCommandMatcher.match(first_arg_name)) {
- RootCommandMatcher.case("init") => .InitCommand,
- RootCommandMatcher.case("bun") => .BunCommand,
- RootCommandMatcher.case("discord") => .DiscordCommand,
+ if (comptime FeatureFlags.dev_only) {
+ return switch (RootCommandMatcher.match(first_arg_name)) {
+ RootCommandMatcher.case("init") => .InitCommand,
+ RootCommandMatcher.case("bun") => .BunCommand,
+ RootCommandMatcher.case("discord") => .DiscordCommand,
- RootCommandMatcher.case("b"), RootCommandMatcher.case("build") => .BuildCommand,
- RootCommandMatcher.case("r"), RootCommandMatcher.case("run") => .RunCommand,
- RootCommandMatcher.case("d"), RootCommandMatcher.case("dev") => .DevCommand,
+ RootCommandMatcher.case("b"), RootCommandMatcher.case("build") => .BuildCommand,
+ RootCommandMatcher.case("r"), RootCommandMatcher.case("run") => .RunCommand,
+ RootCommandMatcher.case("d"), RootCommandMatcher.case("dev") => .DevCommand,
- RootCommandMatcher.case("help") => .HelpCommand,
- else => .AutoCommand,
- };
+ RootCommandMatcher.case("help") => .HelpCommand,
+ else => .AutoCommand,
+ };
+ } else {
+ return switch (RootCommandMatcher.match(first_arg_name)) {
+ RootCommandMatcher.case("init") => .InitCommand,
+ RootCommandMatcher.case("bun") => .BunCommand,
+ RootCommandMatcher.case("discord") => .DiscordCommand,
+ RootCommandMatcher.case("d"), RootCommandMatcher.case("dev") => .DevCommand,
+
+ RootCommandMatcher.case("help") => .HelpCommand,
+ else => .AutoCommand,
+ };
+ }
}
pub fn start(allocator: *std.mem.Allocator, log: *logger.Log) !void {
@@ -551,7 +578,7 @@ pub const Command = struct {
try RunCommand.exec(ctx);
},
.AutoCommand => {
- const ctx = Command.Context.create(allocator, log, .AutoCommand) catch |e| {
+ var ctx = Command.Context.create(allocator, log, .AutoCommand) catch |e| {
switch (e) {
error.MissingEntryPoint => {
HelpCommand.execWithReason(allocator, .explicit);
@@ -570,7 +597,11 @@ pub const Command = struct {
return;
}
- try BuildCommand.exec(ctx);
+ if (FeatureFlags.dev_only) {
+ try DevCommand.exec(ctx);
+ } else {
+ try BuildCommand.exec(ctx);
+ }
},
else => unreachable,
}
diff --git a/src/feature_flags.zig b/src/feature_flags.zig
index 1efd806e8..036f86dda 100644
--- a/src/feature_flags.zig
+++ b/src/feature_flags.zig
@@ -34,6 +34,8 @@ pub const css_supports_fence = true;
pub const enable_entry_cache = true;
pub const enable_bytecode_caching = false;
+pub const dev_only = true;
+
pub const verbose_fs = false;
pub const watch_directories = true;
diff --git a/src/fs.zig b/src/fs.zig
index 2bf4cbeb7..93eb16acc 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -191,21 +191,22 @@ pub const FileSystem = struct {
else
strings.StringOrTinyString.initLowerCase(entry.name);
- const result = Entry{
- .base_ = name,
- .base_lowercase_ = name_lowercased,
- .dir = dir.dir,
- .mutex = Mutex.init(),
- // Call "stat" lazily for performance. The "@material-ui/icons" package
- // contains a directory with over 11,000 entries in it and running "stat"
- // for each entry was a big performance issue for that package.
- .need_stat = entry.kind == .SymLink,
- .cache = Entry.Cache{
- .symlink = "",
- .kind = _kind,
+ const stored = try EntryStore.instance.appendGet(
+ Entry{
+ .base_ = name,
+ .base_lowercase_ = name_lowercased,
+ .dir = dir.dir,
+ .mutex = Mutex.init(),
+ // Call "stat" lazily for performance. The "@material-ui/icons" package
+ // contains a directory with over 11,000 entries in it and running "stat"
+ // for each entry was a big performance issue for that package.
+ .need_stat = entry.kind == .SymLink,
+ .cache = Entry.Cache{
+ .symlink = "",
+ .kind = _kind,
+ },
},
- };
- const stored = try EntryStore.instance.appendGet(result);
+ );
const stored_name = stored.value.base();
@@ -317,6 +318,7 @@ pub const FileSystem = struct {
pub const Entry = struct {
cache: Cache = Cache{},
dir: string,
+
base_: strings.StringOrTinyString,
// Necessary because the hash table uses it as a key
diff --git a/src/global.zig b/src/global.zig
index cb0e351b2..b4289a1ba 100644
--- a/src/global.zig
+++ b/src/global.zig
@@ -1,7 +1,7 @@
const std = @import("std");
pub usingnamespace @import("strings.zig");
-pub const default_allocator = @import("./memory_allocator.zig").c_allocator;
+pub const default_allocator: *std.mem.Allocator = if (isTest) std.heap.c_allocator else @import("./memory_allocator.zig").c_allocator;
pub const C = @import("c.zig");
pub usingnamespace @import("env.zig");
diff --git a/src/http.zig b/src/http.zig
index 316bbb802..3e53b349b 100644
--- a/src/http.zig
+++ b/src/http.zig
@@ -2108,6 +2108,15 @@ pub const Server = struct {
}
}
+ pub fn detectFastRefresh(this: *Server) void {
+ defer this.bundler.resetStore();
+
+ _ = this.bundler.resolver.resolve(this.bundler.fs.top_level_dir, "react-refresh/runtime", .internal) catch |err| {
+ this.bundler.options.jsx.supports_fast_refresh = false;
+ return;
+ };
+ }
+
pub fn start(allocator: *std.mem.Allocator, options: Api.TransformOptions) !void {
var log = logger.Log.init(allocator);
var server = try allocator.create(Server);
@@ -2119,10 +2128,13 @@ pub const Server = struct {
.transform_options = options,
.timer = try std.time.Timer.start(),
};
+
server.bundler = try Bundler.init(allocator, &server.log, options, null, null);
server.bundler.configureLinker();
try server.bundler.configureRouter(true);
+ server.detectFastRefresh();
+
try server.initWatcher();
if (server.bundler.router != null and server.bundler.options.routes.static_dir_enabled) {
diff --git a/src/javascript/jsc/WebKit b/src/javascript/jsc/WebKit
-Subproject e17b749830a4e3faf87f751630fdcc149906ee9
+Subproject e7d31961d4bf98b3e8b1df3ea0398ea1517a61d
diff --git a/src/js_lexer.zig b/src/js_lexer.zig
index 507cf7aed..ac7e4b574 100644
--- a/src/js_lexer.zig
+++ b/src/js_lexer.zig
@@ -123,16 +123,6 @@ pub const Lexer = struct {
return logger.usize2Loc(self.start);
}
- inline fn nextCodepointSlice(it: *LexerType) []const u8 {
- @setRuntimeSafety(false);
-
- const cp_len = strings.utf8ByteSequenceLength(it.source.contents[it.current]);
- it.end = it.current;
- it.current += cp_len;
-
- return if (!(it.current > it.source.contents.len)) it.source.contents[it.current - cp_len .. it.current] else "";
- }
-
pub fn syntaxError(self: *LexerType) !void {
@setCold(true);
@@ -187,19 +177,6 @@ pub const Lexer = struct {
return @intCast(CodePoint, a) == self.code_point;
}
- inline fn nextCodepoint(it: *LexerType) !CodePoint {
- const slice = it.nextCodepointSlice();
-
- return switch (slice.len) {
- 0 => -1,
- 1 => @as(CodePoint, slice[0]),
- 2 => @as(CodePoint, unicode.utf8Decode2(slice) catch unreachable),
- 3 => @as(CodePoint, unicode.utf8Decode3(slice) catch unreachable),
- 4 => @as(CodePoint, unicode.utf8Decode4(slice) catch unreachable),
- else => unreachable,
- };
- }
-
/// Look ahead at the next n codepoints without advancing the iterator.
/// If fewer than n codepoints are available, then return the remainder of the string.
fn peek(it: *LexerType, n: usize) string {
@@ -522,7 +499,7 @@ pub const Lexer = struct {
},
'\r' => {
- if (quote != '`') {
+ if (comptime quote != '`') {
try lexer.addDefaultError("Unterminated string literal");
}
@@ -531,13 +508,13 @@ pub const Lexer = struct {
},
'\n' => {
- if (quote != '`') {
+ if (comptime quote != '`') {
try lexer.addDefaultError("Unterminated string literal");
}
},
'$' => {
- if (quote == '`') {
+ if (comptime quote == '`') {
try lexer.step();
if (lexer.code_point == '{') {
suffix_len = 2;
@@ -621,6 +598,29 @@ pub const Lexer = struct {
// // }
}
+ inline fn nextCodepointSlice(it: *LexerType) []const u8 {
+ @setRuntimeSafety(false);
+
+ const cp_len = strings.utf8ByteSequenceLength(it.source.contents[it.current]);
+ it.end = it.current;
+ it.current += cp_len;
+
+ return if (!(it.current > it.source.contents.len)) it.source.contents[it.current - cp_len .. it.current] else "";
+ }
+
+ inline fn nextCodepoint(it: *LexerType) !CodePoint {
+ const slice = it.nextCodepointSlice();
+
+ return switch (slice.len) {
+ 0 => -1,
+ 1 => @as(CodePoint, slice[0]),
+ 2 => @as(CodePoint, unicode.utf8Decode2(slice) catch unreachable),
+ 3 => @as(CodePoint, unicode.utf8Decode3(slice) catch unreachable),
+ 4 => @as(CodePoint, unicode.utf8Decode4(slice) catch unreachable),
+ else => unreachable,
+ };
+ }
+
fn step(lexer: *LexerType) !void {
lexer.code_point = try lexer.nextCodepoint();
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 9d37230cd..28e2e04b1 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -2182,6 +2182,14 @@ pub const Parser = struct {
if (p.options.transform_require_to_import) {
var args = p.allocator.alloc(Expr, 2) catch unreachable;
wrapper_expr = p.callRuntime(logger.Loc.Empty, "__commonJS", args);
+
+ // Disable HMR if we're wrapping it in CommonJS
+ // It's technically possible to support this.
+ // But we need to cut scope for the v0.
+ p.options.features.hot_module_reloading = false;
+ p.runtime_imports.__HMRModule = null;
+ p.runtime_imports.__FastRefreshModule = null;
+ p.runtime_imports.__HMRClient = null;
}
} else {
exports_kind = .esm;
diff --git a/src/lock.zig b/src/lock.zig
index e76a4cdf7..73dfdebd2 100644
--- a/src/lock.zig
+++ b/src/lock.zig
@@ -41,7 +41,7 @@ pub const Mutex = struct {
var acquire_state = LOCKED;
var state = self.state.load(.Monotonic);
- var spin: u8 = if (has_fast_swap) 100 else 10;
+ var spin: u8 = if (comptime has_fast_swap) 100 else 10;
while (true) {
// Try to lock the Mutex if its unlocked.
@@ -75,7 +75,7 @@ pub const Mutex = struct {
// Indicate that there will be a waiting thread by updating to CONTENDED.
// Acquire barrier as this swap could also possibly lock the Mutex.
- if (has_fast_swap) {
+ if (comptime has_fast_swap) {
state = self.state.swap(CONTENDED, .Acquire);
if (state == UNLOCKED) return;
break :uncontended;
@@ -135,3 +135,8 @@ pub const Lock = struct {
this.mutex.release();
}
};
+
+
+pub fn spinCycle() void {
+
+} \ No newline at end of file
diff --git a/src/options.zig b/src/options.zig
index 1fc07191d..c3069c54e 100644
--- a/src/options.zig
+++ b/src/options.zig
@@ -363,7 +363,7 @@ pub const Platform = enum {
};
};
-pub const Loader = enum {
+pub const Loader = enum(u3) {
jsx,
js,
ts,
@@ -398,6 +398,13 @@ pub const Loader = enum {
return loader == .tsx or loader == .ts;
}
+ pub fn isJavaScriptLike(loader: Loader) bool {
+ return switch (loader) {
+ .jsx, .js, .ts, .tsx => true,
+ else => false,
+ };
+ }
+
pub fn forFileName(filename: string, obj: anytype) ?Loader {
const ext = std.fs.path.extension(filename);
if (ext.len == 0 or (ext.len == 1 and ext[0] == '.')) return null;
@@ -966,7 +973,7 @@ pub const BundleOptions = struct {
// Don't switch to it, but just tell "hey try --public-dir=static" next time
if (!static_dir_set) {
_dirs[0] = "static";
- const check_static = try fs.joinAlloc(allocator, &_dirs);
+ const check_static = try fs.absAlloc(allocator, &_dirs);
defer allocator.free(check_static);
std.fs.accessAbsolute(check_static, .{}) catch {
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index b104823b0..46a849dc9 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -10,11 +10,9 @@ const TSConfigJSON = @import("./tsconfig_json.zig").TSConfigJSON;
const PackageJSON = @import("./package_json.zig").PackageJSON;
usingnamespace @import("./data_url.zig");
pub const DirInfo = @import("./dir_info.zig");
-const Expr = @import("../js_ast.zig").Expr;
const HTTPWatcher = @import("../http.zig").Watcher;
const Wyhash = std.hash.Wyhash;
-const hash_map_v2 = @import("../hash_map_v2.zig");
const Mutex = @import("../lock.zig").Lock;
const StringBoolMap = std.StringHashMap(bool);
@@ -148,6 +146,23 @@ pub const Result = struct {
});
}
};
+
+ pub fn hash(this: *const Result, loader: options.Loader) u32 {
+ const HashValue = packed struct {
+ loader: options.Loader,
+ len: u8,
+ path_hash: u21,
+ };
+
+ return @bitCast(
+ u32,
+ HashValue{
+ .loader = loader,
+ .len = @truncate(u8, this.path_pair.primary.text.len),
+ .path_hash = @truncate(u21, std.hash.Wyhash.hash(0, this.path_pair.primary.text)),
+ },
+ );
+ }
};
pub const DirEntryResolveQueueItem = struct {
@@ -430,7 +445,8 @@ pub fn NewResolver(cache_files: bool) type {
// support passing a package.json or path to a package
const pkg: *const PackageJSON = result.package_json orelse r.packageJSONForResolvedNodeModuleWithIgnoreMissingName(&result, true) orelse return error.MissingPackageJSON;
- const json: Expr = (try r.caches.json.parseJSON(r.log, pkg.source, r.allocator)) orelse return error.JSONParseError;
+ const json = (try r.caches.json.parseJSON(r.log, pkg.source, r.allocator)) orelse return error.JSONParseError;
+
pkg.loadFrameworkWithPreference(pair, json, r.allocator, load_defines, preference);
const dir = pkg.source.path.name.dirWithTrailingSlash();
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
@@ -554,8 +570,8 @@ pub fn NewResolver(cache_files: bool) type {
return error.MissingResolveDir;
}
- r.mutex.lock();
- defer r.mutex.unlock();
+ // r.mutex.lock();
+ // defer r.mutex.unlock();
errdefer (r.flushDebugLogs(.fail) catch {});
var result = (try r.resolveWithoutSymlinks(source_dir, import_path, kind)) orelse {
r.flushDebugLogs(.fail) catch {};
@@ -894,11 +910,31 @@ pub fn NewResolver(cache_files: bool) type {
result: *const Result,
) ?*const PackageJSON {
const absolute = result.path_pair.primary.text;
+ // /foo/node_modules/@babel/standalone/index.js
+ // ^------------^
var end = strings.lastIndexOf(absolute, node_module_root_string) orelse return null;
end += node_module_root_string.len;
end += strings.indexOfChar(absolute[end..], std.fs.path.sep) orelse return null;
+ end += 1;
+ // /foo/node_modules/@babel/standalone/index.js
+ // ^
+ if (absolute[end] == '@') {
+ end += strings.indexOfChar(absolute[end..], std.fs.path.sep) orelse return null;
+ end += 1;
+ }
+ // /foo/node_modules/@babel/standalone/index.js
+ // ^
+ const slice = absolute[0..end];
+
+ // Try to avoid the hash table lookup whenever possible
+ // That can cause filesystem lookups in parent directories and it requires a lock
+ if (result.package_json) |pkg| {
+ if (strings.eql(slice, pkg.source.path.name.dirWithTrailingSlash())) {
+ return pkg;
+ }
+ }
- const dir_info = (r.dirInfoCached(absolute[0 .. end + 1]) catch null) orelse return null;
+ const dir_info = (r.dirInfoCached(slice) catch null) orelse return null;
return dir_info.package_json;
}
@@ -1066,6 +1102,9 @@ pub fn NewResolver(cache_files: bool) type {
}
inline fn dirInfoCachedMaybeLog(r: *ThisResolver, path: string, comptime enable_logging: bool, comptime follow_symlinks: bool) !?*DirInfo {
+ r.mutex.lock();
+ defer r.mutex.unlock();
+
const top_result = try r.dir_cache.getOrPut(path);
if (top_result.status != .unknown) {
return r.dir_cache.atIndex(top_result.index);
diff --git a/src/string_immutable.zig b/src/string_immutable.zig
index 52b7e05ce..bac00ba45 100644
--- a/src/string_immutable.zig
+++ b/src/string_immutable.zig
@@ -13,6 +13,16 @@ pub inline fn contains(self: string, str: string) bool {
return std.mem.indexOf(u8, self, str) != null;
}
+pub inline fn containsAny(in: anytype, target: string) bool {
+ for (in) |str| if (contains(str, target)) return true;
+ return false;
+}
+
+pub inline fn indexAny(in: anytype, target: string) ?usize {
+ for (in) |str, i| if (indexOf(str, target) != null) return i;
+ return null;
+}
+
pub inline fn indexOfChar(self: string, char: u8) ?usize {
return std.mem.indexOfScalar(@TypeOf(char), self, char);
}
diff --git a/src/test/project.zig b/src/test/project.zig
new file mode 100644
index 000000000..5715778c1
--- /dev/null
+++ b/src/test/project.zig
@@ -0,0 +1,1466 @@
+pub const lodash = [_][]const u8{
+ "/project/node_modules/lodash/_apply.js",
+ "/project/node_modules/lodash/_arrayAggregator.js",
+ "/project/node_modules/lodash/_arrayEach.js",
+ "/project/node_modules/lodash/_arrayEachRight.js",
+ "/project/node_modules/lodash/_arrayEvery.js",
+ "/project/node_modules/lodash/_arrayFilter.js",
+ "/project/node_modules/lodash/_arrayIncludes.js",
+ "/project/node_modules/lodash/_arrayIncludesWith.js",
+ "/project/node_modules/lodash/_arrayLikeKeys.js",
+ "/project/node_modules/lodash/_arrayMap.js",
+ "/project/node_modules/lodash/_arrayPush.js",
+ "/project/node_modules/lodash/_arrayReduce.js",
+ "/project/node_modules/lodash/_arrayReduceRight.js",
+ "/project/node_modules/lodash/_arraySample.js",
+ "/project/node_modules/lodash/_arraySampleSize.js",
+ "/project/node_modules/lodash/_arrayShuffle.js",
+ "/project/node_modules/lodash/_arraySome.js",
+ "/project/node_modules/lodash/_asciiSize.js",
+ "/project/node_modules/lodash/_asciiToArray.js",
+ "/project/node_modules/lodash/_asciiWords.js",
+ "/project/node_modules/lodash/_assignMergeValue.js",
+ "/project/node_modules/lodash/_assignValue.js",
+ "/project/node_modules/lodash/_assocIndexOf.js",
+ "/project/node_modules/lodash/_baseAggregator.js",
+ "/project/node_modules/lodash/_baseAssign.js",
+ "/project/node_modules/lodash/_baseAssignIn.js",
+ "/project/node_modules/lodash/_baseAssignValue.js",
+ "/project/node_modules/lodash/_baseAt.js",
+ "/project/node_modules/lodash/_baseClamp.js",
+ "/project/node_modules/lodash/_baseClone.js",
+ "/project/node_modules/lodash/_baseConforms.js",
+ "/project/node_modules/lodash/_baseConformsTo.js",
+ "/project/node_modules/lodash/_baseCreate.js",
+ "/project/node_modules/lodash/_baseDelay.js",
+ "/project/node_modules/lodash/_baseDifference.js",
+ "/project/node_modules/lodash/_baseEach.js",
+ "/project/node_modules/lodash/_baseEachRight.js",
+ "/project/node_modules/lodash/_baseEvery.js",
+ "/project/node_modules/lodash/_baseExtremum.js",
+ "/project/node_modules/lodash/_baseFill.js",
+ "/project/node_modules/lodash/_baseFilter.js",
+ "/project/node_modules/lodash/_baseFindIndex.js",
+ "/project/node_modules/lodash/_baseFindKey.js",
+ "/project/node_modules/lodash/_baseFlatten.js",
+ "/project/node_modules/lodash/_baseFor.js",
+ "/project/node_modules/lodash/_baseForOwn.js",
+ "/project/node_modules/lodash/_baseForOwnRight.js",
+ "/project/node_modules/lodash/_baseForRight.js",
+ "/project/node_modules/lodash/_baseFunctions.js",
+ "/project/node_modules/lodash/_baseGet.js",
+ "/project/node_modules/lodash/_baseGetAllKeys.js",
+ "/project/node_modules/lodash/_baseGetTag.js",
+ "/project/node_modules/lodash/_baseGt.js",
+ "/project/node_modules/lodash/_baseHas.js",
+ "/project/node_modules/lodash/_baseHasIn.js",
+ "/project/node_modules/lodash/_baseIndexOf.js",
+ "/project/node_modules/lodash/_baseIndexOfWith.js",
+ "/project/node_modules/lodash/_baseInRange.js",
+ "/project/node_modules/lodash/_baseIntersection.js",
+ "/project/node_modules/lodash/_baseInverter.js",
+ "/project/node_modules/lodash/_baseInvoke.js",
+ "/project/node_modules/lodash/_baseIsArguments.js",
+ "/project/node_modules/lodash/_baseIsArrayBuffer.js",
+ "/project/node_modules/lodash/_baseIsDate.js",
+ "/project/node_modules/lodash/_baseIsEqual.js",
+ "/project/node_modules/lodash/_baseIsEqualDeep.js",
+ "/project/node_modules/lodash/_baseIsMap.js",
+ "/project/node_modules/lodash/_baseIsMatch.js",
+ "/project/node_modules/lodash/_baseIsNaN.js",
+ "/project/node_modules/lodash/_baseIsNative.js",
+ "/project/node_modules/lodash/_baseIsRegExp.js",
+ "/project/node_modules/lodash/_baseIsSet.js",
+ "/project/node_modules/lodash/_baseIsTypedArray.js",
+ "/project/node_modules/lodash/_baseIteratee.js",
+ "/project/node_modules/lodash/_baseKeys.js",
+ "/project/node_modules/lodash/_baseKeysIn.js",
+ "/project/node_modules/lodash/_baseLodash.js",
+ "/project/node_modules/lodash/_baseLt.js",
+ "/project/node_modules/lodash/_baseMap.js",
+ "/project/node_modules/lodash/_baseMatches.js",
+ "/project/node_modules/lodash/_baseMatchesProperty.js",
+ "/project/node_modules/lodash/_baseMean.js",
+ "/project/node_modules/lodash/_baseMerge.js",
+ "/project/node_modules/lodash/_baseMergeDeep.js",
+ "/project/node_modules/lodash/_baseNth.js",
+ "/project/node_modules/lodash/_baseOrderBy.js",
+ "/project/node_modules/lodash/_basePick.js",
+ "/project/node_modules/lodash/_basePickBy.js",
+ "/project/node_modules/lodash/_baseProperty.js",
+ "/project/node_modules/lodash/_basePropertyDeep.js",
+ "/project/node_modules/lodash/_basePropertyOf.js",
+ "/project/node_modules/lodash/_basePullAll.js",
+ "/project/node_modules/lodash/_basePullAt.js",
+ "/project/node_modules/lodash/_baseRandom.js",
+ "/project/node_modules/lodash/_baseRange.js",
+ "/project/node_modules/lodash/_baseReduce.js",
+ "/project/node_modules/lodash/_baseRepeat.js",
+ "/project/node_modules/lodash/_baseRest.js",
+ "/project/node_modules/lodash/_baseSample.js",
+ "/project/node_modules/lodash/_baseSampleSize.js",
+ "/project/node_modules/lodash/_baseSet.js",
+ "/project/node_modules/lodash/_baseSetData.js",
+ "/project/node_modules/lodash/_baseSetToString.js",
+ "/project/node_modules/lodash/_baseShuffle.js",
+ "/project/node_modules/lodash/_baseSlice.js",
+ "/project/node_modules/lodash/_baseSome.js",
+ "/project/node_modules/lodash/_baseSortBy.js",
+ "/project/node_modules/lodash/_baseSortedIndex.js",
+ "/project/node_modules/lodash/_baseSortedIndexBy.js",
+ "/project/node_modules/lodash/_baseSortedUniq.js",
+ "/project/node_modules/lodash/_baseSum.js",
+ "/project/node_modules/lodash/_baseTimes.js",
+ "/project/node_modules/lodash/_baseToNumber.js",
+ "/project/node_modules/lodash/_baseToPairs.js",
+ "/project/node_modules/lodash/_baseToString.js",
+ "/project/node_modules/lodash/_baseTrim.js",
+ "/project/node_modules/lodash/_baseUnary.js",
+ "/project/node_modules/lodash/_baseUniq.js",
+ "/project/node_modules/lodash/_baseUnset.js",
+ "/project/node_modules/lodash/_baseUpdate.js",
+ "/project/node_modules/lodash/_baseValues.js",
+ "/project/node_modules/lodash/_baseWhile.js",
+ "/project/node_modulges/lodash/_baseWrapperValue.js",
+ "/project/node_modules/lodash/_baseXor.js",
+ "/project/node_modules/lodash/_baseZipObject.js",
+ "/project/node_modules/lodash/_cacheHas.js",
+ "/project/node_modules/lodash/_castArrayLikeObject.js",
+ "/project/node_modules/lodash/_castFunction.js",
+ "/project/node_modules/lodash/_castPath.js",
+ "/project/node_modules/lodash/_castRest.js",
+ "/project/node_modules/lodash/_castSlice.js",
+ "/project/node_modules/lodash/_charsEndIndex.js",
+ "/project/node_modules/lodash/_charsStartIndex.js",
+ "/project/node_modules/lodash/_cloneArrayBuffer.js",
+ "/project/node_modules/lodash/_cloneBuffer.js",
+ "/project/node_modules/lodash/_cloneDataView.js",
+ "/project/node_modules/lodash/_cloneRegExp.js",
+ "/project/node_modules/lodash/_cloneSymbol.js",
+ "/project/node_modules/lodash/_cloneTypedArray.js",
+ "/project/node_modules/lodash/_compareAscending.js",
+ "/project/node_modules/lodash/_compareMultiple.js",
+ "/project/node_modules/lodash/_composeArgs.js",
+ "/project/node_modules/lodash/_composeArgsRight.js",
+ "/project/node_modules/lodash/_copyArray.js",
+ "/project/node_modules/lodash/_copyObject.js",
+ "/project/node_modules/lodash/_copySymbols.js",
+ "/project/node_modules/lodash/_copySymbolsIn.js",
+ "/project/node_modules/lodash/_coreJsData.js",
+ "/project/node_modules/lodash/_countHolders.js",
+ "/project/node_modules/lodash/_createAggregator.js",
+ "/project/node_modules/lodash/_createAssigner.js",
+ "/project/node_modules/lodash/_createBaseEach.js",
+ "/project/node_modules/lodash/_createBaseFor.js",
+ "/project/node_modules/lodash/_createBind.js",
+ "/project/node_modules/lodash/_createCaseFirst.js",
+ "/project/node_modules/lodash/_createCompounder.js",
+ "/project/node_modules/lodash/_createCtor.js",
+ "/project/node_modules/lodash/_createCurry.js",
+ "/project/node_modules/lodash/_createFind.js",
+ "/project/node_modules/lodash/_createFlow.js",
+ "/project/node_modules/lodash/_createHybrid.js",
+ "/project/node_modules/lodash/_createInverter.js",
+ "/project/node_modules/lodash/_createMathOperation.js",
+ "/project/node_modules/lodash/_createOver.js",
+ "/project/node_modules/lodash/_createPadding.js",
+ "/project/node_modules/lodash/_createPartial.js",
+ "/project/node_modules/lodash/_createRange.js",
+ "/project/node_modules/lodash/_createRecurry.js",
+ "/project/node_modules/lodash/_createRelationalOperation.js",
+ "/project/node_modules/lodash/_createRound.js",
+ "/project/node_modules/lodash/_createSet.js",
+ "/project/node_modules/lodash/_createToPairs.js",
+ "/project/node_modules/lodash/_createWrap.js",
+ "/project/node_modules/lodash/_customDefaultsAssignIn.js",
+ "/project/node_modules/lodash/_customDefaultsMerge.js",
+ "/project/node_modules/lodash/_customOmitClone.js",
+ "/project/node_modules/lodash/_DataView.js",
+ "/project/node_modules/lodash/_deburrLetter.js",
+ "/project/node_modules/lodash/_defineProperty.js",
+ "/project/node_modules/lodash/_equalArrays.js",
+ "/project/node_modules/lodash/_equalByTag.js",
+ "/project/node_modules/lodash/_equalObjects.js",
+ "/project/node_modules/lodash/_escapeHtmlChar.js",
+ "/project/node_modules/lodash/_escapeStringChar.js",
+ "/project/node_modules/lodash/_flatRest.js",
+ "/project/node_modules/lodash/_freeGlobal.js",
+ "/project/node_modules/lodash/_getAllKeys.js",
+ "/project/node_modules/lodash/_getAllKeysIn.js",
+ "/project/node_modules/lodash/_getData.js",
+ "/project/node_modules/lodash/_getFuncName.js",
+ "/project/node_modules/lodash/_getHolder.js",
+ "/project/node_modules/lodash/_getMapData.js",
+ "/project/node_modules/lodash/_getMatchData.js",
+ "/project/node_modules/lodash/_getNative.js",
+ "/project/node_modules/lodash/_getPrototype.js",
+ "/project/node_modules/lodash/_getRawTag.js",
+ "/project/node_modules/lodash/_getSymbols.js",
+ "/project/node_modules/lodash/_getSymbolsIn.js",
+ "/project/node_modules/lodash/_getTag.js",
+ "/project/node_modules/lodash/_getValue.js",
+ "/project/node_modules/lodash/_getView.js",
+ "/project/node_modules/lodash/_getWrapDetails.js",
+ "/project/node_modules/lodash/_Hash.js",
+ "/project/node_modules/lodash/_hashClear.js",
+ "/project/node_modules/lodash/_hashDelete.js",
+ "/project/node_modules/lodash/_hashGet.js",
+ "/project/node_modules/lodash/_hashHas.js",
+ "/project/node_modules/lodash/_hashSet.js",
+ "/project/node_modules/lodash/_hasPath.js",
+ "/project/node_modules/lodash/_hasUnicode.js",
+ "/project/node_modules/lodash/_hasUnicodeWord.js",
+ "/project/node_modules/lodash/_initCloneArray.js",
+ "/project/node_modules/lodash/_initCloneByTag.js",
+ "/project/node_modules/lodash/_initCloneObject.js",
+ "/project/node_modules/lodash/_insertWrapDetails.js",
+ "/project/node_modules/lodash/_isFlattenable.js",
+ "/project/node_modules/lodash/_isIndex.js",
+ "/project/node_modules/lodash/_isIterateeCall.js",
+ "/project/node_modules/lodash/_isKey.js",
+ "/project/node_modules/lodash/_isKeyable.js",
+ "/project/node_modules/lodash/_isLaziable.js",
+ "/project/node_modules/lodash/_isMaskable.js",
+ "/project/node_modules/lodash/_isMasked.js",
+ "/project/node_modules/lodash/_isPrototype.js",
+ "/project/node_modules/lodash/_isStrictComparable.js",
+ "/project/node_modules/lodash/_iteratorToArray.js",
+ "/project/node_modules/lodash/_lazyClone.js",
+ "/project/node_modules/lodash/_lazyReverse.js",
+ "/project/node_modules/lodash/_lazyValue.js",
+ "/project/node_modules/lodash/_LazyWrapper.js",
+ "/project/node_modules/lodash/_ListCache.js",
+ "/project/node_modules/lodash/_listCacheClear.js",
+ "/project/node_modules/lodash/_listCacheDelete.js",
+ "/project/node_modules/lodash/_listCacheGet.js",
+ "/project/node_modules/lodash/_listCacheHas.js",
+ "/project/node_modules/lodash/_listCacheSet.js",
+ "/project/node_modules/lodash/_LodashWrapper.js",
+ "/project/node_modules/lodash/_Map.js",
+ "/project/node_modules/lodash/_MapCache.js",
+ "/project/node_modules/lodash/_mapCacheClear.js",
+ "/project/node_modules/lodash/_mapCacheDelete.js",
+ "/project/node_modules/lodash/_mapCacheGet.js",
+ "/project/node_modules/lodash/_mapCacheHas.js",
+ "/project/node_modules/lodash/_mapCacheSet.js",
+ "/project/node_modules/lodash/_mapToArray.js",
+ "/project/node_modules/lodash/_matchesStrictComparable.js",
+ "/project/node_modules/lodash/_memoizeCapped.js",
+ "/project/node_modules/lodash/_mergeData.js",
+ "/project/node_modules/lodash/_metaMap.js",
+ "/project/node_modules/lodash/_nativeCreate.js",
+ "/project/node_modules/lodash/_nativeKeys.js",
+ "/project/node_modules/lodash/_nativeKeysIn.js",
+ "/project/node_modules/lodash/_nodeUtil.js",
+ "/project/node_modules/lodash/_objectToString.js",
+ "/project/node_modules/lodash/_overArg.js",
+ "/project/node_modules/lodash/_overRest.js",
+ "/project/node_modules/lodash/_parent.js",
+ "/project/node_modules/lodash/_Promise.js",
+ "/project/node_modules/lodash/_realNames.js",
+ "/project/node_modules/lodash/_reEscape.js",
+ "/project/node_modules/lodash/_reEvaluate.js",
+ "/project/node_modules/lodash/_reInterpolate.js",
+ "/project/node_modules/lodash/_reorder.js",
+ "/project/node_modules/lodash/_replaceHolders.js",
+ "/project/node_modules/lodash/_root.js",
+ "/project/node_modules/lodash/_safeGet.js",
+ "/project/node_modules/lodash/_Set.js",
+ "/project/node_modules/lodash/_SetCache.js",
+ "/project/node_modules/lodash/_setCacheAdd.js",
+ "/project/node_modules/lodash/_setCacheHas.js",
+ "/project/node_modules/lodash/_setData.js",
+ "/project/node_modules/lodash/_setToArray.js",
+ "/project/node_modules/lodash/_setToPairs.js",
+ "/project/node_modules/lodash/_setToString.js",
+ "/project/node_modules/lodash/_setWrapToString.js",
+ "/project/node_modules/lodash/_shortOut.js",
+ "/project/node_modules/lodash/_shuffleSelf.js",
+ "/project/node_modules/lodash/_Stack.js",
+ "/project/node_modules/lodash/_stackClear.js",
+ "/project/node_modules/lodash/_stackDelete.js",
+ "/project/node_modules/lodash/_stackGet.js",
+ "/project/node_modules/lodash/_stackHas.js",
+ "/project/node_modules/lodash/_stackSet.js",
+ "/project/node_modules/lodash/_strictIndexOf.js",
+ "/project/node_modules/lodash/_strictLastIndexOf.js",
+ "/project/node_modules/lodash/_stringSize.js",
+ "/project/node_modules/lodash/_stringToArray.js",
+ "/project/node_modules/lodash/_stringToPath.js",
+ "/project/node_modules/lodash/_Symbol.js",
+ "/project/node_modules/lodash/_toKey.js",
+ "/project/node_modules/lodash/_toSource.js",
+ "/project/node_modules/lodash/_trimmedEndIndex.js",
+ "/project/node_modules/lodash/_Uint8Array.js",
+ "/project/node_modules/lodash/_unescapeHtmlChar.js",
+ "/project/node_modules/lodash/_unicodeSize.js",
+ "/project/node_modules/lodash/_unicodeToArray.js",
+ "/project/node_modules/lodash/_unicodeWords.js",
+ "/project/node_modules/lodash/_updateWrapDetails.js",
+ "/project/node_modules/lodash/_WeakMap.js",
+ "/project/node_modules/lodash/_wrapperClone.js",
+ "/project/node_modules/lodash/add.js",
+ "/project/node_modules/lodash/after.js",
+ "/project/node_modules/lodash/array.js",
+ "/project/node_modules/lodash/ary.js",
+ "/project/node_modules/lodash/assign.js",
+ "/project/node_modules/lodash/assignIn.js",
+ "/project/node_modules/lodash/assignInWith.js",
+ "/project/node_modules/lodash/assignWith.js",
+ "/project/node_modules/lodash/at.js",
+ "/project/node_modules/lodash/attempt.js",
+ "/project/node_modules/lodash/before.js",
+ "/project/node_modules/lodash/bind.js",
+ "/project/node_modules/lodash/bindAll.js",
+ "/project/node_modules/lodash/bindKey.js",
+ "/project/node_modules/lodash/camelCase.js",
+ "/project/node_modules/lodash/capitalize.js",
+ "/project/node_modules/lodash/castArray.js",
+ "/project/node_modules/lodash/ceil.js",
+ "/project/node_modules/lodash/chain.js",
+ "/project/node_modules/lodash/chunk.js",
+ "/project/node_modules/lodash/clamp.js",
+ "/project/node_modules/lodash/clone.js",
+ "/project/node_modules/lodash/cloneDeep.js",
+ "/project/node_modules/lodash/cloneDeepWith.js",
+ "/project/node_modules/lodash/cloneWith.js",
+ "/project/node_modules/lodash/collection.js",
+ "/project/node_modules/lodash/commit.js",
+ "/project/node_modules/lodash/compact.js",
+ "/project/node_modules/lodash/concat.js",
+ "/project/node_modules/lodash/cond.js",
+ "/project/node_modules/lodash/conforms.js",
+ "/project/node_modules/lodash/conformsTo.js",
+ "/project/node_modules/lodash/constant.js",
+ "/project/node_modules/lodash/core.js",
+ "/project/node_modules/lodash/core.min.js",
+ "/project/node_modules/lodash/countBy.js",
+ "/project/node_modules/lodash/create.js",
+ "/project/node_modules/lodash/curry.js",
+ "/project/node_modules/lodash/curryRight.js",
+ "/project/node_modules/lodash/date.js",
+ "/project/node_modules/lodash/debounce.js",
+ "/project/node_modules/lodash/deburr.js",
+ "/project/node_modules/lodash/defaults.js",
+ "/project/node_modules/lodash/defaultsDeep.js",
+ "/project/node_modules/lodash/defaultTo.js",
+ "/project/node_modules/lodash/defer.js",
+ "/project/node_modules/lodash/delay.js",
+ "/project/node_modules/lodash/difference.js",
+ "/project/node_modules/lodash/differenceBy.js",
+ "/project/node_modules/lodash/differenceWith.js",
+ "/project/node_modules/lodash/divide.js",
+ "/project/node_modules/lodash/drop.js",
+ "/project/node_modules/lodash/dropRight.js",
+ "/project/node_modules/lodash/dropRightWhile.js",
+ "/project/node_modules/lodash/dropWhile.js",
+ "/project/node_modules/lodash/each.js",
+ "/project/node_modules/lodash/eachRight.js",
+ "/project/node_modules/lodash/endsWith.js",
+ "/project/node_modules/lodash/entries.js",
+ "/project/node_modules/lodash/entriesIn.js",
+ "/project/node_modules/lodash/eq.js",
+ "/project/node_modules/lodash/escape.js",
+ "/project/node_modules/lodash/escapeRegExp.js",
+ "/project/node_modules/lodash/every.js",
+ "/project/node_modules/lodash/extend.js",
+ "/project/node_modules/lodash/extendWith.js",
+ "/project/node_modules/lodash/fill.js",
+ "/project/node_modules/lodash/filter.js",
+ "/project/node_modules/lodash/find.js",
+ "/project/node_modules/lodash/findIndex.js",
+ "/project/node_modules/lodash/findKey.js",
+ "/project/node_modules/lodash/findLast.js",
+ "/project/node_modules/lodash/findLastIndex.js",
+ "/project/node_modules/lodash/findLastKey.js",
+ "/project/node_modules/lodash/first.js",
+ "/project/node_modules/lodash/flake.lock",
+ "/project/node_modules/lodash/flake.nix",
+ "/project/node_modules/lodash/flatMap.js",
+ "/project/node_modules/lodash/flatMapDeep.js",
+ "/project/node_modules/lodash/flatMapDepth.js",
+ "/project/node_modules/lodash/flatten.js",
+ "/project/node_modules/lodash/flattenDeep.js",
+ "/project/node_modules/lodash/flattenDepth.js",
+ "/project/node_modules/lodash/flip.js",
+ "/project/node_modules/lodash/floor.js",
+ "/project/node_modules/lodash/flow.js",
+ "/project/node_modules/lodash/flowRight.js",
+ "/project/node_modules/lodash/forEach.js",
+ "/project/node_modules/lodash/forEachRight.js",
+ "/project/node_modules/lodash/forIn.js",
+ "/project/node_modules/lodash/forInRight.js",
+ "/project/node_modules/lodash/forOwn.js",
+ "/project/node_modules/lodash/forOwnRight.js",
+ "/project/node_modules/lodash/fp",
+ "/project/node_modules/lodash/fp.js",
+ "/project/node_modules/lodash/fromPairs.js",
+ "/project/node_modules/lodash/function.js",
+ "/project/node_modules/lodash/functions.js",
+ "/project/node_modules/lodash/functionsIn.js",
+ "/project/node_modules/lodash/get.js",
+ "/project/node_modules/lodash/groupBy.js",
+ "/project/node_modules/lodash/gt.js",
+ "/project/node_modules/lodash/gte.js",
+ "/project/node_modules/lodash/has.js",
+ "/project/node_modules/lodash/hasIn.js",
+ "/project/node_modules/lodash/head.js",
+ "/project/node_modules/lodash/identity.js",
+ "/project/node_modules/lodash/includes.js",
+ "/project/node_modules/lodash/index.js",
+ "/project/node_modules/lodash/indexOf.js",
+ "/project/node_modules/lodash/initial.js",
+ "/project/node_modules/lodash/inRange.js",
+ "/project/node_modules/lodash/intersection.js",
+ "/project/node_modules/lodash/intersectionBy.js",
+ "/project/node_modules/lodash/intersectionWith.js",
+ "/project/node_modules/lodash/invert.js",
+ "/project/node_modules/lodash/invertBy.js",
+ "/project/node_modules/lodash/invoke.js",
+ "/project/node_modules/lodash/invokeMap.js",
+ "/project/node_modules/lodash/isArguments.js",
+ "/project/node_modules/lodash/isArray.js",
+ "/project/node_modules/lodash/isArrayBuffer.js",
+ "/project/node_modules/lodash/isArrayLike.js",
+ "/project/node_modules/lodash/isArrayLikeObject.js",
+ "/project/node_modules/lodash/isBoolean.js",
+ "/project/node_modules/lodash/isBuffer.js",
+ "/project/node_modules/lodash/isDate.js",
+ "/project/node_modules/lodash/isElement.js",
+ "/project/node_modules/lodash/isEmpty.js",
+ "/project/node_modules/lodash/isEqual.js",
+ "/project/node_modules/lodash/isEqualWith.js",
+ "/project/node_modules/lodash/isError.js",
+ "/project/node_modules/lodash/isFinite.js",
+ "/project/node_modules/lodash/isFunction.js",
+ "/project/node_modules/lodash/isInteger.js",
+ "/project/node_modules/lodash/isLength.js",
+ "/project/node_modules/lodash/isMap.js",
+ "/project/node_modules/lodash/isMatch.js",
+ "/project/node_modules/lodash/isMatchWith.js",
+ "/project/node_modules/lodash/isNaN.js",
+ "/project/node_modules/lodash/isNative.js",
+ "/project/node_modules/lodash/isNil.js",
+ "/project/node_modules/lodash/isNull.js",
+ "/project/node_modules/lodash/isNumber.js",
+ "/project/node_modules/lodash/isObject.js",
+ "/project/node_modules/lodash/isObjectLike.js",
+ "/project/node_modules/lodash/isPlainObject.js",
+ "/project/node_modules/lodash/isRegExp.js",
+ "/project/node_modules/lodash/isSafeInteger.js",
+ "/project/node_modules/lodash/isSet.js",
+ "/project/node_modules/lodash/isString.js",
+ "/project/node_modules/lodash/isSymbol.js",
+ "/project/node_modules/lodash/isTypedArray.js",
+ "/project/node_modules/lodash/isUndefined.js",
+ "/project/node_modules/lodash/isWeakMap.js",
+ "/project/node_modules/lodash/isWeakSet.js",
+ "/project/node_modules/lodash/iteratee.js",
+ "/project/node_modules/lodash/join.js",
+ "/project/node_modules/lodash/kebabCase.js",
+ "/project/node_modules/lodash/keyBy.js",
+ "/project/node_modules/lodash/keys.js",
+ "/project/node_modules/lodash/keysIn.js",
+ "/project/node_modules/lodash/lang.js",
+ "/project/node_modules/lodash/last.js",
+ "/project/node_modules/lodash/lastIndexOf.js",
+ "/project/node_modules/lodash/LICENSE",
+ "/project/node_modules/lodash/lodash.js",
+ "/project/node_modules/lodash/lodash.min.js",
+ "/project/node_modules/lodash/lowerCase.js",
+ "/project/node_modules/lodash/lowerFirst.js",
+ "/project/node_modules/lodash/lt.js",
+ "/project/node_modules/lodash/lte.js",
+ "/project/node_modules/lodash/map.js",
+ "/project/node_modules/lodash/mapKeys.js",
+ "/project/node_modules/lodash/mapValues.js",
+ "/project/node_modules/lodash/matches.js",
+ "/project/node_modules/lodash/matchesProperty.js",
+ "/project/node_modules/lodash/math.js",
+ "/project/node_modules/lodash/max.js",
+ "/project/node_modules/lodash/maxBy.js",
+ "/project/node_modules/lodash/mean.js",
+ "/project/node_modules/lodash/meanBy.js",
+ "/project/node_modules/lodash/memoize.js",
+ "/project/node_modules/lodash/merge.js",
+ "/project/node_modules/lodash/mergeWith.js",
+ "/project/node_modules/lodash/method.js",
+ "/project/node_modules/lodash/methodOf.js",
+ "/project/node_modules/lodash/min.js",
+ "/project/node_modules/lodash/minBy.js",
+ "/project/node_modules/lodash/mixin.js",
+ "/project/node_modules/lodash/multiply.js",
+ "/project/node_modules/lodash/negate.js",
+ "/project/node_modules/lodash/next.js",
+ "/project/node_modules/lodash/noop.js",
+ "/project/node_modules/lodash/now.js",
+ "/project/node_modules/lodash/nth.js",
+ "/project/node_modules/lodash/nthArg.js",
+ "/project/node_modules/lodash/number.js",
+ "/project/node_modules/lodash/object.js",
+ "/project/node_modules/lodash/omit.js",
+ "/project/node_modules/lodash/omitBy.js",
+ "/project/node_modules/lodash/once.js",
+ "/project/node_modules/lodash/orderBy.js",
+ "/project/node_modules/lodash/over.js",
+ "/project/node_modules/lodash/overArgs.js",
+ "/project/node_modules/lodash/overEvery.js",
+ "/project/node_modules/lodash/overSome.js",
+ "/project/node_modules/lodash/package.json",
+ "/project/node_modules/lodash/pad.js",
+ "/project/node_modules/lodash/padEnd.js",
+ "/project/node_modules/lodash/padStart.js",
+ "/project/node_modules/lodash/parseInt.js",
+ "/project/node_modules/lodash/partial.js",
+ "/project/node_modules/lodash/partialRight.js",
+ "/project/node_modules/lodash/partition.js",
+ "/project/node_modules/lodash/pick.js",
+ "/project/node_modules/lodash/pickBy.js",
+ "/project/node_modules/lodash/plant.js",
+ "/project/node_modules/lodash/property.js",
+ "/project/node_modules/lodash/propertyOf.js",
+ "/project/node_modules/lodash/pull.js",
+ "/project/node_modules/lodash/pullAll.js",
+ "/project/node_modules/lodash/pullAllBy.js",
+ "/project/node_modules/lodash/pullAllWith.js",
+ "/project/node_modules/lodash/pullAt.js",
+ "/project/node_modules/lodash/random.js",
+ "/project/node_modules/lodash/range.js",
+ "/project/node_modules/lodash/rangeRight.js",
+ "/project/node_modules/lodash/README.md",
+ "/project/node_modules/lodash/rearg.js",
+ "/project/node_modules/lodash/reduce.js",
+ "/project/node_modules/lodash/reduceRight.js",
+ "/project/node_modules/lodash/reject.js",
+ "/project/node_modules/lodash/release.md",
+ "/project/node_modules/lodash/remove.js",
+ "/project/node_modules/lodash/repeat.js",
+ "/project/node_modules/lodash/replace.js",
+ "/project/node_modules/lodash/rest.js",
+ "/project/node_modules/lodash/result.js",
+ "/project/node_modules/lodash/reverse.js",
+ "/project/node_modules/lodash/round.js",
+ "/project/node_modules/lodash/sample.js",
+ "/project/node_modules/lodash/sampleSize.js",
+ "/project/node_modules/lodash/seq.js",
+ "/project/node_modules/lodash/set.js",
+ "/project/node_modules/lodash/setWith.js",
+ "/project/node_modules/lodash/shuffle.js",
+ "/project/node_modules/lodash/size.js",
+ "/project/node_modules/lodash/slice.js",
+ "/project/node_modules/lodash/snakeCase.js",
+ "/project/node_modules/lodash/some.js",
+ "/project/node_modules/lodash/sortBy.js",
+ "/project/node_modules/lodash/sortedIndex.js",
+ "/project/node_modules/lodash/sortedIndexBy.js",
+ "/project/node_modules/lodash/sortedIndexOf.js",
+ "/project/node_modules/lodash/sortedLastIndex.js",
+ "/project/node_modules/lodash/sortedLastIndexBy.js",
+ "/project/node_modules/lodash/sortedLastIndexOf.js",
+ "/project/node_modules/lodash/sortedUniq.js",
+ "/project/node_modules/lodash/sortedUniqBy.js",
+ "/project/node_modules/lodash/split.js",
+ "/project/node_modules/lodash/spread.js",
+ "/project/node_modules/lodash/startCase.js",
+ "/project/node_modules/lodash/startsWith.js",
+ "/project/node_modules/lodash/string.js",
+ "/project/node_modules/lodash/stubArray.js",
+ "/project/node_modules/lodash/stubFalse.js",
+ "/project/node_modules/lodash/stubObject.js",
+ "/project/node_modules/lodash/stubString.js",
+ "/project/node_modules/lodash/stubTrue.js",
+ "/project/node_modules/lodash/subtract.js",
+ "/project/node_modules/lodash/sum.js",
+ "/project/node_modules/lodash/sumBy.js",
+ "/project/node_modules/lodash/tail.js",
+ "/project/node_modules/lodash/take.js",
+ "/project/node_modules/lodash/takeRight.js",
+ "/project/node_modules/lodash/takeRightWhile.js",
+ "/project/node_modules/lodash/takeWhile.js",
+ "/project/node_modules/lodash/tap.js",
+ "/project/node_modules/lodash/template.js",
+ "/project/node_modules/lodash/templateSettings.js",
+ "/project/node_modules/lodash/throttle.js",
+ "/project/node_modules/lodash/thru.js",
+ "/project/node_modules/lodash/times.js",
+ "/project/node_modules/lodash/toArray.js",
+ "/project/node_modules/lodash/toFinite.js",
+ "/project/node_modules/lodash/toInteger.js",
+ "/project/node_modules/lodash/toIterator.js",
+ "/project/node_modules/lodash/toJSON.js",
+ "/project/node_modules/lodash/toLength.js",
+ "/project/node_modules/lodash/toLower.js",
+ "/project/node_modules/lodash/toNumber.js",
+ "/project/node_modules/lodash/toPairs.js",
+ "/project/node_modules/lodash/toPairsIn.js",
+ "/project/node_modules/lodash/toPath.js",
+ "/project/node_modules/lodash/toPlainObject.js",
+ "/project/node_modules/lodash/toSafeInteger.js",
+ "/project/node_modules/lodash/toString.js",
+ "/project/node_modules/lodash/toUpper.js",
+ "/project/node_modules/lodash/transform.js",
+ "/project/node_modules/lodash/trim.js",
+ "/project/node_modules/lodash/trimEnd.js",
+ "/project/node_modules/lodash/trimStart.js",
+ "/project/node_modules/lodash/truncate.js",
+ "/project/node_modules/lodash/unary.js",
+ "/project/node_modules/lodash/unescape.js",
+ "/project/node_modules/lodash/union.js",
+ "/project/node_modules/lodash/unionBy.js",
+ "/project/node_modules/lodash/unionWith.js",
+ "/project/node_modules/lodash/uniq.js",
+ "/project/node_modules/lodash/uniqBy.js",
+ "/project/node_modules/lodash/uniqueId.js",
+ "/project/node_modules/lodash/uniqWith.js",
+ "/project/node_modules/lodash/unset.js",
+ "/project/node_modules/lodash/unzip.js",
+ "/project/node_modules/lodash/unzipWith.js",
+ "/project/node_modules/lodash/update.js",
+ "/project/node_modules/lodash/updateWith.js",
+ "/project/node_modules/lodash/upperCase.js",
+ "/project/node_modules/lodash/upperFirst.js",
+ "/project/node_modules/lodash/util.js",
+ "/project/node_modules/lodash/value.js",
+ "/project/node_modules/lodash/valueOf.js",
+ "/project/node_modules/lodash/values.js",
+ "/project/node_modules/lodash/valuesIn.js",
+ "/project/node_modules/lodash/without.js",
+ "/project/node_modules/lodash/words.js",
+ "/project/node_modules/lodash/wrap.js",
+ "/project/node_modules/lodash/wrapperAt.js",
+ "/project/node_modules/lodash/wrapperChain.js",
+ "/project/node_modules/lodash/wrapperLodash.js",
+ "/project/node_modules/lodash/wrapperReverse.js",
+ "/project/node_modules/lodash/wrapperValue.js",
+ "/project/node_modules/lodash/xor.js",
+ "/project/node_modules/lodash/xorBy.js",
+ "/project/node_modules/lodash/xorWith.js",
+ "/project/node_modules/lodash/zip.js",
+ "/project/node_modules/lodash/zipObject.js",
+ "/project/node_modules/lodash/zipObjectDeep.js",
+ "/project/node_modules/lodash/zipWith.js",
+};
+
+pub const three = [_][]const u8{
+ "/project/node_modules/three/src",
+ "/project/node_modules/three/src/renderers",
+ "/project/node_modules/three/src/renderers/webgl",
+ "/project/node_modules/three/src/renderers/webgl/WebGLPrograms.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLGeometries.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLClipping.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLUniforms.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLShader.js",
+ "/project/node_modules/three/src/renderers/webgl/plugins",
+ "/project/node_modules/three/src/renderers/webgl/plugins/SpritePlugin.js",
+ "/project/node_modules/three/src/renderers/webgl/plugins/LensFlarePlugin.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLExtensions.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLBufferRenderer.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLObjects.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLLights.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLCapabilities.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLIndexedBufferRenderer.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLProperties.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLState.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLShadowMap.js",
+ "/project/node_modules/three/src/renderers/webgl/WebGLProgram.js",
+ "/project/node_modules/three/src/renderers/WebGLRenderTargetCube.js",
+ "/project/node_modules/three/src/renderers/shaders",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/color_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv2_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/morphnormal_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/skinnormal_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/ambient_pars.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/roughnessmap_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/roughnessmap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/map_particle_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv2_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/map_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/clipping_planes_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/clipping_planes_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/normal_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/color_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/common.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_pars.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/specularmap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/aomap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/tonemapping_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/skinning_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/skinning_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/encodings_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/clipping_planes_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/alphamap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/map_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/project_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/clipping_planes_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_template.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/packing.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/skinbase_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/specularmap_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/fog_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/bsdfs.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/begin_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/metalnessmap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv2_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/displacementmap_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/emissivemap_pars_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk/displacementmap_pars_vertex.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderChunk.js",
+ "/project/node_modules/three/src/renderers/shaders/UniformsUtils.js",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib.js",
+ "/project/node_modules/three/src/renderers/shaders/DefinesUtils.js",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshbasic_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/shadow_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshlambert_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/points_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/equirect_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/cube_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphong_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/normal_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/normal_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/shadow_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshbasic_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshlambert_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/points_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/equirect_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/cube_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphysical_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphong_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/UniformsLib.js",
+ "/project/node_modules/three/src/renderers/WebGLRenderer.js",
+ "/project/node_modules/three/src/renderers/WebGLRenderTarget.js",
+ "/project/node_modules/three/src/textures",
+ "/project/node_modules/three/src/textures/DepthTexture.js",
+ "/project/node_modules/three/src/textures/CompressedTexture.js",
+ "/project/node_modules/three/src/textures/VideoTexture.js",
+ "/project/node_modules/three/src/textures/CubeTexture.js",
+ "/project/node_modules/three/src/textures/CanvasTexture.js",
+ "/project/node_modules/three/src/textures/Texture.js",
+ "/project/node_modules/three/src/textures/DataTexture.js",
+ "/project/node_modules/three/src/scenes",
+ "/project/node_modules/three/src/scenes/Fog.js",
+ "/project/node_modules/three/src/scenes/Scene.js",
+ "/project/node_modules/three/src/scenes/FogExp2.js",
+ "/project/node_modules/three/src/materials",
+ "/project/node_modules/three/src/materials/MultiMaterial.js",
+ "/project/node_modules/three/src/materials/LineDashedMaterial.js",
+ "/project/node_modules/three/src/materials/LineBasicMaterial.js",
+ "/project/node_modules/three/src/materials/MeshNormalMaterial.js",
+ "/project/node_modules/three/src/materials/Material.js",
+ "/project/node_modules/three/src/materials/MeshPhysicalMaterial.js",
+ "/project/node_modules/three/src/materials/MeshBasicMaterial.js",
+ "/project/node_modules/three/src/materials/MeshStandardMaterial.js",
+ "/project/node_modules/three/src/materials/MeshPhongMaterial.js",
+ "/project/node_modules/three/src/materials/SpriteMaterial.js",
+ "/project/node_modules/three/src/materials/MeshDepthMaterial.js",
+ "/project/node_modules/three/src/materials/ShadowMaterial.js",
+ "/project/node_modules/three/src/materials/PointsMaterial.js",
+ "/project/node_modules/three/src/materials/ShaderMaterial.js",
+ "/project/node_modules/three/src/materials/MeshLambertMaterial.js",
+ "/project/node_modules/three/src/materials/RawShaderMaterial.js",
+ "/project/node_modules/three/src/core",
+ "/project/node_modules/three/src/core/InstancedBufferAttribute.js",
+ "/project/node_modules/three/src/core/Face3.js",
+ "/project/node_modules/three/src/core/Clock.js",
+ "/project/node_modules/three/src/core/BufferAttribute.js",
+ "/project/node_modules/three/src/core/Raycaster.js",
+ "/project/node_modules/three/src/core/InstancedInterleavedBuffer.js",
+ "/project/node_modules/three/src/core/InterleavedBufferAttribute.js",
+ "/project/node_modules/three/src/core/EventDispatcher.js",
+ "/project/node_modules/three/src/core/InstancedBufferGeometry.js",
+ "/project/node_modules/three/src/core/Layers.js",
+ "/project/node_modules/three/src/core/Uniform.js",
+ "/project/node_modules/three/src/core/BufferGeometry.js",
+ "/project/node_modules/three/src/core/DirectGeometry.js",
+ "/project/node_modules/three/src/core/Geometry.js",
+ "/project/node_modules/three/src/core/InterleavedBuffer.js",
+ "/project/node_modules/three/src/core/Object3D.js",
+ "/project/node_modules/three/src/Three.js",
+ "/project/node_modules/three/src/animation",
+ "/project/node_modules/three/src/animation/AnimationUtils.js",
+ "/project/node_modules/three/src/animation/PropertyBinding.js",
+ "/project/node_modules/three/src/animation/KeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks",
+ "/project/node_modules/three/src/animation/tracks/VectorKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/NumberKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/ColorKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/StringKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/QuaternionKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/BooleanKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/AnimationMixer.js",
+ "/project/node_modules/three/src/animation/PropertyMixer.js",
+ "/project/node_modules/three/src/animation/AnimationClip.js",
+ "/project/node_modules/three/src/animation/AnimationAction.js",
+ "/project/node_modules/three/src/animation/AnimationObjectGroup.js",
+ "/project/node_modules/three/src/objects",
+ "/project/node_modules/three/src/objects/Line.js",
+ "/project/node_modules/three/src/objects/Skeleton.js",
+ "/project/node_modules/three/src/objects/Mesh.js",
+ "/project/node_modules/three/src/objects/LensFlare.js",
+ "/project/node_modules/three/src/objects/Points.js",
+ "/project/node_modules/three/src/objects/LOD.js",
+ "/project/node_modules/three/src/objects/LineSegments.js",
+ "/project/node_modules/three/src/objects/Bone.js",
+ "/project/node_modules/three/src/objects/Sprite.js",
+ "/project/node_modules/three/src/objects/SkinnedMesh.js",
+ "/project/node_modules/three/src/objects/Group.js",
+ "/project/node_modules/three/src/cameras",
+ "/project/node_modules/three/src/cameras/CubeCamera.js",
+ "/project/node_modules/three/src/cameras/StereoCamera.js",
+ "/project/node_modules/three/src/cameras/PerspectiveCamera.js",
+ "/project/node_modules/three/src/cameras/Camera.js",
+ "/project/node_modules/three/src/cameras/OrthographicCamera.js",
+ "/project/node_modules/three/src/math",
+ "/project/node_modules/three/src/math/Vector2.js",
+ "/project/node_modules/three/src/math/Quaternion.js",
+ "/project/node_modules/three/src/math/Matrix3.js",
+ "/project/node_modules/three/src/math/Vector3.js",
+ "/project/node_modules/three/src/math/Ray.js",
+ "/project/node_modules/three/src/math/Spline.js",
+ "/project/node_modules/three/src/math/Color.js",
+ "/project/node_modules/three/src/math/Box3.js",
+ "/project/node_modules/three/src/math/Math.js",
+ "/project/node_modules/three/src/math/Euler.js",
+ "/project/node_modules/three/src/math/Frustum.js",
+ "/project/node_modules/three/src/math/Plane.js",
+ "/project/node_modules/three/src/math/Sphere.js",
+ "/project/node_modules/three/src/math/Interpolant.js",
+ "/project/node_modules/three/src/math/Box2.js",
+ "/project/node_modules/three/src/math/Line3.js",
+ "/project/node_modules/three/src/math/interpolants",
+ "/project/node_modules/three/src/math/interpolants/QuaternionLinearInterpolant.js",
+ "/project/node_modules/three/src/math/interpolants/LinearInterpolant.js",
+ "/project/node_modules/three/src/math/interpolants/DiscreteInterpolant.js",
+ "/project/node_modules/three/src/math/interpolants/CubicInterpolant.js",
+ "/project/node_modules/three/src/math/Vector4.js",
+ "/project/node_modules/three/src/math/Matrix4.js",
+ "/project/node_modules/three/src/math/Spherical.js",
+ "/project/node_modules/three/src/math/Triangle.js",
+ "/project/node_modules/three/src/audio",
+ "/project/node_modules/three/src/audio/AudioContext.js",
+ "/project/node_modules/three/src/audio/AudioAnalyser.js",
+ "/project/node_modules/three/src/audio/AudioListener.js",
+ "/project/node_modules/three/src/audio/PositionalAudio.js",
+ "/project/node_modules/three/src/audio/Audio.js",
+ "/project/node_modules/three/src/Three.Legacy.js",
+ "/project/node_modules/three/src/loaders",
+ "/project/node_modules/three/src/loaders/ImageLoader.js",
+ "/project/node_modules/three/src/loaders/FontLoader.js",
+ "/project/node_modules/three/src/loaders/AnimationLoader.js",
+ "/project/node_modules/three/src/loaders/Cache.js",
+ "/project/node_modules/three/src/loaders/MaterialLoader.js",
+ "/project/node_modules/three/src/loaders/TextureLoader.js",
+ "/project/node_modules/three/src/loaders/LoadingManager.js",
+ "/project/node_modules/three/src/loaders/ObjectLoader.js",
+ "/project/node_modules/three/src/loaders/XHRLoader.js",
+ "/project/node_modules/three/src/loaders/CubeTextureLoader.js",
+ "/project/node_modules/three/src/loaders/AudioLoader.js",
+ "/project/node_modules/three/src/loaders/BufferGeometryLoader.js",
+ "/project/node_modules/three/src/loaders/CompressedTextureLoader.js",
+ "/project/node_modules/three/src/loaders/JSONLoader.js",
+ "/project/node_modules/three/src/loaders/BinaryTextureLoader.js",
+ "/project/node_modules/three/src/loaders/Loader.js",
+ "/project/node_modules/three/src/lights",
+ "/project/node_modules/three/src/lights/DirectionalLight.js",
+ "/project/node_modules/three/src/lights/SpotLightShadow.js",
+ "/project/node_modules/three/src/lights/AmbientLight.js",
+ "/project/node_modules/three/src/lights/SpotLight.js",
+ "/project/node_modules/three/src/lights/HemisphereLight.js",
+ "/project/node_modules/three/src/lights/Light.js",
+ "/project/node_modules/three/src/lights/DirectionalLightShadow.js",
+ "/project/node_modules/three/src/lights/LightShadow.js",
+ "/project/node_modules/three/src/lights/PointLight.js",
+ "/project/node_modules/three/src/extras",
+ "/project/node_modules/three/src/extras/SceneUtils.js",
+ "/project/node_modules/three/src/extras/core",
+ "/project/node_modules/three/src/extras/core/Font.js",
+ "/project/node_modules/three/src/extras/core/Path.js",
+ "/project/node_modules/three/src/extras/core/CurvePath.js",
+ "/project/node_modules/three/src/extras/core/Curve.js",
+ "/project/node_modules/three/src/extras/core/Shape.js",
+ "/project/node_modules/three/src/extras/ShapeUtils.js",
+ "/project/node_modules/three/src/extras/objects",
+ "/project/node_modules/three/src/extras/objects/MorphBlendMesh.js",
+ "/project/node_modules/three/src/extras/objects/ImmediateRenderObject.js",
+ "/project/node_modules/three/src/extras/geometries",
+ "/project/node_modules/three/src/extras/geometries/TextGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/WireframeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/PlaneGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/DodecahedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CircleBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ParametricGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/SphereBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/RingBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/BoxGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/EdgesGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TetrahedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/RingGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ConeBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/LatheBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/LatheGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/SphereGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/IcosahedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CircleGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ShapeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/PlaneBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusKnotBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/BoxBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CylinderGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ExtrudeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ConeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusKnotGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TubeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CylinderBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/PolyhedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/OctahedronGeometry.js",
+ "/project/node_modules/three/src/extras/CurveUtils.js",
+ "/project/node_modules/three/src/extras/helpers",
+ "/project/node_modules/three/src/extras/helpers/WireframeHelper.js",
+ "/project/node_modules/three/src/extras/helpers/ArrowHelper.js",
+ "/project/node_modules/three/src/extras/helpers/SkeletonHelper.js",
+ "/project/node_modules/three/src/extras/helpers/PointLightHelper.js",
+ "/project/node_modules/three/src/extras/helpers/AxisHelper.js",
+ "/project/node_modules/three/src/extras/helpers/SpotLightHelper.js",
+ "/project/node_modules/three/src/extras/helpers/CameraHelper.js",
+ "/project/node_modules/three/src/extras/helpers/BoxHelper.js",
+ "/project/node_modules/three/src/extras/helpers/VertexNormalsHelper.js",
+ "/project/node_modules/three/src/extras/helpers/BoundingBoxHelper.js",
+ "/project/node_modules/three/src/extras/helpers/EdgesHelper.js",
+ "/project/node_modules/three/src/extras/helpers/FaceNormalsHelper.js",
+ "/project/node_modules/three/src/extras/helpers/GridHelper.js",
+ "/project/node_modules/three/src/extras/helpers/HemisphereLightHelper.js",
+ "/project/node_modules/three/src/extras/helpers/DirectionalLightHelper.js",
+ "/project/node_modules/three/src/extras/curves",
+ "/project/node_modules/three/src/extras/curves/CubicBezierCurve.js",
+ "/project/node_modules/three/src/extras/curves/EllipseCurve.js",
+ "/project/node_modules/three/src/extras/curves/LineCurve3.js",
+ "/project/node_modules/three/src/extras/curves/SplineCurve3.js",
+ "/project/node_modules/three/src/extras/curves/ArcCurve.js",
+ "/project/node_modules/three/src/extras/curves/ClosedSplineCurve3.js",
+ "/project/node_modules/three/src/extras/curves/CubicBezierCurve3.js",
+ "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve3.js",
+ "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve.js",
+ "/project/node_modules/three/src/extras/curves/LineCurve.js",
+ "/project/node_modules/three/src/extras/curves/CatmullRomCurve3.js",
+ "/project/node_modules/three/src/extras/curves/SplineCurve.js",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/normal_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/shadow_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshbasic_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshlambert_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/points_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/equirect_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/cube_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphysical_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphong_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/UniformsLib.js",
+ "/project/node_modules/three/src/renderers/WebGLRenderer.js",
+ "/project/node_modules/three/src/renderers/WebGLRenderTarget.js",
+ "/project/node_modules/three/src/textures",
+ "/project/node_modules/three/src/textures/DepthTexture.js",
+ "/project/node_modules/three/src/textures/CompressedTexture.js",
+ "/project/node_modules/three/src/textures/VideoTexture.js",
+ "/project/node_modules/three/src/textures/CubeTexture.js",
+ "/project/node_modules/three/src/textures/CanvasTexture.js",
+ "/project/node_modules/three/src/textures/Texture.js",
+ "/project/node_modules/three/src/textures/DataTexture.js",
+ "/project/node_modules/three/src/scenes",
+ "/project/node_modules/three/src/scenes/Fog.js",
+ "/project/node_modules/three/src/scenes/Scene.js",
+ "/project/node_modules/three/src/scenes/FogExp2.js",
+ "/project/node_modules/three/src/materials",
+ "/project/node_modules/three/src/materials/MultiMaterial.js",
+ "/project/node_modules/three/src/materials/LineDashedMaterial.js",
+ "/project/node_modules/three/src/materials/LineBasicMaterial.js",
+ "/project/node_modules/three/src/materials/MeshNormalMaterial.js",
+ "/project/node_modules/three/src/materials/Material.js",
+ "/project/node_modules/three/src/materials/MeshPhysicalMaterial.js",
+ "/project/node_modules/three/src/materials/MeshBasicMaterial.js",
+ "/project/node_modules/three/src/materials/MeshStandardMaterial.js",
+ "/project/node_modules/three/src/materials/MeshPhongMaterial.js",
+ "/project/node_modules/three/src/materials/SpriteMaterial.js",
+ "/project/node_modules/three/src/materials/MeshDepthMaterial.js",
+ "/project/node_modules/three/src/materials/ShadowMaterial.js",
+ "/project/node_modules/three/src/materials/PointsMaterial.js",
+ "/project/node_modules/three/src/materials/ShaderMaterial.js",
+ "/project/node_modules/three/src/materials/MeshLambertMaterial.js",
+ "/project/node_modules/three/src/materials/RawShaderMaterial.js",
+ "/project/node_modules/three/src/core",
+ "/project/node_modules/three/src/core/InstancedBufferAttribute.js",
+ "/project/node_modules/three/src/core/Face3.js",
+ "/project/node_modules/three/src/core/Clock.js",
+ "/project/node_modules/three/src/core/BufferAttribute.js",
+ "/project/node_modules/three/src/core/Raycaster.js",
+ "/project/node_modules/three/src/core/InstancedInterleavedBuffer.js",
+ "/project/node_modules/three/src/core/InterleavedBufferAttribute.js",
+ "/project/node_modules/three/src/core/EventDispatcher.js",
+ "/project/node_modules/three/src/core/InstancedBufferGeometry.js",
+ "/project/node_modules/three/src/core/Layers.js",
+ "/project/node_modules/three/src/core/Uniform.js",
+ "/project/node_modules/three/src/core/BufferGeometry.js",
+ "/project/node_modules/three/src/core/DirectGeometry.js",
+ "/project/node_modules/three/src/core/Geometry.js",
+ "/project/node_modules/three/src/core/InterleavedBuffer.js",
+ "/project/node_modules/three/src/core/Object3D.js",
+ "/project/node_modules/three/src/Three.js",
+ "/project/node_modules/three/src/animation",
+ "/project/node_modules/three/src/animation/AnimationUtils.js",
+ "/project/node_modules/three/src/animation/PropertyBinding.js",
+ "/project/node_modules/three/src/animation/KeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks",
+ "/project/node_modules/three/src/animation/tracks/VectorKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/NumberKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/ColorKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/StringKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/QuaternionKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/BooleanKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/AnimationMixer.js",
+ "/project/node_modules/three/src/animation/PropertyMixer.js",
+ "/project/node_modules/three/src/animation/AnimationClip.js",
+ "/project/node_modules/three/src/animation/AnimationAction.js",
+ "/project/node_modules/three/src/animation/AnimationObjectGroup.js",
+ "/project/node_modules/three/src/objects",
+ "/project/node_modules/three/src/objects/Line.js",
+ "/project/node_modules/three/src/objects/Skeleton.js",
+ "/project/node_modules/three/src/objects/Mesh.js",
+ "/project/node_modules/three/src/objects/LensFlare.js",
+ "/project/node_modules/three/src/objects/Points.js",
+ "/project/node_modules/three/src/objects/LOD.js",
+ "/project/node_modules/three/src/objects/LineSegments.js",
+ "/project/node_modules/three/src/objects/Bone.js",
+ "/project/node_modules/three/src/objects/Sprite.js",
+ "/project/node_modules/three/src/objects/SkinnedMesh.js",
+ "/project/node_modules/three/src/objects/Group.js",
+ "/project/node_modules/three/src/cameras",
+ "/project/node_modules/three/src/cameras/CubeCamera.js",
+ "/project/node_modules/three/src/cameras/StereoCamera.js",
+ "/project/node_modules/three/src/cameras/PerspectiveCamera.js",
+ "/project/node_modules/three/src/cameras/Camera.js",
+ "/project/node_modules/three/src/cameras/OrthographicCamera.js",
+ "/project/node_modules/three/src/math",
+ "/project/node_modules/three/src/math/Vector2.js",
+ "/project/node_modules/three/src/math/Quaternion.js",
+ "/project/node_modules/three/src/math/Matrix3.js",
+ "/project/node_modules/three/src/math/Vector3.js",
+ "/project/node_modules/three/src/math/Ray.js",
+ "/project/node_modules/three/src/math/Spline.js",
+ "/project/node_modules/three/src/math/Color.js",
+ "/project/node_modules/three/src/math/Box3.js",
+ "/project/node_modules/three/src/math/Math.js",
+ "/project/node_modules/three/src/math/Euler.js",
+ "/project/node_modules/three/src/math/Frustum.js",
+ "/project/node_modules/three/src/math/Plane.js",
+ "/project/node_modules/three/src/math/Sphere.js",
+ "/project/node_modules/three/src/math/Interpolant.js",
+ "/project/node_modules/three/src/math/Box2.js",
+ "/project/node_modules/three/src/math/Line3.js",
+ "/project/node_modules/three/src/math/interpolants",
+ "/project/node_modules/three/src/math/interpolants/QuaternionLinearInterpolant.js",
+ "/project/node_modules/three/src/math/interpolants/LinearInterpolant.js",
+ "/project/node_modules/three/src/math/interpolants/DiscreteInterpolant.js",
+ "/project/node_modules/three/src/math/interpolants/CubicInterpolant.js",
+ "/project/node_modules/three/src/math/Vector4.js",
+ "/project/node_modules/three/src/math/Matrix4.js",
+ "/project/node_modules/three/src/math/Spherical.js",
+ "/project/node_modules/three/src/math/Triangle.js",
+ "/project/node_modules/three/src/audio",
+ "/project/node_modules/three/src/audio/AudioContext.js",
+ "/project/node_modules/three/src/audio/AudioAnalyser.js",
+ "/project/node_modules/three/src/audio/AudioListener.js",
+ "/project/node_modules/three/src/audio/PositionalAudio.js",
+ "/project/node_modules/three/src/audio/Audio.js",
+ "/project/node_modules/three/src/Three.Legacy.js",
+ "/project/node_modules/three/src/loaders",
+ "/project/node_modules/three/src/loaders/ImageLoader.js",
+ "/project/node_modules/three/src/loaders/FontLoader.js",
+ "/project/node_modules/three/src/loaders/AnimationLoader.js",
+ "/project/node_modules/three/src/loaders/Cache.js",
+ "/project/node_modules/three/src/loaders/MaterialLoader.js",
+ "/project/node_modules/three/src/loaders/TextureLoader.js",
+ "/project/node_modules/three/src/loaders/LoadingManager.js",
+ "/project/node_modules/three/src/loaders/ObjectLoader.js",
+ "/project/node_modules/three/src/loaders/XHRLoader.js",
+ "/project/node_modules/three/src/loaders/CubeTextureLoader.js",
+ "/project/node_modules/three/src/loaders/AudioLoader.js",
+ "/project/node_modules/three/src/loaders/BufferGeometryLoader.js",
+ "/project/node_modules/three/src/loaders/CompressedTextureLoader.js",
+ "/project/node_modules/three/src/loaders/JSONLoader.js",
+ "/project/node_modules/three/src/loaders/BinaryTextureLoader.js",
+ "/project/node_modules/three/src/loaders/Loader.js",
+ "/project/node_modules/three/src/lights",
+ "/project/node_modules/three/src/lights/DirectionalLight.js",
+ "/project/node_modules/three/src/lights/SpotLightShadow.js",
+ "/project/node_modules/three/src/lights/AmbientLight.js",
+ "/project/node_modules/three/src/lights/SpotLight.js",
+ "/project/node_modules/three/src/lights/HemisphereLight.js",
+ "/project/node_modules/three/src/lights/Light.js",
+ "/project/node_modules/three/src/lights/DirectionalLightShadow.js",
+ "/project/node_modules/three/src/lights/LightShadow.js",
+ "/project/node_modules/three/src/lights/PointLight.js",
+ "/project/node_modules/three/src/extras",
+ "/project/node_modules/three/src/extras/SceneUtils.js",
+ "/project/node_modules/three/src/extras/core",
+ "/project/node_modules/three/src/extras/core/Font.js",
+ "/project/node_modules/three/src/extras/core/Path.js",
+ "/project/node_modules/three/src/extras/core/CurvePath.js",
+ "/project/node_modules/three/src/extras/core/Curve.js",
+ "/project/node_modules/three/src/extras/core/Shape.js",
+ "/project/node_modules/three/src/extras/ShapeUtils.js",
+ "/project/node_modules/three/src/extras/objects",
+ "/project/node_modules/three/src/extras/objects/MorphBlendMesh.js",
+ "/project/node_modules/three/src/extras/objects/ImmediateRenderObject.js",
+ "/project/node_modules/three/src/extras/geometries",
+ "/project/node_modules/three/src/extras/geometries/TextGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/WireframeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/PlaneGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/DodecahedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CircleBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ParametricGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/SphereBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/RingBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/BoxGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/EdgesGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TetrahedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/RingGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ConeBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/LatheBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/LatheGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/SphereGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/IcosahedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CircleGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ShapeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/PlaneBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusKnotBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/BoxBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CylinderGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ExtrudeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ConeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusKnotGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TubeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CylinderBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/PolyhedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/OctahedronGeometry.js",
+ "/project/node_modules/three/src/extras/CurveUtils.js",
+ "/project/node_modules/three/src/extras/helpers",
+ "/project/node_modules/three/src/extras/helpers/WireframeHelper.js",
+ "/project/node_modules/three/src/extras/helpers/ArrowHelper.js",
+ "/project/node_modules/three/src/extras/helpers/SkeletonHelper.js",
+ "/project/node_modules/three/src/extras/helpers/PointLightHelper.js",
+ "/project/node_modules/three/src/extras/helpers/AxisHelper.js",
+ "/project/node_modules/three/src/extras/helpers/SpotLightHelper.js",
+ "/project/node_modules/three/src/extras/helpers/CameraHelper.js",
+ "/project/node_modules/three/src/extras/helpers/BoxHelper.js",
+ "/project/node_modules/three/src/extras/helpers/VertexNormalsHelper.js",
+ "/project/node_modules/three/src/extras/helpers/BoundingBoxHelper.js",
+ "/project/node_modules/three/src/extras/helpers/EdgesHelper.js",
+ "/project/node_modules/three/src/extras/helpers/FaceNormalsHelper.js",
+ "/project/node_modules/three/src/extras/helpers/GridHelper.js",
+ "/project/node_modules/three/src/extras/helpers/HemisphereLightHelper.js",
+ "/project/node_modules/three/src/extras/helpers/DirectionalLightHelper.js",
+ "/project/node_modules/three/src/extras/curves",
+ "/project/node_modules/three/src/extras/curves/CubicBezierCurve.js",
+ "/project/node_modules/three/src/extras/curves/EllipseCurve.js",
+ "/project/node_modules/three/src/extras/curves/LineCurve3.js",
+ "/project/node_modules/three/src/extras/curves/SplineCurve3.js",
+ "/project/node_modules/three/src/extras/curves/ArcCurve.js",
+ "/project/node_modules/three/src/extras/curves/ClosedSplineCurve3.js",
+ "/project/node_modules/three/src/extras/curves/CubicBezierCurve3.js",
+ "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve3.js",
+ "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve.js",
+ "/project/node_modules/three/src/extras/curves/LineCurve.js",
+ "/project/node_modules/three/src/extras/curves/CatmullRomCurve3.js",
+ "/project/node_modules/three/src/extras/curves/SplineCurve.js",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/normal_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/shadow_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshbasic_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshlambert_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/points_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/equirect_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/cube_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphysical_vert.glsl",
+ "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphong_frag.glsl",
+ "/project/node_modules/three/src/renderers/shaders/UniformsLib.js",
+ "/project/node_modules/three/src/renderers/WebGLRenderer.js",
+ "/project/node_modules/three/src/renderers/WebGLRenderTarget.js",
+ "/project/node_modules/three/src/textures",
+ "/project/node_modules/three/src/textures/DepthTexture.js",
+ "/project/node_modules/three/src/textures/CompressedTexture.js",
+ "/project/node_modules/three/src/textures/VideoTexture.js",
+ "/project/node_modules/three/src/textures/CubeTexture.js",
+ "/project/node_modules/three/src/textures/CanvasTexture.js",
+ "/project/node_modules/three/src/textures/Texture.js",
+ "/project/node_modules/three/src/textures/DataTexture.js",
+ "/project/node_modules/three/src/scenes",
+ "/project/node_modules/three/src/scenes/Fog.js",
+ "/project/node_modules/three/src/scenes/Scene.js",
+ "/project/node_modules/three/src/scenes/FogExp2.js",
+ "/project/node_modules/three/src/materials",
+ "/project/node_modules/three/src/materials/MultiMaterial.js",
+ "/project/node_modules/three/src/materials/LineDashedMaterial.js",
+ "/project/node_modules/three/src/materials/LineBasicMaterial.js",
+ "/project/node_modules/three/src/materials/MeshNormalMaterial.js",
+ "/project/node_modules/three/src/materials/Material.js",
+ "/project/node_modules/three/src/materials/MeshPhysicalMaterial.js",
+ "/project/node_modules/three/src/materials/MeshBasicMaterial.js",
+ "/project/node_modules/three/src/materials/MeshStandardMaterial.js",
+ "/project/node_modules/three/src/materials/MeshPhongMaterial.js",
+ "/project/node_modules/three/src/materials/SpriteMaterial.js",
+ "/project/node_modules/three/src/materials/MeshDepthMaterial.js",
+ "/project/node_modules/three/src/materials/ShadowMaterial.js",
+ "/project/node_modules/three/src/materials/PointsMaterial.js",
+ "/project/node_modules/three/src/materials/ShaderMaterial.js",
+ "/project/node_modules/three/src/materials/MeshLambertMaterial.js",
+ "/project/node_modules/three/src/materials/RawShaderMaterial.js",
+ "/project/node_modules/three/src/core",
+ "/project/node_modules/three/src/core/InstancedBufferAttribute.js",
+ "/project/node_modules/three/src/core/Face3.js",
+ "/project/node_modules/three/src/core/Clock.js",
+ "/project/node_modules/three/src/core/BufferAttribute.js",
+ "/project/node_modules/three/src/core/Raycaster.js",
+ "/project/node_modules/three/src/core/InstancedInterleavedBuffer.js",
+ "/project/node_modules/three/src/core/InterleavedBufferAttribute.js",
+ "/project/node_modules/three/src/core/EventDispatcher.js",
+ "/project/node_modules/three/src/core/InstancedBufferGeometry.js",
+ "/project/node_modules/three/src/core/Layers.js",
+ "/project/node_modules/three/src/core/Uniform.js",
+ "/project/node_modules/three/src/core/BufferGeometry.js",
+ "/project/node_modules/three/src/core/DirectGeometry.js",
+ "/project/node_modules/three/src/core/Geometry.js",
+ "/project/node_modules/three/src/core/InterleavedBuffer.js",
+ "/project/node_modules/three/src/core/Object3D.js",
+ "/project/node_modules/three/src/Three.js",
+ "/project/node_modules/three/src/animation",
+ "/project/node_modules/three/src/animation/AnimationUtils.js",
+ "/project/node_modules/three/src/animation/PropertyBinding.js",
+ "/project/node_modules/three/src/animation/KeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks",
+ "/project/node_modules/three/src/animation/tracks/VectorKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/NumberKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/ColorKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/StringKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/QuaternionKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/tracks/BooleanKeyframeTrack.js",
+ "/project/node_modules/three/src/animation/AnimationMixer.js",
+ "/project/node_modules/three/src/animation/PropertyMixer.js",
+ "/project/node_modules/three/src/animation/AnimationClip.js",
+ "/project/node_modules/three/src/animation/AnimationAction.js",
+ "/project/node_modules/three/src/animation/AnimationObjectGroup.js",
+ "/project/node_modules/three/src/objects",
+ "/project/node_modules/three/src/objects/Line.js",
+ "/project/node_modules/three/src/objects/Skeleton.js",
+ "/project/node_modules/three/src/objects/Mesh.js",
+ "/project/node_modules/three/src/objects/LensFlare.js",
+ "/project/node_modules/three/src/objects/Points.js",
+ "/project/node_modules/three/src/objects/LOD.js",
+ "/project/node_modules/three/src/objects/LineSegments.js",
+ "/project/node_modules/three/src/objects/Bone.js",
+ "/project/node_modules/three/src/objects/Sprite.js",
+ "/project/node_modules/three/src/objects/SkinnedMesh.js",
+ "/project/node_modules/three/src/objects/Group.js",
+ "/project/node_modules/three/src/cameras",
+ "/project/node_modules/three/src/cameras/CubeCamera.js",
+ "/project/node_modules/three/src/cameras/StereoCamera.js",
+ "/project/node_modules/three/src/cameras/PerspectiveCamera.js",
+ "/project/node_modules/three/src/cameras/Camera.js",
+ "/project/node_modules/three/src/cameras/OrthographicCamera.js",
+ "/project/node_modules/three/src/math",
+ "/project/node_modules/three/src/math/Vector2.js",
+ "/project/node_modules/three/src/math/Quaternion.js",
+ "/project/node_modules/three/src/math/Matrix3.js",
+ "/project/node_modules/three/src/math/Vector3.js",
+ "/project/node_modules/three/src/math/Ray.js",
+ "/project/node_modules/three/src/math/Spline.js",
+ "/project/node_modules/three/src/math/Color.js",
+ "/project/node_modules/three/src/math/Box3.js",
+ "/project/node_modules/three/src/math/Math.js",
+ "/project/node_modules/three/src/math/Euler.js",
+ "/project/node_modules/three/src/math/Frustum.js",
+ "/project/node_modules/three/src/math/Plane.js",
+ "/project/node_modules/three/src/math/Sphere.js",
+ "/project/node_modules/three/src/math/Interpolant.js",
+ "/project/node_modules/three/src/math/Box2.js",
+ "/project/node_modules/three/src/math/Line3.js",
+ "/project/node_modules/three/src/math/interpolants",
+ "/project/node_modules/three/src/math/interpolants/QuaternionLinearInterpolant.js",
+ "/project/node_modules/three/src/math/interpolants/LinearInterpolant.js",
+ "/project/node_modules/three/src/math/interpolants/DiscreteInterpolant.js",
+ "/project/node_modules/three/src/math/interpolants/CubicInterpolant.js",
+ "/project/node_modules/three/src/math/Vector4.js",
+ "/project/node_modules/three/src/math/Matrix4.js",
+ "/project/node_modules/three/src/math/Spherical.js",
+ "/project/node_modules/three/src/math/Triangle.js",
+ "/project/node_modules/three/src/audio",
+ "/project/node_modules/three/src/audio/AudioContext.js",
+ "/project/node_modules/three/src/audio/AudioAnalyser.js",
+ "/project/node_modules/three/src/audio/AudioListener.js",
+ "/project/node_modules/three/src/audio/PositionalAudio.js",
+ "/project/node_modules/three/src/audio/Audio.js",
+ "/project/node_modules/three/src/Three.Legacy.js",
+ "/project/node_modules/three/src/loaders",
+ "/project/node_modules/three/src/loaders/ImageLoader.js",
+ "/project/node_modules/three/src/loaders/FontLoader.js",
+ "/project/node_modules/three/src/loaders/AnimationLoader.js",
+ "/project/node_modules/three/src/loaders/Cache.js",
+ "/project/node_modules/three/src/loaders/MaterialLoader.js",
+ "/project/node_modules/three/src/loaders/TextureLoader.js",
+ "/project/node_modules/three/src/loaders/LoadingManager.js",
+ "/project/node_modules/three/src/loaders/ObjectLoader.js",
+ "/project/node_modules/three/src/loaders/XHRLoader.js",
+ "/project/node_modules/three/src/loaders/CubeTextureLoader.js",
+ "/project/node_modules/three/src/loaders/AudioLoader.js",
+ "/project/node_modules/three/src/loaders/BufferGeometryLoader.js",
+ "/project/node_modules/three/src/loaders/CompressedTextureLoader.js",
+ "/project/node_modules/three/src/loaders/JSONLoader.js",
+ "/project/node_modules/three/src/loaders/BinaryTextureLoader.js",
+ "/project/node_modules/three/src/loaders/Loader.js",
+ "/project/node_modules/three/src/lights",
+ "/project/node_modules/three/src/lights/DirectionalLight.js",
+ "/project/node_modules/three/src/lights/SpotLightShadow.js",
+ "/project/node_modules/three/src/lights/AmbientLight.js",
+ "/project/node_modules/three/src/lights/SpotLight.js",
+ "/project/node_modules/three/src/lights/HemisphereLight.js",
+ "/project/node_modules/three/src/lights/Light.js",
+ "/project/node_modules/three/src/lights/DirectionalLightShadow.js",
+ "/project/node_modules/three/src/lights/LightShadow.js",
+ "/project/node_modules/three/src/lights/PointLight.js",
+ "/project/node_modules/three/src/extras",
+ "/project/node_modules/three/src/extras/SceneUtils.js",
+ "/project/node_modules/three/src/extras/core",
+ "/project/node_modules/three/src/extras/core/Font.js",
+ "/project/node_modules/three/src/extras/core/Path.js",
+ "/project/node_modules/three/src/extras/core/CurvePath.js",
+ "/project/node_modules/three/src/extras/core/Curve.js",
+ "/project/node_modules/three/src/extras/core/Shape.js",
+ "/project/node_modules/three/src/extras/ShapeUtils.js",
+ "/project/node_modules/three/src/extras/objects",
+ "/project/node_modules/three/src/extras/objects/MorphBlendMesh.js",
+ "/project/node_modules/three/src/extras/objects/ImmediateRenderObject.js",
+ "/project/node_modules/three/src/extras/geometries",
+ "/project/node_modules/three/src/extras/geometries/TextGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/WireframeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/PlaneGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/DodecahedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CircleBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ParametricGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/SphereBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/RingBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/BoxGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/EdgesGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TetrahedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/RingGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ConeBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/LatheBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/LatheGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/SphereGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/IcosahedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CircleGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ShapeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/PlaneBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusKnotBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/BoxBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CylinderGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ExtrudeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/ConeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TorusKnotGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/TubeGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/CylinderBufferGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/PolyhedronGeometry.js",
+ "/project/node_modules/three/src/extras/geometries/OctahedronGeometry.js",
+ "/project/node_modules/three/src/extras/CurveUtils.js",
+ "/project/node_modules/three/src/extras/helpers",
+ "/project/node_modules/three/src/extras/helpers/WireframeHelper.js",
+ "/project/node_modules/three/src/extras/helpers/ArrowHelper.js",
+ "/project/node_modules/three/src/extras/helpers/SkeletonHelper.js",
+ "/project/node_modules/three/src/extras/helpers/PointLightHelper.js",
+ "/project/node_modules/three/src/extras/helpers/AxisHelper.js",
+ "/project/node_modules/three/src/extras/helpers/SpotLightHelper.js",
+ "/project/node_modules/three/src/extras/helpers/CameraHelper.js",
+ "/project/node_modules/three/src/extras/helpers/BoxHelper.js",
+ "/project/node_modules/three/src/extras/helpers/VertexNormalsHelper.js",
+ "/project/node_modules/three/src/extras/helpers/BoundingBoxHelper.js",
+ "/project/node_modules/three/src/extras/helpers/EdgesHelper.js",
+ "/project/node_modules/three/src/extras/helpers/FaceNormalsHelper.js",
+ "/project/node_modules/three/src/extras/helpers/GridHelper.js",
+ "/project/node_modules/three/src/extras/helpers/HemisphereLightHelper.js",
+ "/project/node_modules/three/src/extras/helpers/DirectionalLightHelper.js",
+ "/project/node_modules/three/src/extras/curves",
+ "/project/node_modules/three/src/extras/curves/CubicBezierCurve.js",
+ "/project/node_modules/three/src/extras/curves/EllipseCurve.js",
+ "/project/node_modules/three/src/extras/curves/LineCurve3.js",
+ "/project/node_modules/three/src/extras/curves/SplineCurve3.js",
+ "/project/node_modules/three/src/extras/curves/ArcCurve.js",
+ "/project/node_modules/three/src/extras/curves/ClosedSplineCurve3.js",
+ "/project/node_modules/three/src/extras/curves/CubicBezierCurve3.js",
+ "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve3.js",
+ "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve.js",
+ "/project/node_modules/three/src/extras/curves/LineCurve.js",
+ "/project/node_modules/three/src/extras/curves/CatmullRomCurve3.js",
+ "/project/node_modules/three/src/extras/curves/SplineCurve.js",
+};