diff --git a/third_party/flatbuffers/js/README.md b/third_party/flatbuffers/js/README.md
new file mode 100644
index 0000000..cbcebe0
--- /dev/null
+++ b/third_party/flatbuffers/js/README.md
@@ -0,0 +1 @@
+This folder is intentionally empty and will contain transpiled js modules in Common JS format after compiling with tsc.
\ No newline at end of file
diff --git a/third_party/flatbuffers/js/builder.js b/third_party/flatbuffers/js/builder.js
new file mode 100644
index 0000000..dce81e5
--- /dev/null
+++ b/third_party/flatbuffers/js/builder.js
@@ -0,0 +1,562 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Builder = void 0;
+var byte_buffer_1 = require("./byte-buffer");
+var constants_1 = require("./constants");
+var long_1 = require("./long");
+var Builder = /** @class */ (function () {
+    /**
+     * Create a FlatBufferBuilder.
+     */
+    function Builder(opt_initial_size) {
+        /** Minimum alignment encountered so far. */
+        this.minalign = 1;
+        /** The vtable for the current table. */
+        this.vtable = null;
+        /** The amount of fields we're actually using. */
+        this.vtable_in_use = 0;
+        /** Whether we are currently serializing a table. */
+        this.isNested = false;
+        /** Starting offset of the current struct/table. */
+        this.object_start = 0;
+        /** List of offsets of all vtables. */
+        this.vtables = [];
+        /** For the current vector being built. */
+        this.vector_num_elems = 0;
+        /** False omits default values from the serialized data */
+        this.force_defaults = false;
+        this.string_maps = null;
+        var initial_size;
+        if (!opt_initial_size) {
+            initial_size = 1024;
+        }
+        else {
+            initial_size = opt_initial_size;
+        }
+        /**
+         * @type {ByteBuffer}
+         * @private
+         */
+        this.bb = byte_buffer_1.ByteBuffer.allocate(initial_size);
+        this.space = initial_size;
+    }
+    Builder.prototype.clear = function () {
+        this.bb.clear();
+        this.space = this.bb.capacity();
+        this.minalign = 1;
+        this.vtable = null;
+        this.vtable_in_use = 0;
+        this.isNested = false;
+        this.object_start = 0;
+        this.vtables = [];
+        this.vector_num_elems = 0;
+        this.force_defaults = false;
+        this.string_maps = null;
+    };
+    /**
+     * In order to save space, fields that are set to their default value
+     * don't get serialized into the buffer. Forcing defaults provides a
+     * way to manually disable this optimization.
+     *
+     * @param forceDefaults true always serializes default values
+     */
+    Builder.prototype.forceDefaults = function (forceDefaults) {
+        this.force_defaults = forceDefaults;
+    };
+    /**
+     * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
+     * called finish(). The actual data starts at the ByteBuffer's current position,
+     * not necessarily at 0.
+     */
+    Builder.prototype.dataBuffer = function () {
+        return this.bb;
+    };
+    /**
+     * Get the bytes representing the FlatBuffer. Only call this after you've
+     * called finish().
+     */
+    Builder.prototype.asUint8Array = function () {
+        return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
+    };
+    /**
+     * Prepare to write an element of `size` after `additional_bytes` have been
+     * written, e.g. if you write a string, you need to align such the int length
+     * field is aligned to 4 bytes, and the string data follows it directly. If all
+     * you need to do is alignment, `additional_bytes` will be 0.
+     *
+     * @param size This is the of the new element to write
+     * @param additional_bytes The padding size
+     */
+    Builder.prototype.prep = function (size, additional_bytes) {
+        // Track the biggest thing we've ever aligned to.
+        if (size > this.minalign) {
+            this.minalign = size;
+        }
+        // Find the amount of alignment needed such that `size` is properly
+        // aligned after `additional_bytes`
+        var align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1);
+        // Reallocate the buffer if needed.
+        while (this.space < align_size + size + additional_bytes) {
+            var old_buf_size = this.bb.capacity();
+            this.bb = Builder.growByteBuffer(this.bb);
+            this.space += this.bb.capacity() - old_buf_size;
+        }
+        this.pad(align_size);
+    };
+    Builder.prototype.pad = function (byte_size) {
+        for (var i = 0; i < byte_size; i++) {
+            this.bb.writeInt8(--this.space, 0);
+        }
+    };
+    Builder.prototype.writeInt8 = function (value) {
+        this.bb.writeInt8(this.space -= 1, value);
+    };
+    Builder.prototype.writeInt16 = function (value) {
+        this.bb.writeInt16(this.space -= 2, value);
+    };
+    Builder.prototype.writeInt32 = function (value) {
+        this.bb.writeInt32(this.space -= 4, value);
+    };
+    Builder.prototype.writeInt64 = function (value) {
+        this.bb.writeInt64(this.space -= 8, value);
+    };
+    Builder.prototype.writeFloat32 = function (value) {
+        this.bb.writeFloat32(this.space -= 4, value);
+    };
+    Builder.prototype.writeFloat64 = function (value) {
+        this.bb.writeFloat64(this.space -= 8, value);
+    };
+    /**
+     * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int8` to add the the buffer.
+     */
+    Builder.prototype.addInt8 = function (value) {
+        this.prep(1, 0);
+        this.writeInt8(value);
+    };
+    /**
+     * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int16` to add the the buffer.
+     */
+    Builder.prototype.addInt16 = function (value) {
+        this.prep(2, 0);
+        this.writeInt16(value);
+    };
+    /**
+     * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int32` to add the the buffer.
+     */
+    Builder.prototype.addInt32 = function (value) {
+        this.prep(4, 0);
+        this.writeInt32(value);
+    };
+    /**
+     * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `int64` to add the the buffer.
+     */
+    Builder.prototype.addInt64 = function (value) {
+        this.prep(8, 0);
+        this.writeInt64(value);
+    };
+    /**
+     * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `float32` to add the the buffer.
+     */
+    Builder.prototype.addFloat32 = function (value) {
+        this.prep(4, 0);
+        this.writeFloat32(value);
+    };
+    /**
+     * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
+     * @param value The `float64` to add the the buffer.
+     */
+    Builder.prototype.addFloat64 = function (value) {
+        this.prep(8, 0);
+        this.writeFloat64(value);
+    };
+    Builder.prototype.addFieldInt8 = function (voffset, value, defaultValue) {
+        if (this.force_defaults || value != defaultValue) {
+            this.addInt8(value);
+            this.slot(voffset);
+        }
+    };
+    Builder.prototype.addFieldInt16 = function (voffset, value, defaultValue) {
+        if (this.force_defaults || value != defaultValue) {
+            this.addInt16(value);
+            this.slot(voffset);
+        }
+    };
+    Builder.prototype.addFieldInt32 = function (voffset, value, defaultValue) {
+        if (this.force_defaults || value != defaultValue) {
+            this.addInt32(value);
+            this.slot(voffset);
+        }
+    };
+    Builder.prototype.addFieldInt64 = function (voffset, value, defaultValue) {
+        if (this.force_defaults || !value.equals(defaultValue)) {
+            this.addInt64(value);
+            this.slot(voffset);
+        }
+    };
+    Builder.prototype.addFieldFloat32 = function (voffset, value, defaultValue) {
+        if (this.force_defaults || value != defaultValue) {
+            this.addFloat32(value);
+            this.slot(voffset);
+        }
+    };
+    Builder.prototype.addFieldFloat64 = function (voffset, value, defaultValue) {
+        if (this.force_defaults || value != defaultValue) {
+            this.addFloat64(value);
+            this.slot(voffset);
+        }
+    };
+    Builder.prototype.addFieldOffset = function (voffset, value, defaultValue) {
+        if (this.force_defaults || value != defaultValue) {
+            this.addOffset(value);
+            this.slot(voffset);
+        }
+    };
+    /**
+     * Structs are stored inline, so nothing additional is being added. `d` is always 0.
+     */
+    Builder.prototype.addFieldStruct = function (voffset, value, defaultValue) {
+        if (value != defaultValue) {
+            this.nested(value);
+            this.slot(voffset);
+        }
+    };
+    /**
+     * Structures are always stored inline, they need to be created right
+     * where they're used.  You'll get this assertion failure if you
+     * created it elsewhere.
+     */
+    Builder.prototype.nested = function (obj) {
+        if (obj != this.offset()) {
+            throw new Error('FlatBuffers: struct must be serialized inline.');
+        }
+    };
+    /**
+     * Should not be creating any other object, string or vector
+     * while an object is being constructed
+     */
+    Builder.prototype.notNested = function () {
+        if (this.isNested) {
+            throw new Error('FlatBuffers: object serialization must not be nested.');
+        }
+    };
+    /**
+     * Set the current vtable at `voffset` to the current location in the buffer.
+     */
+    Builder.prototype.slot = function (voffset) {
+        if (this.vtable !== null)
+            this.vtable[voffset] = this.offset();
+    };
+    /**
+     * @returns Offset relative to the end of the buffer.
+     */
+    Builder.prototype.offset = function () {
+        return this.bb.capacity() - this.space;
+    };
+    /**
+     * Doubles the size of the backing ByteBuffer and copies the old data towards
+     * the end of the new buffer (since we build the buffer backwards).
+     *
+     * @param bb The current buffer with the existing data
+     * @returns A new byte buffer with the old data copied
+     * to it. The data is located at the end of the buffer.
+     *
+     * uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
+     * it a uint8Array we need to suppress the type check:
+     * @suppress {checkTypes}
+     */
+    Builder.growByteBuffer = function (bb) {
+        var old_buf_size = bb.capacity();
+        // Ensure we don't grow beyond what fits in an int.
+        if (old_buf_size & 0xC0000000) {
+            throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.');
+        }
+        var new_buf_size = old_buf_size << 1;
+        var nbb = byte_buffer_1.ByteBuffer.allocate(new_buf_size);
+        nbb.setPosition(new_buf_size - old_buf_size);
+        nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
+        return nbb;
+    };
+    /**
+     * Adds on offset, relative to where it will be written.
+     *
+     * @param offset The offset to add.
+     */
+    Builder.prototype.addOffset = function (offset) {
+        this.prep(constants_1.SIZEOF_INT, 0); // Ensure alignment is already done.
+        this.writeInt32(this.offset() - offset + constants_1.SIZEOF_INT);
+    };
+    /**
+     * Start encoding a new object in the buffer.  Users will not usually need to
+     * call this directly. The FlatBuffers compiler will generate helper methods
+     * that call this method internally.
+     */
+    Builder.prototype.startObject = function (numfields) {
+        this.notNested();
+        if (this.vtable == null) {
+            this.vtable = [];
+        }
+        this.vtable_in_use = numfields;
+        for (var i = 0; i < numfields; i++) {
+            this.vtable[i] = 0; // This will push additional elements as needed
+        }
+        this.isNested = true;
+        this.object_start = this.offset();
+    };
+    /**
+     * Finish off writing the object that is under construction.
+     *
+     * @returns The offset to the object inside `dataBuffer`
+     */
+    Builder.prototype.endObject = function () {
+        if (this.vtable == null || !this.isNested) {
+            throw new Error('FlatBuffers: endObject called without startObject');
+        }
+        this.addInt32(0);
+        var vtableloc = this.offset();
+        // Trim trailing zeroes.
+        var i = this.vtable_in_use - 1;
+        // eslint-disable-next-line no-empty
+        for (; i >= 0 && this.vtable[i] == 0; i--) { }
+        var trimmed_size = i + 1;
+        // Write out the current vtable.
+        for (; i >= 0; i--) {
+            // Offset relative to the start of the table.
+            this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
+        }
+        var standard_fields = 2; // The fields below:
+        this.addInt16(vtableloc - this.object_start);
+        var len = (trimmed_size + standard_fields) * constants_1.SIZEOF_SHORT;
+        this.addInt16(len);
+        // Search for an existing vtable that matches the current one.
+        var existing_vtable = 0;
+        var vt1 = this.space;
+        outer_loop: for (i = 0; i < this.vtables.length; i++) {
+            var vt2 = this.bb.capacity() - this.vtables[i];
+            if (len == this.bb.readInt16(vt2)) {
+                for (var j = constants_1.SIZEOF_SHORT; j < len; j += constants_1.SIZEOF_SHORT) {
+                    if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
+                        continue outer_loop;
+                    }
+                }
+                existing_vtable = this.vtables[i];
+                break;
+            }
+        }
+        if (existing_vtable) {
+            // Found a match:
+            // Remove the current vtable.
+            this.space = this.bb.capacity() - vtableloc;
+            // Point table to existing vtable.
+            this.bb.writeInt32(this.space, existing_vtable - vtableloc);
+        }
+        else {
+            // No match:
+            // Add the location of the current vtable to the list of vtables.
+            this.vtables.push(this.offset());
+            // Point table to current vtable.
+            this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc);
+        }
+        this.isNested = false;
+        return vtableloc;
+    };
+    /**
+     * Finalize a buffer, poiting to the given `root_table`.
+     */
+    Builder.prototype.finish = function (root_table, opt_file_identifier, opt_size_prefix) {
+        var size_prefix = opt_size_prefix ? constants_1.SIZE_PREFIX_LENGTH : 0;
+        if (opt_file_identifier) {
+            var file_identifier = opt_file_identifier;
+            this.prep(this.minalign, constants_1.SIZEOF_INT +
+                constants_1.FILE_IDENTIFIER_LENGTH + size_prefix);
+            if (file_identifier.length != constants_1.FILE_IDENTIFIER_LENGTH) {
+                throw new Error('FlatBuffers: file identifier must be length ' +
+                    constants_1.FILE_IDENTIFIER_LENGTH);
+            }
+            for (var i = constants_1.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
+                this.writeInt8(file_identifier.charCodeAt(i));
+            }
+        }
+        this.prep(this.minalign, constants_1.SIZEOF_INT + size_prefix);
+        this.addOffset(root_table);
+        if (size_prefix) {
+            this.addInt32(this.bb.capacity() - this.space);
+        }
+        this.bb.setPosition(this.space);
+    };
+    /**
+     * Finalize a size prefixed buffer, pointing to the given `root_table`.
+     */
+    Builder.prototype.finishSizePrefixed = function (root_table, opt_file_identifier) {
+        this.finish(root_table, opt_file_identifier, true);
+    };
+    /**
+     * This checks a required field has been set in a given table that has
+     * just been constructed.
+     */
+    Builder.prototype.requiredField = function (table, field) {
+        var table_start = this.bb.capacity() - table;
+        var vtable_start = table_start - this.bb.readInt32(table_start);
+        var ok = this.bb.readInt16(vtable_start + field) != 0;
+        // If this fails, the caller will show what field needs to be set.
+        if (!ok) {
+            throw new Error('FlatBuffers: field ' + field + ' must be set');
+        }
+    };
+    /**
+     * Start a new array/vector of objects.  Users usually will not call
+     * this directly. The FlatBuffers compiler will create a start/end
+     * method for vector types in generated code.
+     *
+     * @param elem_size The size of each element in the array
+     * @param num_elems The number of elements in the array
+     * @param alignment The alignment of the array
+     */
+    Builder.prototype.startVector = function (elem_size, num_elems, alignment) {
+        this.notNested();
+        this.vector_num_elems = num_elems;
+        this.prep(constants_1.SIZEOF_INT, elem_size * num_elems);
+        this.prep(alignment, elem_size * num_elems); // Just in case alignment > int.
+    };
+    /**
+     * Finish off the creation of an array and all its elements. The array must be
+     * created with `startVector`.
+     *
+     * @returns The offset at which the newly created array
+     * starts.
+     */
+    Builder.prototype.endVector = function () {
+        this.writeInt32(this.vector_num_elems);
+        return this.offset();
+    };
+    /**
+     * Encode the string `s` in the buffer using UTF-8. If the string passed has
+     * already been seen, we return the offset of the already written string
+     *
+     * @param s The string to encode
+     * @return The offset in the buffer where the encoded string starts
+     */
+    Builder.prototype.createSharedString = function (s) {
+        if (!s) {
+            return 0;
+        }
+        if (!this.string_maps) {
+            this.string_maps = new Map();
+        }
+        if (this.string_maps.has(s)) {
+            return this.string_maps.get(s);
+        }
+        var offset = this.createString(s);
+        this.string_maps.set(s, offset);
+        return offset;
+    };
+    /**
+     * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
+     * instead of a string, it is assumed to contain valid UTF-8 encoded data.
+     *
+     * @param s The string to encode
+     * @return The offset in the buffer where the encoded string starts
+     */
+    Builder.prototype.createString = function (s) {
+        if (!s) {
+            return 0;
+        }
+        var utf8;
+        if (s instanceof Uint8Array) {
+            utf8 = s;
+        }
+        else {
+            utf8 = [];
+            var i = 0;
+            while (i < s.length) {
+                var codePoint = void 0;
+                // Decode UTF-16
+                var a = s.charCodeAt(i++);
+                if (a < 0xD800 || a >= 0xDC00) {
+                    codePoint = a;
+                }
+                else {
+                    var b = s.charCodeAt(i++);
+                    codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00);
+                }
+                // Encode UTF-8
+                if (codePoint < 0x80) {
+                    utf8.push(codePoint);
+                }
+                else {
+                    if (codePoint < 0x800) {
+                        utf8.push(((codePoint >> 6) & 0x1F) | 0xC0);
+                    }
+                    else {
+                        if (codePoint < 0x10000) {
+                            utf8.push(((codePoint >> 12) & 0x0F) | 0xE0);
+                        }
+                        else {
+                            utf8.push(((codePoint >> 18) & 0x07) | 0xF0, ((codePoint >> 12) & 0x3F) | 0x80);
+                        }
+                        utf8.push(((codePoint >> 6) & 0x3F) | 0x80);
+                    }
+                    utf8.push((codePoint & 0x3F) | 0x80);
+                }
+            }
+        }
+        this.addInt8(0);
+        this.startVector(1, utf8.length, 1);
+        this.bb.setPosition(this.space -= utf8.length);
+        for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) {
+            bytes[offset++] = utf8[i];
+        }
+        return this.endVector();
+    };
+    /**
+     * A helper function to avoid generated code depending on this file directly.
+     */
+    Builder.prototype.createLong = function (low, high) {
+        return long_1.Long.create(low, high);
+    };
+    /**
+     * A helper function to pack an object
+     *
+     * @returns offset of obj
+     */
+    Builder.prototype.createObjectOffset = function (obj) {
+        if (obj === null) {
+            return 0;
+        }
+        if (typeof obj === 'string') {
+            return this.createString(obj);
+        }
+        else {
+            return obj.pack(this);
+        }
+    };
+    /**
+     * A helper function to pack a list of object
+     *
+     * @returns list of offsets of each non null object
+     */
+    Builder.prototype.createObjectOffsetList = function (list) {
+        var ret = [];
+        for (var i = 0; i < list.length; ++i) {
+            var val = list[i];
+            if (val !== null) {
+                ret.push(this.createObjectOffset(val));
+            }
+            else {
+                throw new Error('FlatBuffers: Argument for createObjectOffsetList cannot contain null.');
+            }
+        }
+        return ret;
+    };
+    Builder.prototype.createStructOffsetList = function (list, startFunc) {
+        startFunc(this, list.length);
+        this.createObjectOffsetList(list);
+        return this.endVector();
+    };
+    return Builder;
+}());
+exports.Builder = Builder;
diff --git a/third_party/flatbuffers/js/byte-buffer.js b/third_party/flatbuffers/js/byte-buffer.js
new file mode 100644
index 0000000..961c53d
--- /dev/null
+++ b/third_party/flatbuffers/js/byte-buffer.js
@@ -0,0 +1,306 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ByteBuffer = void 0;
+var constants_1 = require("./constants");
+var long_1 = require("./long");
+var utils_1 = require("./utils");
+var encoding_1 = require("./encoding");
+var ByteBuffer = /** @class */ (function () {
+    /**
+     * Create a new ByteBuffer with a given array of bytes (`Uint8Array`)
+     */
+    function ByteBuffer(bytes_) {
+        this.bytes_ = bytes_;
+        this.position_ = 0;
+    }
+    /**
+     * Create and allocate a new ByteBuffer with a given size.
+     */
+    ByteBuffer.allocate = function (byte_size) {
+        return new ByteBuffer(new Uint8Array(byte_size));
+    };
+    ByteBuffer.prototype.clear = function () {
+        this.position_ = 0;
+    };
+    /**
+     * Get the underlying `Uint8Array`.
+     */
+    ByteBuffer.prototype.bytes = function () {
+        return this.bytes_;
+    };
+    /**
+     * Get the buffer's position.
+     */
+    ByteBuffer.prototype.position = function () {
+        return this.position_;
+    };
+    /**
+     * Set the buffer's position.
+     */
+    ByteBuffer.prototype.setPosition = function (position) {
+        this.position_ = position;
+    };
+    /**
+     * Get the buffer's capacity.
+     */
+    ByteBuffer.prototype.capacity = function () {
+        return this.bytes_.length;
+    };
+    ByteBuffer.prototype.readInt8 = function (offset) {
+        return this.readUint8(offset) << 24 >> 24;
+    };
+    ByteBuffer.prototype.readUint8 = function (offset) {
+        return this.bytes_[offset];
+    };
+    ByteBuffer.prototype.readInt16 = function (offset) {
+        return this.readUint16(offset) << 16 >> 16;
+    };
+    ByteBuffer.prototype.readUint16 = function (offset) {
+        return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
+    };
+    ByteBuffer.prototype.readInt32 = function (offset) {
+        return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
+    };
+    ByteBuffer.prototype.readUint32 = function (offset) {
+        return this.readInt32(offset) >>> 0;
+    };
+    ByteBuffer.prototype.readInt64 = function (offset) {
+        return new long_1.Long(this.readInt32(offset), this.readInt32(offset + 4));
+    };
+    ByteBuffer.prototype.readUint64 = function (offset) {
+        return new long_1.Long(this.readUint32(offset), this.readUint32(offset + 4));
+    };
+    ByteBuffer.prototype.readFloat32 = function (offset) {
+        utils_1.int32[0] = this.readInt32(offset);
+        return utils_1.float32[0];
+    };
+    ByteBuffer.prototype.readFloat64 = function (offset) {
+        utils_1.int32[utils_1.isLittleEndian ? 0 : 1] = this.readInt32(offset);
+        utils_1.int32[utils_1.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
+        return utils_1.float64[0];
+    };
+    ByteBuffer.prototype.writeInt8 = function (offset, value) {
+        this.bytes_[offset] = value;
+    };
+    ByteBuffer.prototype.writeUint8 = function (offset, value) {
+        this.bytes_[offset] = value;
+    };
+    ByteBuffer.prototype.writeInt16 = function (offset, value) {
+        this.bytes_[offset] = value;
+        this.bytes_[offset + 1] = value >> 8;
+    };
+    ByteBuffer.prototype.writeUint16 = function (offset, value) {
+        this.bytes_[offset] = value;
+        this.bytes_[offset + 1] = value >> 8;
+    };
+    ByteBuffer.prototype.writeInt32 = function (offset, value) {
+        this.bytes_[offset] = value;
+        this.bytes_[offset + 1] = value >> 8;
+        this.bytes_[offset + 2] = value >> 16;
+        this.bytes_[offset + 3] = value >> 24;
+    };
+    ByteBuffer.prototype.writeUint32 = function (offset, value) {
+        this.bytes_[offset] = value;
+        this.bytes_[offset + 1] = value >> 8;
+        this.bytes_[offset + 2] = value >> 16;
+        this.bytes_[offset + 3] = value >> 24;
+    };
+    ByteBuffer.prototype.writeInt64 = function (offset, value) {
+        this.writeInt32(offset, value.low);
+        this.writeInt32(offset + 4, value.high);
+    };
+    ByteBuffer.prototype.writeUint64 = function (offset, value) {
+        this.writeUint32(offset, value.low);
+        this.writeUint32(offset + 4, value.high);
+    };
+    ByteBuffer.prototype.writeFloat32 = function (offset, value) {
+        utils_1.float32[0] = value;
+        this.writeInt32(offset, utils_1.int32[0]);
+    };
+    ByteBuffer.prototype.writeFloat64 = function (offset, value) {
+        utils_1.float64[0] = value;
+        this.writeInt32(offset, utils_1.int32[utils_1.isLittleEndian ? 0 : 1]);
+        this.writeInt32(offset + 4, utils_1.int32[utils_1.isLittleEndian ? 1 : 0]);
+    };
+    /**
+     * Return the file identifier.   Behavior is undefined for FlatBuffers whose
+     * schema does not include a file_identifier (likely points at padding or the
+     * start of a the root vtable).
+     */
+    ByteBuffer.prototype.getBufferIdentifier = function () {
+        if (this.bytes_.length < this.position_ + constants_1.SIZEOF_INT +
+            constants_1.FILE_IDENTIFIER_LENGTH) {
+            throw new Error('FlatBuffers: ByteBuffer is too short to contain an identifier.');
+        }
+        var result = "";
+        for (var i = 0; i < constants_1.FILE_IDENTIFIER_LENGTH; i++) {
+            result += String.fromCharCode(this.readInt8(this.position_ + constants_1.SIZEOF_INT + i));
+        }
+        return result;
+    };
+    /**
+     * Look up a field in the vtable, return an offset into the object, or 0 if the
+     * field is not present.
+     */
+    ByteBuffer.prototype.__offset = function (bb_pos, vtable_offset) {
+        var vtable = bb_pos - this.readInt32(bb_pos);
+        return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
+    };
+    /**
+     * Initialize any Table-derived type to point to the union at the given offset.
+     */
+    ByteBuffer.prototype.__union = function (t, offset) {
+        t.bb_pos = offset + this.readInt32(offset);
+        t.bb = this;
+        return t;
+    };
+    /**
+     * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
+     * This allocates a new string and converts to wide chars upon each access.
+     *
+     * To avoid the conversion to UTF-16, pass Encoding.UTF8_BYTES as
+     * the "optionalEncoding" argument. This is useful for avoiding conversion to
+     * and from UTF-16 when the data will just be packaged back up in another
+     * FlatBuffer later on.
+     *
+     * @param offset
+     * @param opt_encoding Defaults to UTF16_STRING
+     */
+    ByteBuffer.prototype.__string = function (offset, opt_encoding) {
+        offset += this.readInt32(offset);
+        var length = this.readInt32(offset);
+        var result = '';
+        var i = 0;
+        offset += constants_1.SIZEOF_INT;
+        if (opt_encoding === encoding_1.Encoding.UTF8_BYTES) {
+            return this.bytes_.subarray(offset, offset + length);
+        }
+        while (i < length) {
+            var codePoint = void 0;
+            // Decode UTF-8
+            var a = this.readUint8(offset + i++);
+            if (a < 0xC0) {
+                codePoint = a;
+            }
+            else {
+                var b = this.readUint8(offset + i++);
+                if (a < 0xE0) {
+                    codePoint =
+                        ((a & 0x1F) << 6) |
+                            (b & 0x3F);
+                }
+                else {
+                    var c = this.readUint8(offset + i++);
+                    if (a < 0xF0) {
+                        codePoint =
+                            ((a & 0x0F) << 12) |
+                                ((b & 0x3F) << 6) |
+                                (c & 0x3F);
+                    }
+                    else {
+                        var d = this.readUint8(offset + i++);
+                        codePoint =
+                            ((a & 0x07) << 18) |
+                                ((b & 0x3F) << 12) |
+                                ((c & 0x3F) << 6) |
+                                (d & 0x3F);
+                    }
+                }
+            }
+            // Encode UTF-16
+            if (codePoint < 0x10000) {
+                result += String.fromCharCode(codePoint);
+            }
+            else {
+                codePoint -= 0x10000;
+                result += String.fromCharCode((codePoint >> 10) + 0xD800, (codePoint & ((1 << 10) - 1)) + 0xDC00);
+            }
+        }
+        return result;
+    };
+    /**
+     * Handle unions that can contain string as its member, if a Table-derived type then initialize it,
+     * if a string then return a new one
+     *
+     * WARNING: strings are immutable in JS so we can't change the string that the user gave us, this
+     * makes the behaviour of __union_with_string different compared to __union
+     */
+    ByteBuffer.prototype.__union_with_string = function (o, offset) {
+        if (typeof o === 'string') {
+            return this.__string(offset);
+        }
+        return this.__union(o, offset);
+    };
+    /**
+     * Retrieve the relative offset stored at "offset"
+     */
+    ByteBuffer.prototype.__indirect = function (offset) {
+        return offset + this.readInt32(offset);
+    };
+    /**
+     * Get the start of data of a vector whose offset is stored at "offset" in this object.
+     */
+    ByteBuffer.prototype.__vector = function (offset) {
+        return offset + this.readInt32(offset) + constants_1.SIZEOF_INT; // data starts after the length
+    };
+    /**
+     * Get the length of a vector whose offset is stored at "offset" in this object.
+     */
+    ByteBuffer.prototype.__vector_len = function (offset) {
+        return this.readInt32(offset + this.readInt32(offset));
+    };
+    ByteBuffer.prototype.__has_identifier = function (ident) {
+        if (ident.length != constants_1.FILE_IDENTIFIER_LENGTH) {
+            throw new Error('FlatBuffers: file identifier must be length ' +
+                constants_1.FILE_IDENTIFIER_LENGTH);
+        }
+        for (var i = 0; i < constants_1.FILE_IDENTIFIER_LENGTH; i++) {
+            if (ident.charCodeAt(i) != this.readInt8(this.position() + constants_1.SIZEOF_INT + i)) {
+                return false;
+            }
+        }
+        return true;
+    };
+    /**
+     * A helper function to avoid generated code depending on this file directly.
+     */
+    ByteBuffer.prototype.createLong = function (low, high) {
+        return long_1.Long.create(low, high);
+    };
+    /**
+     * A helper function for generating list for obj api
+     */
+    ByteBuffer.prototype.createScalarList = function (listAccessor, listLength) {
+        var ret = [];
+        for (var i = 0; i < listLength; ++i) {
+            if (listAccessor(i) !== null) {
+                ret.push(listAccessor(i));
+            }
+        }
+        return ret;
+    };
+    /**
+     * This function is here only to get around typescript type system
+     */
+    ByteBuffer.prototype.createStringList = function (listAccessor, listLength) {
+        return this.createScalarList(listAccessor, listLength);
+    };
+    /**
+     * A helper function for generating list for obj api
+     * @param listAccessor function that accepts an index and return data at that index
+     * @param listLength listLength
+     * @param res result list
+     */
+    ByteBuffer.prototype.createObjList = function (listAccessor, listLength) {
+        var ret = [];
+        for (var i = 0; i < listLength; ++i) {
+            var val = listAccessor(i);
+            if (val !== null) {
+                ret.push(val.unpack());
+            }
+        }
+        return ret;
+    };
+    return ByteBuffer;
+}());
+exports.ByteBuffer = ByteBuffer;
diff --git a/third_party/flatbuffers/js/constants.js b/third_party/flatbuffers/js/constants.js
new file mode 100644
index 0000000..450e2a1
--- /dev/null
+++ b/third_party/flatbuffers/js/constants.js
@@ -0,0 +1,7 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.SIZE_PREFIX_LENGTH = exports.FILE_IDENTIFIER_LENGTH = exports.SIZEOF_INT = exports.SIZEOF_SHORT = void 0;
+exports.SIZEOF_SHORT = 2;
+exports.SIZEOF_INT = 4;
+exports.FILE_IDENTIFIER_LENGTH = 4;
+exports.SIZE_PREFIX_LENGTH = 4;
diff --git a/third_party/flatbuffers/js/encoding.js b/third_party/flatbuffers/js/encoding.js
new file mode 100644
index 0000000..abe2e29
--- /dev/null
+++ b/third_party/flatbuffers/js/encoding.js
@@ -0,0 +1,8 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Encoding = void 0;
+var Encoding;
+(function (Encoding) {
+    Encoding[Encoding["UTF8_BYTES"] = 1] = "UTF8_BYTES";
+    Encoding[Encoding["UTF16_STRING"] = 2] = "UTF16_STRING";
+})(Encoding = exports.Encoding || (exports.Encoding = {}));
diff --git a/third_party/flatbuffers/js/flatbuffers.js b/third_party/flatbuffers/js/flatbuffers.js
index 461cd7a..836ff88 100644
--- a/third_party/flatbuffers/js/flatbuffers.js
+++ b/third_party/flatbuffers/js/flatbuffers.js
@@ -1,1259 +1,45 @@
-/// @file
-/// @addtogroup flatbuffers_javascript_api
-/// @{
-/// @cond FLATBUFFERS_INTERNAL
-
-/**
- * @fileoverview
- *
- * Need to suppress 'global this' error so the Node.js export line doesn't cause
- * closure compile to error out.
- * @suppress {globalThis}
- */
-
-/**
- * @const
- * @namespace
- */
-var flatbuffers = {};
-
-/**
- * @typedef {number}
- */
-flatbuffers.Offset;
-
-/**
- * @typedef {{
- *   bb: flatbuffers.ByteBuffer,
- *   bb_pos: number
- * }}
- */
-flatbuffers.Table;
-
-/**
- * @type {number}
- * @const
- */
-flatbuffers.SIZEOF_SHORT = 2;
-
-/**
- * @type {number}
- * @const
- */
-flatbuffers.SIZEOF_INT = 4;
-
-/**
- * @type {number}
- * @const
- */
-flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
-
-/**
- * @type {number}
- * @const
- */
-flatbuffers.SIZE_PREFIX_LENGTH = 4;
-
-/**
- * @enum {number}
- */
-flatbuffers.Encoding = {
-  UTF8_BYTES: 1,
-  UTF16_STRING: 2
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+    Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+    o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+    if (mod && mod.__esModule) return mod;
+    var result = {};
+    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+    __setModuleDefault(result, mod);
+    return result;
 };
-
-/**
- * @type {Int32Array}
- * @const
- */
-flatbuffers.int32 = new Int32Array(2);
-
-/**
- * @type {Float32Array}
- * @const
- */
-flatbuffers.float32 = new Float32Array(flatbuffers.int32.buffer);
-
-/**
- * @type {Float64Array}
- * @const
- */
-flatbuffers.float64 = new Float64Array(flatbuffers.int32.buffer);
-
-/**
- * @type {boolean}
- * @const
- */
-flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
-
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @constructor
- * @param {number} low
- * @param {number} high
- */
-flatbuffers.Long = function(low, high) {
-  /**
-   * @type {number}
-   * @const
-   */
-  this.low = low | 0;
-
-  /**
-   * @type {number}
-   * @const
-   */
-  this.high = high | 0;
-};
-
-/**
- * @param {number} low
- * @param {number} high
- * @returns {flatbuffers.Long}
- */
-flatbuffers.Long.create = function(low, high) {
-  // Special-case zero to avoid GC overhead for default values
-  return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high);
-};
-
-/**
- * @returns {number}
- */
-flatbuffers.Long.prototype.toFloat64 = function() {
-  return (this.low >>> 0) + this.high * 0x100000000;
-};
-
-/**
- * @param {flatbuffers.Long} other
- * @returns {boolean}
- */
-flatbuffers.Long.prototype.equals = function(other) {
-  return this.low == other.low && this.high == other.high;
-};
-
-/**
- * @type {flatbuffers.Long}
- * @const
- */
-flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
-
-/// @endcond
-////////////////////////////////////////////////////////////////////////////////
-/**
- * Create a FlatBufferBuilder.
- *
- * @constructor
- * @param {number=} opt_initial_size
- */
-flatbuffers.Builder = function(opt_initial_size) {
-  if (!opt_initial_size) {
-    var initial_size = 1024;
-  } else {
-    var initial_size = opt_initial_size;
-  }
-
-  /**
-   * @type {flatbuffers.ByteBuffer}
-   * @private
-   */
-  this.bb = flatbuffers.ByteBuffer.allocate(initial_size);
-
-  /**
-   * Remaining space in the ByteBuffer.
-   *
-   * @type {number}
-   * @private
-   */
-  this.space = initial_size;
-
-  /**
-   * Minimum alignment encountered so far.
-   *
-   * @type {number}
-   * @private
-   */
-  this.minalign = 1;
-
-  /**
-   * The vtable for the current table.
-   *
-   * @type {Array.<number>}
-   * @private
-   */
-  this.vtable = null;
-
-  /**
-   * The amount of fields we're actually using.
-   *
-   * @type {number}
-   * @private
-   */
-  this.vtable_in_use = 0;
-
-  /**
-   * Whether we are currently serializing a table.
-   *
-   * @type {boolean}
-   * @private
-   */
-  this.isNested = false;
-
-  /**
-   * Starting offset of the current struct/table.
-   *
-   * @type {number}
-   * @private
-   */
-  this.object_start = 0;
-
-  /**
-   * List of offsets of all vtables.
-   *
-   * @type {Array.<number>}
-   * @private
-   */
-  this.vtables = [];
-
-  /**
-   * For the current vector being built.
-   *
-   * @type {number}
-   * @private
-   */
-  this.vector_num_elems = 0;
-
-  /**
-   * False omits default values from the serialized data
-   *
-   * @type {boolean}
-   * @private
-   */
-  this.force_defaults = false;
-};
-
-flatbuffers.Builder.prototype.clear = function() {
-  this.bb.clear();
-  this.space = this.bb.capacity();
-  this.minalign = 1;
-  this.vtable = null;
-  this.vtable_in_use = 0;
-  this.isNested = false;
-  this.object_start = 0;
-  this.vtables = [];
-  this.vector_num_elems = 0;
-  this.force_defaults = false;
-};
-
-/**
- * In order to save space, fields that are set to their default value
- * don't get serialized into the buffer. Forcing defaults provides a
- * way to manually disable this optimization.
- *
- * @param {boolean} forceDefaults true always serializes default values
- */
-flatbuffers.Builder.prototype.forceDefaults = function(forceDefaults) {
-  this.force_defaults = forceDefaults;
-};
-
-/**
- * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
- * called finish(). The actual data starts at the ByteBuffer's current position,
- * not necessarily at 0.
- *
- * @returns {flatbuffers.ByteBuffer}
- */
-flatbuffers.Builder.prototype.dataBuffer = function() {
-  return this.bb;
-};
-
-/**
- * Get the bytes representing the FlatBuffer. Only call this after you've
- * called finish().
- *
- * @returns {Uint8Array}
- */
-flatbuffers.Builder.prototype.asUint8Array = function() {
-  return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
-};
-
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * Prepare to write an element of `size` after `additional_bytes` have been
- * written, e.g. if you write a string, you need to align such the int length
- * field is aligned to 4 bytes, and the string data follows it directly. If all
- * you need to do is alignment, `additional_bytes` will be 0.
- *
- * @param {number} size This is the of the new element to write
- * @param {number} additional_bytes The padding size
- */
-flatbuffers.Builder.prototype.prep = function(size, additional_bytes) {
-  // Track the biggest thing we've ever aligned to.
-  if (size > this.minalign) {
-    this.minalign = size;
-  }
-
-  // Find the amount of alignment needed such that `size` is properly
-  // aligned after `additional_bytes`
-  var align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1);
-
-  // Reallocate the buffer if needed.
-  while (this.space < align_size + size + additional_bytes) {
-    var old_buf_size = this.bb.capacity();
-    this.bb = flatbuffers.Builder.growByteBuffer(this.bb);
-    this.space += this.bb.capacity() - old_buf_size;
-  }
-
-  this.pad(align_size);
-};
-
-/**
- * @param {number} byte_size
- */
-flatbuffers.Builder.prototype.pad = function(byte_size) {
-  for (var i = 0; i < byte_size; i++) {
-    this.bb.writeInt8(--this.space, 0);
-  }
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeInt8 = function(value) {
-  this.bb.writeInt8(this.space -= 1, value);
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeInt16 = function(value) {
-  this.bb.writeInt16(this.space -= 2, value);
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeInt32 = function(value) {
-  this.bb.writeInt32(this.space -= 4, value);
-};
-
-/**
- * @param {flatbuffers.Long} value
- */
-flatbuffers.Builder.prototype.writeInt64 = function(value) {
-  this.bb.writeInt64(this.space -= 8, value);
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeFloat32 = function(value) {
-  this.bb.writeFloat32(this.space -= 4, value);
-};
-
-/**
- * @param {number} value
- */
-flatbuffers.Builder.prototype.writeFloat64 = function(value) {
-  this.bb.writeFloat64(this.space -= 8, value);
-};
-/// @endcond
-
-/**
- * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `int8` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addInt8 = function(value) {
-  this.prep(1, 0);
-  this.writeInt8(value);
-};
-
-/**
- * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `int16` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addInt16 = function(value) {
-  this.prep(2, 0);
-  this.writeInt16(value);
-};
-
-/**
- * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `int32` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addInt32 = function(value) {
-  this.prep(4, 0);
-  this.writeInt32(value);
-};
-
-/**
- * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {flatbuffers.Long} value The `int64` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addInt64 = function(value) {
-  this.prep(8, 0);
-  this.writeInt64(value);
-};
-
-/**
- * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `float32` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addFloat32 = function(value) {
-  this.prep(4, 0);
-  this.writeFloat32(value);
-};
-
-/**
- * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
- * @param {number} value The `float64` to add the the buffer.
- */
-flatbuffers.Builder.prototype.addFloat64 = function(value) {
-  this.prep(8, 0);
-  this.writeFloat64(value);
-};
-
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldInt8 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addInt8(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldInt16 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addInt16(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldInt32 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addInt32(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {flatbuffers.Long} value
- * @param {flatbuffers.Long} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldInt64 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || !value.equals(defaultValue)) {
-    this.addInt64(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldFloat32 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addFloat32(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {number} value
- * @param {number} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldFloat64 = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addFloat64(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * @param {number} voffset
- * @param {flatbuffers.Offset} value
- * @param {flatbuffers.Offset} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldOffset = function(voffset, value, defaultValue) {
-  if (this.force_defaults || value != defaultValue) {
-    this.addOffset(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * Structs are stored inline, so nothing additional is being added. `d` is always 0.
- *
- * @param {number} voffset
- * @param {flatbuffers.Offset} value
- * @param {flatbuffers.Offset} defaultValue
- */
-flatbuffers.Builder.prototype.addFieldStruct = function(voffset, value, defaultValue) {
-  if (value != defaultValue) {
-    this.nested(value);
-    this.slot(voffset);
-  }
-};
-
-/**
- * Structures are always stored inline, they need to be created right
- * where they're used.  You'll get this assertion failure if you
- * created it elsewhere.
- *
- * @param {flatbuffers.Offset} obj The offset of the created object
- */
-flatbuffers.Builder.prototype.nested = function(obj) {
-  if (obj != this.offset()) {
-    throw new Error('FlatBuffers: struct must be serialized inline.');
-  }
-};
-
-/**
- * Should not be creating any other object, string or vector
- * while an object is being constructed
- */
-flatbuffers.Builder.prototype.notNested = function() {
-  if (this.isNested) {
-    throw new Error('FlatBuffers: object serialization must not be nested.');
-  }
-};
-
-/**
- * Set the current vtable at `voffset` to the current location in the buffer.
- *
- * @param {number} voffset
- */
-flatbuffers.Builder.prototype.slot = function(voffset) {
-  this.vtable[voffset] = this.offset();
-};
-
-/**
- * @returns {flatbuffers.Offset} Offset relative to the end of the buffer.
- */
-flatbuffers.Builder.prototype.offset = function() {
-  return this.bb.capacity() - this.space;
-};
-
-/**
- * Doubles the size of the backing ByteBuffer and copies the old data towards
- * the end of the new buffer (since we build the buffer backwards).
- *
- * @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
- * @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied
- * to it. The data is located at the end of the buffer.
- *
- * uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
- * it a uint8Array we need to suppress the type check:
- * @suppress {checkTypes}
- */
-flatbuffers.Builder.growByteBuffer = function(bb) {
-  var old_buf_size = bb.capacity();
-
-  // Ensure we don't grow beyond what fits in an int.
-  if (old_buf_size & 0xC0000000) {
-    throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.');
-  }
-
-  var new_buf_size = old_buf_size << 1;
-  var nbb = flatbuffers.ByteBuffer.allocate(new_buf_size);
-  nbb.setPosition(new_buf_size - old_buf_size);
-  nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
-  return nbb;
-};
-/// @endcond
-
-/**
- * Adds on offset, relative to where it will be written.
- *
- * @param {flatbuffers.Offset} offset The offset to add.
- */
-flatbuffers.Builder.prototype.addOffset = function(offset) {
-  this.prep(flatbuffers.SIZEOF_INT, 0); // Ensure alignment is already done.
-  this.writeInt32(this.offset() - offset + flatbuffers.SIZEOF_INT);
-};
-
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * Start encoding a new object in the buffer.  Users will not usually need to
- * call this directly. The FlatBuffers compiler will generate helper methods
- * that call this method internally.
- *
- * @param {number} numfields
- */
-flatbuffers.Builder.prototype.startObject = function(numfields) {
-  this.notNested();
-  if (this.vtable == null) {
-    this.vtable = [];
-  }
-  this.vtable_in_use = numfields;
-  for (var i = 0; i < numfields; i++) {
-    this.vtable[i] = 0; // This will push additional elements as needed
-  }
-  this.isNested = true;
-  this.object_start = this.offset();
-};
-
-/**
- * Finish off writing the object that is under construction.
- *
- * @returns {flatbuffers.Offset} The offset to the object inside `dataBuffer`
- */
-flatbuffers.Builder.prototype.endObject = function() {
-  if (this.vtable == null || !this.isNested) {
-    throw new Error('FlatBuffers: endObject called without startObject');
-  }
-
-  this.addInt32(0);
-  var vtableloc = this.offset();
-
-  // Trim trailing zeroes.
-  var i = this.vtable_in_use - 1;
-  for (; i >= 0 && this.vtable[i] == 0; i--) {}
-  var trimmed_size = i + 1;
-
-  // Write out the current vtable.
-  for (; i >= 0; i--) {
-    // Offset relative to the start of the table.
-    this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
-  }
-
-  var standard_fields = 2; // The fields below:
-  this.addInt16(vtableloc - this.object_start);
-  var len = (trimmed_size + standard_fields) * flatbuffers.SIZEOF_SHORT;
-  this.addInt16(len);
-
-  // Search for an existing vtable that matches the current one.
-  var existing_vtable = 0;
-  var vt1 = this.space;
-outer_loop:
-  for (i = 0; i < this.vtables.length; i++) {
-    var vt2 = this.bb.capacity() - this.vtables[i];
-    if (len == this.bb.readInt16(vt2)) {
-      for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
-        if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
-          continue outer_loop;
-        }
-      }
-      existing_vtable = this.vtables[i];
-      break;
-    }
-  }
-
-  if (existing_vtable) {
-    // Found a match:
-    // Remove the current vtable.
-    this.space = this.bb.capacity() - vtableloc;
-
-    // Point table to existing vtable.
-    this.bb.writeInt32(this.space, existing_vtable - vtableloc);
-  } else {
-    // No match:
-    // Add the location of the current vtable to the list of vtables.
-    this.vtables.push(this.offset());
-
-    // Point table to current vtable.
-    this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc);
-  }
-
-  this.isNested = false;
-  return vtableloc;
-};
-/// @endcond
-
-/**
- * Finalize a buffer, poiting to the given `root_table`.
- *
- * @param {flatbuffers.Offset} root_table
- * @param {string=} opt_file_identifier
- * @param {boolean=} opt_size_prefix
- */
-flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier, opt_size_prefix) {
-  var size_prefix = opt_size_prefix ? flatbuffers.SIZE_PREFIX_LENGTH : 0;
-  if (opt_file_identifier) {
-    var file_identifier = opt_file_identifier;
-    this.prep(this.minalign, flatbuffers.SIZEOF_INT +
-      flatbuffers.FILE_IDENTIFIER_LENGTH + size_prefix);
-    if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
-      throw new Error('FlatBuffers: file identifier must be length ' +
-        flatbuffers.FILE_IDENTIFIER_LENGTH);
-    }
-    for (var i = flatbuffers.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
-      this.writeInt8(file_identifier.charCodeAt(i));
-    }
-  }
-  this.prep(this.minalign, flatbuffers.SIZEOF_INT + size_prefix);
-  this.addOffset(root_table);
-  if (size_prefix) {
-    this.addInt32(this.bb.capacity() - this.space);
-  }
-  this.bb.setPosition(this.space);
-};
-
-/**
- * Finalize a size prefixed buffer, pointing to the given `root_table`.
- *
- * @param {flatbuffers.Offset} root_table
- * @param {string=} opt_file_identifier
- */
-flatbuffers.Builder.prototype.finishSizePrefixed = function (root_table, opt_file_identifier) {
-  this.finish(root_table, opt_file_identifier, true);
-};
-
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * This checks a required field has been set in a given table that has
- * just been constructed.
- *
- * @param {flatbuffers.Offset} table
- * @param {number} field
- */
-flatbuffers.Builder.prototype.requiredField = function(table, field) {
-  var table_start = this.bb.capacity() - table;
-  var vtable_start = table_start - this.bb.readInt32(table_start);
-  var ok = this.bb.readInt16(vtable_start + field) != 0;
-
-  // If this fails, the caller will show what field needs to be set.
-  if (!ok) {
-    throw new Error('FlatBuffers: field ' + field + ' must be set');
-  }
-};
-
-/**
- * Start a new array/vector of objects.  Users usually will not call
- * this directly. The FlatBuffers compiler will create a start/end
- * method for vector types in generated code.
- *
- * @param {number} elem_size The size of each element in the array
- * @param {number} num_elems The number of elements in the array
- * @param {number} alignment The alignment of the array
- */
-flatbuffers.Builder.prototype.startVector = function(elem_size, num_elems, alignment) {
-  this.notNested();
-  this.vector_num_elems = num_elems;
-  this.prep(flatbuffers.SIZEOF_INT, elem_size * num_elems);
-  this.prep(alignment, elem_size * num_elems); // Just in case alignment > int.
-};
-
-/**
- * Finish off the creation of an array and all its elements. The array must be
- * created with `startVector`.
- *
- * @returns {flatbuffers.Offset} The offset at which the newly created array
- * starts.
- */
-flatbuffers.Builder.prototype.endVector = function() {
-  this.writeInt32(this.vector_num_elems);
-  return this.offset();
-};
-/// @endcond
-
-/**
- * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
- * instead of a string, it is assumed to contain valid UTF-8 encoded data.
- *
- * @param {string|Uint8Array} s The string to encode
- * @return {flatbuffers.Offset} The offset in the buffer where the encoded string starts
- */
-flatbuffers.Builder.prototype.createString = function(s) {
-  if (s instanceof Uint8Array) {
-    var utf8 = s;
-  } else {
-    var utf8 = [];
-    var i = 0;
-
-    while (i < s.length) {
-      var codePoint;
-
-      // Decode UTF-16
-      var a = s.charCodeAt(i++);
-      if (a < 0xD800 || a >= 0xDC00) {
-        codePoint = a;
-      } else {
-        var b = s.charCodeAt(i++);
-        codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00);
-      }
-
-      // Encode UTF-8
-      if (codePoint < 0x80) {
-        utf8.push(codePoint);
-      } else {
-        if (codePoint < 0x800) {
-          utf8.push(((codePoint >> 6) & 0x1F) | 0xC0);
-        } else {
-          if (codePoint < 0x10000) {
-            utf8.push(((codePoint >> 12) & 0x0F) | 0xE0);
-          } else {
-            utf8.push(
-              ((codePoint >> 18) & 0x07) | 0xF0,
-              ((codePoint >> 12) & 0x3F) | 0x80);
-          }
-          utf8.push(((codePoint >> 6) & 0x3F) | 0x80);
-        }
-        utf8.push((codePoint & 0x3F) | 0x80);
-      }
-    }
-  }
-
-  this.addInt8(0);
-  this.startVector(1, utf8.length, 1);
-  this.bb.setPosition(this.space -= utf8.length);
-  for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) {
-    bytes[offset++] = utf8[i];
-  }
-  return this.endVector();
-};
-
-/**
- * A helper function to avoid generated code depending on this file directly.
- *
- * @param {number} low
- * @param {number} high
- * @returns {flatbuffers.Long}
- */
-flatbuffers.Builder.prototype.createLong = function(low, high) {
-  return flatbuffers.Long.create(low, high);
-};
-////////////////////////////////////////////////////////////////////////////////
-/// @cond FLATBUFFERS_INTERNAL
-/**
- * Create a new ByteBuffer with a given array of bytes (`Uint8Array`).
- *
- * @constructor
- * @param {Uint8Array} bytes
- */
-flatbuffers.ByteBuffer = function(bytes) {
-  /**
-   * @type {Uint8Array}
-   * @private
-   */
-  this.bytes_ = bytes;
-
-  /**
-   * @type {number}
-   * @private
-   */
-  this.position_ = 0;
-};
-
-/**
- * Create and allocate a new ByteBuffer with a given size.
- *
- * @param {number} byte_size
- * @returns {flatbuffers.ByteBuffer}
- */
-flatbuffers.ByteBuffer.allocate = function(byte_size) {
-  return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
-};
-
-flatbuffers.ByteBuffer.prototype.clear = function() {
-  this.position_ = 0;
-};
-
-/**
- * Get the underlying `Uint8Array`.
- *
- * @returns {Uint8Array}
- */
-flatbuffers.ByteBuffer.prototype.bytes = function() {
-  return this.bytes_;
-};
-
-/**
- * Get the buffer's position.
- *
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.position = function() {
-  return this.position_;
-};
-
-/**
- * Set the buffer's position.
- *
- * @param {number} position
- */
-flatbuffers.ByteBuffer.prototype.setPosition = function(position) {
-  this.position_ = position;
-};
-
-/**
- * Get the buffer's capacity.
- *
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.capacity = function() {
-  return this.bytes_.length;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readInt8 = function(offset) {
-  return this.readUint8(offset) << 24 >> 24;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readUint8 = function(offset) {
-  return this.bytes_[offset];
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readInt16 = function(offset) {
-  return this.readUint16(offset) << 16 >> 16;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readUint16 = function(offset) {
-  return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readInt32 = function(offset) {
-  return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) {
-  return this.readInt32(offset) >>> 0;
-};
-
-/**
- * @param {number} offset
- * @returns {flatbuffers.Long}
- */
-flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
-  return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
-};
-
-/**
- * @param {number} offset
- * @returns {flatbuffers.Long}
- */
-flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
-  return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readFloat32 = function(offset) {
-  flatbuffers.int32[0] = this.readInt32(offset);
-  return flatbuffers.float32[0];
-};
-
-/**
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) {
-  flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1] = this.readInt32(offset);
-  flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
-  return flatbuffers.float64[0];
-};
-
-/**
- * @param {number} offset
- * @param {number|boolean} value
- */
-flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) {
-  this.bytes_[offset] = /** @type {number} */(value);
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeUint8 = function(offset, value) {
-  this.bytes_[offset] = value;
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) {
-  this.bytes_[offset] = value;
-  this.bytes_[offset + 1] = value >> 8;
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeUint16 = function(offset, value) {
-    this.bytes_[offset] = value;
-    this.bytes_[offset + 1] = value >> 8;
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) {
-  this.bytes_[offset] = value;
-  this.bytes_[offset + 1] = value >> 8;
-  this.bytes_[offset + 2] = value >> 16;
-  this.bytes_[offset + 3] = value >> 24;
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeUint32 = function(offset, value) {
-    this.bytes_[offset] = value;
-    this.bytes_[offset + 1] = value >> 8;
-    this.bytes_[offset + 2] = value >> 16;
-    this.bytes_[offset + 3] = value >> 24;
-};
-
-/**
- * @param {number} offset
- * @param {flatbuffers.Long} value
- */
-flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) {
-  this.writeInt32(offset, value.low);
-  this.writeInt32(offset + 4, value.high);
-};
-
-/**
- * @param {number} offset
- * @param {flatbuffers.Long} value
- */
-flatbuffers.ByteBuffer.prototype.writeUint64 = function(offset, value) {
-    this.writeUint32(offset, value.low);
-    this.writeUint32(offset + 4, value.high);
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeFloat32 = function(offset, value) {
-  flatbuffers.float32[0] = value;
-  this.writeInt32(offset, flatbuffers.int32[0]);
-};
-
-/**
- * @param {number} offset
- * @param {number} value
- */
-flatbuffers.ByteBuffer.prototype.writeFloat64 = function(offset, value) {
-  flatbuffers.float64[0] = value;
-  this.writeInt32(offset, flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1]);
-  this.writeInt32(offset + 4, flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0]);
-};
-
-/**
- * Return the file identifier.   Behavior is undefined for FlatBuffers whose
- * schema does not include a file_identifier (likely points at padding or the
- * start of a the root vtable).
- * @returns {string}
- */
-flatbuffers.ByteBuffer.prototype.getBufferIdentifier = function() {
-  if (this.bytes_.length < this.position_ + flatbuffers.SIZEOF_INT +
-      flatbuffers.FILE_IDENTIFIER_LENGTH) {
-    throw new Error(
-        'FlatBuffers: ByteBuffer is too short to contain an identifier.');
-  }
-  var result = "";
-  for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
-    result += String.fromCharCode(
-        this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i));
-  }
-  return result;
-};
-
-/**
- * Look up a field in the vtable, return an offset into the object, or 0 if the
- * field is not present.
- *
- * @param {number} bb_pos
- * @param {number} vtable_offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.__offset = function(bb_pos, vtable_offset) {
-  var vtable = bb_pos - this.readInt32(bb_pos);
-  return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
-};
-
-/**
- * Initialize any Table-derived type to point to the union at the given offset.
- *
- * @param {flatbuffers.Table} t
- * @param {number} offset
- * @returns {flatbuffers.Table}
- */
-flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
-  t.bb_pos = offset + this.readInt32(offset);
-  t.bb = this;
-  return t;
-};
-
-/**
- * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
- * This allocates a new string and converts to wide chars upon each access.
- *
- * To avoid the conversion to UTF-16, pass flatbuffers.Encoding.UTF8_BYTES as
- * the "optionalEncoding" argument. This is useful for avoiding conversion to
- * and from UTF-16 when the data will just be packaged back up in another
- * FlatBuffer later on.
- *
- * @param {number} offset
- * @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
- * @returns {string|Uint8Array}
- */
-flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
-  offset += this.readInt32(offset);
-
-  var length = this.readInt32(offset);
-  var result = '';
-  var i = 0;
-
-  offset += flatbuffers.SIZEOF_INT;
-
-  if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) {
-    return this.bytes_.subarray(offset, offset + length);
-  }
-
-  while (i < length) {
-    var codePoint;
-
-    // Decode UTF-8
-    var a = this.readUint8(offset + i++);
-    if (a < 0xC0) {
-      codePoint = a;
-    } else {
-      var b = this.readUint8(offset + i++);
-      if (a < 0xE0) {
-        codePoint =
-          ((a & 0x1F) << 6) |
-          (b & 0x3F);
-      } else {
-        var c = this.readUint8(offset + i++);
-        if (a < 0xF0) {
-          codePoint =
-            ((a & 0x0F) << 12) |
-            ((b & 0x3F) << 6) |
-            (c & 0x3F);
-        } else {
-          var d = this.readUint8(offset + i++);
-          codePoint =
-            ((a & 0x07) << 18) |
-            ((b & 0x3F) << 12) |
-            ((c & 0x3F) << 6) |
-            (d & 0x3F);
-        }
-      }
-    }
-
-    // Encode UTF-16
-    if (codePoint < 0x10000) {
-      result += String.fromCharCode(codePoint);
-    } else {
-      codePoint -= 0x10000;
-      result += String.fromCharCode(
-        (codePoint >> 10) + 0xD800,
-        (codePoint & ((1 << 10) - 1)) + 0xDC00);
-    }
-  }
-
-  return result;
-};
-
-/**
- * Retrieve the relative offset stored at "offset"
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.__indirect = function(offset) {
-  return offset + this.readInt32(offset);
-};
-
-/**
- * Get the start of data of a vector whose offset is stored at "offset" in this object.
- *
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.__vector = function(offset) {
-  return offset + this.readInt32(offset) + flatbuffers.SIZEOF_INT; // data starts after the length
-};
-
-/**
- * Get the length of a vector whose offset is stored at "offset" in this object.
- *
- * @param {number} offset
- * @returns {number}
- */
-flatbuffers.ByteBuffer.prototype.__vector_len = function(offset) {
-  return this.readInt32(offset + this.readInt32(offset));
-};
-
-/**
- * @param {string} ident
- * @returns {boolean}
- */
-flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
-  if (ident.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
-    throw new Error('FlatBuffers: file identifier must be length ' +
-                    flatbuffers.FILE_IDENTIFIER_LENGTH);
-  }
-  for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
-    if (ident.charCodeAt(i) != this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i)) {
-      return false;
-    }
-  }
-  return true;
-};
-
-/**
- * A helper function to avoid generated code depending on this file directly.
- *
- * @param {number} low
- * @param {number} high
- * @returns {flatbuffers.Long}
- */
-flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
-  return flatbuffers.Long.create(low, high);
-};
-
-// Exports for Node.js and RequireJS
-this.flatbuffers = flatbuffers;
-
-/// @endcond
-/// @}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.flatbuffers = void 0;
+/* eslint-disable @typescript-eslint/no-namespace */
+var constants = __importStar(require("./constants"));
+var utils = __importStar(require("./utils"));
+var long_1 = require("./long");
+var encoding_1 = require("./encoding");
+var builder_1 = require("./builder");
+var byte_buffer_1 = require("./byte-buffer");
+var flatbuffers;
+(function (flatbuffers) {
+    flatbuffers.SIZEOF_SHORT = constants.SIZEOF_SHORT;
+    flatbuffers.SIZEOF_INT = constants.SIZEOF_INT;
+    flatbuffers.FILE_IDENTIFIER_LENGTH = constants.FILE_IDENTIFIER_LENGTH;
+    flatbuffers.SIZE_PREFIX_LENGTH = constants.SIZE_PREFIX_LENGTH;
+    flatbuffers.Encoding = encoding_1.Encoding;
+    flatbuffers.int32 = utils.int32;
+    flatbuffers.float32 = utils.float32;
+    flatbuffers.float64 = utils.float64;
+    flatbuffers.isLittleEndian = utils.isLittleEndian;
+    flatbuffers.Long = long_1.Long;
+    flatbuffers.Builder = builder_1.Builder;
+    flatbuffers.ByteBuffer = byte_buffer_1.ByteBuffer;
+})(flatbuffers = exports.flatbuffers || (exports.flatbuffers = {}));
+exports.default = flatbuffers;
diff --git a/third_party/flatbuffers/js/flexbuffers.js b/third_party/flatbuffers/js/flexbuffers.js
new file mode 100644
index 0000000..b5fc8c1
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers.js
@@ -0,0 +1,35 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.flexbuffers = exports.encode = exports.toObject = exports.builder = void 0;
+/* eslint-disable @typescript-eslint/no-namespace */
+var builder_1 = require("./flexbuffers/builder");
+var reference_1 = require("./flexbuffers/reference");
+function builder() {
+    return new builder_1.Builder();
+}
+exports.builder = builder;
+function toObject(buffer) {
+    return reference_1.toReference(buffer).toObject();
+}
+exports.toObject = toObject;
+function encode(object, size, deduplicateStrings, deduplicateKeys, deduplicateKeyVectors) {
+    if (size === void 0) { size = 2048; }
+    if (deduplicateStrings === void 0) { deduplicateStrings = true; }
+    if (deduplicateKeys === void 0) { deduplicateKeys = true; }
+    if (deduplicateKeyVectors === void 0) { deduplicateKeyVectors = true; }
+    var builder = new builder_1.Builder(size > 0 ? size : 2048, deduplicateStrings, deduplicateKeys, deduplicateKeyVectors);
+    builder.add(object);
+    return builder.finish();
+}
+exports.encode = encode;
+var builderFunction = builder;
+var toObjectFunction = toObject;
+var encodeFunction = encode;
+var flexbuffers;
+(function (flexbuffers) {
+    flexbuffers.builder = builderFunction;
+    flexbuffers.toObject = toObjectFunction;
+    flexbuffers.encode = encodeFunction;
+    flexbuffers.toReference = reference_1.toReference;
+})(flexbuffers = exports.flexbuffers || (exports.flexbuffers = {}));
+exports.default = flexbuffers;
diff --git a/third_party/flatbuffers/js/flexbuffers/bit-width-util.js b/third_party/flatbuffers/js/flexbuffers/bit-width-util.js
new file mode 100644
index 0000000..16f9d26
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers/bit-width-util.js
@@ -0,0 +1,46 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.paddingSize = exports.fromByteWidth = exports.uwidth = exports.fwidth = exports.iwidth = exports.toByteWidth = void 0;
+var bit_width_1 = require("./bit-width");
+function toByteWidth(bitWidth) {
+    return 1 << bitWidth;
+}
+exports.toByteWidth = toByteWidth;
+function iwidth(value) {
+    if (value >= -128 && value <= 127)
+        return bit_width_1.BitWidth.WIDTH8;
+    if (value >= -32768 && value <= 32767)
+        return bit_width_1.BitWidth.WIDTH16;
+    if (value >= -2147483648 && value <= 2147483647)
+        return bit_width_1.BitWidth.WIDTH32;
+    return bit_width_1.BitWidth.WIDTH64;
+}
+exports.iwidth = iwidth;
+function fwidth(value) {
+    return value === Math.fround(value) ? bit_width_1.BitWidth.WIDTH32 : bit_width_1.BitWidth.WIDTH64;
+}
+exports.fwidth = fwidth;
+function uwidth(value) {
+    if (value <= 255)
+        return bit_width_1.BitWidth.WIDTH8;
+    if (value <= 65535)
+        return bit_width_1.BitWidth.WIDTH16;
+    if (value <= 4294967295)
+        return bit_width_1.BitWidth.WIDTH32;
+    return bit_width_1.BitWidth.WIDTH64;
+}
+exports.uwidth = uwidth;
+function fromByteWidth(value) {
+    if (value === 1)
+        return bit_width_1.BitWidth.WIDTH8;
+    if (value === 2)
+        return bit_width_1.BitWidth.WIDTH16;
+    if (value === 4)
+        return bit_width_1.BitWidth.WIDTH32;
+    return bit_width_1.BitWidth.WIDTH64;
+}
+exports.fromByteWidth = fromByteWidth;
+function paddingSize(bufSize, scalarSize) {
+    return (~bufSize + 1) & (scalarSize - 1);
+}
+exports.paddingSize = paddingSize;
diff --git a/third_party/flatbuffers/js/flexbuffers/bit-width.js b/third_party/flatbuffers/js/flexbuffers/bit-width.js
new file mode 100644
index 0000000..d0c5c05
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers/bit-width.js
@@ -0,0 +1,10 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.BitWidth = void 0;
+var BitWidth;
+(function (BitWidth) {
+    BitWidth[BitWidth["WIDTH8"] = 0] = "WIDTH8";
+    BitWidth[BitWidth["WIDTH16"] = 1] = "WIDTH16";
+    BitWidth[BitWidth["WIDTH32"] = 2] = "WIDTH32";
+    BitWidth[BitWidth["WIDTH64"] = 3] = "WIDTH64";
+})(BitWidth = exports.BitWidth || (exports.BitWidth = {}));
diff --git a/third_party/flatbuffers/js/flexbuffers/builder.js b/third_party/flatbuffers/js/flexbuffers/builder.js
new file mode 100644
index 0000000..3243417
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers/builder.js
@@ -0,0 +1,541 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Builder = void 0;
+var bit_width_1 = require("./bit-width");
+var bit_width_util_1 = require("./bit-width-util");
+var flexbuffers_util_1 = require("./flexbuffers-util");
+var value_type_1 = require("./value-type");
+var value_type_util_1 = require("./value-type-util");
+var stack_value_1 = require("./stack-value");
+var Builder = /** @class */ (function () {
+    function Builder(size, dedupStrings, dedupKeys, dedupKeyVectors) {
+        if (size === void 0) { size = 2048; }
+        if (dedupStrings === void 0) { dedupStrings = true; }
+        if (dedupKeys === void 0) { dedupKeys = true; }
+        if (dedupKeyVectors === void 0) { dedupKeyVectors = true; }
+        this.dedupStrings = dedupStrings;
+        this.dedupKeys = dedupKeys;
+        this.dedupKeyVectors = dedupKeyVectors;
+        this.stack = [];
+        this.stackPointers = [];
+        this.offset = 0;
+        this.finished = false;
+        this.stringLookup = {};
+        this.keyLookup = {};
+        this.keyVectorLookup = {};
+        this.indirectIntLookup = {};
+        this.indirectUIntLookup = {};
+        this.indirectFloatLookup = {};
+        this.buffer = new ArrayBuffer(size > 0 ? size : 2048);
+        this.view = new DataView(this.buffer);
+    }
+    Builder.prototype.align = function (width) {
+        var byteWidth = bit_width_util_1.toByteWidth(width);
+        this.offset += bit_width_util_1.paddingSize(this.offset, byteWidth);
+        return byteWidth;
+    };
+    Builder.prototype.computeOffset = function (newValueSize) {
+        var targetOffset = this.offset + newValueSize;
+        var size = this.buffer.byteLength;
+        var prevSize = size;
+        while (size < targetOffset) {
+            size <<= 1;
+        }
+        if (prevSize < size) {
+            var prevBuffer = this.buffer;
+            this.buffer = new ArrayBuffer(size);
+            this.view = new DataView(this.buffer);
+            new Uint8Array(this.buffer).set(new Uint8Array(prevBuffer), 0);
+        }
+        return targetOffset;
+    };
+    Builder.prototype.pushInt = function (value, width) {
+        if (width === bit_width_1.BitWidth.WIDTH8) {
+            this.view.setInt8(this.offset, value);
+        }
+        else if (width === bit_width_1.BitWidth.WIDTH16) {
+            this.view.setInt16(this.offset, value, true);
+        }
+        else if (width === bit_width_1.BitWidth.WIDTH32) {
+            this.view.setInt32(this.offset, value, true);
+        }
+        else if (width === bit_width_1.BitWidth.WIDTH64) {
+            this.view.setBigInt64(this.offset, BigInt(value), true);
+        }
+        else {
+            throw "Unexpected width: " + width + " for value: " + value;
+        }
+    };
+    Builder.prototype.pushUInt = function (value, width) {
+        if (width === bit_width_1.BitWidth.WIDTH8) {
+            this.view.setUint8(this.offset, value);
+        }
+        else if (width === bit_width_1.BitWidth.WIDTH16) {
+            this.view.setUint16(this.offset, value, true);
+        }
+        else if (width === bit_width_1.BitWidth.WIDTH32) {
+            this.view.setUint32(this.offset, value, true);
+        }
+        else if (width === bit_width_1.BitWidth.WIDTH64) {
+            this.view.setBigUint64(this.offset, BigInt(value), true);
+        }
+        else {
+            throw "Unexpected width: " + width + " for value: " + value;
+        }
+    };
+    Builder.prototype.writeInt = function (value, byteWidth) {
+        var newOffset = this.computeOffset(byteWidth);
+        this.pushInt(value, bit_width_util_1.fromByteWidth(byteWidth));
+        this.offset = newOffset;
+    };
+    Builder.prototype.writeUInt = function (value, byteWidth) {
+        var newOffset = this.computeOffset(byteWidth);
+        this.pushUInt(value, bit_width_util_1.fromByteWidth(byteWidth));
+        this.offset = newOffset;
+    };
+    Builder.prototype.writeBlob = function (arrayBuffer) {
+        var length = arrayBuffer.byteLength;
+        var bitWidth = bit_width_util_1.uwidth(length);
+        var byteWidth = this.align(bitWidth);
+        this.writeUInt(length, byteWidth);
+        var blobOffset = this.offset;
+        var newOffset = this.computeOffset(length);
+        new Uint8Array(this.buffer).set(new Uint8Array(arrayBuffer), blobOffset);
+        this.stack.push(this.offsetStackValue(blobOffset, value_type_1.ValueType.BLOB, bitWidth));
+        this.offset = newOffset;
+    };
+    Builder.prototype.writeString = function (str) {
+        if (this.dedupStrings && Object.prototype.hasOwnProperty.call(this.stringLookup, str)) {
+            this.stack.push(this.stringLookup[str]);
+            return;
+        }
+        var utf8 = flexbuffers_util_1.toUTF8Array(str);
+        var length = utf8.length;
+        var bitWidth = bit_width_util_1.uwidth(length);
+        var byteWidth = this.align(bitWidth);
+        this.writeUInt(length, byteWidth);
+        var stringOffset = this.offset;
+        var newOffset = this.computeOffset(length + 1);
+        new Uint8Array(this.buffer).set(utf8, stringOffset);
+        var stackValue = this.offsetStackValue(stringOffset, value_type_1.ValueType.STRING, bitWidth);
+        this.stack.push(stackValue);
+        if (this.dedupStrings) {
+            this.stringLookup[str] = stackValue;
+        }
+        this.offset = newOffset;
+    };
+    Builder.prototype.writeKey = function (str) {
+        if (this.dedupKeys && Object.prototype.hasOwnProperty.call(this.keyLookup, str)) {
+            this.stack.push(this.keyLookup[str]);
+            return;
+        }
+        var utf8 = flexbuffers_util_1.toUTF8Array(str);
+        var length = utf8.length;
+        var newOffset = this.computeOffset(length + 1);
+        new Uint8Array(this.buffer).set(utf8, this.offset);
+        var stackValue = this.offsetStackValue(this.offset, value_type_1.ValueType.KEY, bit_width_1.BitWidth.WIDTH8);
+        this.stack.push(stackValue);
+        if (this.dedupKeys) {
+            this.keyLookup[str] = stackValue;
+        }
+        this.offset = newOffset;
+    };
+    Builder.prototype.writeStackValue = function (value, byteWidth) {
+        var newOffset = this.computeOffset(byteWidth);
+        if (value.isOffset()) {
+            var relativeOffset = this.offset - value.offset;
+            if (byteWidth === 8 || BigInt(relativeOffset) < (BigInt(1) << BigInt(byteWidth * 8))) {
+                this.writeUInt(relativeOffset, byteWidth);
+            }
+            else {
+                throw "Unexpected size " + byteWidth + ". This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new";
+            }
+        }
+        else {
+            value.writeToBuffer(byteWidth);
+        }
+        this.offset = newOffset;
+    };
+    Builder.prototype.integrityCheckOnValueAddition = function () {
+        if (this.finished) {
+            throw "Adding values after finish is prohibited";
+        }
+        if (this.stackPointers.length !== 0 && this.stackPointers[this.stackPointers.length - 1].isVector === false) {
+            if (this.stack[this.stack.length - 1].type !== value_type_1.ValueType.KEY) {
+                throw "Adding value to a map before adding a key is prohibited";
+            }
+        }
+    };
+    Builder.prototype.integrityCheckOnKeyAddition = function () {
+        if (this.finished) {
+            throw "Adding values after finish is prohibited";
+        }
+        if (this.stackPointers.length === 0 || this.stackPointers[this.stackPointers.length - 1].isVector) {
+            throw "Adding key before starting a map is prohibited";
+        }
+    };
+    Builder.prototype.startVector = function () {
+        this.stackPointers.push({ stackPosition: this.stack.length, isVector: true });
+    };
+    Builder.prototype.startMap = function (presorted) {
+        if (presorted === void 0) { presorted = false; }
+        this.stackPointers.push({ stackPosition: this.stack.length, isVector: false, presorted: presorted });
+    };
+    Builder.prototype.endVector = function (stackPointer) {
+        var vecLength = this.stack.length - stackPointer.stackPosition;
+        var vec = this.createVector(stackPointer.stackPosition, vecLength, 1);
+        this.stack.splice(stackPointer.stackPosition, vecLength);
+        this.stack.push(vec);
+    };
+    Builder.prototype.endMap = function (stackPointer) {
+        if (!stackPointer.presorted) {
+            this.sort(stackPointer);
+        }
+        var keyVectorHash = "";
+        for (var i = stackPointer.stackPosition; i < this.stack.length; i += 2) {
+            keyVectorHash += "," + this.stack[i].offset;
+        }
+        var vecLength = (this.stack.length - stackPointer.stackPosition) >> 1;
+        if (this.dedupKeyVectors && !Object.prototype.hasOwnProperty.call(this.keyVectorLookup, keyVectorHash)) {
+            this.keyVectorLookup[keyVectorHash] = this.createVector(stackPointer.stackPosition, vecLength, 2);
+        }
+        var keysStackValue = this.dedupKeyVectors ? this.keyVectorLookup[keyVectorHash] : this.createVector(stackPointer.stackPosition, vecLength, 2);
+        var valuesStackValue = this.createVector(stackPointer.stackPosition + 1, vecLength, 2, keysStackValue);
+        this.stack.splice(stackPointer.stackPosition, vecLength << 1);
+        this.stack.push(valuesStackValue);
+    };
+    Builder.prototype.sort = function (stackPointer) {
+        var view = this.view;
+        var stack = this.stack;
+        function shouldFlip(v1, v2) {
+            if (v1.type !== value_type_1.ValueType.KEY || v2.type !== value_type_1.ValueType.KEY) {
+                throw "Stack values are not keys " + v1 + " | " + v2 + ". Check if you combined [addKey] with add... method calls properly.";
+            }
+            var c1, c2;
+            var index = 0;
+            do {
+                c1 = view.getUint8(v1.offset + index);
+                c2 = view.getUint8(v2.offset + index);
+                if (c2 < c1)
+                    return true;
+                if (c1 < c2)
+                    return false;
+                index += 1;
+            } while (c1 !== 0 && c2 !== 0);
+            return false;
+        }
+        function swap(stack, flipIndex, i) {
+            if (flipIndex === i)
+                return;
+            var k = stack[flipIndex];
+            var v = stack[flipIndex + 1];
+            stack[flipIndex] = stack[i];
+            stack[flipIndex + 1] = stack[i + 1];
+            stack[i] = k;
+            stack[i + 1] = v;
+        }
+        function selectionSort() {
+            for (var i = stackPointer.stackPosition; i < stack.length; i += 2) {
+                var flipIndex = i;
+                for (var j = i + 2; j < stack.length; j += 2) {
+                    if (shouldFlip(stack[flipIndex], stack[j])) {
+                        flipIndex = j;
+                    }
+                }
+                if (flipIndex !== i) {
+                    swap(stack, flipIndex, i);
+                }
+            }
+        }
+        function smaller(v1, v2) {
+            if (v1.type !== value_type_1.ValueType.KEY || v2.type !== value_type_1.ValueType.KEY) {
+                throw "Stack values are not keys " + v1 + " | " + v2 + ". Check if you combined [addKey] with add... method calls properly.";
+            }
+            if (v1.offset === v2.offset) {
+                return false;
+            }
+            var c1, c2;
+            var index = 0;
+            do {
+                c1 = view.getUint8(v1.offset + index);
+                c2 = view.getUint8(v2.offset + index);
+                if (c1 < c2)
+                    return true;
+                if (c2 < c1)
+                    return false;
+                index += 1;
+            } while (c1 !== 0 && c2 !== 0);
+            return false;
+        }
+        function quickSort(left, right) {
+            if (left < right) {
+                var mid = left + (((right - left) >> 2)) * 2;
+                var pivot = stack[mid];
+                var left_new = left;
+                var right_new = right;
+                do {
+                    while (smaller(stack[left_new], pivot)) {
+                        left_new += 2;
+                    }
+                    while (smaller(pivot, stack[right_new])) {
+                        right_new -= 2;
+                    }
+                    if (left_new <= right_new) {
+                        swap(stack, left_new, right_new);
+                        left_new += 2;
+                        right_new -= 2;
+                    }
+                } while (left_new <= right_new);
+                quickSort(left, right_new);
+                quickSort(left_new, right);
+            }
+        }
+        var sorted = true;
+        for (var i = stackPointer.stackPosition; i < this.stack.length - 2; i += 2) {
+            if (shouldFlip(this.stack[i], this.stack[i + 2])) {
+                sorted = false;
+                break;
+            }
+        }
+        if (!sorted) {
+            if (this.stack.length - stackPointer.stackPosition > 40) {
+                quickSort(stackPointer.stackPosition, this.stack.length - 2);
+            }
+            else {
+                selectionSort();
+            }
+        }
+    };
+    Builder.prototype.end = function () {
+        if (this.stackPointers.length < 1)
+            return;
+        var pointer = this.stackPointers.pop();
+        if (pointer.isVector) {
+            this.endVector(pointer);
+        }
+        else {
+            this.endMap(pointer);
+        }
+    };
+    Builder.prototype.createVector = function (start, vecLength, step, keys) {
+        if (keys === void 0) { keys = null; }
+        var bitWidth = bit_width_util_1.uwidth(vecLength);
+        var prefixElements = 1;
+        if (keys !== null) {
+            var elementWidth = keys.elementWidth(this.offset, 0);
+            if (elementWidth > bitWidth) {
+                bitWidth = elementWidth;
+            }
+            prefixElements += 2;
+        }
+        var vectorType = value_type_1.ValueType.KEY;
+        var typed = keys === null;
+        for (var i = start; i < this.stack.length; i += step) {
+            var elementWidth = this.stack[i].elementWidth(this.offset, i + prefixElements);
+            if (elementWidth > bitWidth) {
+                bitWidth = elementWidth;
+            }
+            if (i === start) {
+                vectorType = this.stack[i].type;
+                typed = typed && value_type_util_1.isTypedVectorElement(vectorType);
+            }
+            else {
+                if (vectorType !== this.stack[i].type) {
+                    typed = false;
+                }
+            }
+        }
+        var byteWidth = this.align(bitWidth);
+        var fix = typed && value_type_util_1.isNumber(vectorType) && vecLength >= 2 && vecLength <= 4;
+        if (keys !== null) {
+            this.writeStackValue(keys, byteWidth);
+            this.writeUInt(1 << keys.width, byteWidth);
+        }
+        if (!fix) {
+            this.writeUInt(vecLength, byteWidth);
+        }
+        var vecOffset = this.offset;
+        for (var i = start; i < this.stack.length; i += step) {
+            this.writeStackValue(this.stack[i], byteWidth);
+        }
+        if (!typed) {
+            for (var i = start; i < this.stack.length; i += step) {
+                this.writeUInt(this.stack[i].storedPackedType(), 1);
+            }
+        }
+        if (keys !== null) {
+            return this.offsetStackValue(vecOffset, value_type_1.ValueType.MAP, bitWidth);
+        }
+        if (typed) {
+            var vType = value_type_util_1.toTypedVector(vectorType, fix ? vecLength : 0);
+            return this.offsetStackValue(vecOffset, vType, bitWidth);
+        }
+        return this.offsetStackValue(vecOffset, value_type_1.ValueType.VECTOR, bitWidth);
+    };
+    Builder.prototype.nullStackValue = function () {
+        return new stack_value_1.StackValue(this, value_type_1.ValueType.NULL, bit_width_1.BitWidth.WIDTH8);
+    };
+    Builder.prototype.boolStackValue = function (value) {
+        return new stack_value_1.StackValue(this, value_type_1.ValueType.BOOL, bit_width_1.BitWidth.WIDTH8, value);
+    };
+    Builder.prototype.intStackValue = function (value) {
+        return new stack_value_1.StackValue(this, value_type_1.ValueType.INT, bit_width_util_1.iwidth(value), value);
+    };
+    Builder.prototype.uintStackValue = function (value) {
+        return new stack_value_1.StackValue(this, value_type_1.ValueType.UINT, bit_width_util_1.uwidth(value), value);
+    };
+    Builder.prototype.floatStackValue = function (value) {
+        return new stack_value_1.StackValue(this, value_type_1.ValueType.FLOAT, bit_width_util_1.fwidth(value), value);
+    };
+    Builder.prototype.offsetStackValue = function (offset, valueType, bitWidth) {
+        return new stack_value_1.StackValue(this, valueType, bitWidth, null, offset);
+    };
+    Builder.prototype.finishBuffer = function () {
+        if (this.stack.length !== 1) {
+            throw "Stack has to be exactly 1, but it is " + this.stack.length + ". You have to end all started vectors and maps before calling [finish]";
+        }
+        var value = this.stack[0];
+        var byteWidth = this.align(value.elementWidth(this.offset, 0));
+        this.writeStackValue(value, byteWidth);
+        this.writeUInt(value.storedPackedType(), 1);
+        this.writeUInt(byteWidth, 1);
+        this.finished = true;
+    };
+    Builder.prototype.add = function (value) {
+        this.integrityCheckOnValueAddition();
+        if (typeof value === 'undefined') {
+            throw "You need to provide a value";
+        }
+        if (value === null) {
+            this.stack.push(this.nullStackValue());
+        }
+        else if (typeof value === "boolean") {
+            this.stack.push(this.boolStackValue(value));
+        }
+        else if (typeof value === "bigint") {
+            this.stack.push(this.intStackValue(value));
+        }
+        else if (typeof value == 'number') {
+            if (Number.isInteger(value)) {
+                this.stack.push(this.intStackValue(value));
+            }
+            else {
+                this.stack.push(this.floatStackValue(value));
+            }
+        }
+        else if (ArrayBuffer.isView(value)) {
+            this.writeBlob(value.buffer);
+        }
+        else if (typeof value === 'string' || value instanceof String) {
+            this.writeString(value);
+        }
+        else if (Array.isArray(value)) {
+            this.startVector();
+            for (var i = 0; i < value.length; i++) {
+                this.add(value[i]);
+            }
+            this.end();
+        }
+        else if (typeof value === 'object') {
+            var properties = Object.getOwnPropertyNames(value).sort();
+            this.startMap(true);
+            for (var i = 0; i < properties.length; i++) {
+                var key = properties[i];
+                this.addKey(key);
+                this.add(value[key]);
+            }
+            this.end();
+        }
+        else {
+            throw "Unexpected value input " + value;
+        }
+    };
+    Builder.prototype.finish = function () {
+        if (!this.finished) {
+            this.finishBuffer();
+        }
+        var result = this.buffer.slice(0, this.offset);
+        return new Uint8Array(result);
+    };
+    Builder.prototype.isFinished = function () {
+        return this.finished;
+    };
+    Builder.prototype.addKey = function (key) {
+        this.integrityCheckOnKeyAddition();
+        this.writeKey(key);
+    };
+    Builder.prototype.addInt = function (value, indirect, deduplicate) {
+        if (indirect === void 0) { indirect = false; }
+        if (deduplicate === void 0) { deduplicate = false; }
+        this.integrityCheckOnValueAddition();
+        if (!indirect) {
+            this.stack.push(this.intStackValue(value));
+            return;
+        }
+        if (deduplicate && Object.prototype.hasOwnProperty.call(this.indirectIntLookup, value)) {
+            this.stack.push(this.indirectIntLookup[value]);
+            return;
+        }
+        var stackValue = this.intStackValue(value);
+        var byteWidth = this.align(stackValue.width);
+        var newOffset = this.computeOffset(byteWidth);
+        var valueOffset = this.offset;
+        stackValue.writeToBuffer(byteWidth);
+        var stackOffset = this.offsetStackValue(valueOffset, value_type_1.ValueType.INDIRECT_INT, stackValue.width);
+        this.stack.push(stackOffset);
+        this.offset = newOffset;
+        if (deduplicate) {
+            this.indirectIntLookup[value] = stackOffset;
+        }
+    };
+    Builder.prototype.addUInt = function (value, indirect, deduplicate) {
+        if (indirect === void 0) { indirect = false; }
+        if (deduplicate === void 0) { deduplicate = false; }
+        this.integrityCheckOnValueAddition();
+        if (!indirect) {
+            this.stack.push(this.uintStackValue(value));
+            return;
+        }
+        if (deduplicate && Object.prototype.hasOwnProperty.call(this.indirectUIntLookup, value)) {
+            this.stack.push(this.indirectUIntLookup[value]);
+            return;
+        }
+        var stackValue = this.uintStackValue(value);
+        var byteWidth = this.align(stackValue.width);
+        var newOffset = this.computeOffset(byteWidth);
+        var valueOffset = this.offset;
+        stackValue.writeToBuffer(byteWidth);
+        var stackOffset = this.offsetStackValue(valueOffset, value_type_1.ValueType.INDIRECT_UINT, stackValue.width);
+        this.stack.push(stackOffset);
+        this.offset = newOffset;
+        if (deduplicate) {
+            this.indirectUIntLookup[value] = stackOffset;
+        }
+    };
+    Builder.prototype.addFloat = function (value, indirect, deduplicate) {
+        if (indirect === void 0) { indirect = false; }
+        if (deduplicate === void 0) { deduplicate = false; }
+        this.integrityCheckOnValueAddition();
+        if (!indirect) {
+            this.stack.push(this.floatStackValue(value));
+            return;
+        }
+        if (deduplicate && Object.prototype.hasOwnProperty.call(this.indirectFloatLookup, value)) {
+            this.stack.push(this.indirectFloatLookup[value]);
+            return;
+        }
+        var stackValue = this.floatStackValue(value);
+        var byteWidth = this.align(stackValue.width);
+        var newOffset = this.computeOffset(byteWidth);
+        var valueOffset = this.offset;
+        stackValue.writeToBuffer(byteWidth);
+        var stackOffset = this.offsetStackValue(valueOffset, value_type_1.ValueType.INDIRECT_FLOAT, stackValue.width);
+        this.stack.push(stackOffset);
+        this.offset = newOffset;
+        if (deduplicate) {
+            this.indirectFloatLookup[value] = stackOffset;
+        }
+    };
+    return Builder;
+}());
+exports.Builder = Builder;
diff --git a/third_party/flatbuffers/js/flexbuffers/flexbuffers-util.js b/third_party/flatbuffers/js/flexbuffers/flexbuffers-util.js
new file mode 100644
index 0000000..0d4e166
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers/flexbuffers-util.js
@@ -0,0 +1,13 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.toUTF8Array = exports.fromUTF8Array = void 0;
+function fromUTF8Array(data) {
+    var decoder = new TextDecoder();
+    return decoder.decode(data);
+}
+exports.fromUTF8Array = fromUTF8Array;
+function toUTF8Array(str) {
+    var encoder = new TextEncoder();
+    return encoder.encode(str);
+}
+exports.toUTF8Array = toUTF8Array;
diff --git a/third_party/flatbuffers/js/flexbuffers/reference-util.js b/third_party/flatbuffers/js/flexbuffers/reference-util.js
new file mode 100644
index 0000000..fc035b9
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers/reference-util.js
@@ -0,0 +1,129 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.keyForIndex = exports.valueForIndexWithKey = exports.diffKeys = exports.keyIndex = exports.indirect = exports.readFloat = exports.readUInt = exports.readInt = exports.validateOffset = void 0;
+var bit_width_1 = require("./bit-width");
+var bit_width_util_1 = require("./bit-width-util");
+var flexbuffers_util_1 = require("./flexbuffers-util");
+var reference_1 = require("./reference");
+var long_1 = require("../long");
+function validateOffset(dataView, offset, width) {
+    if (dataView.byteLength <= offset + width || (offset & (bit_width_util_1.toByteWidth(width) - 1)) !== 0) {
+        throw "Bad offset: " + offset + ", width: " + width;
+    }
+}
+exports.validateOffset = validateOffset;
+function readInt(dataView, offset, width) {
+    if (width < 2) {
+        if (width < 1) {
+            return dataView.getInt8(offset);
+        }
+        else {
+            return dataView.getInt16(offset, true);
+        }
+    }
+    else {
+        if (width < 3) {
+            return dataView.getInt32(offset, true);
+        }
+        else {
+            if (dataView.setBigInt64 === undefined) {
+                return new long_1.Long(dataView.getUint32(offset, true), dataView.getUint32(offset + 4, true));
+            }
+            return dataView.getBigInt64(offset, true);
+        }
+    }
+}
+exports.readInt = readInt;
+function readUInt(dataView, offset, width) {
+    if (width < 2) {
+        if (width < 1) {
+            return dataView.getUint8(offset);
+        }
+        else {
+            return dataView.getUint16(offset, true);
+        }
+    }
+    else {
+        if (width < 3) {
+            return dataView.getUint32(offset, true);
+        }
+        else {
+            if (dataView.getBigUint64 === undefined) {
+                return new long_1.Long(dataView.getUint32(offset, true), dataView.getUint32(offset + 4, true));
+            }
+            return dataView.getBigUint64(offset, true);
+        }
+    }
+}
+exports.readUInt = readUInt;
+function readFloat(dataView, offset, width) {
+    if (width < bit_width_1.BitWidth.WIDTH32) {
+        throw "Bad width: " + width;
+    }
+    if (width === bit_width_1.BitWidth.WIDTH32) {
+        return dataView.getFloat32(offset, true);
+    }
+    return dataView.getFloat64(offset, true);
+}
+exports.readFloat = readFloat;
+function indirect(dataView, offset, width) {
+    var step = readUInt(dataView, offset, width);
+    return offset - step;
+}
+exports.indirect = indirect;
+function keyIndex(key, dataView, offset, parentWidth, byteWidth, length) {
+    var input = flexbuffers_util_1.toUTF8Array(key);
+    var keysVectorOffset = indirect(dataView, offset, parentWidth) - byteWidth * 3;
+    var bitWidth = bit_width_util_1.fromByteWidth(byteWidth);
+    var indirectOffset = keysVectorOffset - readUInt(dataView, keysVectorOffset, bitWidth);
+    var _byteWidth = readUInt(dataView, keysVectorOffset + byteWidth, bitWidth);
+    var low = 0;
+    var high = length - 1;
+    while (low <= high) {
+        var mid = (high + low) >> 1;
+        var dif = diffKeys(input, mid, dataView, indirectOffset, _byteWidth);
+        if (dif === 0)
+            return mid;
+        if (dif < 0) {
+            high = mid - 1;
+        }
+        else {
+            low = mid + 1;
+        }
+    }
+    return null;
+}
+exports.keyIndex = keyIndex;
+function diffKeys(input, index, dataView, offset, width) {
+    var keyOffset = offset + index * width;
+    var keyIndirectOffset = keyOffset - readUInt(dataView, keyOffset, bit_width_util_1.fromByteWidth(width));
+    for (var i = 0; i < input.length; i++) {
+        var dif = input[i] - dataView.getUint8(keyIndirectOffset + i);
+        if (dif !== 0) {
+            return dif;
+        }
+    }
+    return dataView.getUint8(keyIndirectOffset + input.length) === 0 ? 0 : -1;
+}
+exports.diffKeys = diffKeys;
+function valueForIndexWithKey(index, key, dataView, offset, parentWidth, byteWidth, length, path) {
+    var _indirect = indirect(dataView, offset, parentWidth);
+    var elementOffset = _indirect + index * byteWidth;
+    var packedType = dataView.getUint8(_indirect + length * byteWidth + index);
+    return new reference_1.Reference(dataView, elementOffset, bit_width_util_1.fromByteWidth(byteWidth), packedType, path + "/" + key);
+}
+exports.valueForIndexWithKey = valueForIndexWithKey;
+function keyForIndex(index, dataView, offset, parentWidth, byteWidth) {
+    var keysVectorOffset = indirect(dataView, offset, parentWidth) - byteWidth * 3;
+    var bitWidth = bit_width_util_1.fromByteWidth(byteWidth);
+    var indirectOffset = keysVectorOffset - readUInt(dataView, keysVectorOffset, bitWidth);
+    var _byteWidth = readUInt(dataView, keysVectorOffset + byteWidth, bitWidth);
+    var keyOffset = indirectOffset + index * _byteWidth;
+    var keyIndirectOffset = keyOffset - readUInt(dataView, keyOffset, bit_width_util_1.fromByteWidth(_byteWidth));
+    var length = 0;
+    while (dataView.getUint8(keyIndirectOffset + length) !== 0) {
+        length++;
+    }
+    return flexbuffers_util_1.fromUTF8Array(new Uint8Array(dataView.buffer, keyIndirectOffset, length));
+}
+exports.keyForIndex = keyForIndex;
diff --git a/third_party/flatbuffers/js/flexbuffers/reference.js b/third_party/flatbuffers/js/flexbuffers/reference.js
new file mode 100644
index 0000000..748d2b7
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers/reference.js
@@ -0,0 +1,184 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Reference = exports.toReference = void 0;
+var bit_width_util_1 = require("./bit-width-util");
+var value_type_1 = require("./value-type");
+var value_type_util_1 = require("./value-type-util");
+var reference_util_1 = require("./reference-util");
+var flexbuffers_util_1 = require("./flexbuffers-util");
+var bit_width_1 = require("./bit-width");
+function toReference(buffer) {
+    var len = buffer.byteLength;
+    if (len < 3) {
+        throw "Buffer needs to be bigger than 3";
+    }
+    var dataView = new DataView(buffer);
+    var byteWidth = dataView.getUint8(len - 1);
+    var packedType = dataView.getUint8(len - 2);
+    var parentWidth = bit_width_util_1.fromByteWidth(byteWidth);
+    var offset = len - byteWidth - 2;
+    return new Reference(dataView, offset, parentWidth, packedType, "/");
+}
+exports.toReference = toReference;
+var Reference = /** @class */ (function () {
+    function Reference(dataView, offset, parentWidth, packedType, path) {
+        this.dataView = dataView;
+        this.offset = offset;
+        this.parentWidth = parentWidth;
+        this.packedType = packedType;
+        this.path = path;
+        this._length = -1;
+        this.byteWidth = 1 << (packedType & 3);
+        this.valueType = packedType >> 2;
+    }
+    Reference.prototype.isNull = function () { return this.valueType === value_type_1.ValueType.NULL; };
+    Reference.prototype.isNumber = function () { return value_type_util_1.isNumber(this.valueType) || value_type_util_1.isIndirectNumber(this.valueType); };
+    Reference.prototype.isFloat = function () { return value_type_1.ValueType.FLOAT === this.valueType || value_type_1.ValueType.INDIRECT_FLOAT === this.valueType; };
+    Reference.prototype.isInt = function () { return this.isNumber() && !this.isFloat(); };
+    Reference.prototype.isString = function () { return value_type_1.ValueType.STRING === this.valueType || value_type_1.ValueType.KEY === this.valueType; };
+    Reference.prototype.isBool = function () { return value_type_1.ValueType.BOOL === this.valueType; };
+    Reference.prototype.isBlob = function () { return value_type_1.ValueType.BLOB === this.valueType; };
+    Reference.prototype.isVector = function () { return value_type_util_1.isAVector(this.valueType); };
+    Reference.prototype.isMap = function () { return value_type_1.ValueType.MAP === this.valueType; };
+    Reference.prototype.boolValue = function () {
+        if (this.isBool()) {
+            return reference_util_1.readInt(this.dataView, this.offset, this.parentWidth) > 0;
+        }
+        return null;
+    };
+    Reference.prototype.intValue = function () {
+        if (this.valueType === value_type_1.ValueType.INT) {
+            return reference_util_1.readInt(this.dataView, this.offset, this.parentWidth);
+        }
+        if (this.valueType === value_type_1.ValueType.UINT) {
+            return reference_util_1.readUInt(this.dataView, this.offset, this.parentWidth);
+        }
+        if (this.valueType === value_type_1.ValueType.INDIRECT_INT) {
+            return reference_util_1.readInt(this.dataView, reference_util_1.indirect(this.dataView, this.offset, this.parentWidth), bit_width_util_1.fromByteWidth(this.byteWidth));
+        }
+        if (this.valueType === value_type_1.ValueType.INDIRECT_UINT) {
+            return reference_util_1.readUInt(this.dataView, reference_util_1.indirect(this.dataView, this.offset, this.parentWidth), bit_width_util_1.fromByteWidth(this.byteWidth));
+        }
+        return null;
+    };
+    Reference.prototype.floatValue = function () {
+        if (this.valueType === value_type_1.ValueType.FLOAT) {
+            return reference_util_1.readFloat(this.dataView, this.offset, this.parentWidth);
+        }
+        if (this.valueType === value_type_1.ValueType.INDIRECT_FLOAT) {
+            return reference_util_1.readFloat(this.dataView, reference_util_1.indirect(this.dataView, this.offset, this.parentWidth), bit_width_util_1.fromByteWidth(this.byteWidth));
+        }
+        return null;
+    };
+    Reference.prototype.numericValue = function () { return this.floatValue() || this.intValue(); };
+    Reference.prototype.stringValue = function () {
+        if (this.valueType === value_type_1.ValueType.STRING || this.valueType === value_type_1.ValueType.KEY) {
+            var begin = reference_util_1.indirect(this.dataView, this.offset, this.parentWidth);
+            return flexbuffers_util_1.fromUTF8Array(new Uint8Array(this.dataView.buffer, begin, this.length()));
+        }
+        return null;
+    };
+    Reference.prototype.blobValue = function () {
+        if (this.isBlob()) {
+            var begin = reference_util_1.indirect(this.dataView, this.offset, this.parentWidth);
+            return new Uint8Array(this.dataView.buffer, begin, this.length());
+        }
+        return null;
+    };
+    Reference.prototype.get = function (key) {
+        var length = this.length();
+        if (Number.isInteger(key) && value_type_util_1.isAVector(this.valueType)) {
+            if (key >= length || key < 0) {
+                throw "Key: [" + key + "] is not applicable on " + this.path + " of " + this.valueType + " length: " + length;
+            }
+            var _indirect = reference_util_1.indirect(this.dataView, this.offset, this.parentWidth);
+            var elementOffset = _indirect + key * this.byteWidth;
+            var _packedType = this.dataView.getUint8(_indirect + length * this.byteWidth + key);
+            if (value_type_util_1.isTypedVector(this.valueType)) {
+                var _valueType = value_type_util_1.typedVectorElementType(this.valueType);
+                _packedType = value_type_util_1.packedType(_valueType, bit_width_1.BitWidth.WIDTH8);
+            }
+            else if (value_type_util_1.isFixedTypedVector(this.valueType)) {
+                var _valueType = value_type_util_1.fixedTypedVectorElementType(this.valueType);
+                _packedType = value_type_util_1.packedType(_valueType, bit_width_1.BitWidth.WIDTH8);
+            }
+            return new Reference(this.dataView, elementOffset, bit_width_util_1.fromByteWidth(this.byteWidth), _packedType, this.path + "[" + key + "]");
+        }
+        if (typeof key === 'string') {
+            var index = reference_util_1.keyIndex(key, this.dataView, this.offset, this.parentWidth, this.byteWidth, length);
+            if (index !== null) {
+                return reference_util_1.valueForIndexWithKey(index, key, this.dataView, this.offset, this.parentWidth, this.byteWidth, length, this.path);
+            }
+        }
+        throw "Key [" + key + "] is not applicable on " + this.path + " of " + this.valueType;
+    };
+    Reference.prototype.length = function () {
+        var size;
+        if (this._length > -1) {
+            return this._length;
+        }
+        if (value_type_util_1.isFixedTypedVector(this.valueType)) {
+            this._length = value_type_util_1.fixedTypedVectorElementSize(this.valueType);
+        }
+        else if (this.valueType === value_type_1.ValueType.BLOB
+            || this.valueType === value_type_1.ValueType.MAP
+            || value_type_util_1.isAVector(this.valueType)) {
+            this._length = reference_util_1.readUInt(this.dataView, reference_util_1.indirect(this.dataView, this.offset, this.parentWidth) - this.byteWidth, bit_width_util_1.fromByteWidth(this.byteWidth));
+        }
+        else if (this.valueType === value_type_1.ValueType.NULL) {
+            this._length = 0;
+        }
+        else if (this.valueType === value_type_1.ValueType.STRING) {
+            var _indirect = reference_util_1.indirect(this.dataView, this.offset, this.parentWidth);
+            var sizeByteWidth = this.byteWidth;
+            size = reference_util_1.readUInt(this.dataView, _indirect - sizeByteWidth, bit_width_util_1.fromByteWidth(this.byteWidth));
+            while (this.dataView.getInt8(_indirect + size) !== 0) {
+                sizeByteWidth <<= 1;
+                size = reference_util_1.readUInt(this.dataView, _indirect - sizeByteWidth, bit_width_util_1.fromByteWidth(this.byteWidth));
+            }
+            this._length = size;
+        }
+        else if (this.valueType === value_type_1.ValueType.KEY) {
+            var _indirect = reference_util_1.indirect(this.dataView, this.offset, this.parentWidth);
+            size = 1;
+            while (this.dataView.getInt8(_indirect + size) !== 0) {
+                size++;
+            }
+            this._length = size;
+        }
+        else {
+            this._length = 1;
+        }
+        return this._length;
+    };
+    Reference.prototype.toObject = function () {
+        var length = this.length();
+        if (this.isVector()) {
+            var result = [];
+            for (var i = 0; i < length; i++) {
+                result.push(this.get(i).toObject());
+            }
+            return result;
+        }
+        if (this.isMap()) {
+            var result = {};
+            for (var i = 0; i < length; i++) {
+                var key = reference_util_1.keyForIndex(i, this.dataView, this.offset, this.parentWidth, this.byteWidth);
+                result[key] = reference_util_1.valueForIndexWithKey(i, key, this.dataView, this.offset, this.parentWidth, this.byteWidth, length, this.path).toObject();
+            }
+            return result;
+        }
+        if (this.isNull()) {
+            return null;
+        }
+        if (this.isBool()) {
+            return this.boolValue();
+        }
+        if (this.isNumber()) {
+            return this.numericValue();
+        }
+        return this.blobValue() || this.stringValue();
+    };
+    return Reference;
+}());
+exports.Reference = Reference;
diff --git a/third_party/flatbuffers/js/flexbuffers/stack-value.js b/third_party/flatbuffers/js/flexbuffers/stack-value.js
new file mode 100644
index 0000000..98ca482
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers/stack-value.js
@@ -0,0 +1,74 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.StackValue = void 0;
+var bit_width_1 = require("./bit-width");
+var bit_width_util_1 = require("./bit-width-util");
+var value_type_1 = require("./value-type");
+var value_type_util_1 = require("./value-type-util");
+var StackValue = /** @class */ (function () {
+    function StackValue(builder, type, width, value, offset) {
+        if (value === void 0) { value = null; }
+        if (offset === void 0) { offset = 0; }
+        this.builder = builder;
+        this.type = type;
+        this.width = width;
+        this.value = value;
+        this.offset = offset;
+    }
+    StackValue.prototype.elementWidth = function (size, index) {
+        if (value_type_util_1.isInline(this.type))
+            return this.width;
+        for (var i = 0; i < 4; i++) {
+            var width = 1 << i;
+            var offsetLoc = size + bit_width_util_1.paddingSize(size, width) + index * width;
+            var offset = offsetLoc - this.offset;
+            var bitWidth = bit_width_util_1.uwidth(offset);
+            if (1 << bitWidth === width) {
+                return bitWidth;
+            }
+        }
+        throw "Element is unknown. Size: " + size + " at index: " + index + ". This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new";
+    };
+    StackValue.prototype.writeToBuffer = function (byteWidth) {
+        var newOffset = this.builder.computeOffset(byteWidth);
+        if (this.type === value_type_1.ValueType.FLOAT) {
+            if (this.width === bit_width_1.BitWidth.WIDTH32) {
+                this.builder.view.setFloat32(this.builder.offset, this.value, true);
+            }
+            else {
+                this.builder.view.setFloat64(this.builder.offset, this.value, true);
+            }
+        }
+        else if (this.type === value_type_1.ValueType.INT) {
+            var bitWidth = bit_width_util_1.fromByteWidth(byteWidth);
+            this.builder.pushInt(this.value, bitWidth);
+        }
+        else if (this.type === value_type_1.ValueType.UINT) {
+            var bitWidth = bit_width_util_1.fromByteWidth(byteWidth);
+            this.builder.pushUInt(this.value, bitWidth);
+        }
+        else if (this.type === value_type_1.ValueType.NULL) {
+            this.builder.pushInt(0, this.width);
+        }
+        else if (this.type === value_type_1.ValueType.BOOL) {
+            this.builder.pushInt(this.value ? 1 : 0, this.width);
+        }
+        else {
+            throw "Unexpected type: " + this.type + ". This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new";
+        }
+        this.offset = newOffset;
+    };
+    StackValue.prototype.storedWidth = function (width) {
+        if (width === void 0) { width = bit_width_1.BitWidth.WIDTH8; }
+        return value_type_util_1.isInline(this.type) ? Math.max(width, this.width) : this.width;
+    };
+    StackValue.prototype.storedPackedType = function (width) {
+        if (width === void 0) { width = bit_width_1.BitWidth.WIDTH8; }
+        return value_type_util_1.packedType(this.type, this.storedWidth(width));
+    };
+    StackValue.prototype.isOffset = function () {
+        return !value_type_util_1.isInline(this.type);
+    };
+    return StackValue;
+}());
+exports.StackValue = StackValue;
diff --git a/third_party/flatbuffers/js/flexbuffers/value-type-util.js b/third_party/flatbuffers/js/flexbuffers/value-type-util.js
new file mode 100644
index 0000000..996a6e9
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers/value-type-util.js
@@ -0,0 +1,71 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.packedType = exports.fixedTypedVectorElementSize = exports.fixedTypedVectorElementType = exports.typedVectorElementType = exports.toTypedVector = exports.isAVector = exports.isFixedTypedVector = exports.isTypedVector = exports.isTypedVectorElement = exports.isIndirectNumber = exports.isNumber = exports.isInline = void 0;
+var value_type_1 = require("./value-type");
+function isInline(value) {
+    return value === value_type_1.ValueType.BOOL
+        || value <= value_type_1.ValueType.FLOAT;
+}
+exports.isInline = isInline;
+function isNumber(value) {
+    return value >= value_type_1.ValueType.INT
+        && value <= value_type_1.ValueType.FLOAT;
+}
+exports.isNumber = isNumber;
+function isIndirectNumber(value) {
+    return value >= value_type_1.ValueType.INDIRECT_INT
+        && value <= value_type_1.ValueType.INDIRECT_FLOAT;
+}
+exports.isIndirectNumber = isIndirectNumber;
+function isTypedVectorElement(value) {
+    return value === value_type_1.ValueType.BOOL
+        || (value >= value_type_1.ValueType.INT
+            && value <= value_type_1.ValueType.STRING);
+}
+exports.isTypedVectorElement = isTypedVectorElement;
+function isTypedVector(value) {
+    return value === value_type_1.ValueType.VECTOR_BOOL
+        || (value >= value_type_1.ValueType.VECTOR_INT
+            && value <= value_type_1.ValueType.VECTOR_STRING_DEPRECATED);
+}
+exports.isTypedVector = isTypedVector;
+function isFixedTypedVector(value) {
+    return value >= value_type_1.ValueType.VECTOR_INT2
+        && value <= value_type_1.ValueType.VECTOR_FLOAT4;
+}
+exports.isFixedTypedVector = isFixedTypedVector;
+function isAVector(value) {
+    return isTypedVector(value)
+        || isFixedTypedVector(value)
+        || value === value_type_1.ValueType.VECTOR;
+}
+exports.isAVector = isAVector;
+function toTypedVector(valueType, length) {
+    if (length === 0)
+        return valueType - value_type_1.ValueType.INT + value_type_1.ValueType.VECTOR_INT;
+    if (length === 2)
+        return valueType - value_type_1.ValueType.INT + value_type_1.ValueType.VECTOR_INT2;
+    if (length === 3)
+        return valueType - value_type_1.ValueType.INT + value_type_1.ValueType.VECTOR_INT3;
+    if (length === 4)
+        return valueType - value_type_1.ValueType.INT + value_type_1.ValueType.VECTOR_INT4;
+    throw "Unexpected length " + length;
+}
+exports.toTypedVector = toTypedVector;
+function typedVectorElementType(valueType) {
+    return valueType - value_type_1.ValueType.VECTOR_INT + value_type_1.ValueType.INT;
+}
+exports.typedVectorElementType = typedVectorElementType;
+function fixedTypedVectorElementType(valueType) {
+    return ((valueType - value_type_1.ValueType.VECTOR_INT2) % 3) + value_type_1.ValueType.INT;
+}
+exports.fixedTypedVectorElementType = fixedTypedVectorElementType;
+function fixedTypedVectorElementSize(valueType) {
+    // The x / y >> 0 trick is to have an int division. Suppose to be faster than Math.floor()
+    return (((valueType - value_type_1.ValueType.VECTOR_INT2) / 3) >> 0) + 2;
+}
+exports.fixedTypedVectorElementSize = fixedTypedVectorElementSize;
+function packedType(valueType, bitWidth) {
+    return bitWidth | (valueType << 2);
+}
+exports.packedType = packedType;
diff --git a/third_party/flatbuffers/js/flexbuffers/value-type.js b/third_party/flatbuffers/js/flexbuffers/value-type.js
new file mode 100644
index 0000000..0ffbf1f
--- /dev/null
+++ b/third_party/flatbuffers/js/flexbuffers/value-type.js
@@ -0,0 +1,34 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ValueType = void 0;
+var ValueType;
+(function (ValueType) {
+    ValueType[ValueType["NULL"] = 0] = "NULL";
+    ValueType[ValueType["INT"] = 1] = "INT";
+    ValueType[ValueType["UINT"] = 2] = "UINT";
+    ValueType[ValueType["FLOAT"] = 3] = "FLOAT";
+    ValueType[ValueType["KEY"] = 4] = "KEY";
+    ValueType[ValueType["STRING"] = 5] = "STRING";
+    ValueType[ValueType["INDIRECT_INT"] = 6] = "INDIRECT_INT";
+    ValueType[ValueType["INDIRECT_UINT"] = 7] = "INDIRECT_UINT";
+    ValueType[ValueType["INDIRECT_FLOAT"] = 8] = "INDIRECT_FLOAT";
+    ValueType[ValueType["MAP"] = 9] = "MAP";
+    ValueType[ValueType["VECTOR"] = 10] = "VECTOR";
+    ValueType[ValueType["VECTOR_INT"] = 11] = "VECTOR_INT";
+    ValueType[ValueType["VECTOR_UINT"] = 12] = "VECTOR_UINT";
+    ValueType[ValueType["VECTOR_FLOAT"] = 13] = "VECTOR_FLOAT";
+    ValueType[ValueType["VECTOR_KEY"] = 14] = "VECTOR_KEY";
+    ValueType[ValueType["VECTOR_STRING_DEPRECATED"] = 15] = "VECTOR_STRING_DEPRECATED";
+    ValueType[ValueType["VECTOR_INT2"] = 16] = "VECTOR_INT2";
+    ValueType[ValueType["VECTOR_UINT2"] = 17] = "VECTOR_UINT2";
+    ValueType[ValueType["VECTOR_FLOAT2"] = 18] = "VECTOR_FLOAT2";
+    ValueType[ValueType["VECTOR_INT3"] = 19] = "VECTOR_INT3";
+    ValueType[ValueType["VECTOR_UINT3"] = 20] = "VECTOR_UINT3";
+    ValueType[ValueType["VECTOR_FLOAT3"] = 21] = "VECTOR_FLOAT3";
+    ValueType[ValueType["VECTOR_INT4"] = 22] = "VECTOR_INT4";
+    ValueType[ValueType["VECTOR_UINT4"] = 23] = "VECTOR_UINT4";
+    ValueType[ValueType["VECTOR_FLOAT4"] = 24] = "VECTOR_FLOAT4";
+    ValueType[ValueType["BLOB"] = 25] = "BLOB";
+    ValueType[ValueType["BOOL"] = 26] = "BOOL";
+    ValueType[ValueType["VECTOR_BOOL"] = 36] = "VECTOR_BOOL";
+})(ValueType = exports.ValueType || (exports.ValueType = {}));
diff --git a/third_party/flatbuffers/js/long.js b/third_party/flatbuffers/js/long.js
new file mode 100644
index 0000000..9fc7e7e
--- /dev/null
+++ b/third_party/flatbuffers/js/long.js
@@ -0,0 +1,26 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Long = exports.createLong = void 0;
+function createLong(low, high) {
+    return Long.create(low, high);
+}
+exports.createLong = createLong;
+var Long = /** @class */ (function () {
+    function Long(low, high) {
+        this.low = low | 0;
+        this.high = high | 0;
+    }
+    Long.create = function (low, high) {
+        // Special-case zero to avoid GC overhead for default values
+        return low == 0 && high == 0 ? Long.ZERO : new Long(low, high);
+    };
+    Long.prototype.toFloat64 = function () {
+        return (this.low >>> 0) + this.high * 0x100000000;
+    };
+    Long.prototype.equals = function (other) {
+        return this.low == other.low && this.high == other.high;
+    };
+    Long.ZERO = new Long(0, 0);
+    return Long;
+}());
+exports.Long = Long;
diff --git a/third_party/flatbuffers/js/types.js b/third_party/flatbuffers/js/types.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/third_party/flatbuffers/js/types.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/third_party/flatbuffers/js/utils.js b/third_party/flatbuffers/js/utils.js
new file mode 100644
index 0000000..1ed60d2
--- /dev/null
+++ b/third_party/flatbuffers/js/utils.js
@@ -0,0 +1,7 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.isLittleEndian = exports.float64 = exports.float32 = exports.int32 = void 0;
+exports.int32 = new Int32Array(2);
+exports.float32 = new Float32Array(exports.int32.buffer);
+exports.float64 = new Float64Array(exports.int32.buffer);
+exports.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
